Commit c4086e98 authored by Ghislain MARY's avatar Ghislain MARY

Add ICE state to the call stats.

parent 5a7090cc
...@@ -324,6 +324,7 @@ void linphone_call_init_stats(LinphoneCallStats *stats, int type) { ...@@ -324,6 +324,7 @@ void linphone_call_init_stats(LinphoneCallStats *stats, int type) {
stats->type = type; stats->type = type;
stats->received_rtcp = NULL; stats->received_rtcp = NULL;
stats->sent_rtcp = NULL; stats->sent_rtcp = NULL;
stats->ice_state = LinphoneIceStateNotActivated;
} }
static void update_media_description_from_stun(SalMediaDescription *md, const StunCandidate *ac, const StunCandidate *vc){ static void update_media_description_from_stun(SalMediaDescription *md, const StunCandidate *ac, const StunCandidate *vc){
...@@ -1541,6 +1542,8 @@ void linphone_call_delete_ice_session(LinphoneCall *call){ ...@@ -1541,6 +1542,8 @@ void linphone_call_delete_ice_session(LinphoneCall *call){
call->ice_session = NULL; call->ice_session = NULL;
if (call->audiostream != NULL) call->audiostream->ice_check_list = NULL; if (call->audiostream != NULL) call->audiostream->ice_check_list = NULL;
if (call->videostream != NULL) call->videostream->ice_check_list = NULL; if (call->videostream != NULL) call->videostream->ice_check_list = NULL;
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateNotActivated;
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateNotActivated;
} }
} }
...@@ -1766,6 +1769,7 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){ ...@@ -1766,6 +1769,7 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){
if (ice_session_role(call->ice_session) == IR_Controlling) { if (ice_session_role(call->ice_session) == IR_Controlling) {
ice_session_select_candidates(call->ice_session); ice_session_select_candidates(call->ice_session);
linphone_core_update_call(call->core, call, &call->current_params); linphone_core_update_call(call->core, call, &call->current_params);
linphone_core_update_ice_state_in_call_stats(call);
} }
break; break;
case IS_Failed: case IS_Failed:
...@@ -1774,6 +1778,7 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){ ...@@ -1774,6 +1778,7 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){
/* At least one ICE session has succeeded, so perform a call update. */ /* At least one ICE session has succeeded, so perform a call update. */
ice_session_select_candidates(call->ice_session); ice_session_select_candidates(call->ice_session);
linphone_core_update_call(call->core, call, &call->current_params); linphone_core_update_call(call->core, call, &call->current_params);
linphone_core_update_ice_state_in_call_stats(call);
} }
} }
break; break;
......
...@@ -261,6 +261,24 @@ typedef struct _LinphoneCall LinphoneCall; ...@@ -261,6 +261,24 @@ typedef struct _LinphoneCall LinphoneCall;
#define LINPHONE_CALL_STATS_AUDIO 0 #define LINPHONE_CALL_STATS_AUDIO 0
#define LINPHONE_CALL_STATS_VIDEO 1 #define LINPHONE_CALL_STATS_VIDEO 1
/**
* Enum describing ICE states.
* @ingroup initializing
**/
enum _LinphoneIceState{
LinphoneIceStateNotActivated, /**< ICE has not been activated for this call */
LinphoneIceStateInProgress, /**< ICE process is in progress */
LinphoneIceStateHostConnection, /**< ICE has established a direct connection to the remote host */
LinphoneIceStateReflexiveConnection, /**< ICE has established a connection to the remote host through one or several NATs */
LinphoneIceStateRelayConnection /**< ICE has established a connection through a relay */
};
/**
* Enum describing Ice states.
* @ingroup initializing
**/
typedef enum _LinphoneIceState LinphoneIceState;
/** /**
* The LinphoneCallStats objects carries various statistic informations regarding quality of audio or video streams. * The LinphoneCallStats objects carries various statistic informations regarding quality of audio or video streams.
* *
...@@ -285,6 +303,7 @@ struct _LinphoneCallStats { ...@@ -285,6 +303,7 @@ struct _LinphoneCallStats {
mblk_t* received_rtcp; /**<Last RTCP packet received, as a mblk_t structure. See oRTP documentation for details how to extract information from it*/ mblk_t* received_rtcp; /**<Last RTCP packet received, as a mblk_t structure. See oRTP documentation for details how to extract information from it*/
mblk_t* sent_rtcp;/**<Last RTCP packet sent, as a mblk_t structure. See oRTP documentation for details how to extract information from it*/ mblk_t* sent_rtcp;/**<Last RTCP packet sent, as a mblk_t structure. See oRTP documentation for details how to extract information from it*/
float round_trip_delay; /**<Round trip propagation time in seconds if known, -1 if unknown.*/ float round_trip_delay; /**<Round trip propagation time in seconds if known, -1 if unknown.*/
LinphoneIceState ice_state; /**< State of ICE processing. */
}; };
/** /**
......
...@@ -624,9 +624,11 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call) ...@@ -624,9 +624,11 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
} }
ice_add_local_candidate(audio_check_list, "host", local_addr, call->audio_port, 1, NULL); ice_add_local_candidate(audio_check_list, "host", local_addr, call->audio_port, 1, NULL);
ice_add_local_candidate(audio_check_list, "host", local_addr, call->audio_port + 1, 2, NULL); ice_add_local_candidate(audio_check_list, "host", local_addr, call->audio_port + 1, 2, NULL);
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateInProgress;
if (call->params.has_video && (video_check_list != NULL)) { if (call->params.has_video && (video_check_list != NULL)) {
ice_add_local_candidate(video_check_list, "host", local_addr, call->video_port, 1, NULL); ice_add_local_candidate(video_check_list, "host", local_addr, call->video_port, 1, NULL);
ice_add_local_candidate(video_check_list, "host", local_addr, call->video_port + 1, 2, NULL); ice_add_local_candidate(video_check_list, "host", local_addr, call->video_port + 1, 2, NULL);
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateInProgress;
} }
ms_message("ICE: gathering candidate from [%s]",server); ms_message("ICE: gathering candidate from [%s]",server);
...@@ -635,6 +637,44 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call) ...@@ -635,6 +637,44 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
return 0; return 0;
} }
void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call)
{
IceCheckList *audio_check_list;
IceCheckList *video_check_list;
if (call->ice_session == NULL) return;
audio_check_list = ice_session_check_list(call->ice_session, 0);
video_check_list = ice_session_check_list(call->ice_session, 1);
if (audio_check_list == NULL) return;
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_video && (video_check_list != NULL)) {
switch (ice_check_list_selected_valid_candidate_type(video_check_list)) {
case ICT_HostCandidate:
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateHostConnection;
break;
case ICT_ServerReflexiveCandidate:
case ICT_PeerReflexiveCandidate:
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateReflexiveConnection;
break;
case ICT_RelayedCandidate:
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateRelayConnection;
break;
}
}
}
void linphone_core_update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session) void linphone_core_update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session)
{ {
const char *rtp_addr, *rtcp_addr; const char *rtp_addr, *rtcp_addr;
......
...@@ -241,6 +241,7 @@ typedef struct StunCandidate{ ...@@ -241,6 +241,7 @@ typedef struct StunCandidate{
int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call, StunCandidate *ac, StunCandidate *vc); int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call, StunCandidate *ac, StunCandidate *vc);
void linphone_core_adapt_to_network(LinphoneCore *lc, int ping_time_ms, LinphoneCallParams *params); void linphone_core_adapt_to_network(LinphoneCore *lc, int ping_time_ms, LinphoneCallParams *params);
int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call); int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call);
void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call);
void linphone_core_update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session); void linphone_core_update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session);
void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md); void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md);
void linphone_core_deactivate_ice_for_deactivated_media_streams(LinphoneCall *call, const SalMediaDescription *md); void linphone_core_deactivate_ice_for_deactivated_media_streams(LinphoneCall *call, const SalMediaDescription *md);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment