Files
freeswitch/libs/sipcc/core/ccapp/ccapi_snapshot.c
T

716 lines
28 KiB
C

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "string.h"
#include "string_lib.h"
#include "text_strings.h"
#include "ccapi_snapshot.h"
#include "ccapi_device.h"
#include "ccapi_device_listener.h"
#include "ccapi_line.h"
#include "ccapi_line_listener.h"
#include "ccapi_line_info.h"
#include "ccapi_call.h"
#include "ccapi_call_listener.h"
#include "CCProvider.h"
#include "capability_set.h"
#include "phone_debug.h"
cc_device_info_t g_deviceInfo;
accessory_cfg_info_t g_accessoryCfgInfo;
cc_line_info_t lineInfo[MAX_CONFIG_LINES+1];
cc_feature_info_t featureInfo[MAX_CONFIG_LINES+1];
static void printCallInfo(cc_callinfo_ref_t info, const char* fname);
static void printFeatureInfo (ccapi_device_event_e type, cc_featureinfo_ref_t feature_info, const char* fname);
cc_string_t lineLabels[MAX_CONFIG_LINES+1] = {0};
void ccsnap_set_line_label(int btn, cc_string_t label) {
CCAPP_ERROR(DEB_F_PREFIX"btn=%d label=%s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_set_line_label"), btn, label);
if ( btn > 0 && btn <= MAX_CONFIG_LINES+1 ) {
if ( label == NULL ) {
label = strlib_empty();
}
if ( lineLabels[btn] == NULL ) {
lineLabels[btn] = strlib_empty();
}
lineLabels[btn] = strlib_update(lineLabels[btn], label);
}
}
cc_string_t ccsnap_get_line_label(int btn) {
if ( btn > 0 && btn <= MAX_CONFIG_LINES+1 ) {
return lineLabels[btn];
}
return strlib_empty();
}
/*
* The below two functions are borrowed from CUCM/CUP as they both perform
* identical functions. That is, taking a DN 1555 and
* a mask 919476XXXX to build a true external number 9194761555.
*/
static void stringInsert(char *string, int num, char ch)
{
int len = strlen(string);
int k, j;
char tempString[100];
sstrncpy(tempString, string, 100);
for (k = 0; k < num; k++)
string[k] = ch;
for (j = 0; j < len; j++)
string[k++] = tempString[j];
string[k] = 0;
}
/*
* Taken from CUCM/CUP code as they have done this already.
*/
cc_string_t CCAPI_ApplyTranslationMask (const char *ext, const char *mask)
{
char translationMask[100] = {'\0'};
char dn[100] = {'\0'};
char translatedString[100] = {'\0'};
cc_string_t result;
unsigned int maskLen,
dnLen,
i, j = 0;
if ((ext == NULL) || (mask == NULL)) {
return NULL;
}
maskLen = strlen(mask);
dnLen = strlen(ext);
if ((dnLen == 0) || (maskLen == 0)) {
CCAPP_DEBUG(DEB_F_PREFIX"CCAPI_ApplyTranslationMask DN or mask has len=0\n",
DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_ApplyTranslationMask"));
return NULL;
}
/* make sure there's enough space in the buffer to
* hold the translated string.
*/
if (dnLen + maskLen > 99) {
CCAPP_DEBUG(DEB_F_PREFIX"CCAPI_ApplyTranslationMask length overflow\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_ApplyTranslationMask"));
return NULL;
}
sstrncpy(translationMask, mask, 100);
sstrncpy(dn, ext, 100);
/* make sure DN is numeric only */
for (i=0; i< dnLen; i++) {
if (isalpha(dn[i])) {
return 0;
}
}
if (maskLen > dnLen) {
stringInsert(dn, maskLen - dnLen, '?');
}
/* if the digit string is longer than the translation mask
* prepad the translation mask with '%'.
*/
if (dnLen > maskLen) {
stringInsert(translationMask, dnLen - maskLen, '%');
}
dnLen = strlen(dn);
for (i=0; i < dnLen; i++) {
if (translationMask[i] == '%')
continue;
else if (translationMask[i] == 'X')
translatedString[j++] = dn[i];
else
translatedString[j++] = translationMask[i];
}
translatedString[j] = 0;
result = strlib_malloc(translatedString, strlen(translatedString));
return result;
}
/**
* Before initing the line_info release any memory which has been used
* so we do not leak any here.
*/
void ccsnap_line_pre_init () {
int i;
CCAPP_DEBUG(DEB_F_PREFIX"Entering line_pre_init to clear it out to avoid mem leaks\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_line_pre_init"));
for (i=1;i<MAX_CONFIG_LINES;i++) {
if ((lineInfo[i].name) && (strlen(lineInfo[i].name) > 0)) {
strlib_free(lineInfo[i].name);
}
if ((lineInfo[i].dn) && (strlen(lineInfo[i].dn) > 0)) {
strlib_free(lineInfo[i].dn);
}
if ((lineInfo[i].cfwd_dest) && (strlen(lineInfo[i].cfwd_dest) > 0)) {
strlib_free(lineInfo[i].cfwd_dest);
}
if ((lineInfo[i].externalNumber) &&
(strlen(lineInfo[i].externalNumber) > 0)) {
strlib_free(lineInfo[i].externalNumber);
}
if ((featureInfo[i].speedDialNumber) &&
(strlen(featureInfo[i].speedDialNumber) > 0)) {
strlib_free(featureInfo[i].speedDialNumber);
}
if ((featureInfo[i].contact) && (strlen(featureInfo[i].contact) > 0)) {
strlib_free(featureInfo[i].contact);
}
if ((featureInfo[i].name) && (strlen(featureInfo[i].name) > 0)) {
strlib_free(featureInfo[i].name);
}
if ((featureInfo[i].retrievalPrefix) &&
(strlen(featureInfo[i].retrievalPrefix) > 0)) {
strlib_free(featureInfo[i].retrievalPrefix);
}
}
}
/**
* Initialize lineinfo and featureinfo arrays
*/
void ccsnap_line_init() {
int i;
cc_uint32_t tmpInt;
char tempStr[MAX_URL_LENGTH];
char maskStr[MAX_EXTERNAL_NUMBER_MASK_SIZE];
/* clean up structure if need be */
ccsnap_line_pre_init();
memset(lineInfo, 0, MAX_CONFIG_LINES*sizeof(cc_line_info_t));
memset(featureInfo, 0, MAX_CONFIG_LINES*sizeof(cc_feature_info_t));
for (i=1;i<=MAX_CONFIG_LINES;i++) {
config_get_line_value(CFGID_LINE_FEATURE, &tmpInt, sizeof(tmpInt), i);
if ( tmpInt == cfgLineFeatureDN ) {
lineInfo[i].button = i;
lineInfo[i].line_type = tmpInt;
config_get_line_value(CFGID_LINE_INDEX, &tmpInt, sizeof(tmpInt), i);
lineInfo[i].line_id = tmpInt;
config_get_line_value(CFGID_LINE_DISPLAYNAME_STRING, tempStr,
MAX_URL_LENGTH, i);
lineInfo[i].dn = strlib_malloc(tempStr, strlen(tempStr));
config_get_line_value(CFGID_LINE_NAME_STRING, tempStr,
MAX_URL_LENGTH, i);
lineInfo[i].name = strlib_malloc(tempStr, strlen(tempStr));
config_get_line_value(CFGID_LINE_CFWDALL, tempStr,
MAX_URL_LENGTH, i);
lineInfo[i].cfwd_dest = strlib_malloc(tempStr, strlen(tempStr));
config_get_line_value(CFGID_LINE_SPEEDDIAL_NUMBER_STRING, tempStr,
MAX_URL_LENGTH, i);
memset(maskStr, 0, sizeof(maskStr));
config_get_string(CFGID_CCM_EXTERNAL_NUMBER_MASK, maskStr, MAX_EXTERNAL_NUMBER_MASK_SIZE);
if (strlen(maskStr) > 0) {
lineInfo[i].externalNumber = CCAPI_ApplyTranslationMask(lineInfo[i].name, maskStr);
CCAPP_DEBUG("Setting lineInfo[i].externalNumber to %s\n", lineInfo[i].externalNumber);
} else {
lineInfo[i].externalNumber = strlib_empty();
}
} else {
lineInfo[i].line_id = MAX_CONFIG_LINES+1; // invalid line id
lineInfo[i].button = i;
lineInfo[i].dn = strlib_empty();
lineInfo[i].name = strlib_empty();
lineInfo[i].cfwd_dest = strlib_empty();
lineInfo[i].externalNumber = strlib_empty();
}
capset_get_idleset(CC_MODE_CCM, lineInfo[i].allowed_features);
// get feature again because it might have been changed if it is a DN
// and the tmpInt might have a different value
config_get_line_value(CFGID_LINE_FEATURE, &tmpInt, sizeof(tmpInt), i);
// features which have no properties
if ( tmpInt == cfgLineFeatureAllCalls ||
tmpInt == cfgLineFeatureMaliciousCallID ||
tmpInt == cfgLineFeatureRedial || tmpInt == cfgLineFeatureAnswerOldest || tmpInt == cfgLineFeatureServices ) {
featureInfo[i].feature_id = tmpInt;
featureInfo[i].button = i;
featureInfo[i].speedDialNumber = strlib_empty();
featureInfo[i].contact = strlib_empty();
featureInfo[i].name = strlib_empty();
featureInfo[i].retrievalPrefix = strlib_empty();
featureInfo[i].featureOptionMask = 0;
} else if ( tmpInt == cfgLineFeatureSpeedDialBLF || tmpInt == cfgLineFeatureSpeedDial){
featureInfo[i].feature_id = tmpInt;
featureInfo[i].button = i;
config_get_line_value(CFGID_LINE_SPEEDDIAL_NUMBER_STRING, tempStr,
MAX_URL_LENGTH, i);
featureInfo[i].speedDialNumber = strlib_malloc(tempStr, strlen(tempStr));
featureInfo[i].contact = strlib_empty();
config_get_line_value(CFGID_LINE_NAME_STRING, tempStr,
MAX_URL_LENGTH, i);
featureInfo[i].name = strlib_malloc(tempStr, strlen(tempStr));
featureInfo[i].retrievalPrefix = strlib_empty();
config_get_line_value(CFGID_LINE_FEATURE_OPTION_MASK, &tmpInt, sizeof(tmpInt), i);
featureInfo[i].featureOptionMask = tmpInt;
featureInfo[i].blf_state = CC_SIP_BLF_UNKNOWN;
} else {
featureInfo[i].feature_id = 0;
featureInfo[i].button = MAX_CONFIG_LINES+1; // invalid button value
featureInfo[i].speedDialNumber = strlib_empty();
featureInfo[i].contact = strlib_empty();
featureInfo[i].name = strlib_empty();
featureInfo[i].retrievalPrefix = strlib_empty();
featureInfo[i].featureOptionMask = 0;
}
}
}
cc_line_info_t* ccsnap_getLineInfo(int lineID)
{
int i;
cc_lineid_t line = (cc_lineid_t)lineID;
for (i=1;i<=MAX_CONFIG_LINES;i++) {
if ( lineInfo[i].line_id == line ) {
return &lineInfo[i];
}
}
return NULL;
}
cc_line_info_t* ccsnap_getLineInfoFromBtn(int btnID)
{
int i;
for (i=1;i<=MAX_CONFIG_LINES;i++) {
if ( lineInfo[i].button == btnID ) {
return &lineInfo[i];
}
}
return NULL;
}
cc_boolean allowedFeature(int fid){
return TRUE;
}
cc_feature_info_t* ccsnap_getFeatureInfo(int featureIndex)
{
if ( ( featureIndex<=MAX_CONFIG_LINES ) &&
( featureIndex>= 1 ) &&
( featureInfo[featureIndex].button == featureIndex ) ) {
if ( allowedFeature(featureInfo[featureIndex].feature_id) ){
return &featureInfo[featureIndex];
}
}
return NULL;
}
/**
* Release any used mem to avoid a leak.
*/
void ccsnap_device_pre_init () {
int i = 0;
CCAPP_DEBUG(DEB_F_PREFIX"Entering device_pre_init to clear it out to avoid mem leaks\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_device_pre_init"));
if ((g_deviceInfo.name) && (strlen(g_deviceInfo.name) > 0)) {
strlib_free(g_deviceInfo.name);
}
if ((g_deviceInfo.not_prompt) && (strlen(g_deviceInfo.not_prompt) > 0)) {
strlib_free(g_deviceInfo.not_prompt);
}
i = 0;
while (i < CCAPI_MAX_SERVERS) {
if ((g_deviceInfo.ucm[i].name) &&
(strlen(g_deviceInfo.ucm[i].name) > 0)) {
strlib_free(g_deviceInfo.ucm[i].name);
}
i++;
}
}
void ccsnap_device_init() {
char temp[MAX_SIP_URL_LENGTH];
/* clean up structure if need be */
ccsnap_device_pre_init();
memset (&g_deviceInfo, 0, sizeof(g_deviceInfo));
g_deviceInfo.name =strlib_empty();
g_deviceInfo.not_prompt =strlib_empty();
g_deviceInfo.not_prompt_prio = 0;
g_deviceInfo.not_prompt_prog = 0;
g_deviceInfo.mwi_lamp = FALSE;
g_deviceInfo.cucm_mode = CC_MODE_CCM;
g_deviceInfo.ins_state = CC_STATE_IDLE;
g_deviceInfo.ins_cause = CC_CAUSE_NONE;
g_deviceInfo.reg_time = 0;
config_get_string(CFGID_CCM1_ADDRESS, temp, MAX_SIP_URL_LENGTH);
g_deviceInfo.ucm[0].name = strlib_malloc(temp, strlen(temp));
g_deviceInfo.ucm[0].type = CC_MODE_CCM;
g_deviceInfo.ucm[0].status = CC_CCM_STATUS_NONE;
config_get_string(CFGID_CCM2_ADDRESS, temp, MAX_SIP_URL_LENGTH);
g_deviceInfo.ucm[1].name = strlib_malloc(temp, strlen(temp));
g_deviceInfo.ucm[1].type = CC_MODE_CCM;
g_deviceInfo.ucm[1].status = CC_CCM_STATUS_NONE;
config_get_string(CFGID_CCM3_ADDRESS, temp, MAX_SIP_URL_LENGTH);
g_deviceInfo.ucm[2].name = strlib_malloc(temp, strlen(temp));
g_deviceInfo.ucm[2].type = CC_MODE_CCM;
g_deviceInfo.ucm[2].status = CC_CCM_STATUS_NONE;
config_get_string(CFGID_CCM_TFTP_IP_ADDR, temp, MAX_SIP_URL_LENGTH);
g_deviceInfo.ucm[3].name = strlib_malloc(temp, strlen(temp));
g_deviceInfo.ucm[3].type = CC_MODE_CCM;
g_deviceInfo.ucm[3].status = CC_CCM_STATUS_NONE;
g_accessoryCfgInfo.camera = ACCSRY_CFGD_CFG;
g_accessoryCfgInfo.video = ACCSRY_CFGD_CFG;
}
void ccsnap_gen_deviceEvent(ccapi_device_event_e event, cc_device_handle_t handle){
const char* fname = "ccsnap_gen_deviceEvent";
cc_device_info_t *device_info = CCAPI_Device_getDeviceInfo(handle);
if ( device_info != NULL ) {
CCAPP_DEBUG(DEB_F_PREFIX"data->ref_count=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->ref_count);
switch (event) {
case CCAPI_DEVICE_EV_NOTIFYPROMPT:
CCAPP_DEBUG(DEB_F_PREFIX"data->not_prompt=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->not_prompt);
CCAPP_DEBUG(DEB_F_PREFIX"data->not_prompt_prio=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->not_prompt_prio);
CCAPP_DEBUG(DEB_F_PREFIX"data->not_prompt_prog=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->not_prompt_prog);
break;
case CCAPI_DEVICE_EV_STATE:
CCAPP_DEBUG(DEB_F_PREFIX"setting property %s to %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), "FullyRegistered", ((device_info->ins_state == CC_STATE_INS) ? "1" : "0"));
//intentional follow through to let the debugs get printed.
default:
CCAPP_DEBUG(DEB_F_PREFIX"data->name=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->name);
CCAPP_DEBUG(DEB_F_PREFIX"data->mwi_lamp=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->mwi_lamp);
CCAPP_DEBUG(DEB_F_PREFIX"data->ins_state=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->ins_state);
CCAPP_DEBUG(DEB_F_PREFIX"data->cucm_mode=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->cucm_mode);
CCAPP_DEBUG(DEB_F_PREFIX"data->ins_cause=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), device_info->ins_cause);
break;
}
CCAPI_DeviceListener_onDeviceEvent(event, handle, device_info);
}
CCAPI_Device_releaseDeviceInfo(device_info);
}
void ccsnap_gen_lineEvent(ccapi_line_event_e event, cc_lineid_t handle){
const char* fname = "ccsnap_gen_lineEvent";
cc_line_info_t *line_info = CCAPI_Line_getLineInfo(handle);
if ( line_info != NULL ) {
if (g_CCAppDebug) {
CCAPP_DEBUG(DEB_F_PREFIX"data->ref_count=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->ref_count);
CCAPP_DEBUG(DEB_F_PREFIX"data->line_id=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->line_id);
CCAPP_DEBUG(DEB_F_PREFIX"data->button=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->button);
CCAPP_DEBUG(DEB_F_PREFIX"data->reg_state=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->reg_state);
CCAPP_DEBUG(DEB_F_PREFIX"data->isCFWD=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->isCFWD);
CCAPP_DEBUG(DEB_F_PREFIX"data->isLocalCFWD=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->isLocalCFWD);
CCAPP_DEBUG(DEB_F_PREFIX"data->mwi=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->mwi);
CCAPP_DEBUG(DEB_F_PREFIX"data->name=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->name);
CCAPP_DEBUG(DEB_F_PREFIX"data->dn=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->dn);
CCAPP_DEBUG(DEB_F_PREFIX"data->cfwd_dest=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), line_info->cfwd_dest);
}
CCAPI_LineListener_onLineEvent(event, handle, line_info);
}
CCAPI_Line_releaseLineInfo(line_info);
}
void ccsnap_gen_callEvent(ccapi_call_event_e event, cc_call_handle_t handle){
session_data_t *call_info = CCAPI_Call_getCallInfo(handle);
if ( call_info == NULL ) {
call_info = getDeepCopyOfSessionData(NULL);
}
//print all info
if (g_CCAppDebug) {
printCallInfo(call_info, "ccsnap_gen_callEvent");
}
CCAPI_CallListener_onCallEvent(event, handle, call_info);
CCAPI_Call_releaseCallInfo(call_info);
}
void ccsnap_update_ccm_status(cc_string_t addr, cc_ccm_status_t status)
{
int i;
CCAPP_DEBUG(DEB_F_PREFIX"entry ccm %s status=%d\n",
DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_update_ccm_status"), addr, status);
for (i=0;i< CCAPI_MAX_SERVERS;i++) {
if ( g_deviceInfo.ucm[i].status == status ) {
//move the status to the new addr
g_deviceInfo.ucm[i].status = CC_CCM_STATUS_NONE;
}
if ( !strcmp(addr, g_deviceInfo.ucm[i].name) ) {
g_deviceInfo.ucm[i].status = status;
CCAPP_DEBUG(DEB_F_PREFIX"server %s is now status=%d\n",
DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_update_ccm_status"),
g_deviceInfo.ucm[i].name, status);
}
}
}
void ccsnap_handle_mnc_reached (cc_line_info_t *line_info, cc_boolean mnc_reached, cc_cucm_mode_t mode)
{
cc_call_handle_t handles[MAX_CALLS];
int count = MAX_CALLS, i;
session_data_t *cinfo;
if (mnc_reached) {
line_info->allowed_features[CCAPI_CALL_CAP_NEWCALL] = FALSE;
line_info->allowed_features[CCAPI_CALL_CAP_REDIAL] = FALSE;
line_info->allowed_features[CCAPI_CALL_CAP_CALLFWD] = FALSE;
} else {
capset_get_idleset(mode, line_info->allowed_features);
}
// update connected calls caps on this line
CCAPI_LineInfo_getCallsByState(line_info->line_id, CONNECTED, handles, &count);
for ( i=0; i<count; i++) {
cinfo = CCAPI_Call_getCallInfo(handles[i]);
if (cinfo) {
if ( cinfo->attr == (cc_call_attr_t) CONF_CONSULT ||
cinfo->attr == (cc_call_attr_t) XFR_CONSULT ) {
CCAPI_Call_releaseCallInfo(cinfo);
continue;
}
cinfo->allowed_features[CCAPI_CALL_CAP_TRANSFER] = mnc_reached?FALSE:TRUE;
cinfo->allowed_features[CCAPI_CALL_CAP_CONFERENCE] = mnc_reached?FALSE:TRUE;
//print call info
if (g_CCAppDebug) {
printCallInfo(cinfo, "ccsnap_handle_mnc_reached");
}
CCAPI_CallListener_onCallEvent(CCAPI_CALL_EV_CAPABILITY, handles[i], cinfo);
}
}
// update RIU call caps on this line
CCAPI_LineInfo_getCallsByState(line_info->line_id, REMINUSE, handles, &count);
for ( i=0; i<count; i++) {
cinfo = CCAPI_Call_getCallInfo(handles[i]);
if (cinfo) {
cinfo->allowed_features[CCAPI_CALL_CAP_BARGE] = mnc_reached?FALSE:TRUE;
//print call info
if (g_CCAppDebug) {
printCallInfo(cinfo, "ccsnap_handle_mnc_reached");
}
CCAPI_CallListener_onCallEvent(CCAPI_CALL_EV_CAPABILITY, handles[i], cinfo);
}
}
}
void ccsnap_gen_blfFeatureEvent(cc_blf_state_t state, int appId)
{
cc_feature_info_t *feature_info = NULL;
feature_info = ccsnap_getFeatureInfo(appId);
// if the feature exists
if (feature_info != NULL) {
feature_info->blf_state = state;
printFeatureInfo(CCAPI_DEVICE_EV_BLF, feature_info, "ccsnap_gen_blfFeatureEvent");
CCAPI_DeviceListener_onFeatureEvent(CCAPI_DEVICE_EV_BLF, CC_DEVICE_ID, feature_info);
}
}
/**
* Inserts localized strings into existing strings with escape characters.
* @param destination the return phrase holder
* @param source the phrase with escape characters.
* @param len the input length to cap the maximum value
* @return pointer to the new string
*/
cc_string_t ccsnap_EscapeStrToLocaleStr(cc_string_t destination, cc_string_t source, int len)
{
static const char *fname="ccsnap_EscapeStrToLocaleStr";
char phrase_collector[MAX_LOCALE_STRING_LEN] = { '\0' };
char* phrase_collector_ptr = phrase_collector;
char* esc_string_itr = (char*)source;
int remaining_length = 0;
cc_string_t ret_str = strlib_empty();
if(destination == NULL){
CCAPP_DEBUG(DEB_F_PREFIX"Error: destination is NULL\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname));
return NULL;
}
if(source == NULL){
CCAPP_DEBUG(DEB_F_PREFIX"Error: source is NULL\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname));
strlib_free(destination);
return strlib_empty();
}
if(source[0] == '\0'){
strlib_free(destination);
return strlib_empty();
}
if (len == LEN_UNKNOWN) {
len = strlen(source) + MAX_LOCALE_PHRASE_LEN;
}
if (len <= 0){
CCAPP_DEBUG(DEB_F_PREFIX"Error: cannot write string of length <= 0\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname));
strlib_free(destination);
return strlib_empty();
}
if (len > MAX_LOCALE_STRING_LEN){
len = MAX_LOCALE_STRING_LEN;
}
remaining_length = len;
while( *esc_string_itr != NUL &&
remaining_length > 0 &&
strlen(phrase_collector_ptr) < (size_t)(len-1))
{
int rtn = CC_SUCCESS;
int phrase_index = 0;
char* phrase_bucket_ptr = (char*)cpr_malloc(remaining_length * sizeof(char));
if (phrase_bucket_ptr == NULL) {
CCAPP_ERROR(DEB_F_PREFIX"Error: phrase_bucket_ptr is NULL\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname));
strlib_free(destination);
return NULL;
}
phrase_bucket_ptr[0] = '\0';
switch(*esc_string_itr){
case OLD_CUCM_DICTIONARY_ESCAPE_TAG:
phrase_index += CALL_CONTROL_PHRASE_OFFSET;
// Do not set break to combine common code
case NEW_CUCM_DICTIONARY_ESCAPE_TAG:
esc_string_itr++;
phrase_index += (int)(*esc_string_itr);
rtn = platGetPhraseText(phrase_index, phrase_bucket_ptr, remaining_length-1);
if(rtn == CC_FAILURE) break;
sstrncat(phrase_collector_ptr, (cc_string_t)phrase_bucket_ptr, remaining_length);
remaining_length--;
break;
default:
// We need length 2 to concat 1 char and a terminating char
sstrncat(phrase_collector_ptr, esc_string_itr, 1 + sizeof(char));
remaining_length--;
break;
}
esc_string_itr++;
cpr_free(phrase_bucket_ptr);
}
ret_str = strlib_malloc(phrase_collector_ptr, len);
if (!ret_str) {
/*
* If a malloc error occurred, give them back what they had.
* It's not right, but it's better than nothing.
*/
ret_str = destination;
} else {
strlib_free(destination);
}
CCAPP_DEBUG(DEB_F_PREFIX"Localization String returning %s\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), ret_str);
return (ret_str);
}
static boolean missed, placed, received;
void ccsnap_set_phone_services_provisioning(boolean misd, boolean plcd, boolean rcvd) {
CCAPP_ERROR(DEB_F_PREFIX"missed=%d placed=%d received=%d\n",
DEB_F_PREFIX_ARGS(SIP_CC_PROV, "ccsnap_set_phone_services_provisioning"), misd, plcd, rcvd);
missed = misd;
placed = plcd;
received = rcvd;
}
boolean ccsnap_isMissedCallLoggingEnabled()
{
return missed;
}
boolean ccsnap_isReceivedCallLoggingEnabled()
{
return received;
}
boolean ccsnap_isPlacedCallLoggingEnabled()
{
return placed;
}
/**
* Helper method
*/
static void printCallInfo(cc_callinfo_ref_t info, const char* fname) {
CCAPP_DEBUG(DEB_F_PREFIX"data->ref_count=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->ref_count);
CCAPP_DEBUG(DEB_F_PREFIX"data->sess_id=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->sess_id);
CCAPP_DEBUG(DEB_F_PREFIX"data->line=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->line);
CCAPP_DEBUG(DEB_F_PREFIX"data->id=%u \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->id);
CCAPP_DEBUG(DEB_F_PREFIX"data->inst=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->inst);
CCAPP_DEBUG(DEB_F_PREFIX"data->state=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->state);
CCAPP_DEBUG(DEB_F_PREFIX"data->attr=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->attr);
CCAPP_DEBUG(DEB_F_PREFIX"data->type=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->type);
CCAPP_DEBUG(DEB_F_PREFIX"data->security=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->security);
CCAPP_DEBUG(DEB_F_PREFIX"data->policy=%02X \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->policy);
CCAPP_DEBUG(DEB_F_PREFIX"data->isSelected=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->isSelected);
CCAPP_DEBUG(DEB_F_PREFIX"data->log_disp=%u \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->log_disp);
CCAPP_DEBUG(DEB_F_PREFIX"data->clg_name=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->clg_name);
CCAPP_DEBUG(DEB_F_PREFIX"data->clg_number=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->clg_number);
CCAPP_DEBUG(DEB_F_PREFIX"data->alt_number=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->alt_number);
CCAPP_DEBUG(DEB_F_PREFIX"data->cld_name=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->cld_name);
CCAPP_DEBUG(DEB_F_PREFIX"data->cld_number=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->cld_number);
CCAPP_DEBUG(DEB_F_PREFIX"data->orig_called_name=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->orig_called_name);
CCAPP_DEBUG(DEB_F_PREFIX"data->orig_called_number=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->orig_called_number);
CCAPP_DEBUG(DEB_F_PREFIX"data->last_redir_name=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->last_redir_name);
CCAPP_DEBUG(DEB_F_PREFIX"data->last_redir_number=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->last_redir_number);
CCAPP_DEBUG(DEB_F_PREFIX"data->plcd_name=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->plcd_name);
CCAPP_DEBUG(DEB_F_PREFIX"data->plcd_number=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->plcd_number);
CCAPP_DEBUG(DEB_F_PREFIX"data->status=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->status);
CCAPP_DEBUG(DEB_F_PREFIX"data->gci=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->gci);
CCAPP_DEBUG(DEB_F_PREFIX"data->cause=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->cause);
CCAPP_DEBUG(DEB_F_PREFIX"data->vid_dir=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->vid_dir);
CCAPP_DEBUG(DEB_F_PREFIX"data->vid_offer=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->vid_offer);
CCAPP_DEBUG(DEB_F_PREFIX"data->is_conf=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->is_conf);
CCAPP_DEBUG(DEB_F_PREFIX"data->ringer_start=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->ringer_start);
CCAPP_DEBUG(DEB_F_PREFIX"data->ringer_mode=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->ringer_mode);
CCAPP_DEBUG(DEB_F_PREFIX"data->ringer_once=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), info->ringer_once);
}
static void printFeatureInfo (ccapi_device_event_e type, cc_featureinfo_ref_t feature_info, const char* fname) {
CCAPP_DEBUG(DEB_F_PREFIX"data->button=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->button);
CCAPP_DEBUG(DEB_F_PREFIX"data->contact=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->contact);
CCAPP_DEBUG(DEB_F_PREFIX"data->featureOptionMask=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->featureOptionMask);
CCAPP_DEBUG(DEB_F_PREFIX"data->feature_id=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->feature_id);
CCAPP_DEBUG(DEB_F_PREFIX"data->name=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->name);
CCAPP_DEBUG(DEB_F_PREFIX"data->retrievalPrefix=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->retrievalPrefix);
CCAPP_DEBUG(DEB_F_PREFIX"data->speedDialNumber=%s \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->speedDialNumber);
if (type == CCAPI_DEVICE_EV_BLF) {
CCAPP_DEBUG(DEB_F_PREFIX"data->blf_state=%d \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname), feature_info->blf_state);
}
}