daemon/handler: Add initial function handler
authorSangchul Lee <sc11.lee@samsung.com>
Wed, 19 Apr 2023 05:58:48 +0000 (14:58 +0900)
committer이상철/Tizen Platform Lab(SR)/삼성전자 <sc11.lee@samsung.com>
Mon, 24 Apr 2023 05:07:39 +0000 (14:07 +0900)
dependency of esplusplayer library is added.

Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
src/common/espp_service_common.h
src/daemon/espp_service.c
src/daemon/espp_service_handler.c [new file with mode: 0644]
src/daemon/espp_service_priv.h
src/daemon/espp_service_socket.c
src/daemon/meson.build

index f1cc934def1efcd8dcdfd75c85888a6f7004c23b..363127e90991f33d6f7491fa62f4d1d90f8d3d58 100644 (file)
@@ -116,8 +116,13 @@ do {\
        } \
 } while (0)
 
+#define ESPP_FUNC_CREATE         "Create"
+#define ESPP_FUNC_DESTROY        "Destroy"
+#define ESPP_FUNC_START          "Start"
+
 #define ESPP_SERVICE_SOCK ESPP_SVC_SOCK_PATH
 #define MAX_FUNC_LEN 32
+#define MAX_ERROR_LEN 64
 
 typedef struct {
        char func[MAX_FUNC_LEN];
index 23d67c1ef02aaf16831a02565d2c70e72ebbf1ea..a03638f027ecbac4b785b386e0b5b1a5991f020e 100644 (file)
@@ -71,13 +71,14 @@ static int get_option(int argc, char **argv, espp_service_s *svc)
 
 static void __sa_handler(int signal)
 {
-       LOG_WARNING("signal[%d]", signal);
+       LOG_ERROR("-------------------- signal[%d] --------------------", signal);
 
        /* signal block -------------- */
        sigset_t old_mask, all_mask;
        sigfillset(&all_mask);
        sigprocmask(SIG_BLOCK, &all_mask, &old_mask);
 
+       g_hash_table_destroy(g_svc->espp_handles);
        espp_service_deinit_socket(g_svc);
 
        sigprocmask(SIG_SETMASK, &old_mask, NULL);
@@ -114,6 +115,8 @@ static void __sa_handler(int signal)
        }
 
        raise(signal);
+
+       LOG_ERROR("----------------------------------------------------");
 }
 
 static void initialize_signals(void)
@@ -161,7 +164,7 @@ static void run(espp_service_s *svc)
 
 int main(int argc, char *argv[])
 {
-       espp_service_s svc = { false, NULL, -1, 0 };
+       espp_service_s svc = { false, NULL, -1, 0, NULL };
 
        LOG_WARNING("launched, version[%s]", ESPP_SVC_VERSION);
 
@@ -184,10 +187,12 @@ int main(int argc, char *argv[])
        if (espp_service_init_socket(&svc) != 0)
                goto exit;
 
+       svc.espp_handles = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, espp_service_handle_destroy_cb);
+
        run(&svc);
 
+       g_hash_table_destroy(svc.espp_handles);
        espp_service_deinit_socket(&svc);
-
        deinitialize_signals();
 
 exit:
