mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-18 03:28:07 +00:00
proxy: add linphone_proxy_config_normalize_phone_number and linphone_proxy_config_normalize_sip_uri to ease high level API usage
This commit is contained in:
parent
2917e8ad98
commit
75ecf665ab
4 changed files with 172 additions and 91 deletions
|
|
@ -2549,87 +2549,8 @@ void linphone_core_iterate(LinphoneCore *lc){
|
|||
}
|
||||
}
|
||||
|
||||
static LinphoneAddress* _linphone_core_destroy_addr_if_not_sip( LinphoneAddress* addr ){
|
||||
if( linphone_address_is_sip(addr) ) {
|
||||
return addr;
|
||||
} else {
|
||||
linphone_address_destroy(addr);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpret a call destination as supplied by the user, and returns a fully qualified
|
||||
* LinphoneAddress.
|
||||
*
|
||||
* @ingroup call_control
|
||||
*
|
||||
* A sip address should look like DisplayName \<sip:username\@domain:port\> .
|
||||
* Basically this function performs the following tasks
|
||||
* - if a phone number is entered, prepend country prefix of the default proxy
|
||||
* configuration, eventually escape the '+' by 00.
|
||||
* - if no domain part is supplied, append the domain name of the default proxy
|
||||
* - if no sip: is present, prepend it
|
||||
*
|
||||
* The result is a syntaxically correct SIP address.
|
||||
**/
|
||||
|
||||
LinphoneAddress * linphone_core_interpret_url(LinphoneCore *lc, const char *url){
|
||||
enum_lookup_res_t *enumres=NULL;
|
||||
char *enum_domain=NULL;
|
||||
LinphoneProxyConfig *proxy=lc->default_proxy;
|
||||
char *tmpurl;
|
||||
LinphoneAddress *uri;
|
||||
|
||||
if (*url=='\0') return NULL;
|
||||
|
||||
if (is_enum(url,&enum_domain)){
|
||||
linphone_core_notify_display_status(lc,_("Looking for telephone number destination..."));
|
||||
if (enum_lookup(enum_domain,&enumres)<0){
|
||||
linphone_core_notify_display_status(lc,_("Could not resolve this number."));
|
||||
ms_free(enum_domain);
|
||||
return NULL;
|
||||
}
|
||||
ms_free(enum_domain);
|
||||
tmpurl=enumres->sip_address[0];
|
||||
uri=linphone_address_new(tmpurl);
|
||||
enum_lookup_res_free(enumres);
|
||||
return _linphone_core_destroy_addr_if_not_sip(uri);
|
||||
}
|
||||
/* check if we have a "sip:" or a "sips:" */
|
||||
if ( (strstr(url,"sip:")==NULL) && (strstr(url,"sips:")==NULL) ){
|
||||
/* this doesn't look like a true sip uri */
|
||||
if (strchr(url,'@')!=NULL){
|
||||
/* seems like sip: is missing !*/
|
||||
tmpurl=ms_strdup_printf("sip:%s",url);
|
||||
uri=linphone_address_new(tmpurl);
|
||||
ms_free(tmpurl);
|
||||
if (uri){
|
||||
return _linphone_core_destroy_addr_if_not_sip(uri);
|
||||
}
|
||||
}
|
||||
|
||||
if (proxy!=NULL){
|
||||
/* append the proxy domain suffix */
|
||||
const char *identity=linphone_proxy_config_get_identity(proxy);
|
||||
char normalized_username[128];
|
||||
uri=linphone_address_new(identity);
|
||||
if (uri==NULL){
|
||||
return NULL;
|
||||
}
|
||||
linphone_address_set_display_name(uri,NULL);
|
||||
linphone_proxy_config_normalize_number(proxy,url,normalized_username,
|
||||
sizeof(normalized_username));
|
||||
linphone_address_set_username(uri,normalized_username);
|
||||
return _linphone_core_destroy_addr_if_not_sip(uri);
|
||||
}else return NULL;
|
||||
}
|
||||
uri=linphone_address_new(url);
|
||||
if (uri!=NULL){
|
||||
return _linphone_core_destroy_addr_if_not_sip(uri);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return linphone_proxy_config_normalize_sip_uri(NULL, url);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1097,6 +1097,29 @@ LINPHONE_PUBLIC bool_t linphone_proxy_config_is_phone_number(LinphoneProxyConfig
|
|||
LINPHONE_PUBLIC bool_t linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const char *username,
|
||||
char *result, size_t result_len);
|
||||
|
||||
/**
|
||||
* Same objective as linphone_proxy_config_normalize_number but allocates a new string
|
||||
* @param proxy #LinphoneProxyConfig object containing country code and/or escape symbol. If NULL passed, will use default configuration.
|
||||
* @param username the string to parse
|
||||
* @return NULL if invalid phone number, normalized phone number from username input otherwise.
|
||||
*/
|
||||
LINPHONE_PUBLIC char* linphone_proxy_config_normalize_phone_number(LinphoneProxyConfig *proxy, const char *username);
|
||||
|
||||
/**
|
||||
* Normalize a human readable sip uri into a fully qualified LinphoneAddress.
|
||||
* A sip address should look like DisplayName \<sip:username\@domain:port\> .
|
||||
* Basically this function performs the following tasks
|
||||
* - if a phone number is entered, prepend country prefix and eventually escape the '+' by 00 of the proxy config.
|
||||
* - if no domain part is supplied, append the domain name of the proxy config.
|
||||
* - if no sip: is present, prepend it.
|
||||
*
|
||||
* The result is a syntactically correct SIP address.
|
||||
* @param proxy #LinphoneProxyConfig object containing country code, escape symbol and/or domain name. If NULL passed, will use default configuration.
|
||||
* @param username the string to parse
|
||||
* @return NULL if invalid phone number, normalized phone number from username input otherwise.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneAddress* linphone_proxy_config_normalize_sip_uri(LinphoneProxyConfig *proxy, const char *username);
|
||||
|
||||
/**
|
||||
* Set default privacy policy for all calls routed through this proxy.
|
||||
* @param cfg #LinphoneProxyConfig object to be modified
|
||||
|
|
@ -2504,6 +2527,7 @@ LINPHONE_PUBLIC void linphone_core_remove_listener(LinphoneCore *lc, const Linph
|
|||
/*sets the user-agent string in sip messages, ideally called just after linphone_core_new() or linphone_core_init() */
|
||||
LINPHONE_PUBLIC void linphone_core_set_user_agent(LinphoneCore *lc, const char *ua_name, const char *version);
|
||||
|
||||
/** @deprecated Use linphone_proxy_config_normalize_sip_uri instead. */
|
||||
LINPHONE_PUBLIC LinphoneAddress * linphone_core_interpret_url(LinphoneCore *lc, const char *url);
|
||||
|
||||
LINPHONE_PUBLIC LinphoneCall * linphone_core_invite(LinphoneCore *lc, const char *url);
|
||||
|
|
|
|||
142
coreapi/proxy.c
142
coreapi/proxy.c
|
|
@ -23,6 +23,7 @@ Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org)
|
|||
#include "lpconfig.h"
|
||||
#include "private.h"
|
||||
#include "mediastreamer2/mediastream.h"
|
||||
#include "enum.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
|
|
@ -938,33 +939,40 @@ static void replace_icp_with_plus(const char *src, char *dest, size_t destlen, c
|
|||
strncpy(dest+i, src+strlen(icp), destlen-i-1);
|
||||
}
|
||||
|
||||
static char* replace_plus_with_icp_new(char *phone, const char* icp){
|
||||
return (icp && phone[0]=='+') ? ms_strdup_printf("%s%s", icp, phone+1) : ms_strdup(phone);
|
||||
}
|
||||
|
||||
bool_t linphone_proxy_config_normalize_number(LinphoneProxyConfig *inproxy, const char *username, char *result, size_t result_len){
|
||||
static char* replace_icp_with_plus_new(char *phone, const char *icp){
|
||||
return (strstr(phone, icp) == phone) ? ms_strdup_printf("+%s", phone+strlen(icp)) : ms_strdup(phone);
|
||||
}
|
||||
|
||||
bool_t linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const char *username, char *result, size_t result_len){
|
||||
bool_t ret;
|
||||
LinphoneProxyConfig *proxy = inproxy ? inproxy : linphone_proxy_config_new();
|
||||
LinphoneProxyConfig *tmpproxy = proxy ? proxy : linphone_proxy_config_new();
|
||||
memset(result, 0, result_len);
|
||||
if (linphone_proxy_config_is_phone_number(proxy, username)){
|
||||
if (linphone_proxy_config_is_phone_number(tmpproxy, username)){
|
||||
dial_plan_t dialplan = {0};
|
||||
char *flatten=flatten_number(username);
|
||||
ms_debug("Flattened number is '%s'",flatten);
|
||||
|
||||
/*username does not contain a dial prefix nor the proxy, nothing else to do*/
|
||||
if (proxy->dial_prefix==NULL || proxy->dial_prefix[0]=='\0'){
|
||||
/*username does not contain a dial prefix nor the tmpproxy, nothing else to do*/
|
||||
if (tmpproxy->dial_prefix==NULL || tmpproxy->dial_prefix[0]=='\0'){
|
||||
strncpy(result,flatten,result_len-1);
|
||||
} else {
|
||||
lookup_dial_plan_by_ccc(proxy->dial_prefix,&dialplan);
|
||||
lookup_dial_plan_by_ccc(tmpproxy->dial_prefix,&dialplan);
|
||||
ms_debug("Using dial plan '%s'",dialplan.country);
|
||||
/* the number has international prefix or +, so nothing to do*/
|
||||
if (flatten[0]=='+'){
|
||||
ms_debug("Prefix already present.");
|
||||
/*eventually replace the plus by the international calling prefix of the country*/
|
||||
if (proxy->dial_escape_plus) {
|
||||
if (tmpproxy->dial_escape_plus) {
|
||||
replace_plus_with_icp(flatten,result,result_len,dialplan.icp);
|
||||
}else{
|
||||
strncpy(result, flatten, result_len-1);
|
||||
}
|
||||
}else if (strstr(flatten,dialplan.icp)==flatten){
|
||||
if (proxy->dial_escape_plus){
|
||||
if (tmpproxy->dial_escape_plus){
|
||||
strncpy(result, flatten, result_len-1);
|
||||
}else{
|
||||
replace_icp_with_plus(flatten, result, result_len, dialplan.icp);
|
||||
|
|
@ -978,7 +986,7 @@ bool_t linphone_proxy_config_normalize_number(LinphoneProxyConfig *inproxy, cons
|
|||
skip=numlen-dialplan.nnl;
|
||||
if (skip<0) skip=0;
|
||||
/*first prepend international calling prefix or +*/
|
||||
if (proxy->dial_escape_plus){
|
||||
if (tmpproxy->dial_escape_plus){
|
||||
strncpy(result,dialplan.icp,result_len);
|
||||
i+=strlen(dialplan.icp);
|
||||
}else{
|
||||
|
|
@ -994,17 +1002,129 @@ bool_t linphone_proxy_config_normalize_number(LinphoneProxyConfig *inproxy, cons
|
|||
strncpy(result+i,flatten+skip,result_len-i-1);
|
||||
}
|
||||
}
|
||||
|
||||
ms_free(flatten);
|
||||
ret = TRUE;
|
||||
} else {
|
||||
strncpy(result,username,result_len-1);
|
||||
ret = FALSE;
|
||||
}
|
||||
if (inproxy==NULL) ms_free(proxy);
|
||||
if (proxy==NULL) ms_free(tmpproxy);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* linphone_proxy_config_normalize_phone_number(LinphoneProxyConfig *proxy, const char *username) {
|
||||
LinphoneProxyConfig *tmpproxy = proxy ? proxy : linphone_proxy_config_new();
|
||||
char* result = NULL;
|
||||
if (linphone_proxy_config_is_phone_number(tmpproxy, username)){
|
||||
dial_plan_t dialplan = {0};
|
||||
char * flatten=flatten_number(username);
|
||||
ms_debug("Flattened number is '%s'",flatten);
|
||||
|
||||
/*if proxy has a dial prefix, modify phonenumber accordingly*/
|
||||
if (tmpproxy->dial_prefix!=NULL && tmpproxy->dial_prefix[0]!='\0'){
|
||||
lookup_dial_plan_by_ccc(tmpproxy->dial_prefix,&dialplan);
|
||||
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_new(flatten,dialplan.icp);
|
||||
} else {
|
||||
result = replace_icp_with_plus_new(flatten,dialplan.icp);
|
||||
}
|
||||
}else{
|
||||
/*0. keep at most national number significant digits */
|
||||
char* flatten_start = flatten + MAX(0, strlen(flatten) - dialplan.nnl);
|
||||
/*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);
|
||||
}
|
||||
}
|
||||
if (result==NULL) {
|
||||
result = flatten;
|
||||
} else {
|
||||
ms_free(flatten);
|
||||
}
|
||||
}
|
||||
if (proxy==NULL) ms_free(tmpproxy);
|
||||
return result;
|
||||
}
|
||||
|
||||
static LinphoneAddress* _linphone_core_destroy_addr_if_not_sip( LinphoneAddress* addr ){
|
||||
if( linphone_address_is_sip(addr) ) {
|
||||
return addr;
|
||||
} else {
|
||||
linphone_address_destroy(addr);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
LinphoneAddress* linphone_proxy_config_normalize_sip_uri(LinphoneProxyConfig *proxy, const char *username) {
|
||||
enum_lookup_res_t *enumres=NULL;
|
||||
char *enum_domain=NULL;
|
||||
char *tmpurl;
|
||||
LinphoneAddress *uri;
|
||||
|
||||
if (*username=='\0') return NULL;
|
||||
|
||||
if (is_enum(username,&enum_domain)){
|
||||
if (proxy) {
|
||||
linphone_core_notify_display_status(proxy->lc,_("Looking for telephone number destination..."));
|
||||
}
|
||||
if (enum_lookup(enum_domain,&enumres)<0){
|
||||
if (proxy) {
|
||||
linphone_core_notify_display_status(proxy->lc,_("Could not resolve this number."));
|
||||
}
|
||||
ms_free(enum_domain);
|
||||
return NULL;
|
||||
}
|
||||
ms_free(enum_domain);
|
||||
tmpurl=enumres->sip_address[0];
|
||||
uri=linphone_address_new(tmpurl);
|
||||
enum_lookup_res_free(enumres);
|
||||
return _linphone_core_destroy_addr_if_not_sip(uri);
|
||||
}
|
||||
/* check if we have a "sip:" or a "sips:" */
|
||||
if ( (strstr(username,"sip:")==NULL) && (strstr(username,"sips:")==NULL) ){
|
||||
/* this doesn't look like a true sip uri */
|
||||
if (strchr(username,'@')!=NULL){
|
||||
/* seems like sip: is missing !*/
|
||||
tmpurl=ms_strdup_printf("sip:%s",username);
|
||||
uri=linphone_address_new(tmpurl);
|
||||
ms_free(tmpurl);
|
||||
if (uri){
|
||||
return _linphone_core_destroy_addr_if_not_sip(uri);
|
||||
}
|
||||
}
|
||||
|
||||
if (proxy!=NULL){
|
||||
/* append the proxy domain suffix */
|
||||
const char *identity=linphone_proxy_config_get_identity(proxy);
|
||||
char normalized_username[128];
|
||||
uri=linphone_address_new(identity);
|
||||
if (uri==NULL){
|
||||
return NULL;
|
||||
}
|
||||
linphone_address_set_display_name(uri,NULL);
|
||||
linphone_proxy_config_normalize_number(proxy,username,normalized_username,
|
||||
sizeof(normalized_username));
|
||||
linphone_address_set_username(uri,normalized_username);
|
||||
return _linphone_core_destroy_addr_if_not_sip(uri);
|
||||
}else return NULL;
|
||||
}
|
||||
uri=linphone_address_new(username);
|
||||
if (uri!=NULL){
|
||||
return _linphone_core_destroy_addr_if_not_sip(uri);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits modification made to the proxy configuration.
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -78,10 +78,26 @@ static void phone_normalization_with_dial_escape_plus(void){
|
|||
linphone_proxy_config_destroy(proxy);
|
||||
}
|
||||
|
||||
#define SIP_URI_CHECK(actual, expected) { \
|
||||
LinphoneAddress* res = linphone_proxy_config_normalize_sip_uri(NULL, actual); \
|
||||
char* actual_str = linphone_address_as_string_uri_only(res); \
|
||||
BC_ASSERT_STRING_EQUAL(actual_str, expected); \
|
||||
ms_free(actual_str); \
|
||||
linphone_address_destroy(res); \
|
||||
}
|
||||
|
||||
|
||||
static void sip_uri_normalization(void) {
|
||||
BC_ASSERT_PTR_NULL(linphone_proxy_config_normalize_sip_uri(NULL, "test"));
|
||||
SIP_URI_CHECK("test@linphone.org", "sip:test@linphone.org");
|
||||
SIP_URI_CHECK("test@linphone.org;transport=tls", "sip:test@linphone.org;transport=tls");
|
||||
}
|
||||
|
||||
test_t proxy_config_tests[] = {
|
||||
{ "Phone normalization without proxy", phone_normalization_without_proxy },
|
||||
{ "Phone normalization with proxy", phone_normalization_with_proxy },
|
||||
{ "Phone normalization with dial escape plus", phone_normalization_with_dial_escape_plus },
|
||||
{ "SIP URI normalization", sip_uri_normalization },
|
||||
};
|
||||
|
||||
test_suite_t proxy_config_test_suite = {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue