diff --git a/linphone/coreapi/Makefile.am b/linphone/coreapi/Makefile.am index 562cf8d1d001d6ab55a2946242c981696d427549..c0a28ade3f4c1c539773f1804fb7fa2e221c183a 100644 --- a/linphone/coreapi/Makefile.am +++ b/linphone/coreapi/Makefile.am @@ -17,6 +17,7 @@ liblinphone_la_SOURCES=\ linphonecore.c linphonecore.h private.h\ exevents.c exevents.h \ misc.c \ + address.c \ enum.c enum.h \ sdphandler.c sdphandler.h \ presence.c \ diff --git a/linphone/coreapi/address.c b/linphone/coreapi/address.c new file mode 100644 index 0000000000000000000000000000000000000000..36f6de9035a21db954e0906e3f74f81533edf058 --- /dev/null +++ b/linphone/coreapi/address.c @@ -0,0 +1,184 @@ +/* +linphone +Copyright (C) 2009 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" +#include "lpconfig.h" +#include "private.h" +#include <eXosip2/eXosip.h> + +/** + * @addtogroup linphone_address + * @{ +**/ + +/** + * Constructs a LinphoneAddress object by parsing the user supplied address, + * given as a string. +**/ +LinphoneAddress * linphone_address_new(const char *uri){ + osip_from_t *from; + osip_from_init(&from); + if (osip_from_parse(from,uri)!=0){ + osip_from_free(from); + return NULL; + } + return from; +} + +/** + * Clones a LinphoneAddress object. +**/ +LinphoneAddress * linphone_address_clone(const LinphoneAddress *uri){ + osip_from_t *ret=NULL; + osip_from_clone(uri,&ret); + return ret; +} + +#define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL ) + +/** + * Returns the address scheme, normally "sip". +**/ +const char *linphone_address_get_scheme(const LinphoneAddress *u){ + return null_if_empty(u->url->scheme); +} + +/** + * Returns the display name. +**/ +const char *linphone_address_get_display_name(const LinphoneAddress* u){ + return null_if_empty(u->displayname); +} + +/** + * Returns the username. +**/ +const char *linphone_address_get_username(const LinphoneAddress *u){ + return null_if_empty(u->url->username); +} + +/** + * Returns the domain name. +**/ +const char *linphone_address_get_domain(const LinphoneAddress *u){ + return null_if_empty(u->url->host); +} + +/** + * Sets the display name. +**/ +void linphone_address_set_display_name(LinphoneAddress *u, const char *display_name){ + if (u->displayname!=NULL){ + osip_free(u->displayname); + u->displayname=NULL; + } + if (display_name!=NULL) + u->displayname=osip_strdup(display_name); +} + +/** + * Sets the username. +**/ +void linphone_address_set_username(LinphoneAddress *uri, const char *username){ + if (uri->url->username!=NULL){ + osip_free(uri->url->username); + uri->url->username=NULL; + } + if (username) + uri->url->username=osip_strdup(username); +} + +/** + * Sets the domain. +**/ +void linphone_address_set_domain(LinphoneAddress *uri, const char *host){ + if (uri->url->host!=NULL){ + osip_free(uri->url->host); + uri->url->host=NULL; + } + if (host) + uri->url->host=osip_strdup(host); +} + +/** + * Sets the port number. +**/ +void linphone_address_set_port(LinphoneAddress *uri, const char *port){ + if (uri->url->port!=NULL){ + osip_free(uri->url->port); + uri->url->port=NULL; + } + if (port) + uri->url->port=osip_strdup(port); +} + +/** + * Sets the port number. +**/ +void linphone_address_set_port_int(LinphoneAddress *uri, int port){ + char tmp[12]; + if (port==5060){ + /*this is the default, special case to leave the port field blank*/ + linphone_address_set_port(uri,NULL); + return; + } + snprintf(tmp,sizeof(tmp),"%i",port); + linphone_address_set_port(uri,tmp); +} + +/** + * Removes address's tags and uri headers so that it is displayable to the user. +**/ +void linphone_address_clean(LinphoneAddress *uri){ + osip_generic_param_freelist(&uri->gen_params); +} + +/** + * Returns the address as a string. + * The returned char * must be freed by the application. Use ms_free(). +**/ +char *linphone_address_as_string(const LinphoneAddress *u){ + char *tmp,*ret; + osip_from_to_str(u,&tmp); + ret=ms_strdup(tmp); + osip_free(tmp); + return ret; +} + +/** + * Returns the SIP uri only as a string, that is display name is removed. + * The returned char * must be freed by the application. Use ms_free(). +**/ +char *linphone_address_as_string_uri_only(const LinphoneAddress *u){ + char *tmp=NULL,*ret; + osip_uri_to_str(u->url,&tmp); + ret=ms_strdup(tmp); + osip_free(tmp); + return ret; +} + +/** + * Destroys a LinphoneAddress object. +**/ +void linphone_address_destroy(LinphoneAddress *u){ + osip_from_free(u); +} + + +/** @} */ diff --git a/linphone/coreapi/enum.c b/linphone/coreapi/enum.c index deb8caff30155ae047906e314b6205b6ec828d0d..8818ae6ee6094e057fd94749423a722f28d7c52d 100644 --- a/linphone/coreapi/enum.c +++ b/linphone/coreapi/enum.c @@ -1,6 +1,6 @@ /* linphone -Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org) +Copyright (C) 2000-2009 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 @@ -30,7 +30,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define DNS_ANSWER_MAX_SIZE 2048 -char *create_enum_domain(const char *number){ +static char *create_enum_domain(const char *number){ int len=strlen(number); char *domain=ms_malloc((len*2)+10); int i,j; @@ -47,7 +47,7 @@ char *create_enum_domain(const char *number){ } -bool_t is_a_number(const char *str){ +static bool_t is_a_number(const char *str){ char *p=(char *)str; bool_t res=FALSE; bool_t space_found=FALSE; diff --git a/linphone/coreapi/linphonecore.c b/linphone/coreapi/linphonecore.c index 7665069b2f5612364359c4e5e58e12ee65430d8f..a0c442ad605f071e47747ccdbba66815cf5e812e 100644 --- a/linphone/coreapi/linphonecore.c +++ b/linphone/coreapi/linphonecore.c @@ -646,6 +646,7 @@ static void sip_config_read(LinphoneCore *lc) break; } } + /*for test*/ lc->sip_conf.sdp_200_ack=lp_config_get_int(lc->config,"sip","sdp_200_ack",0); lc->sip_conf.only_one_codec=lp_config_get_int(lc->config,"sip","only_one_codec",0); @@ -1648,12 +1649,16 @@ bool_t linphone_core_interpret_url(LinphoneCore *lc, const char *url, LinphoneAd /* append the proxy domain suffix */ LinphoneAddress *uri; const char *identity=linphone_proxy_config_get_identity(proxy); + char normalized_username[128]; uri=linphone_address_new(identity); if (uri==NULL){ return FALSE; } linphone_address_set_display_name(uri,NULL); - linphone_address_set_username(uri,url); + linphone_proxy_config_normalize_number(proxy,url,normalized_username, + sizeof(normalized_username)); + linphone_address_set_username(uri,normalized_username); + if (real_parsed_url!=NULL) *real_parsed_url=uri; #if 0 /*if the prompted uri was auto-suffixed with proxy domain, @@ -3477,162 +3482,3 @@ void linphone_core_destroy(LinphoneCore *lc){ ms_free(lc); } -/** - * @addtogroup linphone_address - * @{ -**/ - -/** - * Constructs a LinphoneAddress object by parsing the user supplied address, - * given as a string. -**/ -LinphoneAddress * linphone_address_new(const char *uri){ - osip_from_t *from; - osip_from_init(&from); - if (osip_from_parse(from,uri)!=0){ - osip_from_free(from); - return NULL; - } - return from; -} - -/** - * Clones a LinphoneAddress object. -**/ -LinphoneAddress * linphone_address_clone(const LinphoneAddress *uri){ - osip_from_t *ret=NULL; - osip_from_clone(uri,&ret); - return ret; -} - -#define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL ) - -/** - * Returns the address scheme, normally "sip". -**/ -const char *linphone_address_get_scheme(const LinphoneAddress *u){ - return null_if_empty(u->url->scheme); -} - -/** - * Returns the display name. -**/ -const char *linphone_address_get_display_name(const LinphoneAddress* u){ - return null_if_empty(u->displayname); -} - -/** - * Returns the username. -**/ -const char *linphone_address_get_username(const LinphoneAddress *u){ - return null_if_empty(u->url->username); -} - -/** - * Returns the domain name. -**/ -const char *linphone_address_get_domain(const LinphoneAddress *u){ - return null_if_empty(u->url->host); -} - -/** - * Sets the display name. -**/ -void linphone_address_set_display_name(LinphoneAddress *u, const char *display_name){ - if (u->displayname!=NULL){ - osip_free(u->displayname); - u->displayname=NULL; - } - if (display_name!=NULL) - u->displayname=osip_strdup(display_name); -} - -/** - * Sets the username. -**/ -void linphone_address_set_username(LinphoneAddress *uri, const char *username){ - if (uri->url->username!=NULL){ - osip_free(uri->url->username); - uri->url->username=NULL; - } - if (username) - uri->url->username=osip_strdup(username); -} - -/** - * Sets the domain. -**/ -void linphone_address_set_domain(LinphoneAddress *uri, const char *host){ - if (uri->url->host!=NULL){ - osip_free(uri->url->host); - uri->url->host=NULL; - } - if (host) - uri->url->host=osip_strdup(host); -} - -/** - * Sets the port number. -**/ -void linphone_address_set_port(LinphoneAddress *uri, const char *port){ - if (uri->url->port!=NULL){ - osip_free(uri->url->port); - uri->url->port=NULL; - } - if (port) - uri->url->port=osip_strdup(port); -} - -/** - * Sets the port number. -**/ -void linphone_address_set_port_int(LinphoneAddress *uri, int port){ - char tmp[12]; - if (port==5060){ - /*this is the default, special case to leave the port field blank*/ - linphone_address_set_port(uri,NULL); - return; - } - snprintf(tmp,sizeof(tmp),"%i",port); - linphone_address_set_port(uri,tmp); -} - -/** - * Removes address's tags and uri headers so that it is displayable to the user. -**/ -void linphone_address_clean(LinphoneAddress *uri){ - osip_generic_param_freelist(&uri->gen_params); -} - -/** - * Returns the address as a string. - * The returned char * must be freed by the application. Use ms_free(). -**/ -char *linphone_address_as_string(const LinphoneAddress *u){ - char *tmp,*ret; - osip_from_to_str(u,&tmp); - ret=ms_strdup(tmp); - osip_free(tmp); - return ret; -} - -/** - * Returns the SIP uri only as a string, that is display name is removed. - * The returned char * must be freed by the application. Use ms_free(). -**/ -char *linphone_address_as_string_uri_only(const LinphoneAddress *u){ - char *tmp=NULL,*ret; - osip_uri_to_str(u->url,&tmp); - ret=ms_strdup(tmp); - osip_free(tmp); - return ret; -} - -/** - * Destroys a LinphoneAddress object. -**/ -void linphone_address_destroy(LinphoneAddress *u){ - osip_from_free(u); -} - -/** @} */ diff --git a/linphone/coreapi/linphonecore.h b/linphone/coreapi/linphonecore.h index 50aa8f1d1b7c8cb998255f4900a35fd6ac3b039c..94d15c258f78182ffccf4240df117b918d24f97f 100644 --- a/linphone/coreapi/linphonecore.h +++ b/linphone/coreapi/linphonecore.h @@ -334,10 +334,12 @@ typedef struct _LinphoneProxyConfig int auth_failures; char *contact_addr; /* our IP address as seen by the proxy, read from via 's received= parameter*/ int contact_port; /*our IP port as seen by the proxy, read from via's rport= parameter */ + char *dial_prefix; bool_t commit; bool_t reg_sendregister; bool_t registered; bool_t publish; + bool_t dial_escape_plus; } LinphoneProxyConfig; LinphoneProxyConfig *linphone_proxy_config_new(void); diff --git a/linphone/coreapi/private.h b/linphone/coreapi/private.h index bc23b80e7d36036a929bce9524340958c6e32e64..e9809dc83eb811f809a980c7ab68196561d2225f 100644 --- a/linphone/coreapi/private.h +++ b/linphone/coreapi/private.h @@ -192,4 +192,6 @@ int linphone_core_get_local_ip_for(const char *dest, char *result); LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(struct _LpConfig *config, int index); void linphone_proxy_config_write_to_config_file(struct _LpConfig* config,LinphoneProxyConfig *obj, int index); +int linphone_proxy_config_normalize_number(LinphoneProxyConfig *cfg, const char *username, char *result, size_t result_len); + #endif /* _PRIVATE_H */ diff --git a/linphone/coreapi/proxy.c b/linphone/coreapi/proxy.c index 46d0bf1c7c4ca22b80bbe160de416ad2a7b5ad96..b836feb53fc0dce0cacfb87d24756e3acd48f2e4 100644 --- a/linphone/coreapi/proxy.c +++ b/linphone/coreapi/proxy.c @@ -25,6 +25,10 @@ Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org) #include "lpconfig.h" #include "private.h" + +#include <ctype.h> + + void linphone_proxy_config_write_all_to_config_file(LinphoneCore *lc){ MSList *elem; int i; @@ -69,6 +73,7 @@ void linphone_proxy_config_destroy(LinphoneProxyConfig *obj){ if (obj->realm!=NULL) ms_free(obj->realm); if (obj->type!=NULL) ms_free(obj->type); if (obj->contact_addr!=NULL) ms_free(obj->contact_addr); + if (obj->dial_prefix!=NULL) ms_free(obj->dial_prefix); } /** @@ -334,6 +339,130 @@ static void linphone_proxy_config_register(LinphoneProxyConfig *obj){ } } + +/** + * Sets a dialing prefix to be automatically prepended when inviting a number with + * #linphone_core_invite. + * +**/ +void linphone_proxy_config_set_dial_prefix(LinphoneProxyConfig *cfg, const char *prefix){ + if (cfg->dial_prefix!=NULL){ + ms_free(cfg->dial_prefix); + cfg->dial_prefix=NULL; + } + if (prefix) cfg->dial_prefix=ms_strdup(prefix); +} + +/** + * Returns dialing prefix. + * + * +**/ +const char *linphone_proxy_config_get_dial_prefix(const LinphoneProxyConfig *cfg){ + return cfg->dial_prefix; +} + +/** + * Sets whether liblinphone should replace "+" by "00" in dialed numbers (passed to + * #linphone_core_invite ). + * +**/ +void linphone_proxy_config_set_dial_escape_plus(LinphoneProxyConfig *cfg, bool_t val){ + cfg->dial_escape_plus=val; +} + +/** + * Returns whether liblinphone should replace "+" by "00" in dialed numbers (passed to + * #linphone_core_invite ). + * +**/ +bool_t linphone_proxy_config_get_dial_escape_plus(const LinphoneProxyConfig *cfg){ + return cfg->dial_escape_plus; +} + + +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=='/' || + *p=='+') continue; + else return FALSE; + } + return TRUE; +} + +static char *flatten_number(const char *number){ + char *result=ms_malloc0(strlen(number)+1); + char *w=result; + const char *r; + for(r=number;*r!='\0';++r){ + if (*r=='+' || isdigit(*r)){ + *w++=*r; + } + } + *w++='\0'; + return result; +} + +static void copy_result(const char *src, char *dest, size_t destlen, bool_t escape_plus){ + int i=0; + + if (escape_plus && src[0]=='+' && destlen>2){ + dest[0]='0'; + dest[1]='0'; + src++; + i=2; + } + + for(;i<destlen-1;++i){ + dest[i]=*src; + src++; + } + dest[i]='\0'; +} + + +static char *append_prefix(const char *number, const char *prefix){ + char *res=ms_malloc(strlen(number)+strlen(prefix)+1); + strcpy(res,prefix); + return strcat(res,number); +} + +int linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const char *username, char *result, size_t result_len){ + char *flatten; + int numlen; + if (is_a_phone_number(username)){ + flatten=flatten_number(username); + ms_message("Flattened number is '%s'",flatten); + numlen=strlen(flatten); + if (numlen>10 || flatten[0]=='+' || proxy->dial_prefix==NULL){ + ms_message("No need to add a prefix"); + /* prefix is already there */ + copy_result(flatten,result,result_len,proxy->dial_escape_plus); + ms_free(flatten); + return 0; + }else if (proxy->dial_prefix){ + 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; + } + 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; +} + /** * Commits modification made to the proxy configuration. **/ @@ -669,6 +798,8 @@ void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyC lp_config_set_int(config,key,"reg_expires",obj->expires); lp_config_set_int(config,key,"reg_sendregister",obj->reg_sendregister); lp_config_set_int(config,key,"publish",obj->publish); + lp_config_set_int(config,key,"dial_escape_plus",obj->dial_escape_plus); + lp_config_set_string(config,key,"dial_prefix",obj->dial_prefix); } @@ -702,6 +833,9 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LpConfig *config linphone_proxy_config_enableregister(cfg,lp_config_get_int(config,key,"reg_sendregister",0)); linphone_proxy_config_enable_publish(cfg,lp_config_get_int(config,key,"publish",0)); + + linphone_proxy_config_set_dial_escape_plus(cfg,lp_config_get_int(config,key,"dial_escape_plus",0)); + linphone_proxy_config_set_dial_prefix(cfg,lp_config_get_string(config,key,"dial_prefix",NULL)); tmp=lp_config_get_string(config,key,"type",NULL); if (tmp!=NULL && strlen(tmp)>0)