/* * sip_config_get_line_by_called_number * * Return the line by the given called_number */ line_t sip_config_get_line_by_called_number (line_t start_line, const char *called_number) { int i; line_t max_lines; line_t line = 0; char line_name[MAX_LINE_NAME_SIZE]; char contact[MAX_LINE_CONTACT_SIZE]; char *name; max_lines = sip_config_local_line_get(); /* * Check the called number for the E.164 "+" * and ignore it if present. */ if (called_number[0] == '+') { called_number++; } for (i = start_line; i <= max_lines; i++) { if (sip_config_check_line((line_t)i)) { config_get_line_string(CFGID_LINE_NAME, line_name, i, sizeof(line_name)); /* * Check the configured line name for the E.164 "+" * and ignore it if present. */ name = &line_name[0]; if (line_name[0] == '+') { name++; } if (cpr_strcasecmp(called_number, name) == 0) { line = (line_t)i; break; } } } // If line not found - check with contact list if (line == 0) { for (i = start_line; i <= max_lines; i++) { if (sip_config_check_line((line_t)i)) { config_get_line_string(CFGID_LINE_CONTACT, contact, i, sizeof(contact)); if (cpr_strcasecmp(called_number, contact) == 0) { line = (line_t)i; break; } } } } return (line); }
/* * Function: extract_blf_state() * * Parameters: event_body_p * feature_mask - indicates the feature enabled * * Description: extracts blf state from presence event body. * * Returns: one of CC_SIP_BLF_IDLE, CC_SIP_BLF_UNKNOWN and CC_SIP_BLF_INUSE. */ static int extract_blf_state (Presence_ext_t *event_body_p, int feature_mask) { static const char fname[] = "extract_blf_state"; char *basic_p = NULL; boolean on_the_phone; boolean alerting; int return_code = CC_SIP_BLF_UNKNOWN; BLF_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(BLF, fname)); if (event_body_p == NULL) { BLF_DEBUG(DEB_F_PREFIX "Exiting with return value %d because there is no event body\n", DEB_F_PREFIX_ARGS(BLF, fname), CC_SIP_BLF_UNKNOWN); return CC_SIP_BLF_UNKNOWN; } basic_p = event_body_p->presence_body.person.personStatus.basic; if (basic_p[0] == '\0') { basic_p = event_body_p->presence_body.tuple[0].status.basic; } on_the_phone = event_body_p->onThePhone; alerting = event_body_p->alerting; BLF_DEBUG(DEB_F_PREFIX"basic: %s, onThePhone:%d, alerting:%d", DEB_F_PREFIX_ARGS(BLF, fname), basic_p, on_the_phone, alerting); if ((on_the_phone == FALSE) && (cpr_strcasecmp(basic_p, "closed") == 0)) { BLF_DEBUG(DEB_F_PREFIX"Exiting with return value %d", DEB_F_PREFIX_ARGS(BLF, fname), CC_SIP_BLF_UNKNOWN); return(CC_SIP_BLF_UNKNOWN); } if (feature_mask & BLF_PICKUP_FEATURE) { if (alerting == TRUE) { BLF_DEBUG(DEB_F_PREFIX"Exiting with return value %d", DEB_F_PREFIX_ARGS(BLF, fname), CC_SIP_BLF_ALERTING); return CC_SIP_BLF_ALERTING; } } if (on_the_phone == FALSE) { if (cpr_strcasecmp(basic_p, "open") == 0) { return_code = CC_SIP_BLF_IDLE; } } else { return_code = CC_SIP_BLF_INUSE; } BLF_DEBUG(DEB_F_PREFIX"Exiting with return value %d", DEB_F_PREFIX_ARGS(BLF, fname), return_code); return return_code; }
/* * sip_config_get_nat_ipaddr() * * Get the nat IP address. * Note: the IP Address is returned in the non-Telecaster * SIP format, which is not byte reversed. * Eg. 0xac2c33f8 = 161.44.51.248 */ void sip_config_get_nat_ipaddr (cpr_ip_addr_t *ip_addr) { cpr_ip_addr_t IPAddress; char address[MAX_IPADDR_STR_LEN]; int dnsErrorCode = 1; if (redirected_nat_ipaddr.type == CPR_IP_ADDR_INVALID) { config_get_string(CFGID_NAT_ADDRESS, address, sizeof(address)); if ((cpr_strcasecmp(address, UNPROVISIONED) != 0) && (address[0] != 0)) { dnsErrorCode = dnsGetHostByName(address, &IPAddress, 100, 1); } if (dnsErrorCode == 0) { util_ntohl(ip_addr, &IPAddress); return ; } else { /* * If the NAT address is not provisioned or * unavailable, return the local address instead. */ sip_config_get_net_device_ipaddr(ip_addr); return; } } else { *ip_addr = redirected_nat_ipaddr; return ; } }
/* * which_feature * * Description: * * A quick determination of the feature based on the string. */ static cc_call_info_e which_feature (char *feat_string_p) { if (cpr_strcasecmp(feat_string_p, SIP_CI_HOLD_STR) == 0) return CC_FEAT_HOLD; if (cpr_strcasecmp(feat_string_p, SIP_CI_RESUME_STR) == 0) return CC_FEAT_RESUME; if (cpr_strcasecmp(feat_string_p, SIP_CI_BARGE_STR) == 0) return CC_FEAT_BARGE; if (cpr_strcasecmp(feat_string_p, SIP_CI_CBARGE_STR) == 0) return CC_FEAT_CBARGE; if (cpr_strcasecmp(feat_string_p, SIP_CI_CALL_INFO_STR) == 0) return CC_FEAT_CALLINFO; return CC_FEAT_NONE; }
/* * sip_config_get_backup_proxy_addr() * * Get table entry from the table string and option number */ uint16_t sip_config_get_backup_proxy_addr (cpr_ip_addr_t *IPAddress, char *buffer, int buffer_len) { *IPAddress = ip_addr_invalid; config_get_string(CFGID_PROXY_BACKUP, buffer, buffer_len); if ((cpr_strcasecmp(buffer, UNPROVISIONED) == 0) || (buffer[0] == 0)) { buffer[0] = 0; } else { (void) str2ip(buffer, IPAddress); } return (1); }
/* * Function: ParseDialEntry() * * Parameters: parseptr - pointer to bytes to be parsed * * Description: Parse the contents of a TEMPLATE tag and add the data to * the dial template lists. * The keywords parsed are: * MATCH="string" * Line="number" * Timeout="number" * User="******" | "IP" * Rewrite="string" * All other keywords are silently ignored * The format of the TEMPLATE can be one ofthe following: * 1. <TEMPLATE KEYWORD1="value1" ... KEYWORDN="valueN" /> * 2. <TEMPLATE KEYWORD1="value1" ... KEYWORDN="valueN"></TEMPLATE> * * Returns: Int - The Number of errors encountered */ static int ParseDialEntry (char **parseptr) { char dialtemplate[MAX_TEMPLATE_LENGTH]; char rewrite[MAX_TEMPLATE_LENGTH]; int timeout = DIAL_TIMEOUT; /* Default to DIAL_TIMEOUT if none specified */ unsigned char line = 0; /* Default to 0 if not specified. Zero matches all lines. */ int counter = 0; int tone_counter = 0; UserMode usermode = UserUnspec; RouteMode routeMode = RouteDefault; vcm_tones_t tone[MAX_TONES]; ParseDialState state = STATE_ANY; long strtol_result; char *strtol_end; dialtemplate[0] = '\0'; rewrite[0] = '\0'; // Set all tones to default. Rule may override. for (counter = 0; counter < MAX_TONES; counter++) { tone[counter] = VCM_DEFAULT_TONE; } for (;;) { char buffer[64]; XMLToken tok; tok = parse_xml_tokens(parseptr, buffer, sizeof(buffer)); switch (tok) { case TOK_KEYWORD: if (state != STATE_ANY) { if ((cpr_strcasecmp(buffer, "TEMPLATE") == 0) && (state == STATE_END_TAG_STARTED)) { state = STATE_END_TAG_FOUND; } else { return 1; } } else if (cpr_strcasecmp(buffer, "MATCH") == 0) { state = STATE_GOT_MATCH; } else if (cpr_strcasecmp(buffer, "LINE") == 0) { state = STATE_GOT_LINE; } else if (cpr_strcasecmp(buffer, "TIMEOUT") == 0) { state = STATE_GOT_TIMEOUT; } else if (cpr_strcasecmp(buffer, "USER") == 0) { state = STATE_GOT_USER; } else if (cpr_strcasecmp(buffer, "REWRITE") == 0) { state = STATE_GOT_REWRITE; } else if (cpr_strcasecmp(buffer, "ROUTE") == 0) { state = STATE_GOT_ROUTE; } else if (cpr_strcasecmp(buffer, "TONE") == 0) { state = STATE_GOT_TONE; } else { return 1; } break; case TOK_EQ: switch (state) { case STATE_GOT_MATCH: state = STATE_GOT_MATCH_EQ; break; case STATE_GOT_LINE: state = STATE_GOT_LINE_EQ; break; case STATE_GOT_TIMEOUT: state = STATE_GOT_TIMEOUT_EQ; break; case STATE_GOT_USER: state = STATE_GOT_USER_EQ; break; case STATE_GOT_REWRITE: state = STATE_GOT_REWRITE_EQ; break; case STATE_GOT_ROUTE: state = STATE_GOT_ROUTE_EQ; break; case STATE_GOT_TONE: state = STATE_GOT_TONE_EQ; break; default: return 1; } break; case TOK_STR: switch (state) { case STATE_GOT_MATCH_EQ: sstrncpy(dialtemplate, buffer, sizeof(dialtemplate)); break; case STATE_GOT_LINE_EQ: errno = 0; strtol_result = strtol(buffer, &strtol_end, 10); if (errno || buffer == strtol_end || strtol_result < 0 || strtol_result > UCHAR_MAX) { return 1; } line = (unsigned char) strtol_result; break; case STATE_GOT_TIMEOUT_EQ: errno = 0; strtol_result = strtol(buffer, &strtol_end, 10); if (errno || buffer == strtol_end || strtol_result < 0 || strtol_result > INT_MAX) { return 1; } timeout = (int) strtol_result; break; case STATE_GOT_USER_EQ: if (cpr_strcasecmp(buffer, "PHONE") == 0) { usermode = UserPhone; } else if (cpr_strcasecmp(buffer, "IP") == 0) { usermode = UserIP; } else { return 1; } break; case STATE_GOT_ROUTE_EQ: if (cpr_strcasecmp(buffer, "DEFAULT") == 0) { routeMode = RouteDefault; } else if (cpr_strcasecmp(buffer, "EMERGENCY") == 0) { routeMode = RouteEmergency; } else if (cpr_strcasecmp(buffer, "FQDN") == 0) { routeMode = RouteFQDN; } else { return 1; } break; case STATE_GOT_TONE_EQ: if (tone_counter < MAX_TONES) { /* Tone = "" check */ if (*buffer == '\000') { tone[tone_counter] = VCM_DEFAULT_TONE; } else { for (counter = 0; counter < VCM_MAX_DIALTONE; counter++) { if (cpr_strcasecmp(buffer, tone_names[counter]) == 0) { tone[tone_counter] = (vcm_tones_t) counter; break; } } // Tone string not matched if (counter == VCM_MAX_DIALTONE) { return 1; } } tone_counter++; // Too many tones defined in the rule } else { return 1; } break; case STATE_GOT_REWRITE_EQ: sstrncpy(rewrite, buffer, sizeof(rewrite)); break; default: return 1; } state = STATE_ANY; break; case TOK_EMPTYBRACKET: /* "/>" */ AddDialTemplate(dialtemplate, line, timeout, usermode, rewrite, routeMode, tone, tone_counter); if (state == STATE_ANY) { return 0; } /* * There was a parsing error, so just ignore it */ return 1; case TOK_RBRACKET: /* ">" */ if (state == STATE_ANY) { state = STATE_START_TAG_COMPLETED; } else if (state == STATE_END_TAG_FOUND) { AddDialTemplate(dialtemplate, line, timeout, usermode, rewrite, routeMode, tone, tone_counter); return 0; } else { return 1; } break; case TOK_ENDLBRACKET: /* "</" */ if (state == STATE_START_TAG_COMPLETED) { state = STATE_END_TAG_STARTED; } else { return 1; } break; default: /* * Problem parsing. Let them know */ return 1; } } }
/* * Function: ParseDialTemplate() * * Parameters: parseptr - pointer to bytes to be parsed * * Description: Parse the contents of a dial template XML file * All Start and end tags are ignored * The empty element <TEMPLATE is parsed by ParseDialEntry * * Returns: false if parse fails else true */ boolean ParseDialTemplate (char *parseptr) { char buffer[MAX_TEMPLATE_LENGTH]; XMLToken tok; int LookKey; int LookEndKey; int errors = 0; int insideDialPlan = 0; LookKey = 0; LookEndKey = 0; FreeDialTemplates(); /* * reset the version stamp so that dialplans that do not contain versionStamp * tag will not keep the previous versionstamp. */ g_dp_version_stamp[0] = 0; if (parseptr == NULL) { debugif_printf("ParseDialTempate(): parseptr=NULL Returning.\n"); return (FALSE); } while ((tok = parse_xml_tokens(&parseptr, buffer, sizeof(buffer))) != TOK_EOF) { if (LookEndKey) { if (tok == TOK_RBRACKET) { LookEndKey = 0; } else if ((tok == TOK_KEYWORD) && !cpr_strcasecmp(buffer, "DIALTEMPLATE")) { insideDialPlan = 0; } } else if (tok == TOK_LBRACKET) { LookKey = 1; } else if ((LookKey != 0) && (tok == TOK_KEYWORD) && !cpr_strcasecmp(buffer, "DIALTEMPLATE")) { insideDialPlan = 1; } else if ((LookKey != 0) && (tok == TOK_KEYWORD) && !strcmp(buffer, "TEMPLATE")) { if (insideDialPlan) { errors += ParseDialEntry(&parseptr); } else { errors++; } } else if ((LookKey != 0) && (tok == TOK_KEYWORD) && !cpr_strcasecmp(buffer, "versionStamp")) { if (insideDialPlan) { /* <versionStamp> tag found. parse it */ errors += ParseDialVersion(&parseptr); } else { errors++; } } else if (tok == TOK_ENDLBRACKET) { LookEndKey = 1; } else { LookKey = 0; } } /* * If we had any parse errors, put them into the log */ log_clear(LOG_CFG_PARSE_DIAL); if (errors != 0) { log_msg(LOG_CFG_PARSE_DIAL, errors, DialTemplateFile); return (FALSE); } return (TRUE); }
/* * Function: ParseDialVersion() * * Parameters: parseptr - pointer to bytes to be parsed * * Description: Parse the contents of a versionStamp tag and store it * The format of the versionStamp is as follows: * <versionStamp>value up to 64 chars</versionStamp> * * Returns: 0 - if the version stamp is successfully parsed. * 1 - if the version stamp parsing fails. */ static int ParseDialVersion (char **parseptr) { ParseDialState state = STATE_ANY; char version_stamp[MAX_DP_VERSION_STAMP_LEN] = { 0 }; int len; for (;;) { char buffer[MAX_DP_VERSION_STAMP_LEN]; XMLToken tok; tok = parse_xml_tokens(parseptr, buffer, sizeof(buffer)); switch (tok) { case TOK_KEYWORD: switch (state) { case STATE_START_TAG_COMPLETED: /* * the keyword is version stamp value here. copy it temporarily. */ memcpy(version_stamp, buffer, MAX_DP_VERSION_STAMP_LEN); break; case STATE_END_TAG_STARTED: if (cpr_strcasecmp(buffer, "versionStamp") != 0) { return 1; } state = STATE_END_TAG_FOUND; break; default: break; } break; case TOK_RBRACKET: /* ">" */ if (state == STATE_ANY) { state = STATE_START_TAG_COMPLETED; } else if (state == STATE_END_TAG_FOUND) { /* strip of the warping curly braces if they exist */ len = strlen(version_stamp); if (len <= 2) { CCAPP_ERROR("ParseDialVersion(): Version length [%d] is way too small", len); return (1); } memset(g_dp_version_stamp, 0, MAX_DP_VERSION_STAMP_LEN); if ((version_stamp[0] == '{') && (version_stamp[len - 1] == '}')) { memcpy(g_dp_version_stamp, (version_stamp + 1), (len - 2)); } else { memcpy(g_dp_version_stamp, version_stamp, len); } return 0; } else { return 1; } break; case TOK_ENDLBRACKET: /* "</" */ if (state == STATE_START_TAG_COMPLETED) { state = STATE_END_TAG_STARTED; } else { return 1; } break; default: /* * Problem parsing. Let them know */ return 1; } } }