Add API set for the ICE connection state 55/257355/8
authorSangchul Lee <sc11.lee@samsung.com>
Fri, 23 Apr 2021 04:09:16 +0000 (13:09 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 6 May 2021 04:28:58 +0000 (13:28 +0900)
These correspond to the 'iceConnectionState' and 'oniceconnectionstatechange'
property of the RTCPeerConnection respectively.

Enums are added as below.
 - WEBRTC_ICE_CONNECTION_STATE_NEW
 - WEBRTC_ICE_CONNECTION_STATE_CHECKING
 - WEBRTC_ICE_CONNECTION_STATE_CONNECTED
 - WEBRTC_ICE_CONNECTION_STATE_COMPLETED
 - WEBRTC_ICE_CONNECTION_STATE_FAILED
 - WEBRTC_ICE_CONNECTION_STATE_DISCONNECTED
 - WEBRTC_ICE_CONNECTION_STATE_CLOSED

Functions are added as below.
 - webrtc_set[unset]_ice_connection_state_change_cb()
 - webrtc_get_ice_connection_state()

[Version] 0.1.164
[Issue Type] API

Change-Id: If11019e7d57667d031c676e12c8c688fcc03da30
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
include/webrtc.h
include/webrtc_private.h
packaging/capi-media-webrtc.spec
src/webrtc.c
src/webrtc_private.c

index 1e5b1811a713f2ffae0e7dfbe5b68ad2cb22b7d7..5621930c2c1f7ac5af94c5912590c8887872cf28 100644 (file)
@@ -129,6 +129,20 @@ typedef enum {
     WEBRTC_ICE_GATHERING_STATE_COMPLETE,   /**<  Complete */
 } webrtc_ice_gathering_state_e;
 
+/**
+ * @brief Enumeration for WebRTC ICE connection state.
+ * @since_tizen 6.5
+ */
+typedef enum {
+       WEBRTC_ICE_CONNECTION_STATE_NEW,           /**<  New */
+       WEBRTC_ICE_CONNECTION_STATE_CHECKING,      /**<  Checking */
+       WEBRTC_ICE_CONNECTION_STATE_CONNECTED,     /**<  Connected */
+       WEBRTC_ICE_CONNECTION_STATE_COMPLETED,     /**<  Completed */
+       WEBRTC_ICE_CONNECTION_STATE_FAILED,        /**<  Failed */
+       WEBRTC_ICE_CONNECTION_STATE_DISCONNECTED,  /**<  Disconnected */
+       WEBRTC_ICE_CONNECTION_STATE_CLOSED,        /**<  Closed */
+} webrtc_ice_connection_state_e;
+
 /**
  * @brief Enumeration for WebRTC media source type.
  * @since_tizen 6.5
@@ -258,6 +272,18 @@ typedef void (*webrtc_signaling_state_change_cb)(webrtc_h webrtc, webrtc_signali
  */
 typedef void (*webrtc_ice_gathering_state_change_cb)(webrtc_h webrtc, webrtc_ice_gathering_state_e state, void *user_data);
 
+/**
+ * @brief Called when the WebRTC ICE connection state is changed.
+ * @since_tizen 6.5
+ * @remarks The @a webrtc is the same object for which the callback was set.\nThe @a webrtc should not be released.
+ * @param[in] webrtc     WebRTC handle
+ * @param[in] state      The ICE connection state
+ * @param[in] user_data  The user data passed from the callback registration function
+ * @see webrtc_set_ice_connection_state_change_cb()
+ * @see webrtc_unset_ice_connection_state_change_cb()
+ */
+typedef void (*webrtc_ice_connection_state_change_cb)(webrtc_h webrtc, webrtc_ice_connection_state_e state, void *user_data);
+
 /**
  * @brief Called when the buffer state of media packet source is changed.
  * @since_tizen 6.5
@@ -969,6 +995,52 @@ int webrtc_unset_ice_gathering_state_change_cb(webrtc_h webrtc);
  */
 int webrtc_get_ice_gathering_state(webrtc_h webrtc, webrtc_ice_gathering_state_e *state);
 
+/**
+ * @brief Sets a callback function to be invoked when the WebRTC ICE connection state is changed.
+ * @since_tizen 6.5
+ * @param[in] webrtc      WebRTC handle
+ * @param[in] callback    Callback function pointer
+ * @param[in] user_data   The user data to be passed to the callback function
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #WEBRTC_ERROR_NONE    Successful
+ * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter
+ * @post webrtc_ice_connection_state_change_cb() will be invoked.
+ * @see webrtc_unset_ice_connection_state_change_cb()
+ * @see webrtc_ice_connection_state_change_cb()
+ * @see webrtc_get_ice_connection_state()
+ */
+int webrtc_set_ice_connection_state_change_cb(webrtc_h webrtc, webrtc_ice_connection_state_change_cb callback, void *user_data);
+
+/**
+ * @brief Unsets the ICE connection state change callback function.
+ * @since_tizen 6.5
+ * @param[in] webrtc      WebRTC handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #WEBRTC_ERROR_NONE    Successful
+ * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation
+ * @see webrtc_set_ice_connection_state_change_cb()
+ * @see webrtc_get_ice_connection_state()
+ */
+int webrtc_unset_ice_connection_state_change_cb(webrtc_h webrtc);
+
+/**
+ * @brief Gets the ICE connection state.
+ * @since_tizen 6.5
+ * @remarks The default value is #WEBRTC_ICE_CONNECTION_STATE_NEW.
+ * @param[in] webrtc      WebRTC handle
+ * @param[out] state      The ICE connection state
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #WEBRTC_ERROR_NONE    Successful
+ * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see webrtc_set_ice_connection_state_change_cb()
+ * @see webrtc_unset_ice_connection_state_change_cb()
+ */
+int webrtc_get_ice_connection_state(webrtc_h webrtc, webrtc_ice_connection_state_e *state);
+
 /**
  * @brief Sets a negotiation needed callback function to be invoked when a change has occurred which requires session negotiation.
  * @since_tizen 6.5
index a56d95f7de7034aa2d1eebbbfe6a0c67508c2c3c..8d48ef28821e18300e8823c64d30c00f1ceafbd9 100644 (file)
@@ -358,6 +358,8 @@ typedef struct _webrtc_s {
        webrtc_callbacks_s peer_connection_state_change_cb;
        webrtc_callbacks_s signaling_state_change_cb;
        webrtc_callbacks_s ice_gathering_state_change_cb;
+       webrtc_callbacks_s ice_connection_state_change_cb;
+
        webrtc_callbacks_s negotiation_needed_cb;
        webrtc_callbacks_s ice_candidate_cb;
        webrtc_callbacks_s track_added_cb;
@@ -369,8 +371,8 @@ typedef struct _webrtc_s {
                webrtc_peer_connection_state_e peer_connection_state;
                webrtc_signaling_state_e signaling_state;
                webrtc_ice_gathering_state_e ice_gathering_state;
-               const gchar *ice_connection_state;
-       } internal_states;
+               webrtc_ice_connection_state_e ice_connection_state;
+       } negotiation_states;
 #ifdef TIZEN_FEATURE_RES_MGR
        webrtc_resource_s resource;
 #endif
index 97e0821380d3af518fbfa0e912e8c0a0ac7a7953..bd22eb32dec2474f5d844fcd77b1004d15cf5ef1 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.1.163
+Version:    0.1.164
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 102756c47a35c927e1e85c16505a1b36fbb72feb..fd1924293739431ccb3960bfe7642e93be6a0d35 100644 (file)
@@ -647,7 +647,7 @@ int webrtc_get_peer_connection_state(webrtc_h webrtc, webrtc_peer_connection_sta
 
        g_mutex_lock(&_webrtc->mutex);
 
-       *state = _webrtc->internal_states.peer_connection_state;
+       *state = _webrtc->negotiation_states.peer_connection_state;
 
        LOG_INFO("state[%d]", *state);
 
@@ -710,7 +710,7 @@ int webrtc_get_signaling_state(webrtc_h webrtc, webrtc_signaling_state_e *state)
 
        g_mutex_lock(&_webrtc->mutex);
 
-       *state = _webrtc->internal_states.signaling_state;
+       *state = _webrtc->negotiation_states.signaling_state;
 
        LOG_INFO("state[%d]", *state);
 
@@ -773,7 +773,70 @@ int webrtc_get_ice_gathering_state(webrtc_h webrtc, webrtc_ice_gathering_state_e
 
        g_mutex_lock(&_webrtc->mutex);
 
-       *state = _webrtc->internal_states.ice_gathering_state;
+       *state = _webrtc->negotiation_states.ice_gathering_state;
+
+       LOG_INFO("state[%d]", *state);
+
+       g_mutex_unlock(&_webrtc->mutex);
+
+       return WEBRTC_ERROR_NONE;
+}
+
+int webrtc_set_ice_connection_state_change_cb(webrtc_h webrtc, webrtc_ice_connection_state_change_cb callback, void *user_data)
+{
+       webrtc_s *_webrtc = (webrtc_s*)webrtc;
+
+       RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+       RET_VAL_IF(callback == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "callback is NULL");
+
+       g_mutex_lock(&_webrtc->mutex);
+
+       RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_IDLE, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be IDLE");
+
+       LOG_WARNING_IF_CALLBACK_EXISTS(_webrtc->ice_connection_state_change_cb);
+
+       _webrtc->ice_connection_state_change_cb.callback = callback;
+       _webrtc->ice_connection_state_change_cb.user_data = user_data;
+
+       LOG_INFO("callback[%p] user_data[%p]", callback, user_data);
+
+       g_mutex_unlock(&_webrtc->mutex);
+
+       return WEBRTC_ERROR_NONE;
+}
+
+int webrtc_unset_ice_connection_state_change_cb(webrtc_h webrtc)
+{
+       webrtc_s *_webrtc = (webrtc_s*)webrtc;
+
+       RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+
+       g_mutex_lock(&_webrtc->mutex);
+
+       RET_VAL_WITH_UNLOCK_IF(_webrtc->state != WEBRTC_STATE_IDLE, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should be IDLE");
+       RET_VAL_WITH_UNLOCK_IF(_webrtc->ice_connection_state_change_cb.callback == NULL, WEBRTC_ERROR_INVALID_OPERATION, &_webrtc->mutex, "callback was not set");
+
+       LOG_INFO("callback[%p] user_data[%p] is reset to NULL",
+               _webrtc->ice_connection_state_change_cb.callback, _webrtc->ice_connection_state_change_cb.user_data);
+
+       _webrtc->ice_connection_state_change_cb.callback = NULL;
+       _webrtc->ice_connection_state_change_cb.user_data = NULL;
+
+       g_mutex_unlock(&_webrtc->mutex);
+
+       return WEBRTC_ERROR_NONE;
+}
+
+int webrtc_get_ice_connection_state(webrtc_h webrtc, webrtc_ice_connection_state_e *state)
+{
+       webrtc_s *_webrtc = (webrtc_s*)webrtc;
+
+       RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+       RET_VAL_IF(state == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "state is NULL");
+
+       g_mutex_lock(&_webrtc->mutex);
+
+       *state = _webrtc->negotiation_states.ice_connection_state;
 
        LOG_INFO("state[%d]", *state);
 
index 2439a695aec7ecff59420b89f0b90aabb1f16d64..6f940a3e78ac5d11a57366359245a4229a1bfdcd 100644 (file)
@@ -46,6 +46,11 @@ typedef struct {
        webrtc_ice_gathering_state_e state;
 } ice_gathering_state_info_s;
 
+typedef struct {
+       const char *str;
+       webrtc_ice_connection_state_e state;
+} ice_connection_state_info_s;
+
 static direction_info_s __direction_info[] = {
        [WEBRTC_TRANSCEIVER_DIRECTION_SENDONLY] = { "SENDONLY", GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY },
        [WEBRTC_TRANSCEIVER_DIRECTION_RECVONLY] = { "RECVONLY", GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY },
@@ -76,6 +81,16 @@ static ice_gathering_state_info_s __ice_gathering_state_info[] = {
        [GST_WEBRTC_ICE_GATHERING_STATE_COMPLETE] = { "COMPLETE", WEBRTC_ICE_GATHERING_STATE_COMPLETE },
 };
 
+static ice_connection_state_info_s __ice_connection_state_info[] = {
+       [GST_WEBRTC_ICE_CONNECTION_STATE_NEW] = { "NEW", WEBRTC_ICE_CONNECTION_STATE_NEW },
+       [GST_WEBRTC_ICE_CONNECTION_STATE_CHECKING] = { "CHECKING", WEBRTC_ICE_CONNECTION_STATE_CHECKING },
+       [GST_WEBRTC_ICE_CONNECTION_STATE_CONNECTED] = { "CONNECTED", WEBRTC_ICE_CONNECTION_STATE_CONNECTED },
+       [GST_WEBRTC_ICE_CONNECTION_STATE_COMPLETED] = { "COMPLETED", WEBRTC_ICE_CONNECTION_STATE_COMPLETED },
+       [GST_WEBRTC_ICE_CONNECTION_STATE_FAILED] = { "FAILED", WEBRTC_ICE_CONNECTION_STATE_FAILED },
+       [GST_WEBRTC_ICE_CONNECTION_STATE_DISCONNECTED] = { "DISCONNECTED", WEBRTC_ICE_CONNECTION_STATE_DISCONNECTED },
+       [GST_WEBRTC_ICE_CONNECTION_STATE_CLOSED] = { "CLOSED", WEBRTC_ICE_CONNECTION_STATE_CLOSED },
+};
+
 static const char *__get_error_string(webrtc_error_e error)
 {
        switch (error) {
@@ -292,6 +307,23 @@ static void __invoke_ice_gathering_state_change_cb(webrtc_s *webrtc, GstWebRTCIC
        GENERATE_DOT(webrtc, "ICE_GATHERING_STATE_%s", __ice_gathering_state_info[state].str);
 }
 
+static void __invoke_ice_connection_state_change_cb(webrtc_s *webrtc, GstWebRTCICEConnectionState state)
+{
+       webrtc_callbacks_s *cb;
+
+       RET_IF(webrtc == NULL, "webrtc is NULL");
+
+       cb = &webrtc->ice_connection_state_change_cb;
+
+       if (cb->callback) {
+               LOG_DEBUG(">>> callback[%p], user_data[%p]", cb->callback, cb->user_data);
+               ((webrtc_ice_connection_state_change_cb)(cb->callback))((webrtc_h)webrtc, __ice_connection_state_info[state].state, cb->user_data);
+               LOG_DEBUG("<<< end of the callback");
+       }
+
+       GENERATE_DOT(webrtc, "ICE_CONNECTION_STATE_%s", __ice_connection_state_info[state].str);
+}
+
 static gboolean __bus_watch_cb(GstBus *bus, GstMessage *message, gpointer user_data)
 {
        webrtc_s *webrtc = (webrtc_s *)user_data;
@@ -697,7 +729,7 @@ static void __webrtcbin_peer_connection_state_cb(GstElement *webrtcbin, GParamSp
        g_object_get(webrtcbin, "connection-state", &state, NULL);
 
        LOG_DEBUG("[PeerConnectionState] is changed to [%s]", __peer_connection_state_info[state].str);
-       webrtc->internal_states.peer_connection_state = __peer_connection_state_info[state].state;
+       webrtc->negotiation_states.peer_connection_state = __peer_connection_state_info[state].state;
 
        __invoke_peer_connection_state_change_cb(webrtc, state);
 
@@ -729,7 +761,7 @@ static void __webrtcbin_signaling_state_cb(GstElement *webrtcbin, GParamSpec * p
        g_object_get(webrtcbin, "signaling-state", &state, NULL);
 
        LOG_DEBUG("[SignalingState] is changed to [%s]", __signaling_state_info[state].str);
-       webrtc->internal_states.signaling_state = __signaling_state_info[state].state;
+       webrtc->negotiation_states.signaling_state = __signaling_state_info[state].state;
 
        __invoke_signaling_state_change_cb(webrtc, state);
 }
@@ -745,57 +777,28 @@ static void __webrtcbin_ice_gathering_state_cb(GstElement *webrtcbin, GParamSpec
        g_object_get(webrtcbin, "ice-gathering-state", &state, NULL);
 
        LOG_DEBUG("[IceGatheringState] is changed to [%s]", __ice_gathering_state_info[state].str);
-       webrtc->internal_states.ice_gathering_state = __ice_gathering_state_info[state].state;
+       webrtc->negotiation_states.ice_gathering_state = __ice_gathering_state_info[state].state;
 
        __invoke_ice_gathering_state_change_cb(webrtc, state);
 }
 
-static void __webrtcbin_ice_connection_state_cb(GstElement *webrtcbin, GParamSpec * pspec, gpointer user_data)
+static void __webrtcbin_ice_connection_state_cb(GstElement *webrtcbin, GParamSpec *pspec, gpointer user_data)
 {
        webrtc_s *webrtc = (webrtc_s *)user_data;
-       GstWebRTCICEConnectionState ice_connection_state;
-       const gchar *new_state = "UNKNOWN";
+       GstWebRTCICEConnectionState state;
 
        RET_IF(webrtcbin == NULL, "webrtcbin is NULL");
        RET_IF(webrtc == NULL, "webrtc is NULL");
 
-       g_object_get(webrtcbin, "ice-connection-state", &ice_connection_state, NULL);
-
-       switch (ice_connection_state) {
-       case GST_WEBRTC_ICE_CONNECTION_STATE_NEW:
-               new_state = "NEW";
-               break;
-
-       case GST_WEBRTC_ICE_CONNECTION_STATE_CHECKING:
-               new_state = "CHECKING";
-               break;
-
-       case GST_WEBRTC_ICE_CONNECTION_STATE_CONNECTED:
-               new_state = "CONNECTED";
-               break;
+       g_object_get(webrtcbin, "ice-connection-state", &state, NULL);
 
-       case GST_WEBRTC_ICE_CONNECTION_STATE_COMPLETED:
-               new_state = "COMPLETED";
-               break;
+       LOG_DEBUG("[IceConnectionState] is changed to [%s]", __ice_connection_state_info[state].str);
+       webrtc->negotiation_states.ice_connection_state = __ice_connection_state_info[state].state;
 
-       case GST_WEBRTC_ICE_CONNECTION_STATE_FAILED:
-               new_state = "FAILED";
+       __invoke_ice_connection_state_change_cb(webrtc, state);
 
+       if (state == GST_WEBRTC_ICE_CONNECTION_STATE_FAILED)
                __invoke_error_cb(webrtc, WEBRTC_ERROR_CONNECTION_FAILED);
-               break;
-
-       case GST_WEBRTC_ICE_CONNECTION_STATE_DISCONNECTED:
-               new_state = "DISCONNECTED";
-               break;
-
-       case GST_WEBRTC_ICE_CONNECTION_STATE_CLOSED:
-               new_state = "CLOSED";
-               break;
-       }
-
-       LOG_DEBUG("[IceConnectionState] is changed to [%s]", new_state);
-
-       webrtc->internal_states.ice_connection_state = new_state;
 }
 
 static GstPad* __add_no_target_ghostpad(GstBin *bin, const char *pad_name, bool is_src)