* @{
*/
+/**
+ * @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.
*/
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);
+
/**
* @}
*/
--- /dev/null
+/*
+ * 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;
+}