From 487b375da9f077cc68759c3b6b4d849ddccb903e Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 31 Aug 2012 11:58:44 +0200 Subject: [PATCH] rework linphone_proxy_config_normalize_number() to work with different dialplans --- coreapi/Makefile.am | 6 ++- coreapi/proxy.c | 110 +++++++++++++++++++++++++++++------------ coreapi/test_numbers.c | 40 +++++++++++++++ 3 files changed, 124 insertions(+), 32 deletions(-) create mode 100644 coreapi/test_numbers.c diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 7a6040d1a..c706751ac 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -63,7 +63,7 @@ liblinphone_la_LIBADD= \ $(LIBSOUP_LIBS) if BUILD_TESTS -noinst_PROGRAMS=test_lsd test_ecc +noinst_PROGRAMS=test_lsd test_ecc test_numbers test_lsd_SOURCES=test_lsd.c @@ -72,6 +72,10 @@ test_lsd_LDADD=liblinphone.la $(liblinphone_la_LIBADD) test_ecc_SOURCES=test_ecc.c test_ecc_LDADD=liblinphone.la $(liblinphone_la_LIBADD) + +test_numbers_SOURCES=test_numbers.c + +test_numbers_LDADD=liblinphone.la $(liblinphone_la_LIBADD) endif diff --git a/coreapi/proxy.c b/coreapi/proxy.c index 11a55f59b..bb01f14ee 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -24,7 +24,6 @@ Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org) #include "private.h" #include "mediastreamer2/mediastream.h" - #include @@ -332,7 +331,8 @@ void linphone_proxy_config_refresh_register(LinphoneProxyConfig *obj){ /** * Sets a dialing prefix to be automatically prepended when inviting a number with - * #linphone_core_invite. + * linphone_core_invite(); + * This dialing prefix shall usually be the country code of the country where the user is living. * **/ void linphone_proxy_config_set_dial_prefix(LinphoneProxyConfig *cfg, const char *prefix){ @@ -353,7 +353,7 @@ const char *linphone_proxy_config_get_dial_prefix(const LinphoneProxyConfig *cfg } /** - * Sets whether liblinphone should replace "+" by "00" in dialed numbers (passed to + * Sets whether liblinphone should replace "+" by international calling prefix in dialed numbers (passed to * #linphone_core_invite ). * **/ @@ -369,13 +369,47 @@ void linphone_proxy_config_set_dial_escape_plus(LinphoneProxyConfig *cfg, bool_t bool_t linphone_proxy_config_get_dial_escape_plus(const LinphoneProxyConfig *cfg){ return cfg->dial_escape_plus; } +/* + * http://en.wikipedia.org/wiki/Telephone_numbering_plan + * http://en.wikipedia.org/wiki/Telephone_numbers_in_Europe + */ +typedef struct dial_plan{ + const char *country; + char ccc[8]; /*country calling code*/ + int nnl; /*maximum national number length*/ + const char * icp; /*international call prefix, ex: 00 in europe*/ +}dial_plan_t; +/* TODO: fill with information for all countries over the world*/ +static dial_plan_t const dial_plans[]={ + {"France" , "33" , 9 , "00" }, + {"United States", "1" , 10 , "011" }, + {"Turkey" , "90" , 10 , "00" }, + {"Switzerland" , "41" , 9 , "00" }, + {NULL , "" , 0 , NULL } +}; + +static dial_plan_t most_common_dialplan={ "generic" , "", 10, "00"}; + +static void lookup_dial_plan(const char *ccc, dial_plan_t *plan){ + int i; + for(i=0;dial_plans[i].country!=NULL;++i){ + if (strcmp(ccc,dial_plans[i].ccc)==0){ + *plan=dial_plans[i]; + return; + } + } + /*else return a generic "most common" dial plan*/ + *plan=most_common_dialplan; + strcpy(plan->ccc,ccc); +} static bool_t is_a_phone_number(const char *username){ const char *p; for(p=username;*p!='\0';++p){ if (isdigit(*p) || *p==' ' || + *p=='.' || *p=='-' || *p==')' || *p=='(' || @@ -399,14 +433,12 @@ static char *flatten_number(const char *number){ return result; } -static void copy_result(const char *src, char *dest, size_t destlen, bool_t escape_plus){ +static void replace_plus(const char *src, char *dest, size_t destlen, const char *icp){ int i=0; - if (escape_plus && src[0]=='+' && destlen>2){ - dest[0]='0'; - dest[1]='0'; + if (icp && src[0]=='+' && (destlen>(i=strlen(icp))) ){ src++; - i=2; + strcpy(dest,icp); } for(;(i10 || flatten[0]=='+' || proxy->dial_prefix==NULL || proxy->dial_prefix[0]=='\0'){ - ms_message("No need to add a prefix"); - /* prefix is already there */ - copy_result(flatten,result,result_len,proxy->dial_escape_plus); + + if (proxy->dial_prefix==NULL || proxy->dial_prefix[0]=='\0'){ + /*no prefix configured, nothing else to do*/ + strncpy(result,flatten,result_len); ms_free(flatten); return 0; - }else if (proxy->dial_prefix && proxy->dial_prefix[0]!='\0'){ - char *prefixed; - int skipped=0; - ms_message("Need to prefix with %s",proxy->dial_prefix); - if (numlen==10){ - /*remove initial number before prepending prefix*/ - skipped=1; + }else{ + dial_plan_t dialplan; + lookup_dial_plan(proxy->dial_prefix,&dialplan); + ms_message("Using dialplan '%s'",dialplan.country); + if (flatten[0]=='+' || strstr(flatten,dialplan.icp)==flatten){ + /* the number has international prefix or +, so nothing to do*/ + ms_message("Prefix already present."); + /*eventually replace the plus*/ + replace_plus(flatten,result,result_len,proxy->dial_escape_plus ? dialplan.icp : NULL); + ms_free(flatten); + return 0; + }else{ + int i=0; + int skip; + numlen=strlen(flatten); + /*keep at most national number significant digits */ + skip=numlen-dialplan.nnl; + if (skip<0) skip=0; + /*first prepend internation calling prefix or +*/ + if (proxy->dial_escape_plus){ + strncpy(result,dialplan.icp,result_len); + i+=strlen(dialplan.icp); + }else{ + strncpy(result,"+",result_len); + i+=1; + } + /*add prefix*/ + if (result_len-i>strlen(dialplan.ccc)){ + strcpy(result+i,dialplan.ccc); + i+=strlen(dialplan.ccc); + } + /*add user digits */ + strncpy(result+i,flatten+skip,result_len-i-1); + ms_free(flatten); } - prefixed=append_prefix(flatten+skipped,proxy->dial_prefix); - ms_free(flatten); - copy_result(prefixed,result,result_len,proxy->dial_escape_plus); - ms_free(prefixed); } }else strncpy(result,username,result_len); return 0; diff --git a/coreapi/test_numbers.c b/coreapi/test_numbers.c new file mode 100644 index 000000000..8cf4fb792 --- /dev/null +++ b/coreapi/test_numbers.c @@ -0,0 +1,40 @@ +/* +linphone +Copyright (C) 2012 Belledonne Communications SARL +Author: Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +#include "linphonecore.h" + +int main(int argc , char *argv[]){ + LinphoneProxyConfig *cfg; + char normalized_number[32]; + if (argc<2){ + fprintf(stderr,"Usage:\n%s [] [--escape-plus]\nReturns normalized number.", argv[0]); + return -1; + } + linphone_core_enable_logs(stderr); + cfg=linphone_proxy_config_new(); + if (argc>2) + linphone_proxy_config_set_dial_prefix(cfg,argv[2]); + if (argc>3 && strcmp(argv[3],"--escape-plus")==0) + linphone_proxy_config_set_dial_escape_plus(cfg,TRUE); + linphone_proxy_config_normalize_number(cfg,argv[1],normalized_number,sizeof(normalized_number)); + printf("Normalized number is %s\n",normalized_number); + return 0; +}