diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index bac8c65fa..55852374e 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2846,6 +2846,7 @@ int linphone_core_accept_early_media(LinphoneCore* lc, LinphoneCall* call){ int linphone_core_start_update_call(LinphoneCore *lc, LinphoneCall *call){ const char *subject; + int err; bool_t no_user_consent=call->params->no_user_consent; if (!no_user_consent) linphone_call_make_local_media_description(lc,call); @@ -2862,12 +2863,22 @@ int linphone_core_start_update_call(LinphoneCore *lc, LinphoneCall *call){ subject="Refreshing"; } linphone_core_notify_display_status(lc,_("Modifying call parameters...")); - sal_call_set_local_media_description (call->op,call->localdesc); + if (!lc->sip_conf.sdp_200_ack){ + sal_call_set_local_media_description (call->op,call->localdesc); + } else { + sal_call_set_local_media_description (call->op,NULL); + } if (call->dest_proxy && call->dest_proxy->op){ /*give a chance to update the contact address if connectivity has changed*/ sal_op_set_contact_address(call->op,sal_op_get_contact_address(call->dest_proxy->op)); }else sal_op_set_contact_address(call->op,NULL); - return sal_call_update(call->op,subject,no_user_consent); + err= sal_call_update(call->op,subject,no_user_consent); + if (lc->sip_conf.sdp_200_ack){ + /*we are NOT offering, set local media description after sending the call so that we are ready to + process the remote offer when it will arrive*/ + sal_call_set_local_media_description(call->op,call->localdesc); + } + return err; } /** diff --git a/coreapi/misc.c b/coreapi/misc.c index a91d02432..30100a304 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -937,7 +937,7 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, bool_t linphone_core_media_description_contains_video_stream(const SalMediaDescription *md){ int i; - for (i = 0; i < md->nb_streams; i++) { + for (i = 0; md && i < md->nb_streams; i++) { if (md->streams[i].type == SalVideo && md->streams[i].rtp_port!=0) return TRUE; } diff --git a/tester/call_tester.c b/tester/call_tester.c index 1e6aeef0a..a2feaab92 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -781,6 +781,7 @@ static void call_with_no_sdp(void) { linphone_core_manager_destroy(pauline); } + static bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee, LinphoneIceState state) { LinphoneCall *c1,*c2; bool_t audio_success=FALSE; @@ -3056,7 +3057,57 @@ static void call_with_in_dialog_update(void) { belle_sip_object_dump_active_objects(); } } +static void call_with_in_dialog_codec_change_base(bool_t no_sdp) { + int begin; + int leaked_objects; + int dummy=0; + LinphoneCoreManager* marie; + LinphoneCoreManager* pauline; + LinphoneCallParams *params; + belle_sip_object_enable_leak_detector(TRUE); + begin=belle_sip_object_get_object_count(); + + marie = linphone_core_manager_new( "marie_rc"); + pauline = linphone_core_manager_new( "pauline_rc"); + CU_ASSERT_TRUE(call(pauline,marie)); + liblinphone_tester_check_rtcp(marie,pauline); + params=linphone_core_create_call_params(marie->lc,linphone_core_get_current_call(marie->lc)); + + linphone_core_enable_payload_type(pauline->lc,linphone_core_find_payload_type(pauline->lc,"PCMU",8000,1),FALSE); /*disable PCMU*/ + linphone_core_enable_payload_type(marie->lc,linphone_core_find_payload_type(marie->lc,"PCMU",8000,1),FALSE); /*disable PCMU*/ + linphone_core_enable_payload_type(pauline->lc,linphone_core_find_payload_type(pauline->lc,"PCMA",8000,1),TRUE); /*enable PCMA*/ + linphone_core_enable_payload_type(marie->lc,linphone_core_find_payload_type(marie->lc,"PCMA",8000,1),TRUE); /*enable PCMA*/ + if (no_sdp) { + linphone_core_enable_sdp_200_ack(marie->lc,TRUE); + } + linphone_core_update_call(marie->lc,linphone_core_get_current_call(marie->lc),params); + linphone_call_params_destroy(params); + CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallUpdating,1)); + CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2)); + CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallUpdatedByRemote,1)); + CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); + CU_ASSERT_STRING_EQUAL("PCMA",linphone_payload_type_get_mime_type(linphone_call_params_get_used_audio_codec(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc))))); + wait_for_until(marie->lc, pauline->lc, &dummy, 1, 3000); + CU_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(marie->lc))->download_bandwidth>70); + CU_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(pauline->lc))->download_bandwidth>70); + + end_call(marie,pauline); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + + leaked_objects=belle_sip_object_get_object_count()-begin; + CU_ASSERT_TRUE(leaked_objects==0); + if (leaked_objects>0){ + belle_sip_object_dump_active_objects(); + } +} +static void call_with_in_dialog_codec_change(void) { + call_with_in_dialog_codec_change_base(FALSE); +} +static void call_with_in_dialog_codec_change_no_sdp(void) { + call_with_in_dialog_codec_change_base(TRUE); +} static void call_with_custom_supported_tags(void) { int begin; int leaked_objects; @@ -3188,6 +3239,8 @@ test_t call_tests[] = { { "SAVPF to SAVP call", savpf_to_savp_call }, { "SAVPF to SAVPF call", savpf_to_savpf_call }, { "Call with in-dialog UPDATE request", call_with_in_dialog_update }, + { "Call with in-dialog codec change", call_with_in_dialog_codec_change }, + { "Call with in-dialog codec change no sdp", call_with_in_dialog_codec_change_no_sdp }, { "Call with custom supported tags", call_with_custom_supported_tags } };