From: Sungwook Park Date: Fri, 27 Nov 2020 11:21:12 +0000 (+0900) Subject: Support TIDL / dbus IPC X-Git-Tag: accepted/tizen/unified/20210629.130203~55 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=97bbeac2ebfccd3e4c14973c861624cbd1aee357;p=platform%2Fcore%2Fuifw%2Ftts.git Support TIDL / dbus IPC Change-Id: I06a8fcd1d2f51a79e33a4a1d06a66d6f25e27319 Signed-off-by: Sungwook Park Signed-off-by: Suyeon Hwang --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 1af0966..fe2f89c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,7 @@ INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/common") INCLUDE(FindPkgConfig) pkg_check_modules(pkgs REQUIRED aul capi-media-audio-io capi-appfw-app-manager capi-system-info dbus-1 dlog ecore - glib-2.0 libgum libtzplatform-config libxml-2.0 vconf bundle buxton2 pkgmgr gmock + glib-2.0 libgum libtzplatform-config libxml-2.0 vconf bundle buxton2 pkgmgr gmock capi-appfw-app-common rpc-port ) pkg_check_modules(pkgs_test REQUIRED diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 0ce79cc..46a03a1 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -2,7 +2,10 @@ SET(SRCS tts.c tts_core.c tts_client.c + tts_ipc.c + tts_tidl.c tts_dbus.c + tts_proxy.c ../common/tts_config_mgr.c ../common/tts_config_parser.c ) diff --git a/client/tts.c b/client/tts.c index d9bd7fc..4515d16 100644 --- a/client/tts.c +++ b/client/tts.c @@ -29,6 +29,7 @@ #include "tts_dbus.h" #include "tts_main.h" #include "tts_core.h" +#include "tts_ipc.h" #include "tts_internal.h" @@ -289,6 +290,33 @@ int tts_create(tts_h* tts) SLOG(LOG_ERROR, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%d)", tts, client, client->uid); + if (false == tts_ipc_is_method_set()) { + int pid = getpid(); + char* appid = NULL; + int ret = app_manager_get_app_id(pid, &appid); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get appid, ret(%d), pid(%d), appid(%s)", ret, pid, appid); + tts_ipc_set_method(TTS_IPC_METHOD_DBUS); + } else { + if(NULL == appid ) { + SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts_create : client appid(null) => This is daemon process"); + tts_ipc_set_method(TTS_IPC_METHOD_DBUS); + } else { + SLOG(LOG_INFO, TAG_TTSC, "[INFO] ]tts_create : client appid(%s)", appid); + tts_ipc_set_method(TTS_IPC_METHOD_TIDL); + } + } + if (NULL != appid) { + free(appid); + appid = NULL; + } + } + + if (0 != tts_ipc_open_connection(client->uid)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to open dbus connection"); + return TTS_ERROR_OPERATION_FAILED; + } + int ret = tts_config_mgr_initialize(client->uid); if (0 != ret) { SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to init config manager : %d", ret); @@ -305,12 +333,6 @@ int tts_create(tts_h* tts) if (is_first_client) { // These function would be called only when first client is created. - if (0 != tts_dbus_open_connection()) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to open dbus connection"); - tts_client_destroy(*tts); - return TTS_ERROR_OPERATION_FAILED; - } - if (0 != tts_core_initialize()) { SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize core"); tts_client_destroy(*tts); @@ -375,7 +397,7 @@ int tts_destroy(tts_h tts) if (!(false == g_screen_reader && TTS_MODE_SCREEN_READER == client->mode)) { do { - ret = tts_dbus_request_finalize(client->uid); + ret = tts_ipc_request_finalize(client->uid); if (0 != ret) { //LCOV_EXCL_START if (TTS_ERROR_TIMED_OUT != ret) { @@ -395,9 +417,24 @@ int tts_destroy(tts_h tts) } while (0 != ret); } else { SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Do not request finalize : g_sr(%d) mode(%d)", g_screen_reader, client->mode); - ret = tts_dbus_remove_match(client->mode); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to remove match : %s", __tts_get_error_code(ret)); + tts_ipc_method_e method; + ret = tts_ipc_get_method(&method); + + if (TTS_ERROR_NONE == ret && TTS_IPC_METHOD_DBUS == method) { + ret = tts_dbus_remove_match(client->mode); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to remove match : %s", __tts_get_error_code(ret)); + } + } + } + + if (client->tts->connected) { + if (1 == tts_client_get_size()) { + SLOG(LOG_ERROR, TAG_TTSC, "[INFO] all clients are destroied"); + if (0 != tts_ipc_close_connection(client->uid)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to close connection"); + return TTS_ERROR_OPERATION_FAILED; + } } } @@ -444,7 +481,7 @@ int tts_destroy(tts_h tts) int num_of_client = tts_client_get_size(); if (0 == num_of_client) { SLOG(LOG_ERROR, TAG_TTSC, "[INFO] all clients are destroied"); - if (0 != tts_dbus_close_connection()) { + if (0 != tts_ipc_close_connection(client->uid)) { SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to close connection"); } @@ -1160,7 +1197,7 @@ int tts_add_text(tts_h tts, const char* text, const char* language, int voice_ty int count = 0; bool is_prepared = false; while (0 != ret) { - ret = tts_dbus_request_add_text(client->uid, text, temp, voice_type, speed, client->current_utt_id, client->credential); + ret = tts_ipc_request_add_text(client->uid, text, temp, voice_type, speed, client->current_utt_id, client->credential); if (0 != ret) { //LCOV_EXCL_START if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { @@ -1213,7 +1250,7 @@ static void __tts_play_async(void *data) int count = 0; bool is_prepared = false; while (0 != ret) { - ret = tts_dbus_request_play(client->uid, client->credential); + ret = tts_ipc_request_play(client->uid, client->credential); if (0 != ret) { if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { client->current_state = TTS_STATE_CREATED; @@ -1359,7 +1396,7 @@ int tts_play(tts_h tts) int count = 0; bool is_prepared = false; while (0 != ret) { - ret = tts_dbus_request_play(client->uid, client->credential); + ret = tts_ipc_request_play(client->uid, client->credential); if (0 != ret) { //LCOV_EXCL_START if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { @@ -1408,7 +1445,7 @@ static void __tts_stop_async(void *data) int count = 0; bool is_prepared = false; while (0 != ret) { - ret = tts_dbus_request_stop(client->uid); + ret = tts_ipc_request_stop(client->uid); if (0 != ret) { if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { client->current_state = TTS_STATE_CREATED; @@ -1542,7 +1579,7 @@ int tts_stop(tts_h tts) int count = 0; bool is_prepared = false; while (0 != ret) { - ret = tts_dbus_request_stop(client->uid); + ret = tts_ipc_request_stop(client->uid); if (0 != ret) { //LCOV_EXCL_START if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { @@ -1591,7 +1628,7 @@ static void __tts_pause_async(void *data) int count = 0; bool is_prepared = false; while (0 != ret) { - ret = tts_dbus_request_pause(client->uid); + ret = tts_ipc_request_pause(client->uid); if (0 != ret) { if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { client->current_state = TTS_STATE_CREATED; @@ -1726,7 +1763,7 @@ int tts_pause(tts_h tts) int count = 0; bool is_prepared = false; while (0 != ret) { - ret = tts_dbus_request_pause(client->uid); + ret = tts_ipc_request_pause(client->uid); if (0 != ret) { //LCOV_EXCL_START if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { @@ -1799,7 +1836,7 @@ int tts_set_private_data(tts_h tts, const char* key, const char* data) int count = 0; bool is_prepared = false; while (0 != ret) { - ret = tts_dbus_request_set_private_data(client->uid, key, data); + ret = tts_ipc_request_set_private_data(client->uid, key, data); if (0 != ret) { //LCOV_EXCL_START if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { @@ -1863,7 +1900,7 @@ int tts_get_private_data(tts_h tts, const char* key, char** data) int count = 0; bool is_prepared = false; while (0 != ret) { - ret = tts_dbus_request_get_private_data(client->uid, key, data); + ret = tts_ipc_request_get_private_data(client->uid, key, data); if (0 != ret) { //LCOV_EXCL_START if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { @@ -2329,7 +2366,7 @@ int tts_add_pcm(tts_h tts, int event, const void* data, unsigned int data_size, int count = 0; bool is_prepared = false; while (0 != ret) { - ret = tts_dbus_request_add_pcm(client->uid, event, data, data_size, audio_type, rate); + ret = tts_ipc_request_add_pcm(client->uid, event, data, data_size, audio_type, rate); if (0 != ret) { if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { client->current_state = TTS_STATE_CREATED; @@ -2403,7 +2440,7 @@ int tts_play_pcm(tts_h tts) int count = 0; bool is_prepared = false; while (0 != ret) { - ret = tts_dbus_request_play_pcm(client->uid); + ret = tts_ipc_request_play_pcm(client->uid); if (0 != ret) { if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { client->current_state = TTS_STATE_CREATED; @@ -2481,7 +2518,7 @@ int tts_stop_pcm(tts_h tts) int count = 0; bool is_prepared = false; while (0 != ret) { - ret = tts_dbus_request_stop_pcm(client->uid); + ret = tts_ipc_request_stop_pcm(client->uid); if (0 != ret) { if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { client->current_state = TTS_STATE_CREATED; diff --git a/client/tts_client.c b/client/tts_client.c index 050d6ed..d83c6b5 100644 --- a/client/tts_client.c +++ b/client/tts_client.c @@ -59,6 +59,7 @@ int tts_client_new(tts_h* tts) return TTS_ERROR_OUT_OF_MEMORY; } temp->handle = __client_generate_uid(getpid()); + temp->connected = false; /* initialize client data */ client->tts = temp; diff --git a/client/tts_client.h b/client/tts_client.h index 5e2fd5e..88a541e 100644 --- a/client/tts_client.h +++ b/client/tts_client.h @@ -76,6 +76,7 @@ typedef struct { /* timer */ Ecore_Timer* notify_error_timer; Ecore_Timer* notify_state_timer; + } tts_client_s; int tts_client_new(tts_h* tts); diff --git a/client/tts_core.c b/client/tts_core.c index 7dcac7f..587d066 100644 --- a/client/tts_core.c +++ b/client/tts_core.c @@ -21,6 +21,7 @@ #include "tts_dbus.h" #include "tts_defs.h" #include "tts_core.h" +#include "tts_ipc.h" /* Static variables */ static volatile bool g_is_thread_canceled = false; @@ -272,7 +273,7 @@ static void __create_pkgmgr_thread(void* data, Ecore_Thread* thread) g_pkgmgr = pkgmgr_client_new(PC_LISTENING); if (NULL == g_pkgmgr) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create pkgmgr handle"); +// SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create pkgmgr handle"); } else { int ret = pkgmgr_client_set_status_type(g_pkgmgr, PKGMGR_CLIENT_STATUS_INSTALL | PKGMGR_CLIENT_STATUS_UNINSTALL | PKGMGR_CLIENT_STATUS_UPGRADE); if (0 == ret) { @@ -431,7 +432,7 @@ static int __send_hello_msg(tts_client_s* client) } /* Send hello */ - int ret = tts_dbus_request_hello(client->uid); + int ret = tts_ipc_request_hello(client->uid); if (0 != ret) { SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request hello !!"); //LCOV_EXCL_LINE } else { @@ -522,7 +523,7 @@ static Eina_Bool __prepare_sync_cb(tts_client_s* client) // TODO: make function duplicated block /* Send hello */ - if (0 != tts_dbus_request_hello_sync(client->uid)) { + if (0 != tts_ipc_request_hello_sync(client->uid)) { return EINA_TRUE; } @@ -533,7 +534,7 @@ static Eina_Bool __prepare_sync_cb(tts_client_s* client) int ret = -1; bool credential_needed = false; - ret = tts_dbus_request_initialize(client->uid, &credential_needed); + ret = tts_ipc_request_initialize(client->uid, &credential_needed); if (TTS_ERROR_ENGINE_NOT_FOUND == ret || TTS_ERROR_PERMISSION_DENIED == ret) { SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", __tts_get_error_code(ret)); @@ -937,16 +938,20 @@ int tts_core_unprepare(tts_client_s* client, bool is_screen_reader_on) int count = 0; if (false == is_screen_reader_on && TTS_MODE_SCREEN_READER == client->mode) { SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Do not request finalize : is_screen_reader(%d) mode(%d)", is_screen_reader_on, client->mode); + tts_ipc_method_e method; + ret = tts_ipc_get_method(&method); - ret = tts_dbus_remove_match(client->mode); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to remove match : %s", __tts_get_error_code(ret)); + if (TTS_ERROR_NONE == ret && TTS_IPC_METHOD_DBUS == method) { + ret = tts_dbus_remove_match(client->mode); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to remove match : %s", __tts_get_error_code(ret)); + } } } else { bool is_prepared = false; do { - ret = tts_dbus_request_finalize(client->uid); + ret = tts_ipc_request_finalize(client->uid); if (0 != ret) { //LCOV_EXCL_START if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { diff --git a/client/tts_ipc.c b/client/tts_ipc.c new file mode 100644 index 0000000..eedc255 --- /dev/null +++ b/client/tts_ipc.c @@ -0,0 +1,340 @@ +/* +* 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 "tts_ipc.h" +#include "tts_dbus.h" +#include "tts_tidl.h" + +int(*ttsc_dbus_vtable[])() = { &tts_dbus_open_connection, &tts_dbus_close_connection, &tts_dbus_request_hello, + &tts_dbus_request_hello_sync, &tts_dbus_request_initialize, &tts_dbus_request_finalize, + &tts_dbus_request_add_text, &tts_dbus_request_play, &tts_dbus_request_stop, + &tts_dbus_request_pause, &tts_dbus_request_set_private_data, &tts_dbus_request_get_private_data, + &tts_dbus_request_play_pcm, &tts_dbus_request_stop_pcm, &tts_dbus_request_add_pcm }; + +int(*ttsc_tidl_vtable[])() = { &tts_tidl_open_connection, &tts_tidl_close_connection, &tts_tidl_request_hello, + &tts_tidl_request_hello_sync, &tts_tidl_request_initialize, &tts_tidl_request_finalize, + &tts_tidl_request_add_text, &tts_tidl_request_play, &tts_tidl_request_stop, + &tts_tidl_request_pause, &tts_tidl_request_set_private_data, &tts_tidl_request_get_private_data, + &tts_tidl_request_play_pcm, &tts_tidl_request_stop_pcm, &tts_tidl_request_add_pcm }; + +static int (**g_vtable)(); +static tts_ipc_method_e g_ipc_method = TTS_IPC_METHOD_UNDEFINED; + +int tts_ipc_set_method(tts_ipc_method_e method) { + if (TTS_IPC_METHOD_UNDEFINED > method || TTS_IPC_METHOD_TIDL < method) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] method is not valid"); + return TTS_ERROR_INVALID_PARAMETER; + } + g_ipc_method = method; + + return TTS_ERROR_NONE; +} + +int tts_ipc_get_method(tts_ipc_method_e* method) { + if (NULL == method) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] method is NULL"); + return TTS_ERROR_INVALID_PARAMETER; + } + + *method = g_ipc_method; + return TTS_ERROR_NONE; +} + +bool tts_ipc_is_method_set() { + SLOG(LOG_INFO, TAG_TTSC, "Set method (TIDL or DBUS) for ipc"); + return (g_ipc_method != TTS_IPC_METHOD_UNDEFINED); +} + +int tts_ipc_open_connection(int uid) +{ + SLOG(LOG_INFO, TAG_TTSC, "[IPC] tts_ipc_open_connection"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_INVALID_STATE; + } + + /* choose ipc */ + switch (g_ipc_method) { + case TTS_IPC_METHOD_DBUS: + g_vtable = ttsc_dbus_vtable; + return g_vtable[OPEN_CONNECTION](); + case TTS_IPC_METHOD_TIDL: + g_vtable = ttsc_tidl_vtable; + return g_vtable[OPEN_CONNECTION](uid); + default: + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] IPC method is not set"); + return TTS_ERROR_OPERATION_FAILED; + } +} + +int tts_ipc_close_connection(int uid) +{ + SLOG(LOG_INFO, TAG_TTSC, "[IPC] tts_ipc_close_connection"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (NULL == g_vtable) { + SLOG(LOG_ERROR, TAG_TTSC, "g_vtable is NULL"); + return TTS_ERROR_OPERATION_FAILED; + } + + switch (g_ipc_method) { + case TTS_IPC_METHOD_DBUS: + return g_vtable[CLOSE_CONNECTION](); + case TTS_IPC_METHOD_TIDL: + return g_vtable[CLOSE_CONNECTION](uid); + default: + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] IPC method is not set"); + return TTS_ERROR_OPERATION_FAILED; + } +} + +int tts_ipc_request_hello(int uid) +{ + SLOG(LOG_INFO, TAG_TTSC, "[IPC] tts_ipc_request_hello"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (NULL == g_vtable) { + SLOG(LOG_ERROR, TAG_TTSC, "g_vtable is NULL"); + return TTS_ERROR_OPERATION_FAILED; + } + + return g_vtable[REQUEST_HELLO](uid); +} + +int tts_ipc_request_hello_sync(int uid) +{ + SLOG(LOG_INFO, TAG_TTSC, "[IPC] tts_ipc_request_hello_sync"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (NULL == g_vtable) { + SLOG(LOG_ERROR, TAG_TTSC, "g_vtable is NULL"); + return TTS_ERROR_OPERATION_FAILED; + } + + return g_vtable[REQUEST_HELLO_SYNC](uid); +} + +int tts_ipc_request_initialize(int uid, bool* credential_needed) +{ + SLOG(LOG_INFO, TAG_TTSC, "[IPC] tts_ipc_request_initialize"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (NULL == g_vtable) { + SLOG(LOG_ERROR, TAG_TTSC, "g_vtable is NULL"); + return TTS_ERROR_OPERATION_FAILED; + } + + return g_vtable[REQUEST_INITIALIZE](uid, credential_needed); +} + +int tts_ipc_request_finalize(int uid) +{ + SLOG(LOG_INFO, TAG_TTSC, "[IPC] tts_ipc_request_finalize"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (NULL == g_vtable) { + SLOG(LOG_ERROR, TAG_TTSC, "g_vtable is NULL"); + return TTS_ERROR_OPERATION_FAILED; + } + + return g_vtable[REQUEST_FINALIZE](uid); +} + +int tts_ipc_request_add_text(int uid, const char* text, const char* lang, int vctype, int speed, int uttid, const char* credential) +{ + SLOG(LOG_INFO, TAG_TTSC, "[IPC] tts_ipc_request_add_text"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (NULL == g_vtable) { + SLOG(LOG_ERROR, TAG_TTSC, "g_vtable is NULL"); + return TTS_ERROR_OPERATION_FAILED; + } + + return g_vtable[REQUEST_ADD_TEXT](uid, text, lang, vctype, speed, uttid, credential); +} + +int tts_ipc_request_set_private_data(int uid, const char* key, const char* data) +{ + SLOG(LOG_INFO, TAG_TTSC, "[IPC] tts_ipc_request_set_private_data"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (NULL == g_vtable) { + SLOG(LOG_ERROR, TAG_TTSC, "g_vtable is NULL"); + return TTS_ERROR_OPERATION_FAILED; + } + + return g_vtable[REQUEST_SET_PRIVATE_DATA](uid, key, data); +} + +int tts_ipc_request_get_private_data(int uid, const char* key, char** data) +{ + SLOG(LOG_INFO, TAG_TTSC, "[IPC] tts_ipc_request_get_private_data"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + if (NULL == g_vtable) { + SLOG(LOG_ERROR, TAG_TTSC, "g_vtable is NULL"); + return TTS_ERROR_OPERATION_FAILED; + } + + return g_vtable[REQUEST_GET_PRIVATE_DATA](uid, key, data); +} + +int tts_ipc_request_play(int uid, const char* credential) +{ + SLOG(LOG_INFO, TAG_TTSC, "[IPC] tts_ipc_request_play"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (NULL == g_vtable) { + SLOG(LOG_ERROR, TAG_TTSC, "g_vtable is NULL"); + return TTS_ERROR_OPERATION_FAILED; + } + + return g_vtable[REQUEST_PLAY](uid, credential); +} + +int tts_ipc_request_stop(int uid) +{ + SLOG(LOG_INFO, TAG_TTSC, "[IPC] tts_ipc_request_stop"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (NULL == g_vtable) { + SLOG(LOG_ERROR, TAG_TTSC, "g_vtable is NULL"); + return TTS_ERROR_OPERATION_FAILED; + } + + return g_vtable[REQUEST_STOP](uid); +} + +int tts_ipc_request_pause(int uid) +{ + SLOG(LOG_INFO, TAG_TTSC, "[IPC] tts_ipc_request_pause"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (NULL == g_vtable) { + SLOG(LOG_ERROR, TAG_TTSC, "g_vtable is NULL"); + return TTS_ERROR_OPERATION_FAILED; + } + + return g_vtable[REQUEST_PAUSE](uid); +} + +//LCOV_EXCL_START +int tts_ipc_request_play_pcm(int uid) +{ + SLOG(LOG_INFO, TAG_TTSC, "[IPC] tts_ipc_request_play_pcm"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (NULL == g_vtable) { + SLOG(LOG_ERROR, TAG_TTSC, "g_vtable is NULL"); + return TTS_ERROR_OPERATION_FAILED; + } + + return g_vtable[REQUEST_PLAY_PCM](uid); +} + +int tts_ipc_request_stop_pcm(int uid) +{ + SLOG(LOG_INFO, TAG_TTSC, "[IPC] tts_ipc_request_stop_pcm"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (NULL == g_vtable) { + SLOG(LOG_ERROR, TAG_TTSC, "g_vtable is NULL"); + return TTS_ERROR_OPERATION_FAILED; + } + + return g_vtable[REQUEST_STOP_PCM](uid); +} + +int tts_ipc_request_add_pcm(int uid, int event, const char* data, int data_size, int audio_type, int rate) +{ + SLOG(LOG_INFO, TAG_TTSC, "[IPC] tts_ipc_request_add_pcm"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (NULL == g_vtable) { + SLOG(LOG_ERROR, TAG_TTSC, "g_vtable is NULL"); + return TTS_ERROR_OPERATION_FAILED; + } + + return g_vtable[REQUEST_ADD_PCM](uid, event, data, data_size, audio_type, rate); +} +// LCOV_EXCL_STOP diff --git a/client/tts_ipc.h b/client/tts_ipc.h new file mode 100644 index 0000000..dad79ff --- /dev/null +++ b/client/tts_ipc.h @@ -0,0 +1,86 @@ +/* * 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. +*/ + +#ifndef __TTS_IPC_H_ +#define __TTS_IPC_H_ + +#include "tts_client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + OPEN_CONNECTION, + CLOSE_CONNECTION, + REQUEST_HELLO, + REQUEST_HELLO_SYNC, + REQUEST_INITIALIZE, + REQUEST_FINALIZE, + REQUEST_ADD_TEXT, + REQUEST_PLAY, + REQUEST_STOP, + REQUEST_PAUSE, + REQUEST_SET_PRIVATE_DATA, + REQUEST_GET_PRIVATE_DATA, + REQUEST_PLAY_PCM, + REQUEST_STOP_PCM, + REQUEST_ADD_PCM +} tts_ipc_vtable_e; + +typedef enum { + TTS_IPC_METHOD_UNDEFINED = -1, + TTS_IPC_METHOD_DBUS, + TTS_IPC_METHOD_TIDL +} tts_ipc_method_e; + +int tts_ipc_set_method(tts_ipc_method_e method); + +int tts_ipc_get_method(tts_ipc_method_e* method); + +bool tts_ipc_is_method_set(); + +int tts_ipc_open_connection(int uid); + +int tts_ipc_close_connection(int uid); + +int tts_ipc_request_hello(int uid); + +int tts_ipc_request_hello_sync(int uid); + +int tts_ipc_request_initialize(int uid, bool* credential_needed); + +int tts_ipc_request_finalize(int uid); + +int tts_ipc_request_add_text(int uid, const char* text, const char* lang, int vctype, int speed, int uttid, const char* credential); + +int tts_ipc_request_play(int uid, const char* credential); + +int tts_ipc_request_stop(int uid); + +int tts_ipc_request_pause(int uid); + +int tts_ipc_request_set_private_data(int uid, const char* key, const char* data); + +int tts_ipc_request_get_private_data(int uid, const char* key, char** data); + +int tts_ipc_request_play_pcm(int uid); + +int tts_ipc_request_stop_pcm(int uid); + +int tts_ipc_request_add_pcm(int uid, int event, const char* data, int data_size, int audio_type, int rate); + +#ifdef __cplusplus +} +#endif + +#endif /* __TTS_IPC_H_ */ diff --git a/client/tts_main.h b/client/tts_main.h index ed1183d..24ec64b 100644 --- a/client/tts_main.h +++ b/client/tts_main.h @@ -25,16 +25,19 @@ #include #include "tts_defs.h" +#include "tts_proxy.h" #ifdef __cplusplus extern "C" { #endif -/** +/** * @brief A structure of handle for identification */ struct tts_s { int handle; + rpc_port_proxy_tts_h rpc_h; + bool connected; }; #ifdef __cplusplus diff --git a/client/tts_tidl.c b/client/tts_tidl.c new file mode 100644 index 0000000..ea7be20 --- /dev/null +++ b/client/tts_tidl.c @@ -0,0 +1,759 @@ +/* * 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 +#include "tts_main.h" +#include "tts_tidl.h" +#include "tts_internal.h" +#include "tts_client.h" +#include "tts_core.h" + +#define MAXSLEEP 128 + +static const char* __tts_get_error_code(tts_error_e err) +{ + switch (err) { + case TTS_ERROR_NONE: return "TTS_ERROR_NONE"; + case TTS_ERROR_OUT_OF_MEMORY: return "TTS_ERROR_OUT_OF_MEMORY"; + case TTS_ERROR_IO_ERROR: return "TTS_ERROR_IO_ERROR"; + case TTS_ERROR_INVALID_PARAMETER: return "TTS_ERROR_INVALID_PARAMETER"; + case TTS_ERROR_OUT_OF_NETWORK: return "TTS_ERROR_OUT_OF_NETWORK"; + case TTS_ERROR_TIMED_OUT: return "TTS_ERROR_TIMED_OUT"; + case TTS_ERROR_PERMISSION_DENIED: return "TTS_ERROR_PERMISSION_DENIED"; + case TTS_ERROR_NOT_SUPPORTED: return "TTS_ERROR_NOT_SUPPORTED"; + case TTS_ERROR_INVALID_STATE: return "TTS_ERROR_INVALID_STATE"; + case TTS_ERROR_INVALID_VOICE: return "TTS_ERROR_INVALID_VOICE"; + case TTS_ERROR_ENGINE_NOT_FOUND: return "TTS_ERROR_ENGINE_NOT_FOUND"; + case TTS_ERROR_OPERATION_FAILED: return "TTS_ERROR_OPERATION_FAILED"; + case TTS_ERROR_AUDIO_POLICY_BLOCKED: return "TTS_ERROR_AUDIO_POLICY_BLOCKED"; + case TTS_ERROR_NOT_SUPPORTED_FEATURE: return "TTS_ERROR_NOT_SUPPORTED_FEATURE"; + case TTS_ERROR_SERVICE_RESET: return "TTS_ERROR_SERVICE_RESET"; + default: + return "Invalid error code"; + } + return NULL; +} + +int __tts_cb_hello(int uid, int ret, int credential_needed) +{ + tts_client_s* client = tts_client_get_by_uid(uid); + if (NULL == client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get TTS client or ignore this uid(%d)", uid); + return TTS_ERROR_OPERATION_FAILED; + } + + if (client->hello_timer) { + ecore_timer_del(client->hello_timer); + client->hello_timer = NULL; + } + + if (TTS_STATE_READY == client->current_state) { + SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts client is already READY"); + return TTS_ERROR_NONE; + } + + if (TTS_ERROR_ENGINE_NOT_FOUND == ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", __tts_get_error_code(ret)); + + client->reason = TTS_ERROR_ENGINE_NOT_FOUND; + client->utt_id = -1; + + tts_core_notify_error_async(client, client->utt_id, client->reason); + + return TTS_ERROR_OPERATION_FAILED; + + } else if (TTS_ERROR_PERMISSION_DENIED == ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", __tts_get_error_code(ret)); + + client->reason = TTS_ERROR_PERMISSION_DENIED; + client->utt_id = -1; + + tts_core_notify_error_async(client, client->utt_id, client->reason); + + return TTS_ERROR_PERMISSION_DENIED; + + } else if (TTS_ERROR_NONE != ret) { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to connection. Retry to connect : %s", __tts_get_error_code(ret)); + return TTS_ERROR_OPERATION_FAILED; + + } else { + /* success to connect tts-daemon */ + if (TTS_CREDENTIAL_NEEDED_ALREADY_INITIALIZED != credential_needed) { + client->credential_needed = credential_needed; + SLOG(LOG_ERROR, TAG_TTSC, "Supported options : credential(%s)", credential_needed ? "need" : "no need"); + } + } + + client->before_state = client->current_state; + client->current_state = TTS_STATE_READY; + + tts_core_notify_state_changed_async(client, client->before_state, client->current_state); + + SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); + return TTS_ERROR_NONE; +} + +static int __tts_cb_error(int uid, tts_error_e reason, int utt_id, char* err_msg) +{ + if (-1 == uid) { + GList* client_list = NULL; + client_list = tts_client_get_client_list(); + + if (NULL == client_list) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get client list"); + return TTS_ERROR_OPERATION_FAILED; + } + + GList *iter = NULL; + tts_client_s *data = NULL; + + if (g_list_length(client_list) > 0) { + /* Get a first item */ + iter = g_list_first(client_list); + + while (NULL != iter) { + data = iter->data; + + if (NULL != data->err_msg) { + free(data->err_msg); + data->err_msg = NULL; + } + if (NULL != err_msg) + data->err_msg = strdup(err_msg); + + /* call callback function */ + tts_core_notify_error_async(data, utt_id, reason); + + if (TTS_ERROR_SERVICE_RESET == reason) { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Service Reset"); + + tts_client_s* client = tts_client_get(data->tts); + if (NULL == client) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid"); + return TTS_ERROR_INVALID_PARAMETER; + } + + tts_core_reprepare(data); + } + + /* Next item */ + iter = g_list_next(iter); + } + } + + g_list_free(client_list); + } else { + tts_client_s* client = tts_client_get_by_uid(uid); + + if (NULL == client) { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid"); + return TTS_ERROR_INVALID_PARAMETER; + } + + if (NULL != client->err_msg) { + free(client->err_msg); + client->err_msg = NULL; + } + if (NULL != err_msg) + client->err_msg = strdup(err_msg); + + tts_core_notify_error_async(client, utt_id, reason); + + if (TTS_ERROR_SERVICE_RESET == reason) { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Service Reset"); + + tts_core_reprepare(client); + } + } + + return 0; +} + +static int __tts_cb_set_state(int uid, int state) +{ + tts_client_s* client = tts_client_get_by_uid(uid); + if (NULL == client) { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] The handle is not valid"); + return -1; + } + + tts_state_e state_from_daemon = (tts_state_e)state; + + if (client->current_state == state_from_daemon) { + SLOG(LOG_DEBUG, TAG_TTSC, "Current state has already been %d", client->current_state); + return 0; + } + + tts_core_notify_state_changed_async(client, client->current_state, state_from_daemon); + return 0; +} + +static int __tts_cb_utt_started(int uid, int utt_id) +{ + tts_client_s* client = tts_client_get_by_uid(uid); + if (NULL == client) { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid"); + return TTS_ERROR_INVALID_PARAMETER; + } + + client->utt_id = utt_id; + tts_core_notify_utt_started(client, client->utt_id); + + return 0; +} + +static int __tts_cb_utt_completed(int uid, int utt_id) +{ + tts_client_s* client = tts_client_get_by_uid(uid); + if (NULL == client) { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid"); + return TTS_ERROR_INVALID_PARAMETER; + } + + SLOG(LOG_INFO, TAG_TTSC, "utterance completed : uttid(%d) ", utt_id); + + client->utt_id = utt_id; + tts_core_notify_utt_completeted(client, client->utt_id); + + return 0; +} + +static void __reconnect(void *data) +{ + int uid = (int)data; + + tts_client_s *client = tts_client_get_by_uid(uid); + if (!client) + return; + + for (int nsec = 1; nsec <= MAXSLEEP; nsec <<= 1) { + if (0 == tts_tidl_open_connection(client->uid)) { + SLOG(LOG_DEBUG, TAG_TTSC, "Try to connect the service"); + return; + } + + if (nsec <= MAXSLEEP/2) + sleep(nsec); + + SLOG(LOG_DEBUG, TAG_TTSC, "Retrying..."); + } + return; +} + +static void __notify_cb(void *user_data, int pid, int uid, bundle *msg) +{ + char *method = NULL; + char *val = NULL; + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) + return; + + SLOG(LOG_DEBUG, TAG_TTSC, "__notify_cb is invoked pid(%d) uid(%d)", pid, uid); + + bundle_get_str(msg, TTS_BUNDLE_METHOD, &method); + + if (0 == strncmp(TTSD_METHOD_HELLO, method, strlen(TTSD_METHOD_HELLO))) { + bundle_get_str(msg, TTS_BUNDLE_CREDENTIAL_NEEDED, &val); + if (val) { + __tts_cb_hello(uid, 0, atoi(val)); + } + } else if (0 == strncmp(TTSD_METHOD_UTTERANCE_STARTED, method, strlen(TTSD_METHOD_UTTERANCE_STARTED))) { + bundle_get_str(msg, TTS_BUNDLE_UTTID, &val); + if (val) { + __tts_cb_utt_started(uid, atoi(val)); + } + } else if (0 == strncmp(TTSD_METHOD_UTTERANCE_COMPLETED, method, strlen(TTSD_METHOD_UTTERANCE_COMPLETED))) { + bundle_get_str(msg, TTS_BUNDLE_UTTID, &val); + if (val) { + __tts_cb_utt_completed(uid, atoi(val)); + } + } else if (0 == strncmp(TTSD_METHOD_SET_STATE, method, strlen(TTSD_METHOD_SET_STATE))) { + bundle_get_str(msg, TTS_BUNDLE_STATE, &val); + if (val) { + __tts_cb_set_state(uid, atoi(val)); + } + } else if (0 == strncmp(TTSD_METHOD_ERROR, method, strlen(TTSD_METHOD_ERROR))) { + char *uttid = NULL; + char *reason = NULL; + char *err_msg = NULL; + + bundle_get_str(msg, TTS_BUNDLE_REASON, &reason); + bundle_get_str(msg, TTS_BUNDLE_UTTID, &uttid); + bundle_get_str(msg, TTS_BUNDLE_ERR_MSG, &err_msg); + if (reason && uttid) { + __tts_cb_error(uid, atoi(reason), atoi(uttid), err_msg); + } + } + //TODO add NameOwnerChanged + else { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid msg"); + } +} + +static void __on_connected(rpc_port_proxy_tts_h h, void *user_data) +{ + int uid = (int)user_data; + + tts_client_s *client = tts_client_get_by_uid(uid); + if (!client) + return; + + client->tts->connected = TRUE; + + if (0 != rpc_port_proxy_tts_invoke_set_mode(client->tts->rpc_h, client->mode)) { + SLOG(LOG_ERROR, TAG_TTSC, "Failed to set mode"); + return; + } + + SLOG(LOG_DEBUG, TAG_TTSC, "Connected to server"); +} + +static void __on_disconnected(rpc_port_proxy_tts_h h, void *user_data) +{ + int uid = (int)user_data; + + tts_client_s *client = tts_client_get_by_uid(uid); + if (!client) + return; + + client->tts->connected = FALSE; + __tts_cb_error(-1, TTS_ERROR_SERVICE_RESET, -1, "Daemon Reset"); + SLOG(LOG_DEBUG, TAG_TTSC, "Disconnected from server"); + + ecore_main_loop_thread_safe_call_async(__reconnect, (void*)uid); + SLOG(LOG_DEBUG, TAG_TTSC, "Try to reconnect to server"); +} + +static void __on_rejected(rpc_port_proxy_tts_h h, void *user_data) +{ + int uid = (int)user_data; + + tts_client_s *client = tts_client_get_by_uid(uid); + if (!client) + return; + + __tts_cb_error(client->uid, TTS_ERROR_PERMISSION_DENIED, client->utt_id, "Rejected"); + SLOG(LOG_DEBUG, TAG_TTSC, "Rejected from server"); +} + +int tts_tidl_open_connection(int uid) +{ + SLOG(LOG_DEBUG, TAG_TTSC, "[TIDL] tts_tidl_open_connection"); + + char engine_mode[256] = {0, }; + char* engine_name = NULL; + + rpc_port_proxy_tts_callback_s rpc_callback = { + .connected = __on_connected, + .disconnected = __on_disconnected, + .rejected = __on_rejected + }; + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + engine_name = vconf_get_str(TTS_ENGINE_DB_DEFAULT); + if (NULL == engine_name) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get engine name"); + engine_name = strdup(TTS_SERVER_ENGINE_DEFAULT); + } + + if (TTS_ERROR_SERVICE_RESET != client->reason) { + if (TTS_MODE_DEFAULT == client->mode) { + strcat(engine_mode, engine_name); + } else if (TTS_MODE_NOTIFICATION == client->mode) { + strcat(engine_mode, engine_name); + strcat(engine_mode, TTS_NOTI_SERVER_MODE); + } else if (TTS_MODE_SCREEN_READER == client->mode) { + strcat(engine_mode, engine_name); + strcat(engine_mode, TTS_SR_SERVER_MODE); + } else if (TTS_MODE_INTERRUPT == client->mode) { + strcat(engine_mode, engine_name); + strcat(engine_mode, TTS_INTERRUPT_SERVER_MODE); + } + client->reason = 0; // default value + } + + + if (0 != rpc_port_proxy_tts_create(engine_mode, &rpc_callback, (void*)uid, &client->tts->rpc_h)) { + free(engine_name); + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create proxy"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (0 != rpc_port_proxy_tts_connect(client->tts->rpc_h)) { + rpc_port_proxy_tts_destroy(client->tts->rpc_h); + client->tts->rpc_h = NULL; + free(engine_name); + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connect the service"); + return TTS_ERROR_OPERATION_FAILED; + } + SLOG(LOG_ERROR, TAG_TTSC, "[INFO] tts_h(%p) rpc_h(%p) engine(%s)", client->tts, client->tts->rpc_h, engine_mode); + SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); + free(engine_name); + + return TTS_ERROR_NONE; +} + +int tts_tidl_close_connection(int uid) +{ + SLOG(LOG_DEBUG, TAG_TTSC, "[TIDL] tts_tidl_close_connection"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (0 != rpc_port_proxy_tts_destroy(client->tts->rpc_h)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to disconnect"); + return TTS_ERROR_OPERATION_FAILED; + } + client->tts->rpc_h = NULL; + return TTS_ERROR_NONE; +} + +int tts_tidl_request_hello(int uid) +{ + SLOG(LOG_DEBUG, TAG_TTSC, "[TIDL] tts_tidl_request_hello"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + rpc_port_tts_notify_cb_h cb; + + if (!client->tts->connected) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not Connected"); + return TTS_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_TTSC, ">>>>> TTS Hello"); + /* register callback - needed to create new client before adding callback */ + cb = rpc_port_tts_notify_cb_create(__notify_cb, false, NULL); + if (0 != rpc_port_proxy_tts_invoke_register_cb(client->tts->rpc_h, client->pid, client->uid, cb)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Failed to invoke register"); + return TTS_ERROR_OPERATION_FAILED; + } + SLOG(LOG_DEBUG, TAG_TTSC, "TTS Register callback"); + + if (0 != rpc_port_proxy_tts_invoke_request_hello(client->tts->rpc_h, client->pid, client->uid)) { + SLOG(LOG_ERROR, TAG_TTSC, ">>> Request tts hello : Fail to invoke message"); + return TTS_ERROR_OPERATION_FAILED; + } + SLOG(LOG_DEBUG, TAG_TTSC, "<<<<"); + + return TTS_ERROR_NONE; +} + +int tts_tidl_request_hello_sync(int uid) +{ + //TODO implement when adding sync api + return TTS_ERROR_NONE; +} + +int tts_tidl_request_initialize(int uid, bool* credential_needed) +{ + SLOG(LOG_DEBUG, TAG_TTSC, "[TIDL] tts_tidl_request_initialize"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + bool temp; + + if (!client->tts->connected) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not Connected"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (0 != rpc_port_proxy_tts_invoke_initialize(client->tts->rpc_h, client->uid, client->pid, &temp)) { + SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts initialize : Fail to invoke message"); + return TTS_ERROR_OPERATION_FAILED; + } + + *credential_needed = temp; + + SLOG(LOG_DEBUG, TAG_TTSC, "<<<< tts initialize : credential_needed(%d)", *credential_needed); + + return TTS_ERROR_NONE; +} + +int tts_tidl_request_finalize(int uid) +{ + SLOG(LOG_DEBUG, TAG_TTSC, "[TIDL] tts_tidl_request_finalize"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (!client->tts->connected) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not Connected"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (0 != rpc_port_proxy_tts_invoke_finalize(client->tts->rpc_h, client->uid)) { + SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts initialize : Fail to invoke message"); + return TTS_ERROR_OPERATION_FAILED; + } + + return TTS_ERROR_NONE; +} + +int tts_tidl_request_add_text(int uid, const char* text, const char* lang, int vctype, int speed, int uttid, const char* credential) +{ + SLOG(LOG_DEBUG, TAG_TTSC, "[TIDL] tts_tidl_request_add_text"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (NULL == text || NULL == lang) { + SLOG(LOG_ERROR, TAG_TTSC, "Input parameter is NULL"); + return TTS_ERROR_INVALID_PARAMETER; + } + + if (!client->tts->connected) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not Connected"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (0 != rpc_port_proxy_tts_invoke_add_text(client->tts->rpc_h, client->uid, text, lang, vctype, speed, uttid, credential)) { + SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request add text : Fail to invoke message"); + return TTS_ERROR_OPERATION_FAILED; + } + + return TTS_ERROR_NONE; +} + +int tts_tidl_request_set_private_data(int uid, const char* key, const char* data) +{ + SLOG(LOG_DEBUG, TAG_TTSC, "[TIDL] tts_tidl_request_set_private_data"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (NULL == key || NULL == data) { + SLOG(LOG_ERROR, TAG_TTSC, "Input parameter is NULL"); + return TTS_ERROR_INVALID_PARAMETER; + } + + if (!client->tts->connected) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not Connected"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (0 != rpc_port_proxy_tts_invoke_set_private(client->tts->rpc_h, client->uid, key, data)) { + SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request set private data : Fail to invoke message"); + return TTS_ERROR_OPERATION_FAILED; + } + + return TTS_ERROR_NONE; +} + +int tts_tidl_request_get_private_data(int uid, const char* key, char** data) +{ + SLOG(LOG_DEBUG, TAG_TTSC, "[TIDL] tts_tidl_request_get_private_data"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + char *tmp = NULL; + + if (NULL == key || NULL == data) { + SLOG(LOG_ERROR, TAG_TTSC, "Input parameter is NULL"); + return TTS_ERROR_INVALID_PARAMETER; + } + + if (!client->tts->connected) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not Connected"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (0 != rpc_port_proxy_tts_invoke_get_private(client->tts->rpc_h, client->uid, key, &tmp)) { + SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request get private data : Fail to invoke message"); + return TTS_ERROR_OPERATION_FAILED; + } + SLOG(LOG_DEBUG, TAG_TTSC, "<<<<"); + + *data = tmp; + + return TTS_ERROR_NONE; +} + +int tts_tidl_request_play(int uid, const char* credential) +{ + SLOG(LOG_DEBUG, TAG_TTSC, "[TIDL] tts_tidl_request_play"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (!client->tts->connected) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not Connected"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (0 != rpc_port_proxy_tts_invoke_play(client->tts->rpc_h, client->uid, credential)) { + SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request play : Fail to invoke message"); + return TTS_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_TTSC, "<<<<"); + + return TTS_ERROR_NONE; +} + +int tts_tidl_request_stop(int uid) +{ + SLOG(LOG_DEBUG, TAG_TTSC, "[TIDL] tts_tidl_request_stop"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (!client->tts->connected) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not Connected"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (0 != rpc_port_proxy_tts_invoke_stop(client->tts->rpc_h, client->uid)) { + SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request stop : Fail to invoke message"); + return TTS_ERROR_OPERATION_FAILED; + } + SLOG(LOG_DEBUG, TAG_TTSC, "<<<<"); + + return TTS_ERROR_NONE; +} + +int tts_tidl_request_pause(int uid) +{ + SLOG(LOG_DEBUG, TAG_TTSC, "[TIDL] tts_tidl_request_pause"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (!client->tts->connected) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not Connected"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (0 != rpc_port_proxy_tts_invoke_pause(client->tts->rpc_h, client->uid)) { + SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request pause : Fail to invoke message"); + return TTS_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_TTSC, "<<<<"); + + return TTS_ERROR_NONE; +} + +//LCOV_EXCL_START +int tts_tidl_request_play_pcm(int uid) +{ + SLOG(LOG_DEBUG, TAG_TTSC, "[TIDL] tts_tidl_request_play_pcm"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (!client->tts->connected) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not Connected"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (0 != rpc_port_proxy_tts_invoke_play_pcm(client->tts->rpc_h, client->uid)) { + SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request play pcm : Fail to invoke message"); + return TTS_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_TTSC, "<<<<"); + + return TTS_ERROR_NONE; +} + +int tts_tidl_request_stop_pcm(int uid) +{ + SLOG(LOG_DEBUG, TAG_TTSC, "[TIDL] tts_tidl_request_stop_pcm"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (!client->tts->connected) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not Connected"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (0 != rpc_port_proxy_tts_invoke_stop_pcm(client->tts->rpc_h, client->uid)) { + SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request pause pcm : Fail to invoke message"); + return TTS_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_TTSC, "<<<<"); + + return TTS_ERROR_NONE; +} + +int tts_tidl_request_add_pcm(int uid, int event, const char* data, int data_size, int audio_type, int rate) +{ + SLOG(LOG_DEBUG, TAG_TTSC, "[TIDL] tts_tidl_request_add_pcm"); + + tts_client_s* client = tts_client_get_by_uid(uid); + if (!client) { + SLOG(LOG_ERROR, TAG_TTSC, "Fail to get tts_client with uid"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (!client->tts->connected) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not Connected"); + return TTS_ERROR_OPERATION_FAILED; + } + + if (0 != rpc_port_proxy_tts_invoke_add_pcm(client->tts->rpc_h, client->uid, event, data, data_size, audio_type, rate)) { + SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request pause pcm : Fail to invoke message"); + return TTS_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_TTSC, "<<<<"); + + return TTS_ERROR_NONE; +} +// LCOV_EXCL_STOP diff --git a/client/tts_tidl.h b/client/tts_tidl.h new file mode 100644 index 0000000..076406b --- /dev/null +++ b/client/tts_tidl.h @@ -0,0 +1,57 @@ + +/* * 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. +*/ + +#ifndef __TTS_TIDL_H_ +#define __TTS_TIDL_H_ + +#include "tts_client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int tts_tidl_open_connection(int uid); + +int tts_tidl_close_connection(int uid); + +int tts_tidl_request_hello(int uid); + +int tts_tidl_request_hello_sync(int uid); + +int tts_tidl_request_initialize(int uid, bool* credential_needed); + +int tts_tidl_request_finalize(int uid); + +int tts_tidl_request_add_text(int uid, const char* text, const char* lang, int vctype, int speed, int uttid, const char* credential); + +int tts_tidl_request_play(int uid, const char* credential); + +int tts_tidl_request_stop(int uid); + +int tts_tidl_request_pause(int uid); + +int tts_tidl_request_set_private_data(int uid, const char* key, const char* data); + +int tts_tidl_request_get_private_data(int uid, const char* key, char** data); + +int tts_tidl_request_play_pcm(int uid); + +int tts_tidl_request_stop_pcm(int uid); + +int tts_tidl_request_add_pcm(int uid, int event, const char* data, int data_size, int audio_type, int rate); + +#ifdef __cplusplus +} +#endif + +#endif /* __TTS_IPC_H_ */ diff --git a/common/tts_defs.h b/common/tts_defs.h index 0cb6bcc..b2d66b0 100644 --- a/common/tts_defs.h +++ b/common/tts_defs.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved +* Copyright (c) 2011-2016 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 @@ -26,6 +26,7 @@ extern "C" { /****************************************************************************************** * Definition for IPC *******************************************************************************************/ +#define TTS_SERVER_ENGINE_DEFAULT "org.tizen.tts-engine-default" #define TTS_CLIENT_SERVICE_NAME "org.tizen.tts" #define TTS_CLIENT_SERVICE_OBJECT_PATH "/org/tizen/tts" @@ -38,18 +39,27 @@ extern "C" { #define TTS_NOTI_SERVER_SERVICE_NAME "org.tizen.voice.ttsnotiserver" #define TTS_NOTI_SERVER_SERVICE_OBJECT_PATH "/org/tizen/voice/ttsnotiserver" #define TTS_NOTI_SERVER_SERVICE_INTERFACE "org.tizen.voice.ttsnotiserver" +#define TTS_NOTI_SERVER_MODE "-noti" #define TTS_SR_SERVER_SERVICE_NAME "org.tizen.voice.ttssrserver" #define TTS_SR_SERVER_SERVICE_OBJECT_PATH "/org/tizen/voice/ttssrserver" #define TTS_SR_SERVER_SERVICE_INTERFACE "org.tizen.voice.ttssrserver" +#define TTS_SR_SERVER_MODE "-sr" #define TTS_INTERRUPT_SERVER_SERVICE_NAME "org.tizen.voice.ttsinterruptserver" #define TTS_INTERRUPT_SERVER_SERVICE_OBJECT_PATH "/org/tizen/voice/ttsinterruptserver" #define TTS_INTERRUPT_SERVER_SERVICE_INTERFACE "org.tizen.voice.ttsinterruptserver" +#define TTS_INTERRUPT_SERVER_MODE "-interrupt" /****************************************************************************************** * Message Definition for APIs *******************************************************************************************/ +#define TTS_BUNDLE_METHOD "method" +#define TTS_BUNDLE_STATE "state" +#define TTS_BUNDLE_UTTID "uttid" +#define TTS_BUNDLE_REASON "reason" +#define TTS_BUNDLE_ERR_MSG "err_msg" +#define TTS_BUNDLE_CREDENTIAL_NEEDED "credential_needed" #define TTS_METHOD_HELLO "tts_method_hello" #define TTS_METHOD_HELLO_SYNC "tts_method_hello_sync" diff --git a/packaging/tts.spec b/packaging/tts.spec index 66c1efa..b55b56d 100644 --- a/packaging/tts.spec +++ b/packaging/tts.spec @@ -13,6 +13,7 @@ Requires(postun): /sbin/ldconfig Requires: gawk BuildRequires: pkgconfig(aul) BuildRequires: pkgconfig(capi-appfw-app-manager) +BuildRequires: pkgconfig(capi-appfw-app-common) BuildRequires: pkgconfig(buxton2) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(capi-media-audio-io) @@ -30,9 +31,10 @@ BuildRequires: pkgconfig(pkgmgr-installer) BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(bundle) BuildRequires: pkgconfig(gmock) - +BuildRequires: pkgconfig(rpc-port) BuildRequires: cmake +BuildRequires: tidl %if 0%{?gcov:1} BuildRequires: lcov @@ -88,6 +90,11 @@ GTest for TTS %setup -q -n %{name}-%{version} cp %{SOURCE1001} %{SOURCE1002} . +tidlc -p -l C -i tidl/tts.tidl -o tts_proxy +tidlc -s -l C -i tidl/tts.tidl -o ttsd_stub + +mv tts_proxy* client +mv ttsd_stub* server %build export CFLAGS="$CFLAGS -DTIZEN_ENGINEER_MODE" diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 5fd3eed..40eefa6 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -1,9 +1,12 @@ -SET(SRCS +SET(SRCS ttsd_config.c ttsd_data.cpp + ttsd_ipc.c ttsd_dbus.c + ttsd_tidl.c ttsd_dbus_server.c ttsd_engine_agent.c + ttsd_stub.c ttse.c ttsd_network.c ttsd_player.c diff --git a/server/ttsd_data.cpp b/server/ttsd_data.cpp index fd21a66..271476f 100644 --- a/server/ttsd_data.cpp +++ b/server/ttsd_data.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved +* Copyright (c) 2011-2016 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 @@ -17,6 +17,7 @@ #include "ttsd_main.h" #include "ttsd_data.h" +#include "ttsd_stub.h" using namespace std; @@ -37,7 +38,9 @@ typedef struct std::list m_wav_data; std::list m_used_voice; -}app_data_s; + rpc_port_tts_notify_cb_h notify_cb_h; + bool ipc_tidl; +} app_data_s; static vector g_app_list; @@ -100,7 +103,7 @@ int __data_show_text_list(int index) if (!g_app_list[index].m_speak_data.empty()) { std::list::iterator iter; for (iter = g_app_list[index].m_speak_data.begin(); (NULL != *iter && iter != g_app_list[index].m_speak_data.end()); ++iter) { - SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] lang(%s), vctype(%d), speed(%d), uttid(%d), text(%s)", + SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] lang(%s), vctype(%d), speed(%d), uttid(%d), text(%s)", i + 1, *iter, (*iter)->lang, (*iter)->vctype, (*iter)->speed, (*iter)->utt_id, (*iter)->text); i++; } @@ -162,6 +165,8 @@ int ttsd_data_new_client(int pid, int uid) app.uid = uid; app.utt_id_stopped = 0; app.state = APP_STATE_READY; + app.notify_cb_h = NULL; + app.ipc_tidl = false; g_app_list.insert(g_app_list.end(), app); @@ -240,6 +245,64 @@ int ttsd_data_get_pid(int uid) return g_app_list[index].pid; } +bool ttsd_data_is_client_use_tidl(int uid) +{ + int index; + + index = ttsd_data_is_client(uid); + + if (index < 0) { + SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid); + return false; + } + + return g_app_list[index].ipc_tidl; +} + +int ttsd_data_set_notify_h(int uid, rpc_port_tts_notify_cb_h handle, void* user_data) +{ + int index = ttsd_data_is_client(uid); + + if (index < 0) { + SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid); + return TTSD_ERROR_INVALID_PARAMETER; + } + + if (rpc_port_tts_notify_cb_clone(handle, &(g_app_list[index].notify_cb_h)) != 0) { + return TTSD_ERROR_OPERATION_FAILED; + } + + g_app_list[index].ipc_tidl = true; + + return TTSD_ERROR_NONE; +} + +rpc_port_tts_notify_cb_h ttsd_data_get_notify_handle(int uid) +{ + int index = ttsd_data_is_client(uid); + SLOG(LOG_DEBUG, tts_tag(), "ttsd_data_is_client : index(%d)", index); + if (index < 0) { + SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid); + return NULL; + } + return g_app_list[index].notify_cb_h; +} + +int ttsd_data_unset_notify_h(int uid) +{ + int index = ttsd_data_is_client(uid); + + if (index < 0) { + SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid); + return TTSD_ERROR_INVALID_PARAMETER; + } + + g_app_list[index].notify_cb_h = NULL; + SLOG(LOG_DEBUG, tts_tag(), "[DATA] uid(%d) callback is unseted", g_app_list[index].uid); + + return TTSD_ERROR_NONE; +} + int ttsd_data_get_speak_data_size(int uid) { int index = 0; @@ -562,7 +625,7 @@ int ttsd_data_clear_speak_data(int uid, speak_data_s** speak_data) index = ttsd_data_is_client(uid); if (index >= 0) { if (NULL != *speak_data) { - SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] utt(%d), text(%s), lang(%s), vctype(%d) speed(%d)", + SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] utt(%d), text(%s), lang(%s), vctype(%d) speed(%d)", (*speak_data)->utt_id, (*speak_data)->text, (*speak_data)->lang, (*speak_data)->vctype, (*speak_data)->speed); if (NULL != (*speak_data)->text) { @@ -589,7 +652,7 @@ int ttsd_data_clear_sound_data(sound_data_s** sound_data) pthread_mutex_lock(&g_sound_data_mutex); if (NULL != *sound_data) { - SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] event(%d) data(%p) size(%d) rate(%d) utt(%d)", + SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] event(%d) data(%p) size(%d) rate(%d) utt(%d)", (*sound_data), (*sound_data)->event, (*sound_data)->data, (*sound_data)->data_size, (*sound_data)->rate, (*sound_data)->utt_id); if (NULL != (*sound_data)->data) { @@ -628,7 +691,7 @@ int ttsd_data_clear_data(int uid) } if (NULL != temp_speak) { - SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] utt(%d), text(%s), lang(%s), vctype(%d) speed(%d)", + SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] utt(%d), text(%s), lang(%s), vctype(%d) speed(%d)", temp_speak->utt_id, temp_speak->text, temp_speak->lang, temp_speak->vctype, temp_speak->speed); if (NULL != temp_speak->text) { @@ -660,7 +723,7 @@ int ttsd_data_clear_data(int uid) } if (NULL != temp_sound) { - SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] uid(%d), event(%d) data(%p) size(%d) rate(%d) utt(%d)", + SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] uid(%d), event(%d) data(%p) size(%d) rate(%d) utt(%d)", temp_sound, uid, temp_sound->event, temp_sound->data, temp_sound->data_size, temp_sound->rate, temp_sound->utt_id); if (NULL != temp_sound->data) { diff --git a/server/ttsd_data.h b/server/ttsd_data.h index 34e153d..025caf7 100644 --- a/server/ttsd_data.h +++ b/server/ttsd_data.h @@ -16,6 +16,7 @@ #define __TTSD_DATA_H_ #include "ttse.h" +#include "ttsd_stub.h" #ifdef __cplusplus extern "C" { @@ -36,22 +37,22 @@ typedef enum { } ttsd_synthesis_control_e; typedef struct { - int utt_id; - char* text; - char* lang; - int vctype; - int speed; + int utt_id; + char* text; + char* lang; + int vctype; + int speed; } speak_data_s; typedef struct { - int utt_id; - void* data; - unsigned int data_size; - - ttse_result_event_e event; - ttse_audio_type_e audio_type; - int rate; - int channels; + int utt_id; + void* data; + unsigned int data_size; + + ttse_result_event_e event; + ttse_audio_type_e audio_type; + int rate; + int channels; } sound_data_s; int ttsd_set_synth_control(ttsd_synthesis_control_e control); @@ -70,6 +71,14 @@ int ttsd_data_get_client_count(); int ttsd_data_get_pid(int uid); +bool ttsd_data_is_client_use_tidl(int uid); + +int ttsd_data_set_notify_h(int uid, rpc_port_tts_notify_cb_h handle, void* user_data); + +int ttsd_data_unset_notify_h(int uid); + +rpc_port_tts_notify_cb_h ttsd_data_get_notify_handle(int uid); + /* speak data */ int ttsd_data_add_speak_data(int uid, speak_data_s* data); diff --git a/server/ttsd_ipc.c b/server/ttsd_ipc.c new file mode 100644 index 0000000..bfbb99e --- /dev/null +++ b/server/ttsd_ipc.c @@ -0,0 +1,167 @@ +/* +* 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 "ttsd_main.h" +#include "ttsd_ipc.h" +#include "ttsd_dbus.h" +#include "ttsd_tidl.h" +#include "ttsd_data.h" + + +int(*ttsd_dbus_vtable[])() = {&ttsd_dbus_open_connection, &ttsd_dbus_close_connection, + &ttsdc_send_utt_start_message, &ttsdc_send_error_message}; +int(*ttsd_tidl_vtable[])() = {&ttsd_tidl_open_connection, &ttsd_tidl_close_connection, + &ttsdc_tidl_send_message, &ttsdc_tidl_send_error_message}; + +int ttsd_ipc_open_connection() +{ + SLOG(LOG_INFO, tts_tag(), "[IPC] ttsd_ipc_open_connection"); + + g_tidl_vtable = ttsd_tidl_vtable; + g_dbus_vtable = ttsd_dbus_vtable; + + int ret1, ret2; + ret1 = g_tidl_vtable[OPEN_CONNECTION](); + ret2 = g_dbus_vtable[OPEN_CONNECTION](); + + if (ret1 != TTSE_ERROR_NONE || ret2 != TTSE_ERROR_NONE) { + return TTSD_ERROR_OPERATION_FAILED; + } + + return TTSD_ERROR_NONE; +} + +int ttsd_ipc_close_connection() +{ + SLOG(LOG_INFO, tts_tag(), "[IPC] ttsd_ipc_close_connection"); + + int ret1 = TTSD_ERROR_OPERATION_FAILED; + int ret2 = TTSD_ERROR_OPERATION_FAILED; + + if (NULL != g_tidl_vtable) { + ret1 = g_tidl_vtable[CLOSE_CONNECTION](); + } + + if (NULL != g_dbus_vtable) { + ret2 = g_dbus_vtable[CLOSE_CONNECTION](); + } + + if (ret1 != TTSE_ERROR_NONE || ret2 != TTSE_ERROR_NONE) { + return TTSD_ERROR_OPERATION_FAILED; + } + + return TTSD_ERROR_NONE; +} + +int ttsdc_ipc_send_utt_start_message(int pid, int uid, int uttid) +{ + SLOG(LOG_INFO, tts_tag(), "[IPC] ttsdc_ipc_send_utt_start_message"); + + int index = ttsd_data_is_client(uid); + + if (index < 0) { + SLOG(LOG_ERROR, tts_tag(), "[ERROR] uid is not valid (%d)", uid); + return TTSD_ERROR_INVALID_PARAMETER; + } + + if (ttsd_data_is_client_use_tidl(uid)) { + if (NULL == g_tidl_vtable) { + SLOG(LOG_ERROR, tts_tag(), "vtable is NULL"); + return TTSD_ERROR_OPERATION_FAILED; + } + return g_tidl_vtable[SEND_MESSAGE](pid, uid, uttid, TTSD_METHOD_UTTERANCE_STARTED); + } else { + if (NULL == g_dbus_vtable) { + SLOG(LOG_ERROR, tts_tag(), "vtable is NULL"); + return TTSD_ERROR_OPERATION_FAILED; + } + return g_dbus_vtable[SEND_MESSAGE](pid, uid, uttid, TTSD_METHOD_UTTERANCE_STARTED); + } +} + +int ttsdc_ipc_send_utt_finish_message(int pid, int uid, int uttid) +{ + SLOG(LOG_INFO, tts_tag(), "[IPC] ttsdc_ipc_send_utt_finish_message"); + + int index = ttsd_data_is_client(uid); + + if (index < 0) { + SLOG(LOG_ERROR, tts_tag(), "[ERROR] uid is not valid (%d)", uid); + return TTSD_ERROR_INVALID_PARAMETER; + } + + if (ttsd_data_is_client_use_tidl(uid)) { + if (NULL == g_tidl_vtable) { + SLOG(LOG_ERROR, tts_tag(), "vtable is NULL"); + return TTSD_ERROR_OPERATION_FAILED; + } + return g_tidl_vtable[SEND_MESSAGE](pid, uid, uttid, TTSD_METHOD_UTTERANCE_COMPLETED); + } else { + if (NULL == g_dbus_vtable) { + SLOG(LOG_ERROR, tts_tag(), "vtable is NULL"); + return TTSD_ERROR_OPERATION_FAILED; + } + return g_dbus_vtable[SEND_MESSAGE](pid, uid, uttid, TTSD_METHOD_UTTERANCE_COMPLETED); + } +} + +int ttsdc_ipc_send_set_state_message(int pid, int uid, int state) +{ + SLOG(LOG_INFO, tts_tag(), "[IPC] ttsdc_ipc_send_set_state_message"); + + int index = ttsd_data_is_client(uid); + + if (index < 0) { + SLOG(LOG_ERROR, tts_tag(), "[ERROR] uid is not valid (%d)", uid); + return TTSD_ERROR_INVALID_PARAMETER; + } + + if (ttsd_data_is_client_use_tidl(uid)) { + if (NULL == g_tidl_vtable) { + SLOG(LOG_ERROR, tts_tag(), "vtable is NULL"); + return TTSD_ERROR_OPERATION_FAILED; + } + return g_tidl_vtable[SEND_MESSAGE](pid, uid, state, TTSD_METHOD_SET_STATE); + } else { + if (NULL == g_dbus_vtable) { + SLOG(LOG_ERROR, tts_tag(), "vtable is NULL"); + return TTSD_ERROR_OPERATION_FAILED; + } + return g_dbus_vtable[SEND_MESSAGE](pid, uid, state, TTSD_METHOD_SET_STATE); + } +} + +int ttsdc_ipc_send_error_message(int pid, int uid, int uttid, int reason, char* err_msg) +{ + SLOG(LOG_INFO, tts_tag(), "[IPC] ttsdc_ipc_send_error_message"); + + int index = ttsd_data_is_client(uid); + + if (index < 0) { + SLOG(LOG_ERROR, tts_tag(), "[ERROR] uid is not valid (%d)", uid); + return TTSD_ERROR_INVALID_PARAMETER; + } + + if (ttsd_data_is_client_use_tidl(uid)) { + if (NULL == g_tidl_vtable) { + SLOG(LOG_ERROR, tts_tag(), "vtable is NULL"); + return TTSD_ERROR_OPERATION_FAILED; + } + return g_tidl_vtable[SEND_ERROR](pid, uid, uttid, reason, err_msg); + } else { + if (NULL == g_dbus_vtable) { + SLOG(LOG_ERROR, tts_tag(), "vtable is NULL"); + return TTSD_ERROR_OPERATION_FAILED; + } + return g_dbus_vtable[SEND_ERROR](pid, uid, uttid, reason, err_msg); + } +} diff --git a/server/ttsd_ipc.h b/server/ttsd_ipc.h new file mode 100644 index 0000000..ba8c3eb --- /dev/null +++ b/server/ttsd_ipc.h @@ -0,0 +1,52 @@ +/* +* 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. +*/ + + +#ifndef __TTSD_IPC_h__ +#define __TTSD_IPC_h__ + +#include "ttsd_main.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + OPEN_CONNECTION, + CLOSE_CONNECTION, + SEND_MESSAGE, + SEND_ERROR +} ttsd_ipc_vtable_e; + +int (**g_tidl_vtable)(); +int (**g_dbus_vtable)(); + +int ttsd_ipc_open_connection(); + +int ttsd_ipc_close_connection(); + +int ttsdc_ipc_send_hello(int pid, int uid, int ret, int credential_needed); + +int ttsdc_ipc_send_utt_start_message(int pid, int uid, int uttid); + +int ttsdc_ipc_send_utt_finish_message(int pid, int uid, int uttid); + +int ttsdc_ipc_send_error_message(int pid, int uid, int uttid, int reason, char* err_msg); + +int ttsdc_ipc_send_set_state_message(int pid, int uid, int state); + +#ifdef __cplusplus +} +#endif + +#endif /* __TTSD_IPC_h__ */ diff --git a/server/ttsd_player.c b/server/ttsd_player.c index 539bb56..e065150 100644 --- a/server/ttsd_player.c +++ b/server/ttsd_player.c @@ -21,6 +21,7 @@ #include "ttsd_player.h" #include "ttsd_data.h" #include "ttsd_dbus.h" +#include "ttsd_ipc.h" #include "tts_internal.h" #include "ttsd_server.h" @@ -181,7 +182,7 @@ void __player_focus_state_cb(sound_stream_info_h stream_info, sound_stream_focus } else { /* send message to client about changing state */ SLOG(LOG_INFO, tts_tag(), "[Player INFO] Player paused. pid(%d), uid(%d)", pid, uid); - ttsdc_send_set_state_message(pid, uid, APP_STATE_PAUSED); + ttsdc_ipc_send_set_state_message(pid, uid, APP_STATE_PAUSED); } } } else { @@ -719,7 +720,7 @@ static void __play_thread(void *data, Ecore_Thread *thread) return; } - if (0 != ttsdc_send_utt_start_message(pid, player->uid, sound_data->utt_id)) { + if (0 != ttsdc_ipc_send_utt_start_message(pid, player->uid, sound_data->utt_id)) { SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Start Signal : pid(%d), uid(%d), uttid(%d)", pid, player->uid, sound_data->utt_id); } @@ -747,7 +748,7 @@ static void __play_thread(void *data, Ecore_Thread *thread) __unset_policy_for_playing(); - if (0 != ttsdc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) { + if (0 != ttsdc_ipc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) { SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, player->uid, sound_data->utt_id); } else { @@ -910,7 +911,7 @@ static void __play_thread(void *data, Ecore_Thread *thread) return; } - if (0 != ttsdc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) { + if (0 != ttsdc_ipc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) { SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, player->uid, sound_data->utt_id); /* unset volume policy, volume will be 100% */ diff --git a/server/ttsd_server.c b/server/ttsd_server.c index 4e8e09a..e39343c 100644 --- a/server/ttsd_server.c +++ b/server/ttsd_server.c @@ -19,6 +19,7 @@ #include "ttsd_data.h" #include "ttsd_dbus.h" #include "ttsd_dbus_server.h" +#include "ttsd_ipc.h" #include "ttsd_engine_agent.h" #include "ttsd_main.h" #include "ttsd_network.h" @@ -99,7 +100,7 @@ static int __synthesis(int uid, const char* credential) SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Current data is NOT valid"); ttsd_server_stop(uid); - ttsdc_send_set_state_message(pid, uid, APP_STATE_READY); + ttsdc_ipc_send_set_state_message(pid, uid, APP_STATE_READY); ttsd_data_clear_speak_data(uid, &speak_data); @@ -130,7 +131,7 @@ static int __synthesis(int uid, const char* credential) if (pid <= 0) { SLOG(LOG_WARN, tts_tag(), "[Server WARNING] Fail to send set_state_message. uid(%d)", uid); } else { - ttsdc_send_set_state_message(pid, uid, APP_STATE_READY); + ttsdc_ipc_send_set_state_message(pid, uid, APP_STATE_READY); } } else { g_wait_timer = ecore_timer_add(0.05, __wait_synthesis, (void*)credential); @@ -166,16 +167,16 @@ int ttsd_send_error(ttse_error_e error, const char* msg) SLOG(LOG_WARN, tts_tag(), "[Server] Fail to ttsd_data_clear_data()"); if (tmp_pid > 0) { - if (0 != ttsdc_send_error_message(tmp_pid, uid, uttid, error, (char*)msg)) - SLOG(LOG_WARN, tts_tag(), "[Server] Fail to ttsdc_send_error_message()"); + if (0 != ttsdc_ipc_send_error_message(tmp_pid, uid, uttid, error, (char*)msg)) + SLOG(LOG_WARN, tts_tag(), "[Server] Fail to ttsdc_ipc_send_error_message()"); } if (0 != ttsd_data_set_client_state(uid, APP_STATE_READY)) SLOG(LOG_WARN, tts_tag(), "[Server] Fail to ttsd_data_set_client_state()"); if (tmp_pid > 0) { - if (0 != ttsdc_send_set_state_message(tmp_pid, uid, APP_STATE_READY)) - SLOG(LOG_WARN, tts_tag(), "[Server] Fail to ttsdc_send_set_state_message()"); + if (0 != ttsdc_ipc_send_set_state_message(tmp_pid, uid, APP_STATE_READY)) + SLOG(LOG_WARN, tts_tag(), "[Server] Fail to ttsdc_ipc_send_set_state_message()"); } return 0; } @@ -191,11 +192,11 @@ int ttsd_send_result(ttse_result_event_e event, const void* data, unsigned int d if (TTSE_RESULT_EVENT_START == event || TTSE_RESULT_EVENT_CONTINUE == event || TTSE_RESULT_EVENT_FINISH == event) { if (TTSE_RESULT_EVENT_START == event) { SLOG(LOG_INFO, tts_tag(), "[SERVER] Event : TTSE_RESULT_EVENT_START"); - SECURE_SLOG(LOG_DEBUG, tts_tag(), "[SERVER] Result Info : uid(%d), utt(%d), data(%p), data size(%d) audiotype(%d) rate(%d)", + SECURE_SLOG(LOG_DEBUG, tts_tag(), "[SERVER] Result Info : uid(%d), utt(%d), data(%p), data size(%d) audiotype(%d) rate(%d)", uid, uttid, data, data_size, audio_type, rate); } else if (TTSE_RESULT_EVENT_FINISH == event) { SLOG(LOG_INFO, tts_tag(), "[SERVER] Event : TTSE_RESULT_EVENT_FINISH"); - SECURE_SLOG(LOG_DEBUG, tts_tag(), "[SERVER] Result Info : uid(%d), utt(%d), data(%p), data size(%d) audiotype(%d) rate(%d)", + SECURE_SLOG(LOG_DEBUG, tts_tag(), "[SERVER] Result Info : uid(%d), utt(%d), data(%p), data size(%d) audiotype(%d) rate(%d)", uid, uttid, data, data_size, audio_type, rate); } else { /*if (TTSE_RESULT_EVENT_CONTINUE == event) SLOG(LOG_DEBUG, tts_tag(), "[SERVER] Event : TTSE_RESULT_EVENT_CONTINUE");*/ @@ -233,7 +234,7 @@ int ttsd_send_result(ttse_result_event_e event, const void* data, unsigned int d if (NULL != temp_sound_data->data) { memcpy(temp_sound_data->data, data, data_size); temp_sound_data->data_size = data_size; - SLOG(LOG_INFO, tts_tag(), "[DEBUG][memcpy] uid(%d), event(%d) sound_data(%p) data(%p) size(%d)", + SLOG(LOG_INFO, tts_tag(), "[DEBUG][memcpy] uid(%d), event(%d) sound_data(%p) data(%p) size(%d)", uid, event, temp_sound_data, temp_sound_data->data, temp_sound_data->data_size); } else { SLOG(LOG_ERROR, tts_tag(), "Fail to allocate memory"); @@ -282,7 +283,7 @@ int ttsd_send_result(ttse_result_event_e event, const void* data, unsigned int d /* Change ready state */ ttsd_server_stop(uid); - ttsdc_send_set_state_message(tmp_pid, uid, APP_STATE_READY); + ttsdc_ipc_send_set_state_message(tmp_pid, uid, APP_STATE_READY); } } } else { @@ -306,7 +307,7 @@ bool __get_client_cb(int pid, int uid, app_tts_state_e state, void* user_data) ttsd_data_set_client_state(uid, APP_STATE_READY); /* send message */ - if (0 != ttsdc_send_set_state_message(pid, uid, APP_STATE_READY)) { + if (0 != ttsdc_ipc_send_set_state_message(pid, uid, APP_STATE_READY)) { /* remove client */ ttsd_data_delete_client(uid); } @@ -341,7 +342,7 @@ void __config_changed_cb(tts_config_type_e type, const char* str_param, int int_ return; } - /* stop all player */ + /* stop all player */ ttsd_player_all_stop(); /* send interrupt message to all clients */ @@ -455,7 +456,7 @@ int ttsd_send_all_stop() { SLOG(LOG_INFO, tts_tag(), "[Server] Send to stop all requests"); - /* stop all player */ + /* stop all player */ ttsd_player_all_stop(); /* send interrupt message to all clients */ @@ -572,7 +573,7 @@ int ttsd_terminate() ttsd_terminate_daemon(NULL); - ttsd_dbus_close_connection(); + ttsd_ipc_close_connection(); ttsd_network_finalize(); ttsd_finalize(); @@ -598,7 +599,7 @@ int ttsd_server_initialize(int pid, int uid, bool* credential_needed) { SLOG(LOG_INFO, tts_tag(), "[Server] Server initialize"); - if (-1 != ttsd_data_is_client(uid)) { + if (-1 != ttsd_data_is_client(uid) && false == ttsd_data_is_client_use_tidl(uid)) { SLOG(LOG_WARN, tts_tag(), "[Server WARNING] Uid has already been registered"); return TTSD_ERROR_NONE; } @@ -629,9 +630,11 @@ int ttsd_server_initialize(int pid, int uid, bool* credential_needed) } } - if (0 != ttsd_data_new_client(pid, uid)) { - SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to add client info"); - return TTSD_ERROR_OPERATION_FAILED; + if (false == ttsd_data_is_client_use_tidl(uid)) { + if (0 != ttsd_data_new_client(pid, uid)) { + SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to add client info"); + return TTSD_ERROR_OPERATION_FAILED; + } } if (0 != ttsd_player_create_instance(uid)) { @@ -644,7 +647,7 @@ int ttsd_server_initialize(int pid, int uid, bool* credential_needed) static Eina_Bool __quit_ecore_loop(void *data) { - ttsd_dbus_close_connection(); + ttsd_ipc_close_connection(); ttsd_network_finalize(); ttsd_finalize(); ecore_main_loop_quit(); @@ -909,9 +912,9 @@ Eina_Bool __send_interrupt_client(void *data) if (TTSD_MODE_DEFAULT != ttsd_get_mode()) { /* send message to client about changing state */ - ttsdc_send_set_state_message(pid, uid, APP_STATE_READY); + ttsdc_ipc_send_set_state_message(pid, uid, APP_STATE_READY); } else { - ttsdc_send_set_state_message(pid, uid, APP_STATE_PAUSED); + ttsdc_ipc_send_set_state_message(pid, uid, APP_STATE_PAUSED); } return EINA_FALSE; @@ -1266,7 +1269,7 @@ int ttsd_server_play_pcm(int uid) if (tmp_pid <= 0) { SLOG(LOG_WARN, tts_tag(), "[Server WARNING] Fail to send set_state_message. uid(%d)", uid); } else { - ttsdc_send_set_state_message(tmp_pid, uid, APP_STATE_READY); + ttsdc_ipc_send_set_state_message(tmp_pid, uid, APP_STATE_READY); } } } @@ -1307,11 +1310,11 @@ int ttsd_server_add_pcm(int uid, int event, void* data, int data_size, int audio if (TTSE_RESULT_EVENT_START == event || TTSE_RESULT_EVENT_CONTINUE == event || TTSE_RESULT_EVENT_FINISH == event) { if (TTSE_RESULT_EVENT_START == event) { SLOG(LOG_INFO, tts_tag(), "[SERVER] Event : TTSE_RESULT_EVENT_START"); - SECURE_SLOG(LOG_DEBUG, tts_tag(), "[SERVER] PCM Info : uid(%d), utt(%d), data(%p), data size(%d) audiotype(%d) rate(%d)", + SECURE_SLOG(LOG_DEBUG, tts_tag(), "[SERVER] PCM Info : uid(%d), utt(%d), data(%p), data size(%d) audiotype(%d) rate(%d)", uid, uttid, data, data_size, audio_type, rate); } else if (TTSE_RESULT_EVENT_FINISH == event) { SLOG(LOG_INFO, tts_tag(), "[SERVER] Event : TTSE_RESULT_EVENT_FINISH"); - SECURE_SLOG(LOG_DEBUG, tts_tag(), "[SERVER] PCM Info : uid(%d), utt(%d), data(%p), data size(%d) audiotype(%d) rate(%d)", + SECURE_SLOG(LOG_DEBUG, tts_tag(), "[SERVER] PCM Info : uid(%d), utt(%d), data(%p), data size(%d) audiotype(%d) rate(%d)", uid, uttid, data, data_size, audio_type, rate); } else { /*if (TTSE_RESULT_EVENT_CONTINUE == event) SLOG(LOG_DEBUG, tts_tag(), "[SERVER] Event : TTSE_RESULT_EVENT_CONTINUE");*/ @@ -1340,7 +1343,7 @@ int ttsd_server_add_pcm(int uid, int event, void* data, int data_size, int audio if (NULL != temp_sound_data->data) { memcpy(temp_sound_data->data, data, data_size); temp_sound_data->data_size = data_size; - SLOG(LOG_INFO, tts_tag(), "[DEBUG][memcpy] uid(%d), event(%d) sound_data(%p) data(%p) size(%d)", + SLOG(LOG_INFO, tts_tag(), "[DEBUG][memcpy] uid(%d), event(%d) sound_data(%p) data(%p) size(%d)", uid, event, temp_sound_data, temp_sound_data->data, temp_sound_data->data_size); } else { SLOG(LOG_ERROR, tts_tag(), "Fail to allocate memory"); @@ -1374,7 +1377,7 @@ int ttsd_server_add_pcm(int uid, int event, void* data, int data_size, int audio int tmp_pid; tmp_pid = ttsd_data_get_pid(uid); - ttsdc_send_set_state_message(tmp_pid, uid, APP_STATE_READY); + ttsdc_ipc_send_set_state_message(tmp_pid, uid, APP_STATE_READY); } */ } else { diff --git a/server/ttsd_tidl.c b/server/ttsd_tidl.c new file mode 100644 index 0000000..bebd4eb --- /dev/null +++ b/server/ttsd_tidl.c @@ -0,0 +1,365 @@ +/* +* 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 +#include +#include "ttsd_main.h" +#include "ttsd_ipc.h" +#include "ttsd_data.h" +#include "ttsd_server.h" + +rpc_port_stub_tts_callback_s g_callback; + +void __send_msg(int pid, int uid, bundle* msg) +{ + SLOG(LOG_INFO, tts_tag(), "[TIDL] start : send msg : pid(%d), uid(%d)", pid, uid); + rpc_port_tts_notify_cb_h handle; + + handle = ttsd_data_get_notify_handle(uid); + if (!handle) { + SLOG(LOG_INFO, tts_tag(), "ttsd_data_get_notify_handle handle null"); + return; + } + + if (0 != rpc_port_tts_notify_cb_invoke(handle, pid, uid, msg)) { + SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to send msg"); + return; + } + SLOG(LOG_INFO, tts_tag(), "send msg : pid(%d), uid(%d)", pid, uid); +} + +static void __create_client_cb(rpc_port_stub_tts_context_h context, void *user_data) +{ + char *sender = NULL; + + rpc_port_stub_tts_context_get_sender(context, &sender); + if (!sender) + return; + + free(sender); +} + +static void __destroy_client_cb(rpc_port_stub_tts_context_h context, void *user_data) +{ + char *sender = NULL; + + rpc_port_stub_tts_context_get_sender(context, &sender); + if (!sender) + return; + + free(sender); +} + +static int __register_cb(rpc_port_stub_tts_context_h context, int pid, int uid, rpc_port_tts_notify_cb_h callback, void* user_data) +{ + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS REGISTER CALLBACK uid(%d)", uid); + + if (-1 == ttsd_data_is_client(uid)) { + SLOG(LOG_WARN, tts_tag(), "[Server WARNING] Uid has not yet been registered"); + if (0 != ttsd_data_new_client(pid, uid)) { + SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to add client info"); + return TTSD_ERROR_OPERATION_FAILED; + } + } + + if (0 != ttsd_data_set_notify_h(uid, callback, NULL)) { + SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to set notify callback"); + return TTSD_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_ERROR, tts_tag(), "<<<<<<<<<<<"); + + return TTSE_ERROR_NONE; +} + +static int __unregister_cb(rpc_port_stub_tts_context_h context, int uid, void* user_data) +{ + struct client_s *client = NULL; + + rpc_port_stub_tts_context_get_tag(context, (void *)&client); + if (!client) + return -1; + + if (0 != ttsd_data_unset_notify_h(uid)) { + SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to unset notify callback"); + return TTSD_ERROR_OPERATION_FAILED; + } + + if (0 != ttsd_data_clear_data(uid)) { + SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Failed to remove client"); + return TTSD_ERROR_OPERATION_FAILED; + } + rpc_port_stub_tts_context_set_tag(context, NULL); + + return TTSE_ERROR_NONE; +} + +static int __set_mode_cb(rpc_port_stub_tts_context_h context, int mode, void* user_data) +{ + //ttsd_set_mode(mode); + SLOG(LOG_INFO, tts_tag(), "[Server] TTSD MODE : (%d)", ttsd_get_mode()); + + return TTSE_ERROR_NONE; +} + +int ttsdc_tidl_send_hello(int pid, int uid, int credential_needed) +{ + SLOG(LOG_INFO, tts_tag(), "[TIDL] ttsdc_tidl_send_hello : pid(%d), uid(%d), credential_needed(%d)", pid, uid, credential_needed); + + char tmp_val[10] = {0, }; + bundle* msg = bundle_create(); + snprintf(tmp_val, 10, "%d", (int)credential_needed); + bundle_add_str(msg, TTS_BUNDLE_METHOD, TTSD_METHOD_HELLO); + bundle_add_str(msg, TTS_BUNDLE_CREDENTIAL_NEEDED, tmp_val); + + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTSD SEND HELLO MSG"); + __send_msg(pid, uid, msg); + + return TTSE_ERROR_NONE; +} + +static int __request_hello_cb(rpc_port_stub_tts_context_h context, int pid, int uid, void *user_data) +{ + SLOG(LOG_INFO, tts_tag(), "[IN] ttsd hello : pid(%d), uid(%d)", pid, uid); + + if (ttsd_data_get_notify_handle(uid)) { + SLOG(LOG_INFO, tts_tag(), "notify callback is set"); + + bool credential_needed = 0; + if (0 != ttsd_server_initialize(pid, uid, &credential_needed)) { + SLOG(LOG_ERROR, tts_tag(), "[IN ERROR] ttsd Hello : server initialize"); + return TTSE_ERROR_OPERATION_FAILED; + } + SLOG(LOG_INFO, tts_tag(), "create player instance"); + ttsdc_tidl_send_hello(pid, uid, (int)credential_needed); + } + + return TTSE_ERROR_NONE; +} + +static int __initialize_cb(rpc_port_stub_tts_context_h context, int uid, int pid, bool *credential_needed, void *user_data) +{ + SECURE_SLOG(LOG_DEBUG, tts_tag(), "[IN] tts initialize : pid(%d), uid(%d)", pid , uid); + + if (0 != ttsd_server_initialize(pid, uid, credential_needed)) { + return -1; + } + SLOG(LOG_DEBUG, tts_tag(), "[OUT] tts initialize credential_needed(%d)", *credential_needed); + + return TTSE_ERROR_NONE; +} + +static int __finalize_cb(rpc_port_stub_tts_context_h context, int uid, void *user_data) +{ + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS FINALIZE"); + + if (0 != ttsd_server_finalize(uid)) { + return -1; + } + SLOG(LOG_DEBUG, tts_tag(), "<<<<<"); + + return TTSE_ERROR_NONE; +} + +static int __add_text_cb(rpc_port_stub_tts_context_h context, int uid, const char *text, const char *lang, + int vctype, int speed, int uttid, const char *credential, void *user_data) +{ + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS ADD TEXT"); + + if (0 != ttsd_server_add_queue(uid, text, lang, vctype, speed, uttid, credential)) { + return -1; + } + + SLOG(LOG_DEBUG, tts_tag(), "<<<<<"); + + return TTSE_ERROR_NONE; +} + +static int __stop_cb(rpc_port_stub_tts_context_h context, int uid, void *user_data) +{ + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS STOP"); + + if (0 != ttsd_server_stop(uid)) { + return -1; + } + + SLOG(LOG_DEBUG, tts_tag(), "<<<<<"); + + return TTSE_ERROR_NONE; +} + +static int __pause_cb(rpc_port_stub_tts_context_h context, int uid, void *user_data) +{ + int uttid; + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS PLAYER PAUE"); + + if (0 != ttsd_server_pause(uid, &uttid)) { + return -1; + } + + SLOG(LOG_DEBUG, tts_tag(), "<<<<<"); + + return TTSE_ERROR_NONE; +} + +static int __play_pcm_cb(rpc_port_stub_tts_context_h context, int uid, void *user_data) +{ + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS PLAY PCM"); + + if (0 != ttsd_server_play_pcm(uid)) { + return -1; + } + + SLOG(LOG_DEBUG, tts_tag(), "<<<<<"); + + return TTSE_ERROR_NONE; +} + +static int __stop_pcm_cb(rpc_port_stub_tts_context_h context, int uid, void *user_data) +{ + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS STOP PCM"); + + if (0 != ttsd_server_stop_pcm(uid)) { + return -1; + } + + SLOG(LOG_DEBUG, tts_tag(), "<<<<<"); + + return TTSE_ERROR_NONE; +} + +static int __set_private_cb(rpc_port_stub_tts_context_h context, int uid, const char *key, const char *data, void *user_data) +{ + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS SET PRIVATE DATA"); + + if (0 != ttsd_server_set_private_data(uid, key, data)) { + return -1; + } + + SLOG(LOG_DEBUG, tts_tag(), "<<<<<"); + + return TTSE_ERROR_NONE; +} + +static int __get_private_cb(rpc_port_stub_tts_context_h context, int uid, const char *key, char **data, void *user_data) +{ + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS GET PRIVATE DATA"); + char *tmp = NULL; + + if (0 != ttsd_server_get_private_data(uid, key, &tmp)) { + return -1; + } + + *data = tmp; + + SLOG(LOG_DEBUG, tts_tag(), "<<<<<"); + + return TTSE_ERROR_NONE; +} + +static int __play_cb(rpc_port_stub_tts_context_h context, int uid, const char *credential, void *user_data) +{ + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS PLAY (%d)", uid); + if (0 != ttsd_server_play(uid, credential)) { + return -1; + } + SLOG(LOG_DEBUG, tts_tag(), "<<<<<"); + + return TTSE_ERROR_NONE; +} + +static int __add_pcm_cb(rpc_port_stub_tts_context_h context, int uid, int event, const char *pcm_data, int data_size, int audio_type, int rate, void *user_data) +{ + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS ADD PCM (%d)", uid); + if (0 != ttsd_server_add_pcm(uid, event, (void *)pcm_data, data_size, audio_type, rate)) { + return -1; + } + SLOG(LOG_DEBUG, tts_tag(), "<<<<<"); + + return TTSE_ERROR_NONE; +} + +int ttsd_tidl_open_connection() +{ + SLOG(LOG_DEBUG, tts_tag(), "[TIDL] ttsd_tidl_open_connection"); + + g_callback.create = __create_client_cb; + g_callback.terminate = __destroy_client_cb; + g_callback.set_mode = __set_mode_cb; + g_callback.request_hello = __request_hello_cb; + g_callback.register_cb = __register_cb; + g_callback.unregister_cb = __unregister_cb; + g_callback.initialize = __initialize_cb; + g_callback.finalize = __finalize_cb; + g_callback.add_text = __add_text_cb; + g_callback.stop = __stop_cb; + g_callback.pause = __pause_cb; + g_callback.play_pcm = __play_pcm_cb; + g_callback.stop_pcm = __stop_pcm_cb; + g_callback.set_private = __set_private_cb; + g_callback.get_private = __get_private_cb; + g_callback.play = __play_cb; + g_callback.add_pcm = __add_pcm_cb; + + if (0 != rpc_port_stub_tts_register(&g_callback, NULL)) { + return TTSE_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, tts_tag(), "regitster callback"); + + return TTSE_ERROR_NONE; +} + +int ttsd_tidl_close_connection() +{ + SLOG(LOG_DEBUG, tts_tag(), "[TIDL] ttsd_tidl_close_connection"); + rpc_port_stub_tts_unregister(); + + return TTSE_ERROR_NONE; +} + +int ttsdc_tidl_send_message(int pid, int uid, int uttid, const char *method) +{ + SLOG(LOG_DEBUG, tts_tag(), "[TIDL] ttsdc_tidl_send_message"); + + char tmp_uttid[10] = {0, }; + + bundle* msg = bundle_create(); + snprintf(tmp_uttid, 10, "%d", uttid); + bundle_add_str(msg, TTS_BUNDLE_METHOD, method); + bundle_add_str(msg, TTS_BUNDLE_UTTID, tmp_uttid); + + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTSD SEND MSG"); + __send_msg(pid, uid, msg); + + return TTSE_ERROR_NONE; +} + +int ttsdc_tidl_send_error_message(int pid, int uid, int uttid, int reason, char* err_msg) +{ + SLOG(LOG_DEBUG, tts_tag(), "[TIDL] ttsdc_tidl_send_error_message"); + + char tmp_uttid[10] = {0, }; + char tmp_reason[10] = {0, }; + + bundle* msg = bundle_create(); + snprintf(tmp_uttid, 10, "%d", uttid); + bundle_add_str(msg, TTS_BUNDLE_METHOD, TTSD_METHOD_ERROR); + bundle_add_str(msg, TTS_BUNDLE_UTTID, tmp_uttid); + bundle_add_str(msg, TTS_BUNDLE_REASON, tmp_reason); + bundle_add_str(msg, TTS_BUNDLE_ERR_MSG, err_msg); + + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTSD SEND ERROR MSG"); + __send_msg(pid, uid, msg); + + return TTSE_ERROR_NONE; +} diff --git a/server/ttsd_tidl.h b/server/ttsd_tidl.h new file mode 100644 index 0000000..e047243 --- /dev/null +++ b/server/ttsd_tidl.h @@ -0,0 +1,36 @@ +/* +* 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. +*/ + + +#ifndef __TTSD_TIDL_h__ +#define __TTSD_TIDL_h__ + +#ifdef __cplusplus +extern "C" { +#endif + +int ttsd_tidl_open_connection(); + +int ttsd_tidl_close_connection(); + +int ttsdc_tidl_send_hello(int pid, int uid, int credential_needed); + +int ttsdc_tidl_send_message(int pid, int uid, int data, const char *method); + +int ttsdc_tidl_send_error_message(int pid, int uid, int uttid, int reason, char* err_msg); + +#ifdef __cplusplus +} +#endif + +#endif /* __TTSD_TIDL_h__ */ diff --git a/server/ttse.c b/server/ttse.c index 0b91a2b..a1e98c5 100755 --- a/server/ttse.c +++ b/server/ttse.c @@ -15,6 +15,7 @@ #include "ttsd_main.h" #include "ttsd_server.h" #include "ttsd_dbus.h" +#include "ttsd_ipc.h" #include "ttsd_network.h" #include @@ -125,8 +126,8 @@ int ttse_main(int argc, char** argv, ttse_request_callback_s *callback) } if (TRUE == __is_default_engine()) { - if (0 != ttsd_dbus_open_connection()) { - SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to open dbus connection"); + if (0 != ttsd_ipc_open_connection()) { + SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to open ipc connection"); ecore_shutdown(); return TTSE_ERROR_OPERATION_FAILED; } diff --git a/tidl/tts.tidl b/tidl/tts.tidl new file mode 100644 index 0000000..7a12e24 --- /dev/null +++ b/tidl/tts.tidl @@ -0,0 +1,20 @@ +interface tts { + void notify_cb(int pid, int uid, bundle msg) delegate; + int register_cb(int pid, int uid, notify_cb callback); + int unregister_cb(int uid); + + int set_mode(int mode); + int request_hello(int pid, int uid); + int initialize(in int pid, in int uid, out bool credential_needed); + int finalize(in int uid); + int add_text(int uid, string text, string lang, int vctype, int speed, int uttid, string credential); + int stop(in int uid); + int pause(in int uid); + int play_pcm(in int uid); + int stop_pcm(in int uid); + int set_private(in int uid, string key, string priv_data); + int get_private(in int uid, string key, out string priv_data); + int play(int uid, string credential); + int add_pcm(int uid, int event, string pcm_data, int data_size, int audio_type, int rate); + +}