From: YoungHun Kim Date: Fri, 2 Apr 2021 03:16:37 +0000 (+0900) Subject: Add API set for TURN server X-Git-Tag: submit/tizen/20210729.023123~94 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F03%2F256403%2F31;p=platform%2Fcore%2Fapi%2Fwebrtc.git Add API set for TURN server Functions are added as below. - webrtc_add_turn_server() - webrtc_foreach_turn_server() Callback prototype - typedef bool (*webrtc_turn_server_cb)( const char *turn_server, void *user_data); [Version] 0.1.147 [Issue Type] API Change-Id: Iadfd91db135167556b801ef9dab3a455ca0d3e1f --- diff --git a/include/webrtc.h b/include/webrtc.h index eb3d599f..fd373711 100644 --- a/include/webrtc.h +++ b/include/webrtc.h @@ -196,6 +196,17 @@ typedef void (*webrtc_state_changed_cb)(webrtc_h webrtc, webrtc_state_e previous */ typedef void (*webrtc_media_packet_source_buffer_state_changed_cb)(unsigned int source_id, webrtc_media_packet_source_buffer_state_e state, void *user_data); +/** + * @brief Called iteratively to inform all the TURN server URLs. + * @since_tizen 6.5 + * @param[in] turn_server The TURN server URL + * @param[in] user_data The user data passed from the callback registration function + * @return @c true to continue with the next iteration of the loop, + * otherwise @c false to break out of the loop + * @see webrtc_foreach_turn_server() + */ +typedef bool (*webrtc_turn_server_cb)(const char *turn_server, void *user_data); + /** * @brief Called when the WebRTC needs session negotiation. * @since_tizen 6.5 @@ -670,6 +681,36 @@ int webrtc_set_stun_server(webrtc_h webrtc, const char *stun_server); */ int webrtc_get_stun_server(webrtc_h webrtc, char **stun_server); +/** + * @brief Add a TURN server URL. + * @since_tizen 6.5 + * @param[in] webrtc WebRTC handle + * @param[in] turn_server The TURN server URL of the form turn(s)://username:password@host:port + * @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_STATE Invalid state + * @pre @a webrtc state must be set to #WEBRTC_STATE_IDLE. + * @see webrtc_foreach_turn_server() + */ +int webrtc_add_turn_server(webrtc_h webrtc, const char *turn_server); + +/** + * @brief Retrieves all the TURN server URLs. + * @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 + * @see webrtc_turn_servers_cb() + * @see webrtc_add_turn_server() + */ +int webrtc_foreach_turn_server(webrtc_h webrtc, webrtc_turn_server_cb callback, void *user_data); + /** * @brief Sets a negotiation needed callback function to be invoked when a change has occurred which requires session negotiation. * @since_tizen 6.5 diff --git a/include/webrtc_private.h b/include/webrtc_private.h index 92bc907b..763730c6 100644 --- a/include/webrtc_private.h +++ b/include/webrtc_private.h @@ -339,6 +339,8 @@ typedef struct _webrtc_s { webrtc_gst_s gst; gchar *stun_server_url; + GList *turn_server_urls; + gchar *desc_offer; gchar *desc_answer; diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 9432c882..1daf96c3 100644 --- a/packaging/capi-media-webrtc.spec +++ b/packaging/capi-media-webrtc.spec @@ -1,6 +1,6 @@ Name: capi-media-webrtc Summary: A WebRTC library in Tizen Native API -Version: 0.1.146 +Version: 0.1.147 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc.c b/src/webrtc.c index bf5c0c69..2e2a5515 100644 --- a/src/webrtc.c +++ b/src/webrtc.c @@ -504,6 +504,54 @@ int webrtc_get_stun_server(webrtc_h webrtc, char **stun_server) return WEBRTC_ERROR_NONE; } +int webrtc_add_turn_server(webrtc_h webrtc, const char *turn_server) +{ + gboolean ret = FALSE; + webrtc_s *_webrtc = (webrtc_s*)webrtc; + + RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + RET_VAL_IF(turn_server == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "turn_server 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"); + + g_signal_emit_by_name (G_OBJECT(_webrtc->gst.webrtcbin), "add-turn-server", turn_server, &ret); + RET_VAL_WITH_UNLOCK_IF(!ret, WEBRTC_ERROR_INVALID_PARAMETER, &_webrtc->mutex, "invalid turn server url (%s)", turn_server); + + _webrtc->turn_server_urls = g_list_append(_webrtc->turn_server_urls, g_strdup(turn_server)); + + LOG_INFO("turn_server[%s]", turn_server); + + g_mutex_unlock(&_webrtc->mutex); + + return WEBRTC_ERROR_NONE; +} + +int webrtc_foreach_turn_server(webrtc_h webrtc, webrtc_turn_server_cb callback, void *user_data) +{ + webrtc_s *_webrtc = (webrtc_s*)webrtc; + int idx = 0; + + 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); + + for (idx = 0; idx < (int)g_list_length(_webrtc->turn_server_urls); idx++) { + if (!callback((const char *)g_list_nth(_webrtc->turn_server_urls, idx)->data, user_data)) { + LOG_INFO("stop foreach callback"); + break; + } + } + + LOG_INFO("callback[%p] user_data[%p]", callback, user_data); + + g_mutex_unlock(&_webrtc->mutex); + + return WEBRTC_ERROR_NONE; +} + int webrtc_set_negotiation_needed_cb(webrtc_h webrtc, webrtc_negotiation_needed_cb callback, void *user_data) { webrtc_s *_webrtc = (webrtc_s*)webrtc; diff --git a/src/webrtc_data_channel.c b/src/webrtc_data_channel.c index 708545dc..7b8212aa 100644 --- a/src/webrtc_data_channel.c +++ b/src/webrtc_data_channel.c @@ -285,4 +285,4 @@ int _data_channel_send_bytes(webrtc_data_channel_s *channel, const char *data, u g_bytes_unref(bytes); return WEBRTC_ERROR_NONE; -} \ No newline at end of file +} diff --git a/src/webrtc_private.c b/src/webrtc_private.c index 3b795dda..4e42723a 100644 --- a/src/webrtc_private.c +++ b/src/webrtc_private.c @@ -1076,6 +1076,10 @@ void _gst_destroy_pipeline(webrtc_s *webrtc) g_free(webrtc->stun_server_url); webrtc->stun_server_url = NULL; } + if (webrtc->turn_server_urls) { + g_list_free_full(webrtc->turn_server_urls, g_free); + webrtc->turn_server_urls = NULL; + } if (webrtc->desc_offer) { g_free(webrtc->desc_offer); webrtc->desc_offer = NULL; diff --git a/test/webrtc_test.c b/test/webrtc_test.c index f9a97bf4..0667f413 100644 --- a/test/webrtc_test.c +++ b/test/webrtc_test.c @@ -63,6 +63,7 @@ enum { CURRENT_STATUS_DATA_CHANNEL_SEND_STRING_AS_BYTES, CURRENT_STATUS_DATA_CHANNEL_SEND_FILE, CURRENT_STATUS_SET_STUN_SERVER, + CURRENT_STATUS_ADD_TURN_SERVER, CURRENT_STATUS_SET_LOCAL_DESCRIPTION, CURRENT_STATUS_SET_REMOTE_DESCRIPTION, CURRENT_STATUS_SETTING_SIGNALING_SERVER, @@ -818,6 +819,37 @@ static void _webrtc_get_stun_server(int index) } } +static void _webrtc_add_turn_server(int index, char *uri) +{ + int ret = 0; + + if (!uri) + return; + + ret = webrtc_add_turn_server(g_conns[index].webrtc, uri); + if (ret != WEBRTC_ERROR_NONE) + g_print("failed to webrtc_add_turn_server(), uri[%s], ret[0x%x]\n", uri, ret); + else + g_print("webrtc_add_turn_server() success, uri[%s]\n", uri); +} + +static bool __foreach_turn_server(const char *turn_server, gpointer user_data) +{ + g_print("- turn server %s\n", turn_server); + return true; +} + +static void _webrtc_get_turn_servers(int index) +{ + int ret = 0; + + ret = webrtc_foreach_turn_server(g_conns[index].webrtc, __foreach_turn_server, NULL); + if (ret != WEBRTC_ERROR_NONE) + g_print("failed to webrtc_foreach_turn_server() ret[0x%x]\n", ret); + else + g_print("webrtc_foreach_turn_server() success\n"); +} + static char * __get_channel_label(webrtc_data_channel_h channel) { int ret = WEBRTC_ERROR_NONE; @@ -832,6 +864,7 @@ static char * __get_channel_label(webrtc_data_channel_h channel) return label; } + static void __data_channel_open_cb(webrtc_data_channel_h channel, void *user_data) { connection_s *conn = (connection_s*)user_data; @@ -2835,6 +2868,12 @@ void _interpret_main_menu(char *cmd) } else if (strncmp(cmd, "gt", 2) == 0) { _webrtc_get_stun_server(g_conn_index); + } else if (strncmp(cmd, "su", 2) == 0) { + g_conns[g_conn_index].menu_state = CURRENT_STATUS_ADD_TURN_SERVER; + + } else if (strncmp(cmd, "gu", 2) == 0) { + _webrtc_get_turn_servers(g_conn_index); + } else if (strncmp(cmd, "ss", 2) == 0) { g_conns[g_conn_index].menu_state = CURRENT_STATUS_SETTING_SIGNALING_SERVER; @@ -2926,6 +2965,10 @@ void display_handle_status(int index) if (ret != WEBRTC_ERROR_NONE) return; + ret = webrtc_foreach_turn_server(g_conns[index].webrtc, __foreach_turn_server, NULL); + if (ret != WEBRTC_ERROR_NONE) + return; + g_print(" webrtc[%p]", g_conns[index].webrtc); g_print(" state[%s]", g_webrtc_state_str[state]); if (stun_server) { @@ -3006,6 +3049,8 @@ void display_sub_basic() g_print("------------------------------------- Negotiation ---------------------------------------\n"); g_print("st. Set STUN server\t"); g_print("gt. Get STUN server\n"); + g_print("su. Add TURN server\t"); + g_print("gu. Get TURN servers\n"); g_print("co. Create offer\t"); g_print("ca. Create answer\n"); g_print("sl. Set local description\t"); @@ -3084,6 +3129,9 @@ static void displaymenu() } else if (g_conns[g_conn_index].menu_state == CURRENT_STATUS_SET_STUN_SERVER) { g_print("*** input STUN server address.\n"); + } else if (g_conns[g_conn_index].menu_state == CURRENT_STATUS_ADD_TURN_SERVER) { + g_print("*** input TURN server address.\n"); + } else if (g_conns[g_conn_index].menu_state == CURRENT_STATUS_SET_LOCAL_DESCRIPTION) { g_print("*** input type of local description.(1:offer, 2:answer)\n"); @@ -3263,6 +3311,11 @@ static void interpret(char *cmd) reset_menu_state(); break; } + case CURRENT_STATUS_ADD_TURN_SERVER: { + _webrtc_add_turn_server(g_conn_index, cmd); + reset_menu_state(); + break; + } case CURRENT_STATUS_SET_LOCAL_DESCRIPTION: { value = atoi(cmd); if (value == 1)