2 * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 * http://www.apache.org/licenses/LICENSE-2.0
7 * Unless required by applicable law or agreed to in writing, software
8 * distributed under the License is distributed on an "AS IS" BASIS,
9 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 * See the License for the specific language governing permissions and
11 * limitations under the License.
18 #include "ttsd_main.h"
19 #include "ttsd_server.h"
20 #include "ttsd_stub.h"
22 #include "ttsd_tidl.h"
26 rpc_port_stub_tts_notify_cb_h notify_cb_h;
27 } tts_tidl_proxy_info_s;
29 static GList* g_tidl_proxy_infos = NULL;
31 rpc_port_stub_tts_callback_s g_callback;
33 static pthread_mutex_t g_tidl_proxy_infos_mutex = PTHREAD_MUTEX_INITIALIZER;
36 static tts_tidl_proxy_info_s* __get_tidl_proxy_info_s(unsigned int uid)
39 tts_tidl_proxy_info_s* info = NULL;
41 if (g_list_length(g_tidl_proxy_infos) > 0) {
42 /* Get a first item */
43 iter = g_list_first(g_tidl_proxy_infos);
45 while (NULL != iter) {
47 if (info->uid == uid) {
52 iter = g_list_next(iter);
59 void __send_msg(int pid, unsigned int uid, bundle* msg)
61 SLOG(LOG_INFO, tts_tag(), "[TIDL] start : send msg : pid(%d), uid(%u)", pid, uid);
62 pthread_mutex_lock(&g_tidl_proxy_infos_mutex);
63 tts_tidl_proxy_info_s* info = __get_tidl_proxy_info_s(uid);
65 SLOG(LOG_ERROR, tts_tag(), "[TIDL] Uid is not valid. pid(%d), uid(%u)", pid, uid);
66 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
70 rpc_port_stub_tts_notify_cb_h handle = info->notify_cb_h;
72 SLOG(LOG_INFO, tts_tag(), "notify callback handle null");
73 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
77 if (0 != rpc_port_stub_tts_notify_cb_invoke(handle, pid, (int)uid, msg)) {
78 SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to send msg");
79 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
82 SLOG(LOG_INFO, tts_tag(), "send msg : pid(%d), uid(%u)", pid, uid);
83 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
86 static void __create_client_cb(rpc_port_stub_tts_context_h context, void *user_data)
90 rpc_port_stub_tts_context_get_sender(context, &sender);
94 SLOG(LOG_ERROR, tts_tag(), ">>>>> Client connect. appid(%s)", sender);
98 static void __destroy_client_cb(rpc_port_stub_tts_context_h context, void *user_data)
101 rpc_port_stub_tts_context_get_tag(context, &tag);
104 unsigned int uid = (uintptr_t)tag;
105 SLOG(LOG_ERROR, tts_tag(), ">>>>> TTS FINALIZE. uid(%u)", uid);
107 if (0 != ttsd_server_finalize(uid)) {
111 pthread_mutex_lock(&g_tidl_proxy_infos_mutex);
112 tts_tidl_proxy_info_s* info = __get_tidl_proxy_info_s(uid);
114 SLOG(LOG_ERROR, tts_tag(), "[TIDL ERROR] Fail to set notify callback");
115 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
119 rpc_port_stub_tts_notify_cb_destroy(info->notify_cb_h);
120 info->notify_cb_h = NULL;
122 g_tidl_proxy_infos = g_list_remove(g_tidl_proxy_infos, info);
125 SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
127 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
129 rpc_port_stub_tts_context_set_tag(context, NULL);
132 rpc_port_stub_tts_context_get_sender(context, &sender);
136 SLOG(LOG_INFO, tts_tag(), ">>>>> Client disconnect. appid(%s)", sender);
140 static void __register_cb(rpc_port_stub_tts_context_h context, int pid, int uid, rpc_port_stub_tts_notify_cb_h callback, void* user_data)
142 unsigned int u_uid = (unsigned int)uid;
143 SLOG(LOG_ERROR, tts_tag(), ">>>>> TTS REGISTER CALLBACK uid(%u)", u_uid);
145 bool is_initialized = false;
146 ttsd_server_is_already_initialized(pid, u_uid, &is_initialized);
149 int credential_needed = 0;
150 if (false == is_initialized) {
151 bool is_credential_needed = false;
152 ret = ttsd_server_initialize(pid, u_uid, TTS_IPC_METHOD_TIDL, &is_credential_needed);
154 SLOG(LOG_ERROR, tts_tag(), "[IN ERROR] ttsd Hello : server initialize, ret(%d)", ret);
157 credential_needed = is_credential_needed ? 1 : 0;
159 ret = TTS_ERROR_ALREADY_INITIALIZED;
160 credential_needed = TTS_CREDENTIAL_NEEDED_ALREADY_INITIALIZED;
163 uintptr_t ptr_uid = u_uid;
164 rpc_port_stub_tts_context_set_tag(context, (void*)ptr_uid);
166 pthread_mutex_lock(&g_tidl_proxy_infos_mutex);
167 tts_tidl_proxy_info_s* info = __get_tidl_proxy_info_s(u_uid);
169 info = (tts_tidl_proxy_info_s*)calloc(1, sizeof(tts_tidl_proxy_info_s));
171 SLOG(LOG_ERROR, tts_tag(), "[TIDL ERROR] Fail to allocate memory for tidl proxy");
172 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
176 g_tidl_proxy_infos = g_list_remove(g_tidl_proxy_infos, info);
177 rpc_port_stub_tts_notify_cb_destroy(info->notify_cb_h);
178 info->notify_cb_h = NULL;
181 if (0 != rpc_port_stub_tts_notify_cb_clone(callback, &info->notify_cb_h)) {
182 SLOG(LOG_ERROR, tts_tag(), "[TIDL ERROR] Fail to set notify callback");
184 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
189 g_tidl_proxy_infos = g_list_append(g_tidl_proxy_infos, info);
190 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
192 SLOG(LOG_INFO, tts_tag(), "create player instance");
193 ttsdc_tidl_send_hello(pid, u_uid, ret, credential_needed);
195 SLOG(LOG_ERROR, tts_tag(), "<<<<<<<<<<<");
199 static int __register_cb_sync(rpc_port_stub_tts_context_h context, int pid, int uid, rpc_port_stub_tts_notify_cb_h callback, void* user_data)
201 unsigned int u_uid = (unsigned int)uid;
202 SLOG(LOG_ERROR, tts_tag(), ">>>>> TTS REGISTER CALLBACK synchronously uid(%u)", u_uid);
204 uintptr_t ptr_uid = u_uid;
205 rpc_port_stub_tts_context_set_tag(context, (void*)ptr_uid);
207 pthread_mutex_lock(&g_tidl_proxy_infos_mutex);
208 tts_tidl_proxy_info_s* info = __get_tidl_proxy_info_s(u_uid);
210 info = (tts_tidl_proxy_info_s*)calloc(1, sizeof(tts_tidl_proxy_info_s));
212 SLOG(LOG_ERROR, tts_tag(), "[TIDL ERROR] Fail to allocate memory for tidl proxy");
213 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
214 return TTSD_ERROR_OUT_OF_MEMORY;
217 g_tidl_proxy_infos = g_list_remove(g_tidl_proxy_infos, info);
218 rpc_port_stub_tts_notify_cb_destroy(info->notify_cb_h);
219 info->notify_cb_h = NULL;
222 if (0 != rpc_port_stub_tts_notify_cb_clone(callback, &info->notify_cb_h)) {
223 SLOG(LOG_ERROR, tts_tag(), "[TIDL ERROR] Fail to set notify callback");
225 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
226 return TTSD_ERROR_OPERATION_FAILED;
230 g_tidl_proxy_infos = g_list_append(g_tidl_proxy_infos, info);
231 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
233 SLOG(LOG_ERROR, tts_tag(), "<<<<<<<<<<<");
235 return TTSD_ERROR_NONE;
238 static int __set_mode_cb(rpc_port_stub_tts_context_h context, int uid, int mode, void* user_data)
240 unsigned int u_uid = (unsigned int)uid;
241 SLOG(LOG_INFO, tts_tag(), ">>>>> TTS SET MODE. uid(%u). mode (%d)", u_uid, mode);
243 int ret = ttsd_server_set_mode(u_uid, mode);
244 if (TTSD_ERROR_NONE != ret) {
245 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS SET MODE (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
249 SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
250 return TTSD_ERROR_NONE;
253 int ttsdc_tidl_send_hello(int pid, unsigned int uid, int ret, int credential_needed)
255 SLOG(LOG_INFO, tts_tag(), "[TIDL] ttsdc_tidl_send_hello : pid(%d), uid(%u), credential_needed(%d)", pid, uid, credential_needed);
257 char tmp_val[10] = {0, };
258 char ret_val[12] = {0, };
259 snprintf(tmp_val, 10, "%d", credential_needed);
260 snprintf(ret_val, 12, "%d", ret);
262 bundle* msg = bundle_create();
264 SLOG(LOG_ERROR, tts_tag(), "[TIDL] Fail to create bundle: pid(%d), uid(%u)", pid, uid);
265 return TTSD_ERROR_OUT_OF_MEMORY;
268 bundle_add_str(msg, TTS_BUNDLE_METHOD, TTSD_METHOD_HELLO);
269 bundle_add_str(msg, TTS_BUNDLE_REASON, ret_val);
270 bundle_add_str(msg, TTS_BUNDLE_CREDENTIAL_NEEDED, tmp_val);
272 SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTSD SEND HELLO MSG");
273 __send_msg(pid, uid, msg);
276 return TTSD_ERROR_NONE;
279 static int __initialize_cb(rpc_port_stub_tts_context_h context, int pid, int uid, bool *credential_needed, void *user_data)
281 unsigned int u_uid = (unsigned int)uid;
282 SECURE_SLOG(LOG_ERROR, tts_tag(), "[IN] tts initialize : pid(%d), uid(%u)", pid, u_uid);
284 if (0 != ttsd_server_initialize(pid, u_uid, TTS_IPC_METHOD_TIDL, credential_needed)) {
285 return TTSD_ERROR_OPERATION_FAILED;
288 SLOG(LOG_ERROR, tts_tag(), "[OUT] tts initialize credential_needed(%d)", *credential_needed);
289 return TTSD_ERROR_NONE;
292 static int __finalize_cb(rpc_port_stub_tts_context_h context, int uid, void *user_data)
294 unsigned int u_uid = (unsigned int)uid;
295 SLOG(LOG_ERROR, tts_tag(), ">>>>> TTS FINALIZE. uid(%u)", u_uid);
297 int ret = ttsd_server_finalize(u_uid);
298 if (TTSD_ERROR_NONE != ret) {
299 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS FINALIZE (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
303 pthread_mutex_lock(&g_tidl_proxy_infos_mutex);
304 tts_tidl_proxy_info_s* info = __get_tidl_proxy_info_s(u_uid);
306 SLOG(LOG_ERROR, tts_tag(), "[TIDL ERROR] Fail to set notify callback");
307 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
308 return TTSD_ERROR_INVALID_PARAMETER;
311 rpc_port_stub_tts_notify_cb_destroy(info->notify_cb_h);
312 info->notify_cb_h = NULL;
314 g_tidl_proxy_infos = g_list_remove(g_tidl_proxy_infos, info);
316 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
318 rpc_port_stub_tts_context_set_tag(context, NULL);
319 SLOG(LOG_ERROR, tts_tag(), "<<<<<");
320 return TTSD_ERROR_NONE;
323 static int __add_text_cb(rpc_port_stub_tts_context_h context, int uid, const char *text, const char *lang,
324 int vctype, int speed, int uttid, const char *credential, void *user_data)
326 unsigned int u_uid = (unsigned int)uid;
327 SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS ADD TEXT (%u)", u_uid);
329 int ret = ttsd_server_add_text(u_uid, text, lang, vctype, speed, uttid, credential);
330 if (TTSD_ERROR_NONE != ret) {
331 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS ADD TEXT (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
335 SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
336 return TTSD_ERROR_NONE;
339 static int __stop_cb(rpc_port_stub_tts_context_h context, int uid, void *user_data)
341 unsigned int u_uid = (unsigned int)uid;
342 SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS STOP (%u)", u_uid);
344 int ret = ttsd_server_stop(u_uid);
345 if (TTSD_ERROR_NONE != ret) {
346 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS STOP (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
351 SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
353 return TTSD_ERROR_NONE;
356 static int __pause_cb(rpc_port_stub_tts_context_h context, int uid, void *user_data)
358 unsigned int u_uid = (unsigned int)uid;
359 SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS PLAYER PAUSE (%u)", u_uid);
361 int ret = ttsd_server_pause(u_uid);
362 if (TTSD_ERROR_NONE != ret) {
363 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS PLAYER PAUSE (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
367 SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
369 return TTSD_ERROR_NONE;
372 static int __play_pcm_cb(rpc_port_stub_tts_context_h context, int uid, void *user_data)
374 unsigned int u_uid = (unsigned int)uid;
375 SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS PLAY PCM (%u)", u_uid);
377 int ret = ttsd_server_play_pcm(u_uid);
378 if (TTSD_ERROR_NONE != ret) {
379 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS PLAY PCM (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
383 SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
385 return TTSD_ERROR_NONE;
388 static int __stop_pcm_cb(rpc_port_stub_tts_context_h context, int uid, void *user_data)
390 unsigned int u_uid = (unsigned int)uid;
391 SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS STOP PCM (%u)", u_uid);
393 int ret = ttsd_server_stop(u_uid);
394 if (TTSD_ERROR_NONE != ret) {
395 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS STOP PCM (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
399 SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
400 return TTSD_ERROR_NONE;
403 static int __set_private_cb(rpc_port_stub_tts_context_h context, int uid, const char *key, const char *data, void *user_data)
405 unsigned int u_uid = (unsigned int)uid;
406 SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS SET PRIVATE DATA (%u)", u_uid);
408 int ret = ttsd_server_set_private_data(u_uid, key, data);
409 if (TTSD_ERROR_NONE != ret) {
410 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS SET PRIVATE DATA (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
414 SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
416 return TTSD_ERROR_NONE;
419 static int __get_private_cb(rpc_port_stub_tts_context_h context, int uid, const char *key, char **data, void *user_data)
421 unsigned int u_uid = (unsigned int)uid;
422 SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS GET PRIVATE DATA (%u)", u_uid);
425 int ret = ttsd_server_get_private_data(u_uid, key, &tmp);
426 if (TTSD_ERROR_NONE != ret) {
427 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS GET PRIVATE DATA (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
434 SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
435 return TTSD_ERROR_NONE;
438 static int __play_cb(rpc_port_stub_tts_context_h context, int uid, const char *credential, void *user_data)
440 unsigned int u_uid = (unsigned int)uid;
441 SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS PLAY (%u)", u_uid);
443 int ret = ttsd_server_play(u_uid, credential);
444 if (TTSD_ERROR_NONE != ret) {
445 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS PLAY (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
449 SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
450 return TTSD_ERROR_NONE;
453 static int __add_pcm_cb(rpc_port_stub_tts_context_h context, int uid, int event, rpc_port_stub_array_char_h pcm_data, int data_size, int audio_type, int rate, void *user_data)
455 unsigned int u_uid = (unsigned int)uid;
456 SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS ADD PCM (%u)", u_uid);
458 char* pcm_data_raw = NULL;
459 int pcm_data_size = 0;
460 rpc_port_stub_array_char_get(pcm_data, &pcm_data_raw, &pcm_data_size);
462 int ret = ttsd_server_add_pcm(u_uid, event, (void *)pcm_data_raw, data_size, audio_type, rate);
465 if (TTSD_ERROR_NONE != ret) {
466 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS ADD PCM (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
470 SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
471 return TTSD_ERROR_NONE;
474 int ttsd_tidl_open_connection()
476 SLOG(LOG_DEBUG, tts_tag(), "[TIDL] ttsd_tidl_open_connection");
478 g_callback.create = __create_client_cb;
479 g_callback.terminate = __destroy_client_cb;
480 g_callback.set_mode = __set_mode_cb;
481 g_callback.register_cb = __register_cb;
482 g_callback.register_cb_sync = __register_cb_sync;
483 g_callback.initialize = __initialize_cb;
484 g_callback.finalize = __finalize_cb;
485 g_callback.add_text = __add_text_cb;
486 g_callback.stop = __stop_cb;
487 g_callback.pause = __pause_cb;
488 g_callback.play_pcm = __play_pcm_cb;
489 g_callback.stop_pcm = __stop_pcm_cb;
490 g_callback.set_private = __set_private_cb;
491 g_callback.get_private = __get_private_cb;
492 g_callback.play = __play_cb;
493 g_callback.add_pcm = __add_pcm_cb;
498 while (TTS_RETRY_MIN_COUNT >= count) {
499 ret = rpc_port_stub_tts_register(&g_callback, NULL);
501 SLOG(LOG_DEBUG, tts_tag(), "regitster callback");
502 return TTSD_ERROR_NONE;
508 SLOG(LOG_ERROR, tts_tag(), "Fail to register callback(%d)", ret);
509 return TTSE_ERROR_OPERATION_FAILED;
512 int ttsd_tidl_close_connection()
514 SLOG(LOG_DEBUG, tts_tag(), "[TIDL] ttsd_tidl_close_connection");
515 rpc_port_stub_tts_unregister();
517 return TTSD_ERROR_NONE;
520 static int __send_message(int pid, unsigned int uid, int data, const char *method)
522 SLOG(LOG_DEBUG, tts_tag(), "[TIDL] ttsdc_tidl_send_message");
524 char tmp_msg[10] = {0, };
526 bundle* msg = bundle_create();
527 snprintf(tmp_msg, 10, "%d", data);
528 bundle_add_str(msg, TTS_BUNDLE_METHOD, method);
529 bundle_add_str(msg, TTS_BUNDLE_MESSAGE, tmp_msg);
531 SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTSD SEND MSG");
532 __send_msg(pid, uid, msg);
535 return TTSD_ERROR_NONE;
538 int ttsdc_tidl_send_utt_start_message(int pid, unsigned int uid, int uttid)
540 return __send_message(pid, uid, uttid, TTSD_METHOD_UTTERANCE_STARTED);
543 int ttsdc_tidl_send_utt_finish_message(int pid, unsigned int uid, int uttid)
545 return __send_message(pid, uid, uttid, TTSD_METHOD_UTTERANCE_COMPLETED);
548 int ttsdc_tidl_send_set_state_message(int pid, unsigned int uid, int state)
550 return __send_message(pid, uid, state, TTSD_METHOD_SET_STATE);
553 int ttsdc_tidl_send_error_message(int pid, unsigned int uid, int uttid, int reason, char* err_msg)
555 SLOG(LOG_DEBUG, tts_tag(), "[TIDL] ttsdc_tidl_send_error_message");
557 char tmp_uttid[10] = {0, };
558 char tmp_reason[10] = {0, };
560 bundle* msg = bundle_create();
561 snprintf(tmp_uttid, 10, "%d", uttid);
562 bundle_add_str(msg, TTS_BUNDLE_METHOD, TTSD_METHOD_ERROR);
563 bundle_add_str(msg, TTS_BUNDLE_UTTID, tmp_uttid);
564 bundle_add_str(msg, TTS_BUNDLE_REASON, tmp_reason);
565 bundle_add_str(msg, TTS_BUNDLE_ERR_MSG, err_msg);
567 SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTSD SEND ERROR MSG");
568 __send_msg(pid, uid, msg);
571 return TTSD_ERROR_NONE;