diff --git a/src/daemon/espp_service_handler.c b/src/daemon/espp_service_handler.c
new file mode 100644 (file)
index 0000000..540fcdc
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2023 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 "espp_service_priv.h"
+#include <esplusplayer_capi.h>
+
+typedef void (*func_handler) (espp_service_s *svc, int fd, espp_service_data_from_client_s *param, espp_service_data_from_server_s *result);
+
+enum {
+       ESPP_SERVICE_MSG_CREATE,
+       ESPP_SERVICE_MSG_DESTROY,
+       ESPP_SERVICE_MSG_START,
+};
+
+typedef struct {
+       const char *api;
+       func_handler handler;
+} espp_service_msg_handler_intf_s;
+
+static void __handle_create(espp_service_s *svc, int fd, espp_service_data_from_client_s *param, espp_service_data_from_server_s *result)
+{
+       esplusplayer_handle espp;
+
+       ASSERT(svc);
+       ASSERT(fd >= 0);
+       ASSERT(param);
+       ASSERT(result);
+
+       result->ret = -1;
+
+       espp = esplusplayer_create();
+       ASSERT(espp);
+
+       LOG_INFO("fd[%d], ESPP[%p]: esplusplayer_create() success", fd, espp);
+
+       if (!g_hash_table_insert(svc->espp_handles, GINT_TO_POINTER(fd), (gpointer)espp)) {
+               LOG_ERROR("should not be reached here, fd[%d] already exist, ESPP[%p] will be removed", fd, espp);
+               g_hash_table_remove(svc->espp_handles, GINT_TO_POINTER(fd));
+               esplusplayer_destroy(espp);
+               return;
+       }
+
+       result->ret = 0;
+}
+
+static void __handle_destroy(espp_service_s *svc, int fd, espp_service_data_from_client_s *param, espp_service_data_from_server_s *result)
+{
+       esplusplayer_handle espp;
+
+       ASSERT(svc);
+       ASSERT(fd >= 0);
+       ASSERT(param);
+       ASSERT(result);
+
+       result->ret = -1;
+
+       RET_IF(!(espp = g_hash_table_lookup(svc->espp_handles, GINT_TO_POINTER(fd))), "could not find ESPP by fd[%d]", fd);
+       RET_IF(esplusplayer_destroy(espp) != ESPLUSPLAYER_ERROR_TYPE_NONE, "failed to esplusplayer_destroy()");
+
+       LOG_INFO("fd[%d], ESPP[%p]: esplusplayer_destroy() success", fd, espp);
+
+       ASSERT(g_hash_table_steal(svc->espp_handles, GINT_TO_POINTER(fd)));
+
+       result->ret = 0;
+}
+
+static void __handle_start(espp_service_s *svc, int fd, espp_service_data_from_client_s *param, espp_service_data_from_server_s *result)
+{
+       int ret;
+       esplusplayer_handle espp;
+
+       ASSERT(svc);
+       ASSERT(fd >= 0);
+       ASSERT(param);
+       ASSERT(result);
+
+       result->ret = -1;
+
+       RET_IF(!(espp = g_hash_table_lookup(svc->espp_handles, GINT_TO_POINTER(fd))), "failed to g_hash_table_lookup(), fd[%d]", fd);
+
+       ret = esplusplayer_start(espp);
+       RET_IF(ret != ESPLUSPLAYER_ERROR_TYPE_NONE, "failed to esplusplayer_start(), ESPP[%p]", espp);
+
+       LOG_INFO("fd[%d], ESPP[%p]: esplusplayer_start() success", fd, espp);
+
+       result->ret = 0;
+}
+
+static espp_service_msg_handler_intf_s handlers[] = {
+       [ESPP_SERVICE_MSG_CREATE] = {
+               .api = ESPP_FUNC_CREATE,
+               .handler = __handle_create
+       },
+       [ESPP_SERVICE_MSG_DESTROY] = {
+               .api = ESPP_FUNC_DESTROY,
+               .handler = __handle_destroy
+       },
+       [ESPP_SERVICE_MSG_START] = {
+               .api = ESPP_FUNC_START,
+               .handler = __handle_start
+       },
+};
+
+static int get_msg_type(const char *func)
+{
+       RET_VAL_IF(!func, -1, "func is NULL");
+
+       if (g_strcmp0(func, ESPP_FUNC_CREATE) == 0)
+               return ESPP_SERVICE_MSG_CREATE;
+       if (g_strcmp0(func, ESPP_FUNC_DESTROY) == 0)
+               return ESPP_SERVICE_MSG_DESTROY;
+       if (g_strcmp0(func, ESPP_FUNC_START) == 0)
+               return ESPP_SERVICE_MSG_START;
+
+       LOG_ERROR("not supported func[%s]", func);
+       return -1;
+}
+
+int espp_service_func_handler(espp_service_s *svc, int fd, espp_service_data_from_client_s *request, espp_service_data_from_server_s *result)
+{
+       int ret;
+
+       ASSERT(svc);
+       ASSERT(fd >= 0);
+       ASSERT(request);
+       ASSERT(result);
+
+       LOG_WARNING("fd[%d] request[%p, func:%s]", fd, request, request->func);
+
+       if ((ret = get_msg_type(request->func)) == -1) {
+               result->ret = -1;
+               return ret;
+       }
+
+       handlers[ret].handler(svc, fd, request, result);
+
+       return 0;
+}
+
+void espp_service_handle_destroy_cb(gpointer data)
+{
+       esplusplayer_handle espp = (esplusplayer_handle)data;
+
+       ASSERT(data);
+
+       LOG_INFO("destroy ESPP[%p]", espp);
+
+       RET_IF(esplusplayer_destroy(espp) != ESPLUSPLAYER_ERROR_TYPE_NONE, "failed to esplusplayer_destroy()");
+}
\ No newline at end of file
index 21bded194eb049070da4418e68472a7056a7b22c..633e7c73c1c0696999f03166e051ac0053021965 100644 (file)
@@ -32,10 +32,13 @@ typedef struct {
        GMainLoop *mainloop;
        int fd;
        pthread_t thread_id;
+       GHashTable *espp_handles;
 } espp_service_s;
 
 int espp_service_init_socket(espp_service_s *svc);
 void espp_service_deinit_socket(espp_service_s *svc);
