Add to set playing mode to decide where the synthesized pcm data will be played
[platform/core/uifw/tts.git] / server / ttsd_tidl.c
1 /*
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.
12 */
13
14 #include <stdlib.h>
15 #include <Ecore.h>
16 #include <pthread.h>
17
18 #include "ttsd_main.h"
19 #include "ttsd_server.h"
20 #include "ttsd_stub.h"
21
22 #include "ttsd_tidl.h"
23
24 typedef struct {
25         unsigned int uid;
26         rpc_port_stub_tts_notify_cb_h notify_cb_h;
27 } tts_tidl_proxy_info_s;
28
29 static GList* g_tidl_proxy_infos = NULL;
30
31 static rpc_port_stub_tts_callback_s g_callback;
32
33 static pthread_mutex_t g_tidl_proxy_infos_mutex = PTHREAD_MUTEX_INITIALIZER;
34
35
36 static tts_tidl_proxy_info_s* __get_tidl_proxy_info_s(unsigned int uid)
37 {
38         GList* iter = NULL;
39         tts_tidl_proxy_info_s* info = NULL;
40
41         if (g_list_length(g_tidl_proxy_infos) > 0) {
42                 /* Get a first item */
43                 iter = g_list_first(g_tidl_proxy_infos);
44
45                 while (NULL != iter) {
46                         info = iter->data;
47                         if (info->uid == uid) {
48                                 return info;
49                         }
50
51                         /* Next item */
52                         iter = g_list_next(iter);
53                 }
54         }
55
56         return NULL;
57 }
58
59 void __send_msg(int pid, unsigned int uid, bundle* msg)
60 {
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);
64         if (NULL == info) {
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);
67                 return;
68         }
69
70         rpc_port_stub_tts_notify_cb_h handle = info->notify_cb_h;
71         if (NULL == handle) {
72                 SLOG(LOG_INFO, tts_tag(), "notify callback handle null");
73                 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
74                 return;
75         }
76
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);
80                 return;
81         }
82         SLOG(LOG_INFO, tts_tag(), "send msg : pid(%d), uid(%u)", pid, uid);
83         pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
84 }
85
86 static void __create_client_cb(rpc_port_stub_tts_context_h context, void *user_data)
87 {
88         char *sender = NULL;
89
90         rpc_port_stub_tts_context_get_sender(context, &sender);
91         if (!sender)
92                 return;
93
94         SLOG(LOG_ERROR, tts_tag(), ">>>>> Client connect. appid(%s)", sender);
95         free(sender);
96 }
97
98 static void __destroy_client_cb(rpc_port_stub_tts_context_h context, void *user_data)
99 {
100         void* tag = NULL;
101         rpc_port_stub_tts_context_get_tag(context, &tag);
102
103         if (NULL != tag) {
104                 unsigned int uid = (uintptr_t)tag;
105                 SLOG(LOG_ERROR, tts_tag(), ">>>>> TTS FINALIZE. uid(%u)", uid);
106
107                 if (0 != ttsd_server_finalize(uid)) {
108                         return;
109                 }
110                 ttsd_server_update_instant_reprepare_client();
111
112                 pthread_mutex_lock(&g_tidl_proxy_infos_mutex);
113                 tts_tidl_proxy_info_s* info = __get_tidl_proxy_info_s(uid);
114                 if (NULL == info) {
115                         SLOG(LOG_ERROR, tts_tag(), "[TIDL ERROR] Fail to set notify callback");
116                         pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
117                         return;
118                 }
119
120                 rpc_port_stub_tts_notify_cb_destroy(info->notify_cb_h);
121                 info->notify_cb_h = NULL;
122
123                 g_tidl_proxy_infos = g_list_remove(g_tidl_proxy_infos, info);
124                 free(info);
125
126                 SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
127
128                 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
129         }
130         rpc_port_stub_tts_context_set_tag(context, NULL);
131
132         char *sender = NULL;
133         rpc_port_stub_tts_context_get_sender(context, &sender);
134         if (!sender)
135                 return;
136
137         SLOG(LOG_INFO, tts_tag(), ">>>>> Client disconnect. appid(%s)", sender);
138         free(sender);
139 }
140
141 static void __register_cb(rpc_port_stub_tts_context_h context, int pid, int uid, int mode, int playing_mode, int registered_event_mask, rpc_port_stub_tts_notify_cb_h callback, void *user_data)
142 {
143         unsigned int u_uid = (unsigned int)uid;
144         SLOG(LOG_ERROR, tts_tag(), ">>>>> TTS REGISTER CALLBACK uid(%u), mode(%d), playing_mode(%d), registered mask(%x)", u_uid, mode, playing_mode, registered_event_mask);
145
146         bool is_initialized = false;
147         ttsd_server_is_already_initialized(pid, u_uid, &is_initialized);
148
149         int ret = -1;
150         int credential_needed = 0;
151         ttsd_state_e service_state = TTSD_STATE_INVALID;
152
153         if (false == is_initialized) {
154                 bool is_credential_needed = false;
155                 ret = ttsd_server_initialize(pid, u_uid, mode, playing_mode, registered_event_mask, TTS_IPC_METHOD_TIDL, &service_state, &is_credential_needed);
156                 if (0 != ret) {
157                         SLOG(LOG_ERROR, tts_tag(), "[IN ERROR] ttsd Hello : server initialize, ret(%d)", ret);
158                 }
159                 ttsd_server_update_instant_reprepare_client();
160
161                 credential_needed = is_credential_needed ? 1 : 0;
162         } else {
163                 ret = TTS_ERROR_ALREADY_INITIALIZED;
164                 credential_needed = TTS_CREDENTIAL_NEEDED_ALREADY_INITIALIZED;
165         }
166
167         uintptr_t ptr_uid = u_uid;
168         rpc_port_stub_tts_context_set_tag(context, (void*)ptr_uid);
169
170         pthread_mutex_lock(&g_tidl_proxy_infos_mutex);
171         tts_tidl_proxy_info_s* info = __get_tidl_proxy_info_s(u_uid);
172         if (NULL == info) {
173                 info = (tts_tidl_proxy_info_s*)calloc(1, sizeof(tts_tidl_proxy_info_s));
174                 if (NULL == info) {
175                         SLOG(LOG_ERROR, tts_tag(), "[TIDL ERROR] Fail to allocate memory for tidl proxy");
176                         pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
177                         return;
178                 }
179         } else {
180                 g_tidl_proxy_infos = g_list_remove(g_tidl_proxy_infos, info);
181                 rpc_port_stub_tts_notify_cb_destroy(info->notify_cb_h);
182                 info->notify_cb_h = NULL;
183         }
184
185         if (0 != rpc_port_stub_tts_notify_cb_clone(callback, &info->notify_cb_h)) {
186                 SLOG(LOG_ERROR, tts_tag(), "[TIDL ERROR] Fail to set notify callback");
187                 free(info);
188                 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
189                 return;
190         }
191
192         info->uid = u_uid;
193         g_tidl_proxy_infos = g_list_append(g_tidl_proxy_infos, info);
194         pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
195
196         SLOG(LOG_INFO, tts_tag(), "create player instance");
197         ttsdc_tidl_send_hello(pid, u_uid, ret, (int)service_state, credential_needed);
198
199         SLOG(LOG_ERROR, tts_tag(), "<<<<<<<<<<<");
200         return;
201 }
202
203 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)
204 {
205         unsigned int u_uid = (unsigned int)uid;
206         SLOG(LOG_ERROR, tts_tag(), ">>>>> TTS REGISTER CALLBACK synchronously uid(%u)", u_uid);
207
208         uintptr_t ptr_uid = u_uid;
209         rpc_port_stub_tts_context_set_tag(context, (void*)ptr_uid);
210
211         pthread_mutex_lock(&g_tidl_proxy_infos_mutex);
212         tts_tidl_proxy_info_s* info = __get_tidl_proxy_info_s(u_uid);
213         if (NULL == info) {
214                 info = (tts_tidl_proxy_info_s*)calloc(1, sizeof(tts_tidl_proxy_info_s));
215                 if (NULL == info) {
216                         SLOG(LOG_ERROR, tts_tag(), "[TIDL ERROR] Fail to allocate memory for tidl proxy");
217                         pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
218                         return TTSD_ERROR_OUT_OF_MEMORY;
219                 }
220         } else {
221                 g_tidl_proxy_infos = g_list_remove(g_tidl_proxy_infos, info);
222                 rpc_port_stub_tts_notify_cb_destroy(info->notify_cb_h);
223                 info->notify_cb_h = NULL;
224         }
225
226         if (0 != rpc_port_stub_tts_notify_cb_clone(callback, &info->notify_cb_h)) {
227                 SLOG(LOG_ERROR, tts_tag(), "[TIDL ERROR] Fail to set notify callback");
228                 free(info);
229                 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
230                 return TTSD_ERROR_OPERATION_FAILED;
231         }
232
233         info->uid = u_uid;
234         g_tidl_proxy_infos = g_list_append(g_tidl_proxy_infos, info);
235         pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
236
237         SLOG(LOG_ERROR, tts_tag(), "<<<<<<<<<<<");
238
239         return TTSD_ERROR_NONE;
240 }
241
242 int ttsdc_tidl_send_hello(int pid, unsigned int uid, int ret, int service_state, int credential_needed)
243 {
244         SLOG(LOG_INFO, tts_tag(), "[TIDL] ttsdc_tidl_send_hello : pid(%d), uid(%u), service_state(%d), credential_needed(%d)",
245                         pid, uid, service_state, credential_needed);
246
247         char credential_needed_str[12] = {0, };
248         char service_state_str[12] = {0, };
249         char ret_str[12] = {0, };
250
251         snprintf(credential_needed_str, 12, "%d", credential_needed);
252         snprintf(service_state_str, 12, "%d", service_state);
253         snprintf(ret_str, 12, "%d", ret);
254
255         bundle* msg = bundle_create();
256         if (NULL == msg) {
257                 SLOG(LOG_ERROR, tts_tag(), "[TIDL] Fail to create bundle: pid(%d), uid(%u)", pid, uid);
258                 return TTSD_ERROR_OUT_OF_MEMORY;
259         }
260
261         bundle_add_str(msg, TTS_BUNDLE_METHOD, TTSD_METHOD_HELLO);
262         bundle_add_str(msg, TTS_BUNDLE_REASON, ret_str);
263         bundle_add_str(msg, TTS_BUNDLE_CURRENT_STATE, service_state_str);
264         bundle_add_str(msg, TTS_BUNDLE_CREDENTIAL_NEEDED, credential_needed_str);
265
266         SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTSD SEND HELLO MSG");
267         __send_msg(pid, uid, msg);
268
269         bundle_free(msg);
270         return TTSD_ERROR_NONE;
271 }
272
273 static int __initialize_cb(rpc_port_stub_tts_context_h context, int pid, int uid, int mode, int playing_mode, int registered_event_mask, int *service_state, bool *credential_needed, void *user_data)
274 {
275         unsigned int u_uid = (unsigned int)uid;
276         SECURE_SLOG(LOG_ERROR, tts_tag(), "[IN] tts initialize : pid(%d), uid(%u), mode(%d)", pid, u_uid, mode);
277
278         ttsd_state_e tmp_service_state = TTSD_STATE_INVALID;
279         if (0 != ttsd_server_initialize(pid, u_uid, mode, playing_mode, registered_event_mask, TTS_IPC_METHOD_TIDL, &tmp_service_state, credential_needed)) {
280                 return TTSD_ERROR_OPERATION_FAILED;
281         }
282         ttsd_server_update_instant_reprepare_client();
283
284         *service_state = (int)tmp_service_state;
285         SLOG(LOG_ERROR, tts_tag(), "[OUT] tts initialize service_state(%d), credential_needed(%d)", tmp_service_state, *credential_needed);
286         return TTSD_ERROR_NONE;
287 }
288
289 static int __finalize_cb(rpc_port_stub_tts_context_h context, int uid, void *user_data)
290 {
291         unsigned int u_uid = (unsigned int)uid;
292         SLOG(LOG_ERROR, tts_tag(), ">>>>> TTS FINALIZE. uid(%u)", u_uid);
293
294         int ret = ttsd_server_finalize(u_uid);
295         if (TTSD_ERROR_NONE != ret) {
296                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS FINALIZE (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
297                 return ret;
298         }
299         ttsd_server_update_instant_reprepare_client();
300
301         pthread_mutex_lock(&g_tidl_proxy_infos_mutex);
302         tts_tidl_proxy_info_s* info = __get_tidl_proxy_info_s(u_uid);
303         if (NULL == info) {
304                 SLOG(LOG_ERROR, tts_tag(), "[TIDL ERROR] Fail to set notify callback");
305                 pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
306                 return TTSD_ERROR_INVALID_PARAMETER;
307         }
308
309         rpc_port_stub_tts_notify_cb_destroy(info->notify_cb_h);
310         info->notify_cb_h = NULL;
311
312         g_tidl_proxy_infos = g_list_remove(g_tidl_proxy_infos, info);
313         free(info);
314         pthread_mutex_unlock(&g_tidl_proxy_infos_mutex);
315
316         rpc_port_stub_tts_context_set_tag(context, NULL);
317         SLOG(LOG_ERROR, tts_tag(), "<<<<<");
318         return TTSD_ERROR_NONE;
319 }
320
321 static int __add_text_cb(rpc_port_stub_tts_context_h context, int uid, const char *text, const char *lang,
322                                                         int vctype, int speed, int uttid, const char *credential, void *user_data)
323 {
324         unsigned int u_uid = (unsigned int)uid;
325         SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS ADD TEXT (%u)", u_uid);
326
327         int ret = ttsd_server_add_text(u_uid, text, lang, vctype, speed, uttid, credential);
328         if (TTSD_ERROR_NONE != ret) {
329                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS ADD TEXT (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
330                 return ret;
331         }
332
333         SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
334         return TTSD_ERROR_NONE;
335 }
336
337 static int __stop_cb(rpc_port_stub_tts_context_h context, int uid, void *user_data)
338 {
339         unsigned int u_uid = (unsigned int)uid;
340         SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS STOP (%u)", u_uid);
341
342         int ret = ttsd_server_stop(u_uid);
343         if (TTSD_ERROR_NONE != ret) {
344                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS STOP (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
345                 return ret;
346         }
347
348
349         SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
350
351         return TTSD_ERROR_NONE;
352 }
353
354 static int __pause_cb(rpc_port_stub_tts_context_h context, int uid, void *user_data)
355 {
356         unsigned int u_uid = (unsigned int)uid;
357         SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS PLAYER PAUSE (%u)", u_uid);
358
359         int ret = ttsd_server_pause(u_uid);
360         if (TTSD_ERROR_NONE != ret) {
361                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS PLAYER PAUSE (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
362                 return ret;
363         }
364
365         SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
366
367         return TTSD_ERROR_NONE;
368 }
369
370 static int __play_pcm_cb(rpc_port_stub_tts_context_h context, int uid, void *user_data)
371 {
372         unsigned int u_uid = (unsigned int)uid;
373         SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS PLAY PCM (%u)", u_uid);
374
375         int ret = ttsd_server_play_pcm(u_uid);
376         if (TTSD_ERROR_NONE != ret) {
377                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS PLAY PCM (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
378                 return ret;
379         }
380
381         SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
382
383         return TTSD_ERROR_NONE;
384 }
385
386 static int __stop_pcm_cb(rpc_port_stub_tts_context_h context, int uid, void *user_data)
387 {
388         unsigned int u_uid = (unsigned int)uid;
389         SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS STOP PCM (%u)", u_uid);
390
391         int ret = ttsd_server_stop(u_uid);
392         if (TTSD_ERROR_NONE != ret) {
393                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS STOP PCM (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
394                 return ret;
395         }
396
397         SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
398         return TTSD_ERROR_NONE;
399 }
400
401 static int __set_private_cb(rpc_port_stub_tts_context_h context, int uid, const char *key, const char *data, void *user_data)
402 {
403         unsigned int u_uid = (unsigned int)uid;
404         SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS SET PRIVATE DATA (%u)", u_uid);
405
406         int ret = ttsd_server_set_private_data(u_uid, key, data);
407         if (TTSD_ERROR_NONE != ret) {
408                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS SET PRIVATE DATA (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
409                 return ret;
410         }
411
412         SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
413
414         return TTSD_ERROR_NONE;
415 }
416
417 static int __get_private_cb(rpc_port_stub_tts_context_h context, int uid, const char *key, char **data, void *user_data)
418 {
419         unsigned int u_uid = (unsigned int)uid;
420         SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS GET PRIVATE DATA (%u)", u_uid);
421
422         int ret = ttsd_server_get_private_data(u_uid, key, data);
423         if (TTSD_ERROR_NONE != ret) {
424                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS GET PRIVATE DATA (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
425                 return ret;
426         }
427
428         SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
429         return TTSD_ERROR_NONE;
430 }
431
432 static int __play_cb(rpc_port_stub_tts_context_h context, int uid, const char *credential, void *user_data)
433 {
434         unsigned int u_uid = (unsigned int)uid;
435         SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS PLAY (%u)", u_uid);
436
437         int ret = ttsd_server_play(u_uid, credential);
438         if (TTSD_ERROR_NONE != ret) {
439                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS PLAY (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
440                 return ret;
441         }
442
443         SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
444         return TTSD_ERROR_NONE;
445 }
446
447 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)
448 {
449         unsigned int u_uid = (unsigned int)uid;
450         SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS ADD PCM (%u)", u_uid);
451
452         char* pcm_data_raw = NULL;
453         int pcm_data_size = 0;
454         rpc_port_stub_array_char_get(pcm_data, &pcm_data_raw, &pcm_data_size);
455
456         int ret = ttsd_server_add_pcm(u_uid, event, (void *)pcm_data_raw, data_size, audio_type, rate);
457         free(pcm_data_raw);
458
459         if (TTSD_ERROR_NONE != ret) {
460                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS ADD PCM (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
461                 return ret;
462         }
463
464         SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
465         return TTSD_ERROR_NONE;
466 }
467
468 static int __get_service_state(rpc_port_stub_tts_context_h context, int uid, int* service_state, void *user_data)
469 {
470         unsigned int u_uid = (unsigned int)uid;
471         SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS GET SERVICE STATE (%u)", u_uid);
472
473         int ret = ttsd_server_get_service_state(u_uid, service_state);
474         if (TTSD_ERROR_NONE != ret) {
475                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] TTS GET SERVICE STATE (%u) fail (%d/%s) <<<<<", u_uid, ret, get_error_message(ret));
476                 return ret;
477         }
478
479         SLOG(LOG_DEBUG, tts_tag(), "<<<<<");
480         return TTSD_ERROR_NONE;
481 }
482
483 int ttsd_tidl_open_connection()
484 {
485         SLOG(LOG_DEBUG, tts_tag(), "[TIDL] ttsd_tidl_open_connection");
486
487         g_callback.create = __create_client_cb;
488         g_callback.terminate = __destroy_client_cb;
489         g_callback.register_cb = __register_cb;
490         g_callback.register_cb_sync = __register_cb_sync;
491         g_callback.initialize = __initialize_cb;
492         g_callback.finalize = __finalize_cb;
493         g_callback.add_text = __add_text_cb;
494         g_callback.stop = __stop_cb;
495         g_callback.pause = __pause_cb;
496         g_callback.play_pcm = __play_pcm_cb;
497         g_callback.stop_pcm = __stop_pcm_cb;
498         g_callback.set_private = __set_private_cb;
499         g_callback.get_private = __get_private_cb;
500         g_callback.play = __play_cb;
501         g_callback.add_pcm = __add_pcm_cb;
502         g_callback.get_service_state = __get_service_state;
503
504
505         int ret = -1;
506         int count = 0;
507         while (TTS_RETRY_MIN_COUNT >= count) {
508                 ret = rpc_port_stub_tts_register(&g_callback, NULL);
509                 if (0 == ret) {
510                         SLOG(LOG_DEBUG, tts_tag(), "regitster callback");
511                         return TTSD_ERROR_NONE;
512                 }
513                 usleep(100000);
514                 count++;
515         }
516
517         SLOG(LOG_ERROR, tts_tag(), "Fail to register callback(%d)", ret);
518         return TTSE_ERROR_OPERATION_FAILED;
519 }
520
521 int ttsd_tidl_close_connection()
522 {
523         SLOG(LOG_DEBUG, tts_tag(), "[TIDL] ttsd_tidl_close_connection");
524         rpc_port_stub_tts_unregister();
525
526         return TTSD_ERROR_NONE;
527 }
528
529 static int __send_message(int pid, unsigned int uid, int data, const char *method)
530 {
531         SLOG(LOG_DEBUG, tts_tag(), "[TIDL] ttsdc_tidl_send_message");
532
533         char tmp_msg[10] = {0, };
534
535         bundle* msg = bundle_create();
536         snprintf(tmp_msg, 10, "%d", data);
537         bundle_add_str(msg, TTS_BUNDLE_METHOD, method);
538         bundle_add_str(msg, TTS_BUNDLE_MESSAGE, tmp_msg);
539
540         SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTSD SEND MSG");
541         __send_msg(pid, uid, msg);
542
543         bundle_free(msg);
544         return TTSD_ERROR_NONE;
545 }
546
547 int ttsdc_tidl_send_utt_start_message(int pid, unsigned int uid, int uttid)
548 {
549         return __send_message(pid, uid, uttid, TTSD_METHOD_UTTERANCE_STARTED);
550 }
551
552 int ttsdc_tidl_send_utt_finish_message(int pid, unsigned int uid, int uttid)
553 {
554         return __send_message(pid, uid, uttid, TTSD_METHOD_UTTERANCE_COMPLETED);
555 }
556
557 int ttsdc_tidl_send_set_state_message(int pid, unsigned int uid, int state)
558 {
559         return __send_message(pid, uid, state, TTSD_METHOD_SET_STATE);
560 }
561
562 int ttsdc_tidl_send_set_service_state_message(int pid, unsigned int uid, int before_state, int current_state)
563 {
564         SLOG(LOG_DEBUG, tts_tag(), "[TIDL] ttsdc_tidl_send_set_service_state_message");
565
566         char str_before_state[10] = {0, };
567         char str_current_state[10] = {0, };
568
569         snprintf(str_before_state, 10, "%d", before_state);
570         snprintf(str_current_state, 10, "%d", current_state);
571
572         bundle* msg = bundle_create();
573         bundle_add_str(msg, TTS_BUNDLE_METHOD, TTSD_METHOD_SET_SERVICE_STATE);
574         bundle_add_str(msg, TTS_BUNDLE_BEFORE_STATE, str_before_state);
575         bundle_add_str(msg, TTS_BUNDLE_CURRENT_STATE, str_current_state);
576
577         SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTSD SEND SET SERVICE STATE MESSAGE");
578         __send_msg(pid, uid, msg);
579
580         bundle_free(msg);
581         return TTSD_ERROR_NONE;
582 }
583
584 int ttsdc_tidl_send_error_message(int pid, unsigned int uid, int uttid, int reason, char* err_msg)
585 {
586         SLOG(LOG_DEBUG, tts_tag(), "[TIDL] ttsdc_tidl_send_error_message");
587
588         char tmp_uttid[10] = {0, };
589         char tmp_reason[10] = {0, };
590
591         bundle* msg = bundle_create();
592         snprintf(tmp_uttid, 10, "%d", uttid);
593         bundle_add_str(msg, TTS_BUNDLE_METHOD, TTSD_METHOD_ERROR);
594         bundle_add_str(msg, TTS_BUNDLE_UTTID, tmp_uttid);
595         bundle_add_str(msg, TTS_BUNDLE_REASON, tmp_reason);
596         bundle_add_str(msg, TTS_BUNDLE_ERR_MSG, err_msg);
597
598         SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTSD SEND ERROR MSG");
599         __send_msg(pid, uid, msg);
600
601         bundle_free(msg);
602         return TTSD_ERROR_NONE;
603 }