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);
}
raise(signal);
+
+ LOG_ERROR("----------------------------------------------------");
}
static void initialize_signals(void)
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);
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:
--- /dev/null
+/*
+ * 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
#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)
{
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));
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);
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]",
} while (1);
exit:
- LOG_DEBUG("close fd[%d]", fd);
+ LOG_WARNING("exit, fd[%d]", fd);
+ g_free(userdata);
close(fd);
pthread_exit(NULL);
}
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);
}
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;
}