From a971445719530f649533c7091e62d0bdcf4b0c80 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Wed, 18 Feb 2015 14:53:48 +0100 Subject: [PATCH] Fix problem with missing SDP in 200 OK when the call is in early-media. We should recover correctly, we were not. Also introduced the corresponding unit test. --- coreapi/callbacks.c | 8 +++++ tester/call_tester.c | 72 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 7e0254b99..7de84e19f 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -494,6 +494,14 @@ static void call_accepted(SalOp *op){ break; } + if( (call->prevstate == LinphoneCallOutgoingEarlyMedia) && (md == NULL || sal_media_description_empty(md)) ){ + /* media description is null or empty because no SDP was received in the 200 OK, we can possibly use the early-media SDP. */ + if( call->resultdesc != NULL){ + ms_message("Using early media SDP since none were received with the 200 OK"); + md = call->resultdesc; + } + } + if (md && !sal_media_description_empty(md) && !linphone_core_incompatible_security(lc,md)){ linphone_call_update_remote_session_id_and_ver(call); if (sal_media_description_has_dir(md,SalStreamSendOnly) || diff --git a/tester/call_tester.c b/tester/call_tester.c index 2d1e93e1d..3fcf3da1a 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -3549,6 +3549,77 @@ static void call_with_paused_no_sdp_on_resume() { } } + +static void call_with_183_and_no_sdp_in_200(){ +LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_rc"); + MSList* lcs = NULL; + LinphoneCall* marie_call; + LinphoneCallParams* params = NULL; + LinphoneCallLog *marie_call_log; + uint64_t connected_time=0; + uint64_t ended_time=0; + int dummy=0; + + lcs = ms_list_append(lcs,marie->lc); + lcs = ms_list_append(lcs,pauline->lc); + /* + Marie calls Pauline, and after the call has rung, transitions to an early_media session + */ + params = linphone_core_create_default_call_parameters(marie->lc); + linphone_call_params_enable_video(params, TRUE); + + linphone_core_enable_video_capture(pauline->lc, TRUE); + linphone_core_enable_video_display(pauline->lc, TRUE); + linphone_core_enable_video_capture(marie->lc, TRUE); + linphone_core_enable_video_display(marie->lc, FALSE); + + marie_call = linphone_core_invite_address_with_params(marie->lc, pauline->identity, params); + marie_call_log = linphone_call_get_call_log(marie_call); + + CU_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingReceived,1,3000)); + CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingRinging,1,1000)); + + if (linphone_core_inc_invite_pending(pauline->lc)) { + LinphoneCall* pauline_call = linphone_core_get_current_call(pauline->lc); + + /* send a 183 to initiate the early media */ + linphone_core_accept_early_media(pauline->lc, pauline_call); + + CU_ASSERT_TRUE( wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingEarlyMedia,1,2000) ); + CU_ASSERT_TRUE( wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingEarlyMedia,1,2000) ); + + liblinphone_tester_check_rtcp(marie, pauline); + + // will send the 200OK _without_ SDP + sal_call_set_sdp_handling(pauline_call->op, SalOpSDPSimulateRemove); + linphone_core_accept_call(pauline->lc, pauline_call); + + CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallConnected, 1,1000)); + connected_time=ms_get_cur_time_ms(); + CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallStreamsRunning, 1,3000)); + + ms_error("Streams running= %d", marie->stat.number_of_LinphoneCallStreamsRunning); + + CU_ASSERT_EQUAL(marie_call, linphone_core_get_current_call(marie->lc)); + + liblinphone_tester_check_rtcp(marie, pauline); + /*just to have a call duration !=0*/ + wait_for_list(lcs,&dummy,1,2000); + + linphone_core_terminate_all_calls(pauline->lc); + + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); + ended_time=ms_get_cur_time_ms(); + CU_ASSERT_TRUE( labs((linphone_call_log_get_duration(marie_call_log)*1000) - (int64_t)(ended_time - connected_time)) <=1000 ); + ms_list_free(lcs); + } + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + static void call_with_generic_cn(void) { int begin; int leaked_objects; @@ -3704,6 +3775,7 @@ test_t call_tests[] = { { "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 pause no SDP on resume", call_with_paused_no_sdp_on_resume }, + { "Call with 183 and no SDP on 200", call_with_183_and_no_sdp_in_200 }, { "Call with custom supported tags", call_with_custom_supported_tags }, { "Call log from taken from asserted id",call_log_from_taken_from_p_asserted_id}, { "Incoming INVITE without SDP",incoming_invite_without_sdp},