From d12f596bbe0556e03c629fa661a93998608aad61 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 29 Sep 2015 11:53:23 +0200 Subject: [PATCH] Added some missing pieces for ICE and text stream + fix for textstream always AVP --- coreapi/linphonecall.c | 13 ++++++++- coreapi/linphonecore.h | 1 + coreapi/misc.c | 66 +++++++++++++++++++++++++++++++----------- gtk/main.c | 1 + tester/call_tester.c | 26 +++++++++++++++-- 5 files changed, 87 insertions(+), 20 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 8f670652c..456c33d60 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -737,7 +737,7 @@ void linphone_call_make_local_media_description(LinphoneCall *call) { md->streams[call->main_video_stream_index].dir = SalStreamInactive; } - md->streams[call->main_text_stream_index].proto=md->streams[call->main_text_stream_index].proto; + md->streams[call->main_text_stream_index].proto=md->streams[call->main_audio_stream_index].proto; md->streams[call->main_text_stream_index].dir=SalStreamSendRecv; md->streams[call->main_text_stream_index].type=SalText; strncpy(md->streams[call->main_text_stream_index].name,"Text",sizeof(md->streams[call->main_text_stream_index].name)-1); @@ -3759,6 +3759,17 @@ const LinphoneCallStats *linphone_call_get_video_stats(LinphoneCall *call) { return stats; } +/** + * Access last known statistics for video stream, for a given call. +**/ +const LinphoneCallStats *linphone_call_get_text_stats(LinphoneCall *call) { + LinphoneCallStats *stats = &call->stats[LINPHONE_CALL_STATS_TEXT]; + if (call->textstream){ + update_local_stats(stats,(MediaStream*)call->textstream); + } + return stats; +} + static bool_t ice_in_progress(LinphoneCallStats *stats){ return stats->ice_state==LinphoneIceStateInProgress; } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 2d435223d..77053bfe2 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -563,6 +563,7 @@ struct _LinphoneCallStats { LINPHONE_PUBLIC const LinphoneCallStats *linphone_call_get_audio_stats(LinphoneCall *call); LINPHONE_PUBLIC const LinphoneCallStats *linphone_call_get_video_stats(LinphoneCall *call); +LINPHONE_PUBLIC const LinphoneCallStats *linphone_call_get_text_stats(LinphoneCall *call); LINPHONE_PUBLIC float linphone_call_stats_get_sender_loss_rate(const LinphoneCallStats *stats); LINPHONE_PUBLIC float linphone_call_stats_get_receiver_loss_rate(const LinphoneCallStats *stats); LINPHONE_PUBLIC float linphone_call_stats_get_sender_interarrival_jitter(const LinphoneCallStats *stats, LinphoneCall *call); diff --git a/coreapi/misc.c b/coreapi/misc.c index e68b42d85..847570e40 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -700,31 +700,36 @@ void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call) { IceCheckList *audio_check_list; IceCheckList *video_check_list; + IceCheckList *text_check_list; IceSessionState session_state; if (call->ice_session == NULL) return; audio_check_list = ice_session_check_list(call->ice_session, call->main_audio_stream_index); video_check_list = ice_session_check_list(call->ice_session, call->main_video_stream_index); + text_check_list = ice_session_check_list(call->ice_session, call->main_text_stream_index); if (audio_check_list == NULL) return; session_state = ice_session_state(call->ice_session); if ((session_state == IS_Completed) || ((session_state == IS_Failed) && (ice_session_has_completed_check_list(call->ice_session) == TRUE))) { - if (ice_check_list_state(audio_check_list) == ICL_Completed) { - switch (ice_check_list_selected_valid_candidate_type(audio_check_list)) { - case ICT_HostCandidate: - call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateHostConnection; - break; - case ICT_ServerReflexiveCandidate: - case ICT_PeerReflexiveCandidate: - call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateReflexiveConnection; - break; - case ICT_RelayedCandidate: - call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateRelayConnection; - break; + if (call->params->has_audio && (audio_check_list != NULL)) { + if (ice_check_list_state(audio_check_list) == ICL_Completed) { + switch (ice_check_list_selected_valid_candidate_type(audio_check_list)) { + case ICT_HostCandidate: + call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateHostConnection; + break; + case ICT_ServerReflexiveCandidate: + case ICT_PeerReflexiveCandidate: + call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateReflexiveConnection; + break; + case ICT_RelayedCandidate: + call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateRelayConnection; + break; + } + } else { + call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateFailed; } - } else { - call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateFailed; - } + }else call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateNotActivated; + if (call->params->has_video && (video_check_list != NULL)) { if (ice_check_list_state(video_check_list) == ICL_Completed) { switch (ice_check_list_selected_valid_candidate_type(video_check_list)) { @@ -743,19 +748,44 @@ void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call) call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateFailed; } }else call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateNotActivated; + + if (call->params->realtimetext_enabled && (text_check_list != NULL)) { + if (ice_check_list_state(text_check_list) == ICL_Completed) { + switch (ice_check_list_selected_valid_candidate_type(text_check_list)) { + case ICT_HostCandidate: + call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateHostConnection; + break; + case ICT_ServerReflexiveCandidate: + case ICT_PeerReflexiveCandidate: + call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateReflexiveConnection; + break; + case ICT_RelayedCandidate: + call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateRelayConnection; + break; + } + } else { + call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateFailed; + } + }else call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateNotActivated; } else if (session_state == IS_Running) { call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateInProgress; if (call->params->has_video && (video_check_list != NULL)) { call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateInProgress; } + if (call->params->realtimetext_enabled && (text_check_list != NULL)) { + call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateInProgress; + } } else { call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateFailed; if (call->params->has_video && (video_check_list != NULL)) { call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateFailed; } + if (call->params->realtimetext_enabled && (text_check_list != NULL)) { + call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateFailed; + } } - ms_message("Call [%p] New ICE state: audio: [%s] video: [%s]", call, - linphone_ice_state_to_string(call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state), linphone_ice_state_to_string(call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state)); + ms_message("Call [%p] New ICE state: audio: [%s] video: [%s] text: [%s]", call, + linphone_ice_state_to_string(call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state), linphone_ice_state_to_string(call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state), linphone_ice_state_to_string(call->stats[LINPHONE_CALL_STATS_TEXT].ice_state)); } void linphone_call_stop_ice_for_inactive_streams(LinphoneCall *call, SalMediaDescription *desc) { @@ -895,6 +925,8 @@ static void clear_ice_check_list(LinphoneCall *call, IceCheckList *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; + if (call->textstream && call->textstream->ms.ice_check_list==removed) + call->textstream->ms.ice_check_list=NULL; } void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md) diff --git a/gtk/main.c b/gtk/main.c index 1930f8b89..c0d3a4a03 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -884,6 +884,7 @@ static gboolean linphone_gtk_start_call_do(GtkWidget *uri_bar){ LinphoneCallParams *params=linphone_core_create_default_call_parameters(lc); gchar *record_file=linphone_gtk_get_record_path(addr,FALSE); linphone_call_params_set_record_file(params,record_file); + linphone_call_params_enable_realtime_text(params, TRUE); linphone_core_invite_address_with_params(lc,addr,params); completion_add_text(GTK_ENTRY(uri_bar),entered); linphone_address_destroy(addr); diff --git a/tester/call_tester.c b/tester/call_tester.c index 3307a59da..df3f7c7ab 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -988,7 +988,8 @@ static bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee LinphoneCall *c1,*c2; bool_t audio_success=FALSE; bool_t video_success=FALSE; - bool_t video_enabled; + bool_t text_success=FALSE; + bool_t video_enabled, realtime_text_enabled; MSTimeSpec ts; c1=linphone_core_get_current_call(caller->lc); @@ -1001,7 +1002,9 @@ static bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee linphone_call_ref(c2); BC_ASSERT_EQUAL(linphone_call_params_video_enabled(linphone_call_get_current_params(c1)),linphone_call_params_video_enabled(linphone_call_get_current_params(c2)), int, "%d"); + BC_ASSERT_EQUAL(linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(c1)),linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(c2)), int, "%d"); video_enabled=linphone_call_params_video_enabled(linphone_call_get_current_params(c1)); + realtime_text_enabled=linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(c1)); liblinphone_tester_clock_start(&ts); do{ if ((c1 != NULL) && (c2 != NULL)) { @@ -1032,6 +1035,22 @@ static bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee }while(!liblinphone_tester_clock_elapsed(&ts,10000)); } + if (realtime_text_enabled){ + liblinphone_tester_clock_start(&ts); + do{ + if ((c1 != NULL) && (c2 != NULL)) { + if (linphone_call_get_text_stats(c1)->ice_state==state && + linphone_call_get_text_stats(c2)->ice_state==state ){ + text_success=TRUE; + break; + } + linphone_core_iterate(caller->lc); + linphone_core_iterate(callee->lc); + } + ms_usleep(20000); + }while(!liblinphone_tester_clock_elapsed(&ts,10000)); + } + /*make sure encryption mode are preserved*/ if (c1) { const LinphoneCallParams* call_param = linphone_call_get_current_params(c1); @@ -1043,7 +1062,7 @@ static bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee } linphone_call_unref(c1); linphone_call_unref(c2); - return video_enabled ? audio_success && video_success : audio_success; + return video_enabled ? (realtime_text_enabled ? text_success && audio_success && video_success : audio_success && video_success) : realtime_text_enabled ? text_success && audio_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) { @@ -1057,8 +1076,10 @@ static void _call_with_ice_base(LinphoneCoreManager* pauline,LinphoneCoreManager if (random_ports){ linphone_core_set_audio_port(marie->lc,-1); linphone_core_set_video_port(marie->lc,-1); + linphone_core_set_text_port(marie->lc, -1); linphone_core_set_audio_port(pauline->lc,-1); linphone_core_set_video_port(pauline->lc,-1); + linphone_core_set_text_port(pauline->lc, -1); } @@ -2069,6 +2090,7 @@ static void call_with_ice_video_and_rtt(void) { linphone_call_params_enable_realtime_text(params, TRUE); BC_ASSERT_TRUE(call_ok = call_with_caller_params(pauline, marie, params)); if (!call_ok) goto end; + BC_ASSERT_TRUE(check_ice(pauline, marie, LinphoneIceStateHostConnection)); marie_call = linphone_core_get_current_call(marie->lc); BC_ASSERT_TRUE(linphone_call_params_audio_enabled(linphone_call_get_current_params(marie_call)));