From ab41ae3c45c2f8a729d0cb4d3fde6b6477db1706 Mon Sep 17 00:00:00 2001 From: Benjamin Reis Date: Fri, 25 Aug 2017 11:39:37 +0200 Subject: [PATCH] add gruu support --- coreapi/bellesip_sal/sal_op_registration.c | 11 ++- coreapi/linphonecall.c | 8 +- coreapi/linphonecore.c | 13 +-- coreapi/sal.c | 14 +++ include/sal/sal.h | 1 + tester/call_single_tester.c | 99 +++++++++++++++++++++- tester/register_tester.c | 11 +++ 7 files changed, 139 insertions(+), 18 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_registration.c b/coreapi/bellesip_sal/sal_op_registration.c index 1d0ccbb3e..3526152e0 100644 --- a/coreapi/bellesip_sal/sal_op_registration.c +++ b/coreapi/bellesip_sal/sal_op_registration.c @@ -48,8 +48,17 @@ static void register_refresher_listener (belle_sip_refresher_t* refresher if (service_route_address) belle_sip_object_unref(service_route_address); sal_remove_pending_auth(op->base.root,op); /*just in case*/ + if (contact) { - sal_op_set_contact_address(op,(SalAddress*)(BELLE_SIP_HEADER_ADDRESS(contact))); /*update contact with real value*/ + const char *gruu; + belle_sip_parameters_t* p = (BELLE_SIP_PARAMETERS(contact)); + if((gruu = belle_sip_parameters_get_parameter(p, "pub-gruu"))) { + char *unquoted = belle_sip_unquote_strdup(gruu); + sal_op_set_contact_address(op, (SalAddress*)belle_sip_header_address_parse(unquoted)); + belle_sip_parameters_remove_parameter(p, "pub-gruu"); + } else { + sal_op_set_contact_address(op, (SalAddress*)(BELLE_SIP_HEADER_ADDRESS(contact))); /*update contact with real value*/ + } } op->base.root->callbacks.register_success(op,belle_sip_refresher_get_expires(op->refresher)>0); } else if (status_code>=400) { diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 4471af2f1..c455c68e2 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -4983,13 +4983,7 @@ static LinphoneAddress *get_fixed_contact(LinphoneCore *lc, LinphoneCall *call , void linphone_call_set_contact_op(LinphoneCall* call) { LinphoneAddress *contact; contact=get_fixed_contact(call->core,call,call->dest_proxy); - if (contact){ - SalTransport tport=sal_address_get_transport((SalAddress*)contact); - sal_address_clean((SalAddress*)contact); /* clean out contact_params that come from proxy config*/ - sal_address_set_transport((SalAddress*)contact,tport); - sal_op_set_contact_address(call->op, contact); - linphone_address_unref(contact); - } + sal_op_set_and_clean_contact_address(call->op, (SalAddress *)contact); } LinphonePlayer *linphone_call_get_player(LinphoneCall *call){ diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index bf99af464..262082c31 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1387,7 +1387,7 @@ static void sip_config_read(LinphoneCore *lc) { sal_enable_sip_update_method(lc->sal,lp_config_get_int(lc->config,"sip","sip_update",1)); lc->sip_conf.vfu_with_info=lp_config_get_int(lc->config,"sip","vfu_with_info",1); linphone_core_set_sip_transport_timeout(lc, lp_config_get_int(lc->config, "sip", "transport_timeout", 63000)); - sal_set_supported_tags(lc->sal,lp_config_get_string(lc->config,"sip","supported","replaces, outbound")); + sal_set_supported_tags(lc->sal,lp_config_get_string(lc->config,"sip","supported","replaces, outbound, gruu")); lc->sip_conf.save_auth_info = lp_config_get_int(lc->config, "sip", "save_auth_info", 1); linphone_core_create_im_notif_policy(lc); } @@ -3503,14 +3503,9 @@ void linphone_configure_op_with_proxy(LinphoneCore *lc, SalOp *op, const Linphon sal_op_set_realm(op,linphone_proxy_config_get_realm(proxy)); if (with_contact && proxy && proxy->op){ const SalAddress *contact; - if ((contact=sal_op_get_contact_address(proxy->op))){ - SalTransport tport=sal_address_get_transport((SalAddress*)contact); - SalAddress *new_contact=sal_address_clone(contact); - sal_address_clean(new_contact); /* clean out contact_params that come from proxy config*/ - sal_address_set_transport(new_contact,tport); - sal_op_set_contact_address(op,new_contact); - sal_address_destroy(new_contact); - } + contact=sal_op_get_contact_address(proxy->op); + SalAddress *new_contact = contact ? sal_address_clone(contact) : NULL; + sal_op_set_and_clean_contact_address(proxy->op, new_contact); } sal_op_cnx_ip_to_0000_if_sendonly_enable(op,lp_config_get_default_int(lc->config,"sip","cnx_ip_to_0000_if_sendonly_enabled",0)); /*also set in linphone_call_new_incoming*/ } diff --git a/coreapi/sal.c b/coreapi/sal.c index b52557aad..3870e59e3 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -517,6 +517,20 @@ void sal_op_set_contact_address(SalOp *op, const SalAddress *address){ if (((SalOpBase*)op)->contact_address) sal_address_destroy(((SalOpBase*)op)->contact_address); ((SalOpBase*)op)->contact_address=address?sal_address_clone(address):NULL; } + +void sal_op_set_and_clean_contact_address(SalOp *op, SalAddress *contact) { + if (contact){ + SalTransport tport = sal_address_get_transport((SalAddress*)contact); + const char* gruu = bctbx_strdup(sal_address_get_uri_param(contact, "gr")); + sal_address_clean((SalAddress*)contact); /* clean out contact_params that come from proxy config*/ + sal_address_set_transport((SalAddress*)contact,tport); + if(gruu) + sal_address_set_uri_param(contact, "gr", gruu); + sal_op_set_contact_address(op, contact); + sal_address_unref(contact); + } +} + const SalAddress* sal_op_get_contact_address(const SalOp *op) { return ((SalOpBase*)op)->contact_address; } diff --git a/include/sal/sal.h b/include/sal/sal.h index 1cabcb5fa..0aa5073ae 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -674,6 +674,7 @@ SalOp * sal_op_new(Sal *sal); /*generic SalOp API, working for all operations */ Sal *sal_op_get_sal(const SalOp *op); void sal_op_set_contact_address(SalOp *op, const SalAddress* address); +void sal_op_set_and_clean_contact_address(SalOp *op, SalAddress* address); void sal_op_set_route(SalOp *op, const char *route); void sal_op_set_route_address(SalOp *op, const SalAddress* address); void sal_op_add_route_address(SalOp *op, const SalAddress* address); diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index 383722743..089ac77d6 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -6158,6 +6158,101 @@ static void recreate_zrtpdb_when_corrupted(void) { #endif /* SQLITE_STORAGE_ENABLED */ } +static void simple_call_with_gruu(void) { + LinphoneCoreManager* marie; + LinphoneCoreManager* pauline; + const LinphoneAddress *addr; + LinphoneCall *marie_call = NULL; + LinphoneCall *pauline_call = NULL; + LinphoneProxyConfig* pauline_cfg; + + marie = linphone_core_manager_new( "marie_rc"); + pauline = linphone_core_manager_new("pauline_tcp_rc"); + + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneRegistrationOk, 1)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneRegistrationOk, 1)); + + pauline_cfg = linphone_core_get_default_proxy_config(pauline->lc); + addr = linphone_proxy_config_get_contact(pauline_cfg); + BC_ASSERT_PTR_NOT_NULL(addr); + BC_ASSERT_PTR_NOT_NULL(strstr(linphone_address_as_string_uri_only(addr), "gr")); + + marie_call = linphone_core_invite_address(marie->lc, addr); + BC_ASSERT_PTR_NOT_NULL(marie_call); + if(!marie_call) goto end; + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallIncomingReceived, 1)); + pauline_call = linphone_core_get_current_call(pauline->lc); + BC_ASSERT_PTR_NOT_NULL(pauline_call); + if(!pauline_call) goto end; + linphone_call_accept(pauline_call); + + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1)); + + linphone_call_terminate(pauline_call); + + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1)); + +end: + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie); +} + +static void simple_call_with_gruu_only_one_device_ring(void) { + LinphoneCoreManager* marie; + LinphoneCoreManager* pauline; + LinphoneCoreManager* pauline2; + const LinphoneAddress *pauline_addr; + const LinphoneAddress *pauline_addr2; + LinphoneCall *marie_call = NULL; + LinphoneCall *pauline_call = NULL; + LinphoneProxyConfig* pauline_cfg; + LinphoneProxyConfig* pauline_cfg2; + + marie = linphone_core_manager_new( "marie_rc"); + pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + pauline2 = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneRegistrationOk, 1)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneRegistrationOk, 1)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline2->stat.number_of_LinphoneRegistrationOk, 1)); + + pauline_cfg = linphone_core_get_default_proxy_config(pauline->lc); + pauline_addr = linphone_proxy_config_get_contact(pauline_cfg); + BC_ASSERT_PTR_NOT_NULL(pauline_addr); + BC_ASSERT_PTR_NOT_NULL(strstr(linphone_address_as_string_uri_only(pauline_addr), "gr")); + pauline_cfg2 = linphone_core_get_default_proxy_config(pauline2->lc); + pauline_addr2 = linphone_proxy_config_get_contact(pauline_cfg2); + BC_ASSERT_PTR_NOT_NULL(pauline_addr2); + BC_ASSERT_PTR_NOT_NULL(strstr(linphone_address_as_string_uri_only(pauline_addr2), "gr")); + BC_ASSERT_NOT_EQUAL(linphone_address_as_string_uri_only(pauline_addr), linphone_address_as_string_uri_only(pauline_addr2), char*, "%s"); // Not same GRUU + + marie_call = linphone_core_invite_address(marie->lc, pauline_addr); + BC_ASSERT_PTR_NOT_NULL(marie_call); + if(!marie_call) goto end; + BC_ASSERT_FALSE(wait_for(marie->lc, pauline2->lc, &pauline2->stat.number_of_LinphoneCallIncomingReceived, 1)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallIncomingReceived, 1)); + pauline_call = linphone_core_get_current_call(pauline->lc); + BC_ASSERT_PTR_NOT_NULL(pauline_call); + if(!pauline_call) goto end; + + linphone_call_accept(pauline_call); + + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1)); + + linphone_call_terminate(pauline_call); + + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1)); + +end: + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(pauline2); + linphone_core_manager_destroy(marie); +} + test_t call_tests[] = { TEST_NO_TAG("Early declined call", early_declined_call), TEST_NO_TAG("Call declined", call_declined), @@ -6309,7 +6404,9 @@ test_t call_tests[] = { TEST_NO_TAG("Call cancelled with reason", cancel_call_with_error), TEST_NO_TAG("Call accepted, other ringing device receive CANCEL with reason", cancel_other_device_after_accept), TEST_NO_TAG("Call declined, other ringing device receive CANCEL with reason", cancel_other_device_after_decline), - TEST_NO_TAG("Recreate ZRTP db file when corrupted", recreate_zrtpdb_when_corrupted) + TEST_NO_TAG("Recreate ZRTP db file when corrupted", recreate_zrtpdb_when_corrupted), + TEST_NO_TAG("Simple call with GRUU", simple_call_with_gruu), + TEST_NO_TAG("Simple call with GRUU only one device ring", simple_call_with_gruu_only_one_device_ring) }; test_suite_t call_test_suite = {"Single Call", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, diff --git a/tester/register_tester.c b/tester/register_tester.c index c8f899b2e..c994e8931 100644 --- a/tester/register_tester.c +++ b/tester/register_tester.c @@ -1185,6 +1185,16 @@ static void tls_auth_info_client_cert_cb_2(void) { } } +static void register_get_gruu(void) { + LinphoneCoreManager *marie=linphone_core_manager_new("marie_rc"); + LinphoneProxyConfig *cfg=linphone_core_get_default_proxy_config(marie->lc); + if(cfg) { + const LinphoneAddress *addr = linphone_proxy_config_get_contact(cfg); + BC_ASSERT_PTR_NOT_NULL(addr); + BC_ASSERT_PTR_NOT_NULL(strstr(linphone_address_as_string_uri_only(addr), "gr")); + } + linphone_core_manager_destroy(marie); +} test_t register_tests[] = { TEST_NO_TAG("Simple register", simple_register), @@ -1231,6 +1241,7 @@ test_t register_tests[] = { TEST_NO_TAG("AuthInfo TLS client certificate authentication using API 2", tls_auth_info_client_cert_api_path), TEST_NO_TAG("AuthInfo TLS client certificate authentication in callback", tls_auth_info_client_cert_cb), TEST_NO_TAG("AuthInfo TLS client certificate authentication in callback 2", tls_auth_info_client_cert_cb_2), + TEST_NO_TAG("Register get GRUU", register_get_gruu) }; test_suite_t register_test_suite = {"Register", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,