From 1e0661a2684ebaf3e57219e7b18235773d2b14cb Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Thu, 3 Nov 2016 17:27:28 +0100 Subject: [PATCH] fix linphone_proxy_config_normalize_number for better optionnal num part handling --- coreapi/dial_plan.c | 24 +++++++--- coreapi/linphonecore_utils.h | 8 +++- coreapi/proxy.c | 87 +++++++++++++++++++----------------- tester/local_tester_hosts | 5 ++- tester/proxy_config_tester.c | 20 +++++---- 5 files changed, 86 insertions(+), 58 deletions(-) diff --git a/coreapi/dial_plan.c b/coreapi/dial_plan.c index 6441cb2f3..90bfc7627 100644 --- a/coreapi/dial_plan.c +++ b/coreapi/dial_plan.c @@ -261,6 +261,10 @@ int linphone_dial_plan_lookup_ccc_from_e164(const char* e164) { LinphoneDialPlan* elected_dial_plan=NULL; unsigned int found; unsigned int i=0; + + if (e164[0]!='+') { + return -1;/*not an e164 number*/ + } if (e164[1]=='1') { /*USA case*/ return 1; @@ -292,14 +296,13 @@ int linphone_dial_plan_lookup_ccc_from_iso(const char* iso) { return -1; } -const LinphoneDialPlan* linphone_dial_plan_by_ccc(const char *ccc) { +const LinphoneDialPlan* linphone_dial_plan_by_ccc_as_ushort(unsigned short ccc) { int i; - if (!ccc) { - return &most_common_dialplan; - } - + char ccc_as_char[4] = {0}; + snprintf(ccc_as_char,sizeof(ccc_as_char),"%i",ccc); + for(i=0;dial_plans[i].country!=NULL;++i){ - if (strcmp(ccc,dial_plans[i].ccc)==0){ + if (strcmp(ccc_as_char,dial_plans[i].ccc)==0){ return &dial_plans[i]; } } @@ -307,6 +310,15 @@ const LinphoneDialPlan* linphone_dial_plan_by_ccc(const char *ccc) { return &most_common_dialplan; } + +const LinphoneDialPlan* linphone_dial_plan_by_ccc(const char *ccc) { + if (!ccc) { + return &most_common_dialplan; + } + + return linphone_dial_plan_by_ccc_as_ushort(strtol(ccc,NULL,10)); +} + const LinphoneDialPlan* linphone_dial_plan_get_all() { return dial_plans; } diff --git a/coreapi/linphonecore_utils.h b/coreapi/linphonecore_utils.h index 83c46054c..411608460 100644 --- a/coreapi/linphonecore_utils.h +++ b/coreapi/linphonecore_utils.h @@ -133,7 +133,13 @@ LINPHONE_PUBLIC const LinphoneDialPlan* linphone_dial_plan_get_all(void); * @return Return matching dial plan, or a generic one if none found **/ LINPHONE_PUBLIC const LinphoneDialPlan* linphone_dial_plan_by_ccc(const char *ccc); - +/** + * Find best match for given CCC + * @return Return matching dial plan, or a generic one if none found + **/ +LINPHONE_PUBLIC const LinphoneDialPlan* linphone_dial_plan_by_ccc_as_ushort(unsigned short ccc); + + /** * Return if given plan is generic **/ diff --git a/coreapi/proxy.c b/coreapi/proxy.c index f344f6307..66fa4b01a 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -594,19 +594,8 @@ static char *flatten_number(const char *number){ char *result=ms_malloc0(strlen(number)+1); char *w=result; const char *r; - bool_t removing_trunk_prefix = FALSE; for(r=number;*r!='\0';++r){ - if (result[0] == '+') { - /*e164 case*/ - if (*r=='(') { - /*start removing trunk prefix as we are in form +33 (0) 6 222222*/ - removing_trunk_prefix=TRUE; - } else if (*r==')') { - /*stop removing trunk prefix*/ - removing_trunk_prefix=FALSE; - } - } - if (removing_trunk_prefix == FALSE && (*r=='+' || isdigit(*r))){ + if (*r=='+' || isdigit(*r)){ *w++=*r; } } @@ -634,46 +623,62 @@ bool_t linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const char* linphone_proxy_config_normalize_phone_number(LinphoneProxyConfig *proxy, const char *username) { LinphoneProxyConfig *tmpproxy = proxy ? proxy : linphone_proxy_config_new(); char* result = NULL; + LinphoneDialPlan dialplan = {0}; + char * nationnal_significant_number = NULL; + int ccc = -1; + if (linphone_proxy_config_is_phone_number(tmpproxy, username)){ - LinphoneDialPlan dialplan = *linphone_dial_plan_by_ccc(tmpproxy->dial_prefix); //copy dial plan; char * flatten=flatten_number(username); ms_debug("Flattened number is '%s' for '%s'",flatten, username); - if (tmpproxy->dial_prefix){ - if (strcmp(tmpproxy->dial_prefix,dialplan.ccc) != 0){ - //probably generic dialplan, preserving proxy dial prefix - strncpy(dialplan.ccc,tmpproxy->dial_prefix,sizeof(dialplan.ccc)); + ccc = linphone_dial_plan_lookup_ccc_from_e164(flatten); + if (ccc>-1) { /*e164 like phone number*/ + dialplan = *linphone_dial_plan_by_ccc_as_ushort(ccc); + nationnal_significant_number = strnstr(flatten, dialplan.ccc,4 /*+ +maximun 3 digits*/); + if (nationnal_significant_number) { + nationnal_significant_number +=strlen(dialplan.ccc); } + } else if (flatten[0] =='+') { + ms_message ("Unknown ccc for e164 like number [%s]", flatten); + goto end; + } else { + dialplan = *linphone_dial_plan_by_ccc(tmpproxy->dial_prefix); //copy dial plan; + if (tmpproxy->dial_prefix){ + if (strcmp(tmpproxy->dial_prefix,dialplan.ccc) != 0){ + //probably generic dialplan, preserving proxy dial prefix + strncpy(dialplan.ccc,tmpproxy->dial_prefix,sizeof(dialplan.ccc)); + } + } + if (strnstr(flatten,dialplan.icp,strlen(dialplan.icp))==flatten) { + char *e164 = replace_icp_with_plus(flatten,dialplan.icp); + result = linphone_proxy_config_normalize_phone_number(tmpproxy,e164); + ms_free(e164); + goto end; + } + nationnal_significant_number=flatten; } + /*if proxy has a dial prefix, modify phonenumber accordingly*/ - if (tmpproxy->dial_prefix!=NULL && tmpproxy->dial_prefix[0]!='\0'){ + if (dialplan.ccc[0]!='\0') { ms_debug("Using dial plan '%s'",dialplan.country); /* the number already starts with + or international prefix*/ - if (flatten[0]=='+'||strstr(flatten,dialplan.icp)==flatten){ - ms_debug("Prefix already present."); - if (tmpproxy->dial_escape_plus) { - result = replace_plus_with_icp(flatten,dialplan.icp); - } else { - result = replace_icp_with_plus(flatten,dialplan.icp); - } - }else{ - /*0. keep at most national number significant digits */ - char* flatten_start = flatten + MAX(0, (int)strlen(flatten) - (int)dialplan.nnl); - ms_debug("Prefix not present. Keeping at most %d digits: %s", dialplan.nnl, flatten_start); + /*0. keep at most national number significant digits */ + char* nationnal_significant_number_start = nationnal_significant_number + + MAX(0, (int)strlen(nationnal_significant_number) + - (int)dialplan.nnl); + ms_debug("Prefix not present. Keeping at most %d digits: %s", dialplan.nnl, nationnal_significant_number_start); - /*1. First prepend international calling prefix or +*/ - /*2. Second add prefix*/ - /*3. Finally add user digits */ - result = ms_strdup_printf("%s%s%s" - , tmpproxy->dial_escape_plus ? dialplan.icp : "+" - , dialplan.ccc - , flatten_start); - ms_debug("Prepended prefix resulted in %s", result); - } - }else if (tmpproxy->dial_escape_plus){ - /* user did not provide dial prefix, so we'll take the most generic one */ - result = replace_plus_with_icp(flatten,dialplan.icp); + /*1. First prepend international calling prefix or +*/ + /*2. Second add prefix*/ + /*3. Finally add user digits */ + result = ms_strdup_printf("%s%s%s" + , tmpproxy->dial_escape_plus ? dialplan.icp : "+" + , dialplan.ccc + , nationnal_significant_number_start); + ms_debug("Prepended prefix resulted in %s", result); } + + end: if (result==NULL) { result = flatten; } else { diff --git a/tester/local_tester_hosts b/tester/local_tester_hosts index de1edc48c..0a78dd3e9 100644 --- a/tester/local_tester_hosts +++ b/tester/local_tester_hosts @@ -1 +1,4 @@ -127.0.0.1 sip2.linphone.org sip.example.org sipopen.example.org auth.example.org auth1.example.org auth2.example.org altname.linphone.org sip.wildcard1.linphone.org altname.wildcard2.linphone.org +127.0.0.1 sip2.linphone.org sip.example.org sipopen.example.org auth.example.org auth1.example.org auth2.example.org altname.linphone.org sip.wildcard1.linphone.org altname.wildcard2.linphone.org sipv4.example.org +2001:41d0:2:14b0::1 sip2.linphone.org sip.example.org sipopen.example.org auth.example.org auth1.example.org auth2.example.org altname.linphone.org sip.wildcard1.linphone.org altname.wildcard2.linphone.org +188.165.46.90 tunnel.wildcard2.linphone.org +64:ff9b::94.23.19.176 sipv4-nat64.example.org diff --git a/tester/proxy_config_tester.c b/tester/proxy_config_tester.c index 9e9afd6ec..edd01f04f 100644 --- a/tester/proxy_config_tester.c +++ b/tester/proxy_config_tester.c @@ -36,10 +36,10 @@ static void phone_normalization_without_proxy(void) { BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "012 345 6789"), "0123456789"); BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "+33123456789"), "+33123456789"); BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "+33012345678"), "+33012345678"); - BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "+33 0012345678"), "+330012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "+33 0012345678"), "+33012345678"); BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "+33012345678"), "+33012345678"); - BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "+3301234567891"), "+3301234567891"); - BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "+33 01234567891"), "+3301234567891"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "+3301234567891"), "+33234567891"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "+33 01234567891"), "+33234567891"); BC_ASSERT_PTR_NULL(phone_normalization(NULL, "I_AM_NOT_A_NUMBER")); // invalid phone number BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "0"), "0"); @@ -59,14 +59,16 @@ static void phone_normalization_with_proxy(void) { LinphoneProxyConfig *proxy = linphone_proxy_config_new(); linphone_proxy_config_set_dial_prefix(proxy, "33"); BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012 3456 789"), "+33123456789"); + linphone_proxy_config_set_dial_prefix(proxy, NULL); BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+33123456789"), "+33123456789"); - BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+33 0123456789"), "+330123456789"); - BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+330012345678"), "+330012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+33 0123456789"), "+33123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+330012345678"), "+33012345678"); BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+3301 2345678"), "+33012345678"); - BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+3301234567891"), "+3301234567891"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+3301234567891"), "+33234567891"); BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+33 (0) 1 23 45 67 89"), "+33123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+90 (903) 1234567"), "+909031234567"); - + linphone_proxy_config_set_dial_prefix(proxy, "33"); BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "123456789"), "+33123456789"); BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, " 0123456789"), "+33123456789"); BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0012345678"), "+12345678"); @@ -106,8 +108,8 @@ static void phone_normalization_with_proxy(void) { BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+330123456"), "+330123456"); BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+3301234567"), "+3301234567"); BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+33012345678"), "+33012345678"); - BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+330123456789"), "+330123456789"); - BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+3301234567890"), "+3301234567890"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+330123456789"), "+33123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+3301234567890"), "+33234567890"); // invalid prefix - use a generic dialplan with 10 max length linphone_proxy_config_set_dial_prefix(proxy, "99");