+int espp_service_func_handler(espp_service_s *svc, int fd, espp_service_data_from_client_s *request, espp_service_data_from_server_s *result);
+void espp_service_handle_destroy_cb(gpointer data);
 
 #ifdef __cplusplus
 }
index 3c9c891959500162dbd38b2a68480835c0343d0a..ffae560b2bd02daf4b2048a6ce8dd44f5b2f2967 100644 (file)
 #include <sys/un.h>
 #include <pthread.h>
 
-#define MAX_ERROR_LEN 64
+#define EXIT_IF_NEEDED(x_rx_data) \
+do { \
+       if (g_strcmp0(x_rx_data.func, ESPP_FUNC_DESTROY) == 0) \
+               goto exit; \
+} while (0)
+
+typedef struct {
+       espp_service_s *svc;
+       int fd;
+} work_thread_userdata_s;
 
 static void *__work_thread_func(void *data)
 {
@@ -30,11 +39,16 @@ static void *__work_thread_func(void *data)
        char str_error[MAX_ERROR_LEN] = {'\0',};
        espp_service_data_from_client_s rx_data;
        espp_service_data_from_server_s tx_data;
+       work_thread_userdata_s *userdata = (work_thread_userdata_s *)data;
+       espp_service_s *svc;
+
+       ASSERT(userdata);
+       ASSERT(userdata->fd != -1);
 
-       ASSERT(data);
+       fd = userdata->fd;
+       svc = userdata->svc;
 
-       fd = (int)(uintptr_t)(data);
-       ASSERT(fd != -1);
+       LOG_WARNING("entrance, fd[%d]", fd);
 
        do {
                memset(&rx_data, 0x00, sizeof(espp_service_data_from_client_s));
@@ -47,9 +61,8 @@ static void *__work_thread_func(void *data)
                        LOG_DEBUG("<<<<< from fd[%d]: func[%s]", fd, rx_data.func);
 
                        memset(&tx_data, 0x00, sizeof(espp_service_data_from_server_s));
-
-                       /* TODO: add handler */
-                       tx_data.ret = 0;
+                       if (espp_service_func_handler(svc, fd, &rx_data, &tx_data) != 0)
+                               LOG_ERROR("failed to espp_service_func_handler()");
 
                        LOG_DEBUG(">>>>>> to fd[%d]: ret[%d]", fd, tx_data.ret);
 
@@ -58,8 +71,7 @@ static void *__work_thread_func(void *data)
                                LOG_ERROR("failed to write(), fd[%d], err: %s", fd, str_error);
                        }
 
-                       /* TODO: exit condition from command */
-                       goto exit;
+                       EXIT_IF_NEEDED(rx_data);
 
                } else {
                        LOG_ERROR("failed to read(), fd[%d], read size mismatched: ret[%d], expect size[%zu]",
@@ -69,7 +81,8 @@ static void *__work_thread_func(void *data)
        } while (1);
 
 exit:
-       LOG_DEBUG("close fd[%d]", fd);
+       LOG_WARNING("exit, fd[%d]", fd);
+       g_free(userdata);
        close(fd);
        pthread_exit(NULL);
 }
@@ -82,7 +95,7 @@ static void *__listen_thread_func(void *data)
        int client_fd = -1;
        pthread_attr_t attr;
        char str_error[MAX_ERROR_LEN] = {'\0',};
-
+       work_thread_userdata_s *userdata;
        pthread_t work_thread_id;
 
        ASSERT(svc);
@@ -120,8 +133,13 @@ static void *__listen_thread_func(void *data)
                }
                LOG_DEBUG("client_fd[%d]", client_fd);
 
-               if (pthread_create(&work_thread_id, &attr, (void *)__work_thread_func, (void *)(uintptr_t)client_fd)) {
+               userdata = g_new0(work_thread_userdata_s, 1);
+               userdata->svc = svc;
+               userdata->fd = client_fd;
+
+               if (pthread_create(&work_thread_id, &attr, (void *)__work_thread_func, (void *)userdata)) {
                        LOG_ERROR("failed to pthread_create(), client_fd[%d]", client_fd);
+                       g_free(userdata);
                        goto exit;
                }
 
index 919c93784042c0738f6a5f51e1fd9fe86cc2ca31..ad5287efbeb9cd1d7e17bcf66401a439d0e7f3f3 100644 (file)
@@ -1,14 +1,16 @@
 espp_service_sources = [
   'espp_service.c',
   'espp_service_socket.c',
+  'espp_service_handler.c',
 ]
 
-thread_dep = dependency('threads')
+thread_dep = dependency('threads', required: true)
+espp_dep = dependency('esplusplayer', required: true)
 
 executable('espp-service',
   espp_service_sources,
   include_directories : [configinc],
-  dependencies : [common_deps, thread_dep],
+  dependencies : [common_deps, thread_dep, espp_dep],
   install: true,
   install_rpath : libdir_path,
   pie : true,