diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index c5040be3a..6896496f7 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -423,6 +423,8 @@ static void process_auth_requested(void *sal, belle_sip_auth_event_t *event) { Sal * sal_init(){ belle_sip_listener_callbacks_t listener_callbacks; Sal * sal=ms_new0(Sal,1); + + /*belle_sip_object_enable_marshal_check(TRUE);*/ sal->auto_contacts=TRUE; /*first create the stack, which initializes the belle-sip object's pool for this thread*/ diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index af4ab7b57..a1172229c 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -718,7 +718,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro call->current_params.privacy=(LinphonePrivacyMask)sal_op_get_privacy(call->op); /*set video support */ md=sal_call_get_remote_media_description(op); - call->params.has_video = !!lc->video_policy.automatically_accept; + call->params.has_video = lc->video_policy.automatically_accept; if (md) { // It is licit to receive an INVITE without SDP // In this case WE chose the media parameters according to policy. @@ -1582,7 +1582,7 @@ int linphone_call_prepare_ice(LinphoneCall *call, bool_t incoming_offer){ if ((linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseIce) && (call->ice_session != NULL)){ if (incoming_offer){ remote=sal_call_get_remote_media_description(call->op); - has_video=linphone_core_media_description_contains_video_stream(remote); + has_video=call->params.has_video && linphone_core_media_description_contains_video_stream(remote); }else has_video=call->params.has_video; _linphone_call_prepare_ice_for_stream(call,0,TRUE); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 6c79d7c71..0183979a5 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -3433,6 +3433,7 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call, call->params.media_encryption = LinphoneMediaEncryptionSRTP; } } + linphone_call_prepare_ice(call,TRUE); linphone_call_make_local_media_description(lc,call); sal_call_set_local_media_description(call->op,call->localdesc); sal_op_set_sent_custom_header(call->op,params->custom_headers); diff --git a/coreapi/misc.c b/coreapi/misc.c index 57ebaa32e..2a86db03a 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -803,6 +803,13 @@ static void get_default_addr_and_port(uint16_t componentID, const SalMediaDescri if ((*addr)[0] == '\0') *addr = md->addr; } +static void clear_ice_check_list(LinphoneCall *call, IceCheckList *removed){ + if (call->audiostream && call->audiostream->ms.ice_check_list==removed) + call->audiostream->ms.ice_check_list=NULL; + if (call->videostream && call->videostream->ms.ice_check_list==removed) + call->videostream->ms.ice_check_list=NULL; +} + void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md) { bool_t ice_restarted = FALSE; @@ -853,6 +860,7 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, for (i = 0; i < md->n_total_streams; i++) { const SalStreamDescription *stream = &md->streams[i]; IceCheckList *cl = ice_session_check_list(call->ice_session, i); + /* if ((cl == NULL) && (i < md->n_active_streams)) { cl = ice_check_list_new(); ice_session_add_check_list(call->ice_session, cl); @@ -867,16 +875,13 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, break; } } + */ + if (cl==NULL) continue; if (stream->ice_mismatch == TRUE) { ice_check_list_set_state(cl, ICL_Failed); } else if (stream->rtp_port == 0) { ice_session_remove_check_list(call->ice_session, cl); -#ifdef VIDEO_ENABLED - if (stream->type==SalVideo && call->videostream){ - video_stream_stop(call->videostream); - call->videostream=NULL; - } -#endif + clear_ice_check_list(call,cl); } else { if ((stream->ice_pwd[0] != '\0') && (stream->ice_ufrag[0] != '\0')) ice_check_list_set_remote_credentials(cl, stream->ice_ufrag, stream->ice_pwd); @@ -916,10 +921,7 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, for (i = ice_session_nb_check_lists(call->ice_session); i > md->n_active_streams; i--) { IceCheckList *removed=ice_session_check_list(call->ice_session, i - 1); ice_session_remove_check_list(call->ice_session, removed); - if (call->audiostream && call->audiostream->ms.ice_check_list==removed) - call->audiostream->ms.ice_check_list=NULL; - if (call->videostream && call->videostream->ms.ice_check_list==removed) - call->videostream->ms.ice_check_list=NULL; + clear_ice_check_list(call,removed); } ice_session_check_mismatch(call->ice_session); } else { @@ -932,12 +934,11 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, } } -bool_t linphone_core_media_description_contains_video_stream(const SalMediaDescription *md) -{ +bool_t linphone_core_media_description_contains_video_stream(const SalMediaDescription *md){ int i; - for (i = 0; i < md->n_active_streams; i++) { - if (md->streams[i].type == SalVideo) + for (i = 0; i < md->n_total_streams; i++) { + if (md->streams[i].type == SalVideo && md->streams[i].rtp_port!=0) return TRUE; } return FALSE; @@ -1502,7 +1503,7 @@ const MSCryptoSuite * linphone_core_get_srtp_crypto_suites(LinphoneCore *lc){ np.params=params; suite=ms_crypto_suite_build_from_name_params(&np); if (suite!=MS_CRYPTO_SUITE_INVALID){ - result=ms_realloc(result,found+1+1); + result=ms_realloc(result,(found+2)*sizeof(MSCryptoSuite)); result[found]=suite; result[found+1]=MS_CRYPTO_SUITE_INVALID; found++; diff --git a/coreapi/quality_reporting.c b/coreapi/quality_reporting.c index 50c283cf0..164653e18 100644 --- a/coreapi/quality_reporting.c +++ b/coreapi/quality_reporting.c @@ -479,7 +479,7 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { void linphone_reporting_on_rtcp_received(LinphoneCall *call, int stats_type) { reporting_session_report_t * report = call->log->reports[stats_type]; reporting_content_metrics_t * metrics = NULL; - + MSQosAnalyser *analyser=NULL; LinphoneCallStats stats = call->stats[stats_type]; mblk_t *block = NULL; @@ -497,11 +497,14 @@ void linphone_reporting_on_rtcp_received(LinphoneCall *call, int stats_type) { block = stats.sent_rtcp; } } - - ms_qos_analyser_set_on_action_suggested( - ms_bitrate_controller_get_qos_analyser(call->audiostream->ms.rc), - qos_analyser_on_action_suggested, - &report->local_metrics); + if (call->audiostream->ms.rc){ + analyser=ms_bitrate_controller_get_qos_analyser(call->audiostream->ms.rc); + if (analyser){ + ms_qos_analyser_set_on_action_suggested(analyser, + qos_analyser_on_action_suggested, + &report->local_metrics); + } + } if (block != NULL) { switch (rtcp_XR_get_block_type(block)) { diff --git a/tester/call_tester.c b/tester/call_tester.c index a59313626..23c92ef52 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -552,20 +552,23 @@ static void call_with_no_sdp(void) { static bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee, LinphoneIceState state) { LinphoneCall *c1,*c2; - bool_t success=FALSE; + bool_t audio_success=FALSE; + bool_t video_success=FALSE; int i; + bool_t video_enabled; c1=linphone_core_get_current_call(caller->lc); c2=linphone_core_get_current_call(callee->lc); CU_ASSERT_PTR_NOT_NULL(c1); CU_ASSERT_PTR_NOT_NULL(c2); - + CU_ASSERT_EQUAL(linphone_call_params_video_enabled(linphone_call_get_current_params(c1)),linphone_call_params_video_enabled(linphone_call_get_current_params(c2))); + video_enabled=linphone_call_params_video_enabled(linphone_call_get_current_params(c1)); for (i=0;i<200;i++){ if ((c1 != NULL) && (c2 != NULL)) { - if (linphone_call_get_audio_stats(c1)->ice_state==LinphoneIceStateHostConnection && - linphone_call_get_audio_stats(c2)->ice_state==LinphoneIceStateHostConnection ){ - success=TRUE; + if (linphone_call_get_audio_stats(c1)->ice_state==state && + linphone_call_get_audio_stats(c2)->ice_state==state ){ + audio_success=TRUE; break; } linphone_core_iterate(caller->lc); @@ -573,6 +576,21 @@ static bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee } ms_usleep(50000); } + + if (video_enabled){ + for (i=0;i<200;i++){ + if ((c1 != NULL) && (c2 != NULL)) { + if (linphone_call_get_video_stats(c1)->ice_state==state && + linphone_call_get_video_stats(c2)->ice_state==state ){ + video_success=TRUE; + break; + } + linphone_core_iterate(caller->lc); + linphone_core_iterate(callee->lc); + } + ms_usleep(50000); + } + } /*make sure encryption mode are preserved*/ if (c1) { @@ -584,7 +602,7 @@ static bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee CU_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param),linphone_core_get_media_encryption(callee->lc)); } - return success; + return video_enabled ? audio_success && video_success : audio_success; } static void _call_with_ice_base(LinphoneCoreManager* pauline,LinphoneCoreManager* marie, bool_t caller_with_ice, bool_t callee_with_ice, bool_t random_ports) { @@ -982,6 +1000,54 @@ static void video_call_no_sdp(void) { linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } + +static void call_with_ice_video_to_novideo(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneVideoPolicy vpol={0}; + vpol.automatically_initiate=TRUE; + linphone_core_set_video_policy(pauline->lc,&vpol); + vpol.automatically_initiate=FALSE; + linphone_core_set_video_policy(marie->lc,&vpol); + _call_with_ice_base(pauline,marie,TRUE,TRUE,TRUE); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void call_with_ice_video_added(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneVideoPolicy vpol={0}; + linphone_core_set_video_policy(pauline->lc,&vpol); + linphone_core_set_video_policy(marie->lc,&vpol); + + linphone_core_set_firewall_policy(marie->lc,LinphonePolicyUseIce); + linphone_core_set_stun_server(marie->lc,"stun.linphone.org"); + + + linphone_core_set_firewall_policy(pauline->lc,LinphonePolicyUseIce); + linphone_core_set_stun_server(pauline->lc,"stun.linphone.org"); + + + if (1){ + linphone_core_set_audio_port(marie->lc,-1); + linphone_core_set_video_port(marie->lc,-1); + linphone_core_set_audio_port(pauline->lc,-1); + linphone_core_set_video_port(pauline->lc,-1); + } + + CU_ASSERT_TRUE(call(pauline,marie)); + CU_ASSERT_TRUE(check_ice(pauline,marie,LinphoneIceStateHostConnection)); + /*wait for ICE reINVITEs to complete*/ + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2) + && + wait_for(pauline->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2)); + CU_ASSERT_TRUE(add_video(pauline,marie)); + CU_ASSERT_TRUE(check_ice(pauline,marie,LinphoneIceStateHostConnection)); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + #endif /*VIDEO_ENABLED*/ static void _call_with_media_relay(bool_t random_ports) { @@ -2278,6 +2344,8 @@ test_t call_tests[] = { { "Call with video added (random ports)", call_with_video_added_random_ports }, { "Call with video declined",call_with_declined_video}, { "Call with multiple early media", multiple_early_media }, + { "Call with ICE from video to non-video", call_with_ice_video_to_novideo}, + { "Call with ICE and video added", call_with_ice_video_added }, #endif { "SRTP ice call", srtp_ice_call }, { "ZRTP ice call", zrtp_ice_call },