]> sjero.net Git - linphone/commitdiff
Add ICE state to the call stats.
authorGhislain MARY <ghislain.mary@belledonne-communications.com>
Mon, 17 Sep 2012 12:46:55 +0000 (14:46 +0200)
committerGhislain MARY <ghislain.mary@belledonne-communications.com>
Mon, 17 Sep 2012 13:10:28 +0000 (15:10 +0200)
coreapi/linphonecall.c
coreapi/linphonecore.h
coreapi/misc.c
coreapi/private.h

index 5962badd3a257e2503ca019c4beb3cbe0aa50dce..9243be084c3870d5645426d00db9cce3c451c1b9 100644 (file)
@@ -324,6 +324,7 @@ void linphone_call_init_stats(LinphoneCallStats *stats, int type) {
        stats->type = type;
        stats->received_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){
@@ -1541,6 +1542,8 @@ void linphone_call_delete_ice_session(LinphoneCall *call){
                call->ice_session = NULL;
                if (call->audiostream != NULL) call->audiostream->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){
                                if (ice_session_role(call->ice_session) == IR_Controlling) {
                                        ice_session_select_candidates(call->ice_session);
                                        linphone_core_update_call(call->core, call, &call->current_params);
+                                       linphone_core_update_ice_state_in_call_stats(call);
                                }
                                break;
                        case IS_Failed:
@@ -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. */
                                                ice_session_select_candidates(call->ice_session);
                                                linphone_core_update_call(call->core, call, &call->current_params);
+                                               linphone_core_update_ice_state_in_call_stats(call);
                                        }
                                }
                                break;
index ef24f2c78cbb3894e3a31637699641c9652fc83c..acf81f1df57ea66b8ea9d91c1c86b832438cc70a 100644 (file)
@@ -261,6 +261,24 @@ typedef struct _LinphoneCall LinphoneCall;
 #define LINPHONE_CALL_STATS_AUDIO 0
 #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.
  *
@@ -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*         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.*/
+       LinphoneIceState        ice_state; /**< State of ICE processing. */
 };
 
 /**
index 1e7676bfae7b035a13f1da80c15f6058b069f677..d05a275ba0ca88d0a5f516fc5f4fbf8b69fe3eac 100644 (file)
@@ -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, 2, NULL);
+       call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateInProgress;
        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, 2, NULL);
+               call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateInProgress;
        }
 
        ms_message("ICE: gathering candidate from [%s]",server);
@@ -635,6 +637,44 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
        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)
 {
        const char *rtp_addr, *rtcp_addr;
index f26c6f106f218c97e6748c6eb327483914e3bc43..f0b3b2c302e54b0d394344027864846786426609 100644 (file)
@@ -241,6 +241,7 @@ typedef struct StunCandidate{
 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);
 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_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md);
 void linphone_core_deactivate_ice_for_deactivated_media_streams(LinphoneCall *call, const SalMediaDescription *md);