From 6b2be053e9e9dfeea34d28679d4bab68068f97f7 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 9 Dec 2014 10:14:33 +0100 Subject: [PATCH] Improve change of identity of a proxy config. - Add the function linphone_address_equal(). - The comparison of two proxy config addresses now returns one of these three values: equal, weak-equal or different. - If the new proxy config identity is equal to the previous one, a call to linphone_proxy_config_done() does not unregister and does not delete the sal op. If it's weak-equal the sal op is destroyed but the unregister is not done. Finally, if it's different the unregister is performed and the sal op is destroyed. --- coreapi/address.c | 26 +++++++++++++++++++++++- coreapi/linphonecore.h | 1 + coreapi/private.h | 10 ++++++++-- coreapi/proxy.c | 44 +++++++++++++++++++++++------------------ tester/accountmanager.c | 6 +++++- tester/setup_tester.c | 30 ++++++++++++++++------------ 6 files changed, 81 insertions(+), 36 deletions(-) diff --git a/coreapi/address.c b/coreapi/address.c index 6530551ea..764a8fb24 100644 --- a/coreapi/address.c +++ b/coreapi/address.c @@ -167,7 +167,10 @@ static bool_t strings_equals(const char *s1, const char *s2){ /** * Compare two LinphoneAddress ignoring tags and headers, basically just domain, username, and port. - * Returns TRUE if they are equal. + * @param[in] a1 LinphoneAddress object + * @param[in] a2 LinphoneAddress object + * @return Boolean value telling if the LinphoneAddress objects are equal. + * @see linphone_address_equal() **/ bool_t linphone_address_weak_equal(const LinphoneAddress *a1, const LinphoneAddress *a2){ const char *u1,*u2; @@ -182,6 +185,27 @@ bool_t linphone_address_weak_equal(const LinphoneAddress *a1, const LinphoneAddr return strings_equals(u1,u2) && strings_equals(h1,h2) && p1==p2; } +/** + * Compare two LinphoneAddress taking the tags and headers into account. + * @param[in] a1 LinphoneAddress object + * @param[in] a2 LinphoneAddress object + * @return Boolean value telling if the LinphoneAddress objects are equal. + * @see linphone_address_weak_equal() + */ +bool_t linphone_address_equal(const LinphoneAddress *a1, const LinphoneAddress *a2) { + char *s1; + char *s2; + bool_t res; + if ((a1 == NULL) && (a2 == NULL)) return TRUE; + if ((a1 == NULL) || (a2 == NULL)) return FALSE; + s1 = linphone_address_as_string(a1); + s2 = linphone_address_as_string(a2); + res = (strcmp(s1, s2) == 0) ? TRUE : FALSE; + ms_free(s1); + ms_free(s2); + return res; +} + /** * Destroys a LinphoneAddress object (actually calls linphone_address_unref()). * @deprecated Use linphone_address_unref() instead diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 515bbcf7e..448c9aa57 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -400,6 +400,7 @@ LINPHONE_PUBLIC void linphone_address_set_transport(LinphoneAddress *uri,Linphon LINPHONE_PUBLIC char *linphone_address_as_string(const LinphoneAddress *u); LINPHONE_PUBLIC char *linphone_address_as_string_uri_only(const LinphoneAddress *u); LINPHONE_PUBLIC bool_t linphone_address_weak_equal(const LinphoneAddress *a1, const LinphoneAddress *a2); +LINPHONE_PUBLIC bool_t linphone_address_equal(const LinphoneAddress *a1, const LinphoneAddress *a2); LINPHONE_PUBLIC void linphone_address_set_password(LinphoneAddress *addr, const char *passwd); LINPHONE_PUBLIC const char *linphone_address_get_password(const LinphoneAddress *addr); LINPHONE_PUBLIC void linphone_address_set_header(LinphoneAddress *addr, const char *header_name, const char *header_value); diff --git a/coreapi/private.h b/coreapi/private.h index 424fa1f4e..3aa9b283d 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -445,8 +445,14 @@ bool_t linphone_core_symmetric_rtp_enabled(LinphoneCore*lc); void linphone_core_queue_task(LinphoneCore *lc, belle_sip_source_func_t task_fun, void *data, const char *task_description); -LINPHONE_PUBLIC bool_t linphone_proxy_config_address_equal(const LinphoneAddress *a, const LinphoneAddress *b); -LINPHONE_PUBLIC bool_t linphone_proxy_config_is_server_config_changed(const LinphoneProxyConfig* obj); +typedef enum _LinphoneProxyConfigAddressComparisonResult{ + LinphoneProxyConfigAddressDifferent, + LinphoneProxyConfigAddressEqual, + LinphoneProxyConfigAddressWeakEqual +} LinphoneProxyConfigAddressComparisonResult; + +LINPHONE_PUBLIC LinphoneProxyConfigAddressComparisonResult linphone_proxy_config_address_equal(const LinphoneAddress *a, const LinphoneAddress *b); +LINPHONE_PUBLIC LinphoneProxyConfigAddressComparisonResult linphone_proxy_config_is_server_config_changed(const LinphoneProxyConfig* obj); void _linphone_proxy_config_unregister(LinphoneProxyConfig *obj); void _linphone_proxy_config_release_ops(LinphoneProxyConfig *obj); diff --git a/coreapi/proxy.c b/coreapi/proxy.c index ca9c21c9d..275613477 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -41,33 +41,34 @@ static void linphone_proxy_config_store_server_config(LinphoneProxyConfig* obj) obj->saved_proxy = NULL; } -bool_t linphone_proxy_config_address_equal(const LinphoneAddress *a, const LinphoneAddress *b) { +LinphoneProxyConfigAddressComparisonResult linphone_proxy_config_address_equal(const LinphoneAddress *a, const LinphoneAddress *b) { if (a == NULL && b == NULL) - return TRUE; + return LinphoneProxyConfigAddressEqual; else if (!a || !b) - return FALSE; + return LinphoneProxyConfigAddressDifferent; + if (linphone_address_equal(a,b)) + return LinphoneProxyConfigAddressEqual; if (linphone_address_weak_equal(a,b)) { /*also check both transport and uri */ - return linphone_address_is_secure(a) == linphone_address_is_secure(b) && linphone_address_get_transport(a) == linphone_address_get_transport(b); - } else - return FALSE; /*either username, domain or port ar not equals*/ - + if (linphone_address_is_secure(a) == linphone_address_is_secure(b) && linphone_address_get_transport(a) == linphone_address_get_transport(b)) + return LinphoneProxyConfigAddressWeakEqual; + else + return LinphoneProxyConfigAddressDifferent; + } + return LinphoneProxyConfigAddressDifferent; /*either username, domain or port ar not equals*/ } -bool_t linphone_proxy_config_is_server_config_changed(const LinphoneProxyConfig* obj) { +LinphoneProxyConfigAddressComparisonResult linphone_proxy_config_is_server_config_changed(const LinphoneProxyConfig* obj) { LinphoneAddress *current_identity=obj->reg_identity?linphone_address_new(obj->reg_identity):NULL; LinphoneAddress *current_proxy=obj->reg_proxy?linphone_address_new(obj->reg_proxy):NULL; - bool_t result=FALSE; + LinphoneProxyConfigAddressComparisonResult result=LinphoneProxyConfigAddressDifferent; - if (!linphone_proxy_config_address_equal(obj->saved_identity,current_identity)){ - result=TRUE; - goto end; - } - if (!linphone_proxy_config_address_equal(obj->saved_proxy,current_proxy)){ - result=TRUE; - goto end; - } + result = linphone_proxy_config_address_equal(obj->saved_identity,current_identity); + if (result == LinphoneProxyConfigAddressDifferent) goto end; + + result = linphone_proxy_config_address_equal(obj->saved_proxy,current_proxy); + if (result == LinphoneProxyConfigAddressDifferent) goto end; end: if (current_identity) linphone_address_destroy(current_identity); @@ -976,14 +977,19 @@ int linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const cha **/ int linphone_proxy_config_done(LinphoneProxyConfig *obj) { + LinphoneProxyConfigAddressComparisonResult res; + if (!linphone_proxy_config_check(obj->lc,obj)) return -1; /*check if server address as changed*/ - if (linphone_proxy_config_is_server_config_changed(obj)) { + res = linphone_proxy_config_is_server_config_changed(obj); + if (res != LinphoneProxyConfigAddressEqual) { /* server config has changed, need to unregister from previous first*/ if (obj->op) { - _linphone_proxy_config_unregister(obj); + if (res == LinphoneProxyConfigAddressDifferent) { + _linphone_proxy_config_unregister(obj); + } sal_op_set_user_pointer(obj->op,NULL); /*we don't want to receive status for this un register*/ sal_op_unref(obj->op); /*but we keep refresher to handle authentication if needed*/ obj->op=NULL; diff --git a/tester/accountmanager.c b/tester/accountmanager.c index a3086f9cf..97cf8803b 100644 --- a/tester/accountmanager.c +++ b/tester/accountmanager.c @@ -118,10 +118,15 @@ void account_create_on_server(Account *account, const LinphoneProxyConfig *refcf LinphoneAuthInfo *ai; char *tmp; LinphoneAddress *server_addr; + LCSipTransports tr; vtable.registration_state_changed=account_created_on_server_cb; vtable.auth_info_requested=account_created_auth_requested_cb; lc=configure_lc_from(&vtable,liblinphone_tester_file_prefix,NULL,account); + tr.udp_port=LC_SIP_TRANSPORT_RANDOM; + tr.tcp_port=LC_SIP_TRANSPORT_RANDOM; + tr.tls_port=LC_SIP_TRANSPORT_RANDOM; + linphone_core_set_sip_transports(lc,&tr); cfg=linphone_core_create_proxy_config(lc); linphone_address_set_password(tmp_identity,account->password); @@ -145,7 +150,6 @@ void account_create_on_server(Account *account, const LinphoneProxyConfig *refcf if (wait_for_until(lc,NULL,&account->auth_requested,1,10000)==FALSE){ ms_fatal("Account for %s could not be created on server.", linphone_proxy_config_get_identity(refcfg)); } - linphone_proxy_config_stop_refreshing(cfg); /*so that op is destroyed; we need to remove the X-create-account*/ linphone_proxy_config_edit(cfg); tmp=linphone_address_as_string(account->modified_identity); linphone_proxy_config_set_identity(cfg,tmp); /*remove the X-Create-Account header*/ diff --git a/tester/setup_tester.c b/tester/setup_tester.c index eaa9b6a97..21fcfd091 100644 --- a/tester/setup_tester.c +++ b/tester/setup_tester.c @@ -170,13 +170,17 @@ void linphone_proxy_config_address_equal_test() { LinphoneAddress *c = linphone_address_new("sip:toto@titi;transport=tcp"); LinphoneAddress *d = linphone_address_new("sip:toto@titu"); LinphoneAddress *e = linphone_address_new("sip:toto@titi;transport=udp"); + LinphoneAddress *f = linphone_address_new("sip:toto@titi?X-Create-Account=yes"); - CU_ASSERT_FALSE(linphone_proxy_config_address_equal(a,NULL)); - CU_ASSERT_FALSE(linphone_proxy_config_address_equal(a,b)); - CU_ASSERT_FALSE(linphone_proxy_config_address_equal(a,c)); - CU_ASSERT_FALSE(linphone_proxy_config_address_equal(a,d)); - CU_ASSERT_TRUE(linphone_proxy_config_address_equal(a,e)); - CU_ASSERT_TRUE(linphone_proxy_config_address_equal(NULL,NULL)); + CU_ASSERT_EQUAL(linphone_proxy_config_address_equal(a,NULL), LinphoneProxyConfigAddressDifferent); + CU_ASSERT_EQUAL(linphone_proxy_config_address_equal(a,b), LinphoneProxyConfigAddressDifferent); + CU_ASSERT_EQUAL(linphone_proxy_config_address_equal(a,c), LinphoneProxyConfigAddressDifferent); + CU_ASSERT_EQUAL(linphone_proxy_config_address_equal(a,d), LinphoneProxyConfigAddressDifferent); + CU_ASSERT_EQUAL(linphone_proxy_config_address_equal(a,e), LinphoneProxyConfigAddressWeakEqual); + CU_ASSERT_EQUAL(linphone_proxy_config_address_equal(NULL,NULL), LinphoneProxyConfigAddressEqual); + CU_ASSERT_EQUAL(linphone_proxy_config_address_equal(a,f), LinphoneProxyConfigAddressWeakEqual); + CU_ASSERT_EQUAL(linphone_proxy_config_address_equal(c,f), LinphoneProxyConfigAddressDifferent); + CU_ASSERT_EQUAL(linphone_proxy_config_address_equal(e,f), LinphoneProxyConfigAddressWeakEqual); linphone_address_destroy(a); linphone_address_destroy(b); @@ -192,36 +196,36 @@ void linphone_proxy_config_is_server_config_changed_test() { linphone_proxy_config_set_identity(proxy_config,"sip:toto@titi"); linphone_proxy_config_edit(proxy_config); linphone_proxy_config_set_identity(proxy_config,"sips:toto@titi"); - CU_ASSERT_TRUE(linphone_proxy_config_is_server_config_changed(proxy_config)); + CU_ASSERT_EQUAL(linphone_proxy_config_is_server_config_changed(proxy_config), LinphoneProxyConfigAddressDifferent); linphone_proxy_config_set_server_addr(proxy_config,"sip:sip.linphone.org"); linphone_proxy_config_edit(proxy_config); linphone_proxy_config_set_server_addr(proxy_config,"sip:toto.com"); - CU_ASSERT_TRUE(linphone_proxy_config_is_server_config_changed(proxy_config)); + CU_ASSERT_EQUAL(linphone_proxy_config_is_server_config_changed(proxy_config), LinphoneProxyConfigAddressDifferent); linphone_proxy_config_set_server_addr(proxy_config,"sip:sip.linphone.org"); linphone_proxy_config_edit(proxy_config); linphone_proxy_config_set_server_addr(proxy_config,"sip:sip.linphone.org:4444"); - CU_ASSERT_TRUE(linphone_proxy_config_is_server_config_changed(proxy_config)); + CU_ASSERT_EQUAL(linphone_proxy_config_is_server_config_changed(proxy_config), LinphoneProxyConfigAddressDifferent); linphone_proxy_config_set_server_addr(proxy_config,"sip:sip.linphone.org"); linphone_proxy_config_edit(proxy_config); linphone_proxy_config_set_server_addr(proxy_config,"sip:sip.linphone.org;transport=tcp"); - CU_ASSERT_TRUE(linphone_proxy_config_is_server_config_changed(proxy_config)); + CU_ASSERT_EQUAL(linphone_proxy_config_is_server_config_changed(proxy_config), LinphoneProxyConfigAddressDifferent); linphone_proxy_config_set_server_addr(proxy_config,"sip:sip.linphone.org"); linphone_proxy_config_edit(proxy_config); linphone_proxy_config_set_server_addr(proxy_config,"sip:sip.linphone.org;param=blue"); - CU_ASSERT_FALSE(linphone_proxy_config_is_server_config_changed(proxy_config)); + CU_ASSERT_EQUAL(linphone_proxy_config_is_server_config_changed(proxy_config), LinphoneProxyConfigAddressWeakEqual); linphone_proxy_config_edit(proxy_config); linphone_proxy_config_set_contact_parameters(proxy_config,"blabla=blue"); - CU_ASSERT_FALSE(linphone_proxy_config_is_server_config_changed(proxy_config)); + CU_ASSERT_EQUAL(linphone_proxy_config_is_server_config_changed(proxy_config), LinphoneProxyConfigAddressEqual); linphone_proxy_config_edit(proxy_config); linphone_proxy_config_enable_register(proxy_config,TRUE); - CU_ASSERT_FALSE(linphone_proxy_config_is_server_config_changed(proxy_config)); + CU_ASSERT_EQUAL(linphone_proxy_config_is_server_config_changed(proxy_config), LinphoneProxyConfigAddressEqual); linphone_proxy_config_destroy(proxy_config); }