diff --git a/coreapi/bellesip_sal/sal_address_impl.c b/coreapi/bellesip_sal/sal_address_impl.c index c7a2603ca..540aa701b 100644 --- a/coreapi/bellesip_sal/sal_address_impl.c +++ b/coreapi/bellesip_sal/sal_address_impl.c @@ -109,6 +109,8 @@ void sal_address_set_port_int(SalAddress *addr, int port){ } void sal_address_clean(SalAddress *addr){ belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr); + belle_sip_uri_t* uri=belle_sip_header_address_get_uri(header_addr); + if (uri) belle_sip_parameters_clean(BELLE_SIP_PARAMETERS(uri)); belle_sip_parameters_clean(BELLE_SIP_PARAMETERS(header_addr)); return ; } diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index cf02d532c..b05517fad 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -146,6 +146,17 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(route_header)); } } + if (!sal_op_get_route_addresses(op) && belle_sip_list_size(belle_sip_provider_get_listening_points(op->base.root->prov))==1) { + /*compatibility mode*/ + belle_sip_listening_point_t* lp = (belle_sip_listening_point_t*)belle_sip_provider_get_listening_points(op->base.root->prov)->data; + belle_sip_uri_t* to_uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(belle_sip_message_get_header_by_type(request,belle_sip_header_to_t))); + belle_sip_header_address_t* route=belle_sip_header_address_create(NULL,belle_sip_uri_create(NULL,belle_sip_uri_get_host(to_uri))); + belle_sip_uri_set_transport_param(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(route)),belle_sip_listening_point_get_transport(lp)); + route_header = belle_sip_header_route_create(route); + belle_sip_object_unref(route); + belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(route_header)); + ms_message("Only one lp & no route, forcing transport to lp transport [%s]",belle_sip_listening_point_get_transport(lp)); + } } client_transaction = belle_sip_provider_create_client_transaction(prov,request); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 0b475e15f..e443ae1b6 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2566,14 +2566,27 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const if (sal_address_get_transport((SalAddress*)addr)) { sal_address_set_transport(route,sal_address_get_transport((SalAddress*)addr)); } else { + LinphoneProxyConfig* chosen_proxy=NULL; + if (dest_proxy) - proxy_addr=sal_address_new(linphone_proxy_config_get_addr(dest_proxy)); + chosen_proxy=dest_proxy; else if (proxy) - proxy_addr=sal_address_new(linphone_proxy_config_get_addr(proxy)); + chosen_proxy=proxy; + else + chosen_proxy=NULL; + + if (chosen_proxy) + proxy_addr=sal_address_new(linphone_proxy_config_get_addr(chosen_proxy)); + if (proxy_addr && sal_address_get_transport(proxy_addr)) sal_address_set_transport(route,sal_address_get_transport(proxy_addr)); + else if (proxy_addr && linphone_proxy_config_guess_transport(chosen_proxy) && !sal_address_get_transport((SalAddress*)route)) { + /*compatibility mode*/ + sal_address_set_transport((SalAddress*)route,sal_transport_parse(linphone_proxy_config_guess_transport(chosen_proxy))); + } } + sal_op_add_route_address(call->op,route); } diff --git a/coreapi/misc.c b/coreapi/misc.c index 85dd51d82..cd62a522f 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -1115,7 +1115,8 @@ static int get_local_ip_for_with_connect(int type, const char *dest, char *resul ms_error("getnameinfo error: %s",strerror(errno)); } close_socket(sock); - ms_message("Local interface to reach %s is %s.",dest,result); + + return 0; } diff --git a/coreapi/private.h b/coreapi/private.h index 8645edbff..19e84f9dc 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -240,7 +240,10 @@ void linphone_proxy_config_write_all_to_config_file(LinphoneCore *lc); * Can be NULL * */ const LinphoneAddress* linphone_proxy_config_get_service_route(const LinphoneProxyConfig* cfg); - +/* + *guess the transport if only one trasport is configured at core level (for backward compatibility) + * */ +const char* linphone_proxy_config_guess_transport(const LinphoneProxyConfig *obj); int linphone_online_status_to_eXosip(LinphoneOnlineStatus os); void linphone_friend_close_subscriptions(LinphoneFriend *lf); diff --git a/coreapi/proxy.c b/coreapi/proxy.c index 00f370c14..76f40eb99 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -347,7 +347,7 @@ LinphoneAddress *guess_contact_for_register(LinphoneProxyConfig *obj){ return ret; } /*use for compatibility with linphone supporting only 1 transport at a time*/ -const char* guess_transport(const LinphoneProxyConfig *obj) { +const char* linphone_proxy_config_guess_transport(const LinphoneProxyConfig *obj) { LCSipTransports transports; const char* transport_name; unsigned char transports_count=0; @@ -383,8 +383,8 @@ static void linphone_proxy_config_register(LinphoneProxyConfig *obj){ char *contact; #else LinphoneAddress *contact; - if (guess_transport(obj) && !sal_address_get_transport((SalAddress*)proxy)) { - sal_address_set_transport((SalAddress*)proxy,sal_transport_parse(guess_transport(obj))); + if (linphone_proxy_config_guess_transport(obj) && !sal_address_get_transport((SalAddress*)proxy)) { + sal_address_set_transport((SalAddress*)proxy,sal_transport_parse(linphone_proxy_config_guess_transport(obj))); } #endif proxy_string=linphone_address_as_string_uri_only(proxy); diff --git a/tester/call_tester.c b/tester/call_tester.c index 2131789ea..9c98fa00d 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -190,6 +190,70 @@ static void simple_call(void) { linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } +static void simple_call_compatibility_mode(void) { + LinphoneCoreManager* marie = linphone_core_manager_new(liblinphone_tester_file_prefix, "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(liblinphone_tester_file_prefix, "pauline_rc"); + + LinphoneCore* lc_marie=marie->lc; + LinphoneCore* lc_pauline=pauline->lc; + stats* stat_marie=&marie->stat; + stats* stat_pauline=&pauline->stat; + LinphoneProxyConfig* proxy; + LinphoneAddress* identity; + LinphoneAddress* proxy_address; + char*tmp; + LCSipTransports transport; + + linphone_core_get_default_proxy(lc_marie,&proxy); + CU_ASSERT_PTR_NOT_NULL (proxy); + identity = linphone_address_new(linphone_proxy_config_get_identity(proxy)); + + + proxy_address=linphone_address_new(linphone_proxy_config_get_addr(proxy)); + linphone_address_clean(proxy_address); + tmp=linphone_address_as_string_uri_only(proxy_address); + linphone_proxy_config_set_server_addr(proxy,tmp); + linphone_proxy_config_set_route(proxy,NULL); + ms_free(tmp); + linphone_address_destroy(proxy_address); + linphone_core_get_sip_transports(lc_marie,&transport); + transport.udp_port=0; + transport.tls_port=0; + transport.dtls_port=0; + /*only keep tcp*/ + linphone_core_set_sip_transports(lc_marie,&transport); + stat_marie->number_of_LinphoneRegistrationOk=0; + + CU_ASSERT_TRUE (wait_for(lc_marie,lc_marie,&stat_marie->number_of_LinphoneRegistrationOk,1)); + + linphone_core_invite(lc_marie,"pauline"); + + CU_ASSERT_TRUE (wait_for(lc_pauline,lc_marie,&stat_pauline->number_of_LinphoneCallIncomingReceived,1)); + CU_ASSERT_TRUE(linphone_core_inc_invite_pending(lc_pauline)); + CU_ASSERT_EQUAL(stat_marie->number_of_LinphoneCallOutgoingProgress,1); + CU_ASSERT_TRUE(wait_for(lc_pauline,lc_marie,&stat_marie->number_of_LinphoneCallOutgoingRinging,1)); + + CU_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call_remote_address(lc_pauline)); + if (linphone_core_get_current_call_remote_address(lc_pauline)) { + CU_ASSERT_TRUE(linphone_address_weak_equal(identity,linphone_core_get_current_call_remote_address(lc_pauline))); + linphone_address_destroy(identity); + + linphone_core_accept_call(lc_pauline,linphone_core_get_current_call(lc_pauline)); + + CU_ASSERT_TRUE(wait_for(lc_pauline,lc_marie,&stat_pauline->number_of_LinphoneCallConnected,1)); + CU_ASSERT_TRUE(wait_for(lc_pauline,lc_marie,&stat_marie->number_of_LinphoneCallConnected,1)); + CU_ASSERT_TRUE(wait_for(lc_pauline,lc_marie,&stat_pauline->number_of_LinphoneCallStreamsRunning,1)); + CU_ASSERT_TRUE(wait_for(lc_pauline,lc_marie,&stat_marie->number_of_LinphoneCallStreamsRunning,1)); + /*just to sleep*/ + wait_for(lc_pauline,lc_marie,&stat_marie->number_of_LinphoneCallStreamsRunning,3); + linphone_core_terminate_all_calls(lc_pauline); + CU_ASSERT_TRUE(wait_for(lc_pauline,lc_marie,&stat_pauline->number_of_LinphoneCallEnd,1)); + CU_ASSERT_TRUE(wait_for(lc_pauline,lc_marie,&stat_marie->number_of_LinphoneCallEnd,1)); + } + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + static void cancelled_call(void) { LinphoneCoreManager* marie = linphone_core_manager_new(liblinphone_tester_file_prefix, "marie_rc"); @@ -619,6 +683,7 @@ test_t call_tests[] = { { "Call with DNS timeout", call_with_dns_time_out }, { "Cancelled ringing call", cancelled_ringing_call }, { "Simple call", simple_call }, + { "Simple call compatibility mode", simple_call_compatibility_mode }, { "Early-media call", early_media_call }, { "Call terminated by caller", call_terminated_by_caller }, { "Call paused resumed", call_paused_resumed }, diff --git a/tester/message_tester.c b/tester/message_tester.c index ad172e472..730546a7d 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -72,6 +72,41 @@ static void text_message(void) { linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } +static void text_message_compatibility_mode(void) { + LinphoneCoreManager* marie = linphone_core_manager_new(liblinphone_tester_file_prefix, "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(liblinphone_tester_file_prefix, "pauline_rc"); + LinphoneProxyConfig* proxy; + LinphoneAddress* proxy_address; + char*tmp; + LCSipTransports transport; + char* to = linphone_address_as_string(pauline->identity); + + linphone_core_get_default_proxy(marie->lc,&proxy); + CU_ASSERT_PTR_NOT_NULL (proxy); + proxy_address=linphone_address_new(linphone_proxy_config_get_addr(proxy)); + linphone_address_clean(proxy_address); + tmp=linphone_address_as_string_uri_only(proxy_address); + linphone_proxy_config_set_server_addr(proxy,tmp); + linphone_proxy_config_set_route(proxy,NULL); + ms_free(tmp); + linphone_address_destroy(proxy_address); + linphone_core_get_sip_transports(marie->lc,&transport); + transport.udp_port=0; + transport.tls_port=0; + transport.dtls_port=0; + /*only keep tcp*/ + linphone_core_set_sip_transports(marie->lc,&transport); + marie->stat.number_of_LinphoneRegistrationOk=0; + + CU_ASSERT_TRUE (wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphoneRegistrationOk,1)); + + LinphoneChatRoom* chat_room = linphone_core_create_chat_room(marie->lc,to); + linphone_chat_room_send_message(chat_room,"Bla bla bla bla"); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageReceived,1)); + CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageReceivedLegacy,1); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} static void text_message_with_ack(void) { LinphoneCoreManager* marie = linphone_core_manager_new(liblinphone_tester_file_prefix, "marie_rc"); @@ -126,6 +161,7 @@ static void text_message_with_send_error(void) { test_t message_tests[] = { { "Text message", text_message }, + { "Text message compatibility mode", text_message_compatibility_mode }, { "Text message with ack", text_message_with_ack }, { "Text message with send error", text_message_with_send_error }, { "Text message with external body", text_message_with_external_body } diff --git a/tester/register_tester.c b/tester/register_tester.c index f60ebe4a5..0b5483f43 100644 --- a/tester/register_tester.c +++ b/tester/register_tester.c @@ -47,9 +47,8 @@ void registration_state_changed(struct _LinphoneCore *lc, LinphoneProxyConfig *c } -static void register_with_refresh_base_2(LinphoneCore* lc, bool_t refresh,const char* domain,const char* route,bool_t late_auth_info) { +static void register_with_refresh_base_2(LinphoneCore* lc, bool_t refresh,const char* domain,const char* route,bool_t late_auth_info,LCSipTransports transport) { int retry=0; - LCSipTransports transport = {5070,5070,0,5071}; char* addr; LinphoneProxyConfig* proxy_cfg; stats* counters; @@ -102,7 +101,8 @@ static void register_with_refresh_base_2(LinphoneCore* lc, bool_t refresh,const } static void register_with_refresh_base(LinphoneCore* lc, bool_t refresh,const char* domain,const char* route) { - register_with_refresh_base_2(lc,refresh,domain,route,FALSE); + LCSipTransports transport = {5070,5070,0,5071}; + register_with_refresh_base_2(lc,refresh,domain,route,FALSE,transport); } static void register_with_refresh(LinphoneCore* lc, bool_t refresh,const char* domain,const char* route) { @@ -169,6 +169,14 @@ static void simple_tcp_register(){ register_with_refresh(lc,FALSE,test_domain,route); } +static void simple_tcp_register_compatibility_mode(){ + LinphoneCore* lc; + LCSipTransports transport = {0,5070,0,0}; + lc = create_lc(); + register_with_refresh_base_2(lc,FALSE,test_domain,NULL,FALSE,transport); +} + + static void simple_tls_register(){ char route[256]; LinphoneCore* lc; @@ -221,6 +229,7 @@ static void authenticated_register_with_late_credentials(){ LinphoneCore* lc; stats stat; stats* counters; + LCSipTransports transport = {5070,5070,0,5071}; char route[256]; sprintf(route,"sip:%s",test_route); memset (&v_table,0,sizeof(v_table)); @@ -229,7 +238,7 @@ static void authenticated_register_with_late_credentials(){ lc = linphone_core_new(&v_table,NULL,NULL,NULL); linphone_core_set_user_data(lc,&stat); counters = (stats*)linphone_core_get_user_data(lc); - register_with_refresh_base_2(lc,FALSE,auth_domain,route,TRUE); + register_with_refresh_base_2(lc,FALSE,auth_domain,route,TRUE,transport); CU_ASSERT_EQUAL(counters->number_of_auth_info_requested,1); linphone_core_destroy(lc); } @@ -331,6 +340,7 @@ static void io_recv_error(){ test_t register_tests[] = { { "Simple register", simple_register }, { "TCP register", simple_tcp_register }, + { "TCP register compatibility mode", simple_tcp_register_compatibility_mode }, #ifndef ANDROID { "TLS register", simple_tls_register }, #endif