Commit 23b6729f authored by smorlat's avatar smorlat
Browse files

add support for prefix and + escaping in phone numbers.

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@804 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
parent 675312b0
......@@ -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 \
......
/*
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);
}
/** @} */
/*
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;
......
......@@ -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);
}
/** @} */
......@@ -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);
......
......@@ -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 */
......@@ -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)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment