webrtc_signaling_server: Add internal API set for signaling server 24/251224/16
authorSangchul Lee <sc11.lee@samsung.com>
Mon, 11 Jan 2021 12:10:28 +0000 (21:10 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Mon, 1 Feb 2021 02:44:11 +0000 (11:44 +0900)
This signaling server is only for private network.
Handling messages between server and client will be added with
following patches.

Functions are adde as below.
 - webrtc_signaling_server_create()
 - webrtc_signaling_server_start()
 - webrtc_signaling_server_stop()
 - webrtc_signaling_server_destroy()

[Version] 0.1.90
[Issue Type] API

Change-Id: I7719cacb9bcb1a0639b0e425067beba5fcb4a881
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
include/webrtc_internal.h
include/webrtc_private.h
packaging/capi-media-webrtc.spec
src/webrtc_signaling_server.c [new file with mode: 0644]

index 55224cec139973087725fb1e65bf121b9b448f9f..1e2c53b951a30a17622d1146107d9778b1331977 100644 (file)
@@ -31,6 +31,13 @@ extern "C" {
 * @{
 */
 
+/**
+ * @internal
+ * @brief WebRTC signaling server handle type.
+ * @since_tizen 6.5
+ */
+typedef void *webrtc_signaling_server_h;
+
 /**
  * @internal
  * @brief Set an ecore wayland display to the media track.
@@ -50,6 +57,70 @@ extern "C" {
  */
 int webrtc_set_ecore_wl_display(webrtc_h webrtc, unsigned int track_id, void *ecore_wl_window);
 
+/**
+ * @internal
+ * @brief Create a signaling server for private network.
+ * @since_tizen 6.5
+ * @param[in] port           The port number
+ * @param[out] server        Signaling server 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_signaling_server_start()
+ * @see webrtc_signaling_server_stop()
+ * @see webrtc_signaling_server_destroy()
+ */
+int webrtc_signaling_server_create(int port, webrtc_signaling_server_h *server);
+
+/**
+ * @internal
+ * @brief Start the signaling server.
+ * @since_tizen 6.5
+ * @param[in] server        Signaling server 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
+ * @pre Call webrtc_signaling_server_create() before calling this function.
+ * @see webrtc_signaling_server_stop()
+ * @see webrtc_signaling_server_destroy()
+ */
+int webrtc_signaling_server_start(webrtc_signaling_server_h server);
+
+/**
+ * @internal
+ * @brief Stop the signaling server.
+ * @since_tizen 6.5
+ * @param[in] server        Signaling server 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
+ * @pre Call webrtc_signaling_server_start() before calling this function.
+ * @see webrtc_signaling_server_start()
+ * @see webrtc_signaling_server_destroy()
+ */
+int webrtc_signaling_server_stop(webrtc_signaling_server_h server);
+
+/**
+ * @internal
+ * @brief Destroy the signaling server.
+ * @since_tizen 6.5
+ * @param[in] server        Signaling server handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #WEBRTC_ERROR_NONE    Successful
+ * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre Call webrtc_signaling_server_create() before calling this function.
+ * @see webrtc_signaling_server_start()
+ * @see webrtc_signaling_server_stop()
+ */
+int webrtc_signaling_server_destroy(webrtc_signaling_server_h server);
+
 /**
  * @}
  */
index 6eea4f9b4dfa5fa0b8e6d3eca1383a2282ffb63e..1dd9159fb82f475c9ca604d7c78a84d96e783ae0 100644 (file)
@@ -358,6 +358,13 @@ typedef struct _webrtc_websocket_s {
        struct lws_context *context;
 } webrtc_websocket_s;
 
+typedef struct _webrtc_signaling_server_s {
+       GMutex mutex;
+       webrtc_websocket_s *ws;
+       GThread *thread;
+       bool exit_thread;
+} webrtc_signaling_server_s;
+
 int _load_ini(webrtc_s *webrtc);
 void _unload_ini(webrtc_s *webrtc);
 ini_item_media_source_s* _ini_get_source_by_type(webrtc_ini_s *ini, webrtc_media_source_type_e type);
index c8a08d32e5242377b15c24e3b24efd8e94d091b7..05068d6f1c130c2f1bb9db8e86a18ec9c63b11fd 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-webrtc
 Summary:    A WebRTC library in Tizen Native API
-Version:    0.1.89
+Version:    0.1.90
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
diff --git a/src/webrtc_signaling_server.c b/src/webrtc_signaling_server.c
new file mode 100644 (file)
index 0000000..88208a5
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "webrtc.h"
+#include "webrtc_private.h"
+#include "webrtc_internal.h"
+
+static void __send_message(struct lws *wsi, const char *message)
+{
+       guchar *buffer;
+       int size;
+       int len;
+
+       RET_IF(wsi == NULL, "wsi is NULL");
+       RET_IF(message == NULL, "message is NULL");
+
+       len = strlen(message) + 1;
+
+       buffer = g_malloc0(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING);
+
+       memcpy(buffer + LWS_SEND_BUFFER_PRE_PADDING, message, len);
+
+       size = lws_write(wsi, (buffer + LWS_SEND_BUFFER_PRE_PADDING), len, LWS_WRITE_TEXT);
+       if (size == -1)
+               LOG_ERROR("failed to lws_write()");
+       else
+               LOG_DEBUG("message is sent[size:%d, %s]", size, buffer + LWS_SEND_BUFFER_PRE_PADDING);
+
+       g_free(buffer);
+
+       return;
+}
+
+static int __ws_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
+{
+       LOG_DEBUG("wsi[%p] reason[%d] user[%p] in[%p] size[%zu]", wsi, reason, user, in, len);
+
+       switch (reason) {
+       case LWS_CALLBACK_ESTABLISHED:
+               LOG_INFO("ESTABLISHED");
+               /* FIXME: send message with unique id */
+               __send_message(wsi, "ESTABLISHED");
+               break;
+       case LWS_CALLBACK_RECEIVE: {
+               gchar *message = g_strndup((const gchar*)in, (gsize)len);
+               LOG_INFO("RECEIVE:\n%s", message);
+               /* FIXME: handle received message from client */
+               g_free(message);
+               break;
+       }
+       case LWS_CALLBACK_CLOSED:
+               LOG_INFO("CLOSED");
+               break;
+       case LWS_CALLBACK_PROTOCOL_INIT:
+               LOG_DEBUG("PROTOCOL INIT");
+               break;
+       case LWS_CALLBACK_PROTOCOL_DESTROY:
+               LOG_DEBUG("PROTOCOL DESTROY");
+               break;
+       case LWS_CALLBACK_WSI_CREATE:
+               LOG_DEBUG("WSI CREATE");
+               break;
+       case LWS_CALLBACK_WSI_DESTROY:
+               LOG_DEBUG("WSI DESTROY");
+               break;
+       case LWS_CALLBACK_EVENT_WAIT_CANCELLED:
+               LOG_DEBUG("EVENT WAIT CANCELLED");
+               break;
+       default:
+               LOG_DEBUG("reason(%d)", reason);
+               break;
+       }
+
+       return 0;
+}
+
+static gpointer __thread_func(gpointer data)
+{
+       webrtc_signaling_server_s *server = (webrtc_signaling_server_s *)data;
+       RET_VAL_IF(server == NULL, NULL, "server is NULL");
+       RET_VAL_IF(server->ws == NULL, NULL, "ws is NULL");
+
+       LOG_DEBUG(">>>>> start thread func, server[%p]", server);
+
+       while (!server->exit_thread) {
+               if (_start_websocket(server->ws, 1000) != WEBRTC_ERROR_NONE)
+                       LOG_ERROR("failed to _start_websocket()");
+       }
+
+       LOG_DEBUG("<<<<< exit thread func, server[%p]", server);
+
+       return NULL;
+}
+
+int webrtc_signaling_server_create(int port, webrtc_signaling_server_h *server)
+{
+       webrtc_signaling_server_s *_server;
+
+       RET_VAL_IF(server == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "server is NULL");
+
+       _server = g_new0(webrtc_signaling_server_s, 1);
+
+       /* FIXME: check the parameters from ini */
+       _server->ws = _alloc_websocket(port, NULL, NULL, NULL, __ws_cb, _server);
+       if (!_server->ws) {
+               LOG_ERROR("failed to _alloc_websocket(), port[%d]", port);
+               g_free(_server);
+               return WEBRTC_ERROR_INVALID_OPERATION;
+       }
+
+       g_mutex_init(&_server->mutex);
+
+       *server = _server;
+
+       LOG_INFO("server[%p, port:%d]", *server, port);
+
+       return WEBRTC_ERROR_NONE;
+}
+
+int webrtc_signaling_server_start(webrtc_signaling_server_h server)
+{
+       int ret = WEBRTC_ERROR_NONE;
+       webrtc_signaling_server_s *_server = (webrtc_signaling_server_s *)server;
+       GError *error;
+
+       RET_VAL_IF(server == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "server is NULL");
+
+       g_mutex_lock(&_server->mutex);
+
+       if (_server->thread) {
+               LOG_DEBUG("thread[%p] has been already started", _server->thread);
+               g_mutex_unlock(&_server->mutex);
+               return WEBRTC_ERROR_NONE;
+       }
+
+       _server->exit_thread = false;
+
+       _server->thread = g_thread_try_new("signaling-thread", __thread_func, _server, &error);
+       RET_VAL_WITH_UNLOCK_IF(_server->thread == NULL, WEBRTC_ERROR_INVALID_OPERATION, &_server->mutex,
+               "failed to g_thread_try_new(), error[%s]", error->message);
+
+       LOG_INFO("server[%p, thread:%p]", _server, _server->thread);
+
+       g_mutex_unlock(&_server->mutex);
+
+       return ret;
+}
+
+static void __stop_server(webrtc_signaling_server_s *server)
+{
+       RET_IF(server == NULL, "server is NULL");
+
+       server->exit_thread = true;
+
+       if (_stop_websocket(server->ws) != WEBRTC_ERROR_NONE)
+               LOG_WARNING("failed to _stop_websocket()");
+
+       LOG_DEBUG("thread[%p]", server->thread);
+
+       g_thread_join(server->thread);
+
+       LOG_DEBUG("thread[%p] is joined", server->thread);
+
+       server->thread = NULL;
+}
+
+int webrtc_signaling_server_stop(webrtc_signaling_server_h server)
+{
+       webrtc_signaling_server_s *_server = (webrtc_signaling_server_s *)server;
+
+       RET_VAL_IF(server == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "server is NULL");
+
+       g_mutex_lock(&_server->mutex);
+
+       RET_VAL_WITH_UNLOCK_IF(_server->thread == NULL, WEBRTC_ERROR_INVALID_OPERATION, &_server->mutex, "thread is NULL");
+
+       __stop_server(_server);
+
+       g_mutex_unlock(&_server->mutex);
+
+       return WEBRTC_ERROR_NONE;
+}
+
+int webrtc_signaling_server_destroy(webrtc_signaling_server_h server)
+{
+       webrtc_signaling_server_s *_server = (webrtc_signaling_server_s *)server;
+
+       RET_VAL_IF(server == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "server is NULL");
+
+       g_mutex_lock(&_server->mutex);
+
+       if (!_server->exit_thread)
+               __stop_server(_server);
+
+       _release_websocket(_server->ws);
+
+       LOG_INFO("server[%p]", _server);
+
+       g_mutex_unlock(&_server->mutex);
+       g_mutex_clear(&_server->mutex);
+
+       g_free(_server);
+
+       return WEBRTC_ERROR_NONE;
+}