diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 8a1888341..2f21922e9 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1195,21 +1195,8 @@ static void linphone_call_set_terminated(LinphoneCall *call){ void linphone_call_fix_call_parameters(LinphoneCall *call){ if (sal_call_is_offerer(call->op)) { /*get remote params*/ - const LinphoneCallParams* lcp = linphone_call_get_remote_params(call); - call->current_params->video_declined = call->params->has_video && !lcp->has_video; - } - switch(call->params->media_encryption) { - case LinphoneMediaEncryptionZRTP: - case LinphoneMediaEncryptionDTLS: - case LinphoneMediaEncryptionNone: - /* do nothing */ - break; - case LinphoneMediaEncryptionSRTP: - call->params->media_encryption=call->current_params->media_encryption; - break; - default: - ms_fatal("Unknown media encryption type on call [%p]", call); - break; + const LinphoneCallParams* rcp = linphone_call_get_remote_params(call); + call->current_params->video_declined = call->params->has_video && !rcp->has_video; } } @@ -1447,20 +1434,24 @@ const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call){ } #endif - if (linphone_call_all_streams_encrypted(call)) { - if (linphone_call_get_authentication_token(call)) { - call->current_params->media_encryption=LinphoneMediaEncryptionZRTP; - } else { - /* TODO : check this or presence of dtls_fingerprint in the call? */ - if (call->params->media_encryption == LinphoneMediaEncryptionDTLS) { - call->current_params->media_encryption=LinphoneMediaEncryptionDTLS; - } else { - call->current_params->media_encryption=LinphoneMediaEncryptionSRTP; + /* REVISITED + * Previous code was buggy. + * Relying on the mediastream's state to know the current encryption is unreliable. + * For ZRTP it is though necessary. + * But for all others the current_params->media_encryption state should reflect what is agreed by the offer/answer + * mechanism. + * Typically there can be inactive streams for which the media layer has no idea of whether they are encrypted or not. + */ + if (call->params->media_encryption == LinphoneMediaEncryptionZRTP){ + if (linphone_call_all_streams_encrypted(call)) { + if (linphone_call_get_authentication_token(call)) { + call->current_params->media_encryption=LinphoneMediaEncryptionZRTP; } } - } else { - call->current_params->media_encryption=LinphoneMediaEncryptionNone; + }else{ + call->current_params->media_encryption = call->params->media_encryption; } + call->current_params->avpf_enabled = linphone_call_all_streams_avpf_enabled(call); if (call->current_params->avpf_enabled == TRUE) { call->current_params->avpf_rr_interval = linphone_call_get_avpf_rr_interval(call); @@ -2806,9 +2797,6 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut video_stream_enable_zrtp(call->videostream,call->audiostream,¶ms); } #endif - }else if (call->params->media_encryption==LinphoneMediaEncryptionSRTP){ - call->current_params->media_encryption=linphone_call_all_streams_encrypted(call) ? - LinphoneMediaEncryptionSRTP : LinphoneMediaEncryptionNone; } set_dtls_fingerprint_on_all_streams(call); diff --git a/mediastreamer2 b/mediastreamer2 index 467d48150..4ebcd5b4d 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 467d48150b34b1ead2f5c97ae2f459e04efde1ca +Subproject commit 4ebcd5b4d26feaba9826c88381e9ae9f5df9bab3 diff --git a/tester/call_tester.c b/tester/call_tester.c index b243975af..253f83bdf 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -2233,7 +2233,6 @@ static void call_with_declined_srtp(void) { CU_ASSERT_TRUE(call(pauline,marie)); - /*just to sleep*/ linphone_core_terminate_all_calls(marie->lc); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); @@ -2244,6 +2243,51 @@ static void call_with_declined_srtp(void) { linphone_core_manager_destroy(pauline); } +static void call_srtp_paused_and_resumed(void) { + /* + * This test was made to evidence a bug due to internal usage of current_params while not yet filled by linphone_call_get_current_params(). + * As a result it must not use the call() function because it calls linphone_call_get_current_params(). + */ + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + const LinphoneCallParams *params; + LinphoneCall *pauline_call; + + if (!linphone_core_media_encryption_supported(marie->lc,LinphoneMediaEncryptionSRTP)) goto end; + linphone_core_set_media_encryption(pauline->lc,LinphoneMediaEncryptionSRTP); + + linphone_core_invite_address(pauline->lc, marie->identity); + + if (!BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallIncomingReceived,1))) goto end; + pauline_call = linphone_core_get_current_call(pauline->lc); + linphone_core_accept_call(marie->lc, linphone_core_get_current_call(marie->lc)); + + if (!BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,1))) goto end; + if (!BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,1))) goto end; + + linphone_core_pause_call(pauline->lc, pauline_call); + + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallPaused,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallPausedByRemote,1)); + + linphone_core_resume_call(pauline->lc, pauline_call); + if (!BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2))) goto end; + if (!BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2))) goto end; + + /*assert that after pause and resume, SRTP is still being used*/ + params = linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc)); + CU_ASSERT_TRUE(linphone_call_params_get_media_encryption(params) == LinphoneMediaEncryptionSRTP); + params = linphone_call_get_current_params(linphone_core_get_current_call(marie->lc)); + CU_ASSERT_TRUE(linphone_call_params_get_media_encryption(params) == LinphoneMediaEncryptionSRTP); + + linphone_core_terminate_all_calls(marie->lc); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); +end: + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + static void on_eof(LinphonePlayer *player, void *user_data){ LinphoneCoreManager *marie=(LinphoneCoreManager*)user_data; marie->stat.number_of_player_eof++; @@ -4002,6 +4046,7 @@ test_t call_tests[] = { { "DTLS SRTP call with media relay", dtls_srtp_call_with_media_realy}, { "ZRTP video call",zrtp_video_call}, { "SRTP call with declined srtp", call_with_declined_srtp }, + { "SRTP call paused and resumed", call_srtp_paused_and_resumed }, { "Call with file player", call_with_file_player}, { "Call with mkv file player", call_with_mkv_file_player}, { "Audio call with ICE no matching audio codecs", audio_call_with_ice_no_matching_audio_codecs },