1ff157668b787727fe315270adb342ca0d350164
[platform/core/uifw/tts.git] / client / tts.c
1 /*
2 * Copyright (c) 2011 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
15 #include <sys/wait.h>
16
17 #include "tts_main.h"
18 #include "tts_client.h"
19 #include "tts_dbus.h"
20
21 #define MAX_TEXT_COUNT 1000
22 #define CONNECTION_RETRY_COUNT 3
23
24 /* Function definition */
25 int __tts_check_tts_daemon();
26
27 int tts_create(tts_h* tts)
28 {
29         int ret = 0; 
30
31         SLOG(LOG_DEBUG, TAG_TTSC, "===== Create TTS");
32         
33         /* check param */
34         if (NULL == tts) {
35                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
36                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
37                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
38                 return TTS_ERROR_INVALID_PARAMETER;
39         }       
40
41         /* Check daemon is running */
42         __tts_check_tts_daemon();
43
44         if (0 == tts_client_get_size()) {
45                 if (0 != tts_dbus_open_connection()) {
46                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to open dbus connection\n ");
47                         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
48                         SLOG(LOG_DEBUG, TAG_TTSC, " ");
49                         return TTS_ERROR_OPERATION_FAILED;
50                 }
51         }
52
53         if (0 != tts_client_new(tts)) {
54                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create client!!!!!");
55                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
56                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
57                 return TTS_ERROR_OUT_OF_MEMORY;
58         }
59
60         /* do request initialize */
61         int i = 0;
62         while(1) {
63                 ret = tts_dbus_request_initialize((*tts)->handle);
64
65                 if (TTS_ERROR_ENGINE_NOT_FOUND == ret) {
66                         tts_client_destroy(*tts);
67                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Engine not found");
68                         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
69                         SLOG(LOG_DEBUG, TAG_TTSC, " ");
70                         return ret;
71                 } else if( ret ) {
72                         sleep(1);
73                         if (i == CONNECTION_RETRY_COUNT) {
74                             tts_client_destroy(*tts);
75                             SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Connection Time out");
76                             SLOG(LOG_DEBUG, TAG_TTSC, "=====");
77                             SLOG(LOG_DEBUG, TAG_TTSC, " ");
78                             return TTS_ERROR_TIMED_OUT;                     
79                         }    
80                         i++;
81                 } else {
82                         /* success to connect tts-daemon */
83                         break;
84                 }
85         }
86
87         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] uid(%d)", (*tts)->handle);
88
89         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
90         SLOG(LOG_DEBUG, TAG_TTSC, " ");
91
92         return TTS_ERROR_NONE;
93 }
94
95 int tts_destroy(tts_h tts)
96 {
97         SLOG(LOG_DEBUG, TAG_TTSC, "===== Destroy TTS");
98
99         if (NULL == tts) {
100                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
101                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
102                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
103                 return TTS_ERROR_INVALID_PARAMETER;
104         }
105
106         tts_client_s* client = tts_client_get(tts);
107
108         /* check handle */
109         if (NULL == client) {
110                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
111                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
112                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
113                 return TTS_ERROR_INVALID_PARAMETER;
114         }
115
116         /* Request Finalize */
117         int ret = tts_dbus_request_finalize(client->uid);
118         if (0 != ret) {
119                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request finalize ");
120         }    
121
122         /* Free resources */
123         tts_client_destroy(tts);
124
125         if (0 == tts_client_get_size()) {
126                 if (0 != tts_dbus_close_connection()) {
127                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to close connection\n ");
128                 }
129         }
130
131         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
132         SLOG(LOG_DEBUG, TAG_TTSC, " ");
133
134         return TTS_ERROR_NONE;
135 }
136
137 int tts_foreach_supported_voices(tts_h tts, tts_supported_voice_cb callback, void* user_data)
138 {
139         SLOG(LOG_DEBUG, TAG_TTSC, "===== Foreach supported voices");
140
141         if (NULL == tts || NULL == callback) {
142                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
143                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
144                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
145                 return TTS_ERROR_INVALID_PARAMETER;
146         }
147
148         tts_client_s* client = tts_client_get(tts);
149
150         /* check handle */
151         if (NULL == client) {
152                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
153                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
154                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
155                 return TTS_ERROR_INVALID_PARAMETER;
156         }
157
158         if (TTS_STATE_READY != client->current_state) {
159                 SLOG(LOG_ERROR, TAG_TTSC, "Current state is NOT 'READY'.\n");  
160                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
161                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
162                 return TTS_ERROR_INVALID_STATE;
163         }
164
165         int ret = 0;
166         ret = tts_dbus_request_get_support_voice(client->uid, client->tts, callback, user_data);
167         if (0 != ret) {
168                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
169         }    
170
171         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
172         SLOG(LOG_DEBUG, TAG_TTSC, " ");
173
174         return ret;
175 }
176
177 int tts_get_default_voice(tts_h tts, char** lang, tts_voice_type_e* vctype)
178 {
179         SLOG(LOG_DEBUG, TAG_TTSC, "===== Get default voice");
180
181         if (NULL == tts) {
182                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
183                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
184                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
185                 return TTS_ERROR_INVALID_PARAMETER;
186
187         }
188         tts_client_s* client = tts_client_get(tts);
189
190         if (NULL == client) {
191                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
192                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
193                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
194                 return TTS_ERROR_INVALID_PARAMETER;
195         }
196
197         if (TTS_STATE_READY != client->current_state) {
198                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is NOT 'READY'. ");
199                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
200                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
201                 return TTS_ERROR_INVALID_STATE;
202         }
203
204         /* Request call remote method */
205         int ret = 0;
206         ret = tts_dbus_request_get_default_voice(client->uid, lang, vctype );
207     
208         if (0 != ret) {
209                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
210         }
211         
212         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
213         SLOG(LOG_DEBUG, TAG_TTSC, " ");
214
215         return ret;
216 }
217
218 int tts_get_max_text_count(tts_h tts, int* count)
219 {
220         if (NULL == tts || NULL == count) {
221                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : Input parameter is null");
222                 return TTS_ERROR_INVALID_PARAMETER;
223         }
224
225         tts_client_s* client = tts_client_get(tts);
226
227         if (NULL == client) {
228                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : A handle is not valid");
229                 return TTS_ERROR_INVALID_PARAMETER;
230         }
231         
232         if (TTS_STATE_READY != client->current_state) {
233                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : Current state is NOT 'READY'."); 
234                 return TTS_ERROR_INVALID_STATE;
235         }
236
237         *count = MAX_TEXT_COUNT;
238
239         SLOG(LOG_DEBUG, TAG_TTSC, "[Suceess] Get max text count");
240         return TTS_ERROR_NONE;
241 }
242
243 int tts_get_state(tts_h tts, tts_state_e* state)
244 {
245         if (NULL == tts || NULL == state) {
246                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : Input parameter is null");
247                 return TTS_ERROR_INVALID_PARAMETER;
248         }
249
250         tts_client_s* client = tts_client_get(tts);
251
252         if (NULL == client) {
253                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : A handle is not valid");
254                 return TTS_ERROR_INVALID_PARAMETER;
255         }
256
257         *state = client->current_state;
258
259         switch(*state) {
260                 case TTS_STATE_READY:   SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Ready'");          break;
261                 case TTS_STATE_PLAYING: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Playing'");        break;
262                 case TTS_STATE_PAUSED:  SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Paused'");         break;
263         }
264
265         return TTS_ERROR_NONE;
266 }
267
268 int tts_add_text(tts_h tts, const char* text, const char* language, tts_voice_type_e voice_type, tts_speed_e speed, int* utt_id)
269 {
270         SLOG(LOG_DEBUG, TAG_TTSC, "===== Add text");
271
272         if (NULL == tts || NULL == utt_id) {
273                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
274                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
275                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
276                 return TTS_ERROR_INVALID_PARAMETER;
277         }
278
279         tts_client_s* client = tts_client_get(tts);
280
281         if (NULL == client) {
282                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
283                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
284                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
285                 return TTS_ERROR_INVALID_PARAMETER;
286         }
287
288         /* change default language value */
289         char* temp = NULL;
290
291         if (NULL == language)
292                 temp = strdup("default");
293         else 
294                 temp = strdup(language);
295
296         client->current_utt_id ++;
297         if (client->current_utt_id == 10000) {
298                 client->current_utt_id = 1;
299         }
300
301         /* do request */
302         int ret = 0;
303         ret = tts_dbus_request_add_text(client->uid, text, temp, voice_type, speed, client->current_utt_id);
304         if (0 != ret) {
305                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
306         }
307
308         *utt_id = client->current_utt_id;
309
310         if (NULL != temp)
311                 free(temp);
312
313         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
314         SLOG(LOG_DEBUG, TAG_TTSC, " ");
315
316         return ret;
317 }
318
319 int tts_play(tts_h tts)
320 {
321         SLOG(LOG_DEBUG, TAG_TTSC, "===== Play tts");
322
323         if (NULL == tts) {
324                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
325                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
326                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
327                 return TTS_ERROR_INVALID_PARAMETER;
328         }
329
330         tts_client_s* client = tts_client_get(tts);
331
332         if (NULL == client) {
333                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
334                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
335                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
336                 return TTS_ERROR_INVALID_PARAMETER;
337         }
338
339         if (TTS_STATE_PLAYING == client->current_state) {
340                 SLOG(LOG_ERROR, TAG_TTSC, "Current state is 'playing'. This request should be skipped.\n"); 
341                 return TTS_ERROR_INVALID_STATE;
342         } 
343
344         int ret = 0;
345         ret = tts_dbus_request_play(client->uid);
346         if (0 != ret) {
347                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
348                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
349                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
350                 return ret;
351         }
352
353         /* change state */
354         client->current_state = TTS_STATE_PLAYING;
355
356         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
357         SLOG(LOG_DEBUG, TAG_TTSC, " ");
358
359         return TTS_ERROR_NONE;
360 }
361
362
363 int tts_stop(tts_h tts)
364 {
365         SLOG(LOG_DEBUG, TAG_TTSC, "===== Stop tts");
366
367         if (NULL == tts) {
368                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
369                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
370                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
371                 return TTS_ERROR_INVALID_PARAMETER;
372         }
373
374         tts_client_s* client = tts_client_get(tts);
375
376         if (NULL == client) {
377                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
378                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
379                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
380                 return TTS_ERROR_INVALID_PARAMETER;
381         }
382
383         SLOG(LOG_DEBUG, TAG_TTSC, "change state to ready\n");
384         client->current_state = TTS_STATE_READY;
385
386         int ret = 0;
387         ret = tts_dbus_request_stop(client->uid);
388         if (0 != ret) {
389                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
390                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
391                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
392                 return ret;
393         }       
394
395         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
396         SLOG(LOG_DEBUG, TAG_TTSC, " ");
397
398         return TTS_ERROR_NONE;
399 }
400
401
402 int tts_pause(tts_h tts)
403 {
404         SLOG(LOG_DEBUG, TAG_TTSC, "===== Pause tts");
405
406         if (NULL == tts) {
407                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
408                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
409                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
410                 return TTS_ERROR_INVALID_PARAMETER;
411         }
412
413         tts_client_s* client = tts_client_get(tts);
414
415         if (NULL == client) {
416                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
417                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
418                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
419                 return TTS_ERROR_INVALID_PARAMETER;
420         }
421
422         if (TTS_STATE_PLAYING != client->current_state) {
423                 SLOG(LOG_ERROR, TAG_TTSC, "Error : Current state is NOT 'playing'. So this request should be not running.\n");    
424                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
425                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
426                 return TTS_ERROR_INVALID_STATE;
427         }       
428         
429         int ret = 0;
430         ret = tts_dbus_request_pause(client->uid);
431         if (0 != ret) {
432                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
433                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
434                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
435                 return ret;
436         }
437
438         client->current_state = TTS_STATE_PAUSED;
439
440         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
441         SLOG(LOG_DEBUG, TAG_TTSC, " ");
442
443         return TTS_ERROR_NONE;
444 }
445
446 int __tts_cb_error(int uid, tts_error_e reason, int utt_id)
447 {
448         tts_client_s* client = tts_client_get_by_uid(uid);
449
450         if (NULL == client) {
451                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
452                 return TTS_ERROR_INVALID_PARAMETER;
453         }
454
455         /* call callback function */
456         if (NULL != client->error_cb) {
457                 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of error");
458                 tts_client_use_callback(client);
459                 client->error_cb(client->tts, utt_id, reason, client->error_user_data );
460                 tts_client_not_use_callback(client);
461         } else {
462                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error \n");
463         }
464         
465         return 0;
466 }
467
468 int __tts_cb_interrupt(int uid, tts_interrupted_code_e code)
469 {
470         tts_client_s* client = tts_client_get_by_uid(uid);
471
472         if (NULL == client) {
473                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
474                 return TTS_ERROR_INVALID_PARAMETER;
475         }
476
477         /* change state by interrupt code */
478         if (TTS_INTERRUPTED_PAUSED == code) {
479                 SLOG(LOG_DEBUG, TAG_TTSC, "change state to ready");
480                 client->current_state = TTS_STATE_PAUSED;
481         } else if (TTS_INTERRUPTED_STOPPED == code) {
482                 SLOG(LOG_DEBUG, TAG_TTSC, "change state to ready");
483                 client->current_state = TTS_STATE_READY;
484         } else {
485                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Interrupt code is not available");
486                 return -1;
487         }
488
489         /* call callback function */
490         if (NULL != client->interrupted_cb) {
491                 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of stopped \n");
492                 tts_client_use_callback(client);
493                 client->interrupted_cb(client->tts, code, client->interrupted_user_data);
494                 tts_client_not_use_callback(client);
495         } else {
496                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of stopped \n");
497         }
498
499         return 0;
500 }
501
502 int __tts_cb_utt_started(int uid, int utt_id)
503 {
504         tts_client_s* client = tts_client_get_by_uid(uid);
505
506         if (NULL == client) {
507                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
508                 return TTS_ERROR_INVALID_PARAMETER;
509         }
510
511         SLOG(LOG_DEBUG, TAG_TTSC, "utterance started : uttid(%d) \n", utt_id);
512
513         /* call callback function */
514         if (NULL != client->utt_started_cb) {
515                 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of utterance started \n");
516                 tts_client_use_callback(client);
517                 client->utt_started_cb(client->tts, utt_id, client->utt_started_user_data);
518                 tts_client_not_use_callback(client);
519         } else {
520                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance started \n");
521         }
522
523         return 0;
524 }
525
526 int __tts_cb_utt_completed(int uid, int utt_id)
527 {
528         tts_client_s* client = tts_client_get_by_uid(uid);
529
530         if (NULL == client) {
531                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
532                 return TTS_ERROR_INVALID_PARAMETER;
533         }
534
535         SLOG(LOG_DEBUG, TAG_TTSC, "utterance completed : uttid(%d) \n", utt_id);
536
537         /* call callback function */
538         if (NULL != client->utt_completeted_cb) {
539                 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of utterance completed \n");
540                 tts_client_use_callback(client);
541                 client->utt_completeted_cb(client->tts, utt_id, client->utt_completed_user_data);
542                 tts_client_not_use_callback(client);
543         } else {
544                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance completed \n");
545         }
546
547         return 0;
548 }
549
550 int tts_set_interrupted_cb(tts_h tts, tts_interrupted_cb callback, void* user_data)
551 {
552         if (NULL == tts || NULL == callback) {
553                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set interrupted cb : Input parameter is null");
554                 return TTS_ERROR_INVALID_PARAMETER;
555         }
556
557         tts_client_s* client = tts_client_get(tts);
558
559         if (NULL == client) {
560                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set interrupted cb : A handle is not valid");
561                 return TTS_ERROR_INVALID_PARAMETER;
562         }
563
564         if (TTS_STATE_READY != client->current_state) {
565                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set interrupted cb : Current state is not 'ready'."); 
566                 return TTS_ERROR_INVALID_STATE;
567         }
568
569         client->interrupted_cb = callback;
570         client->interrupted_user_data = user_data;
571
572         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set interrupted cb");
573
574         return 0;
575 }
576
577 int tts_unset_interrupted_cb(tts_h tts)
578 {
579         if (NULL == tts) {
580                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset interrupted cb : Input parameter is null");
581                 return TTS_ERROR_INVALID_PARAMETER;
582         }
583
584         tts_client_s* client = tts_client_get(tts);
585
586         if (NULL == client) {
587                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset interrupted cb : A handle is not valid");
588                 return TTS_ERROR_INVALID_PARAMETER;
589         }
590
591         if (TTS_STATE_READY != client->current_state) {
592                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset interrupted cb : Current state is not 'ready'."); 
593                 return TTS_ERROR_INVALID_STATE;
594         }
595
596         client->interrupted_cb = NULL;
597         client->interrupted_user_data = NULL;
598
599         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset interrupted cb");
600
601         return 0;
602 }
603
604 int tts_set_utterance_started_cb(tts_h tts, tts_utterance_started_cb callback, void* user_data)
605 {
606         if (NULL == tts || NULL == callback) {
607                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
608                 return TTS_ERROR_INVALID_PARAMETER;
609         }
610
611         tts_client_s* client = tts_client_get(tts);
612
613         if (NULL == client) {
614                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
615                 return TTS_ERROR_INVALID_PARAMETER;
616         }
617
618         if (TTS_STATE_READY != client->current_state) {
619                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : Current state is not 'ready'."); 
620                 return TTS_ERROR_INVALID_STATE;
621         }
622
623         client->utt_started_cb = callback;
624         client->utt_started_user_data = user_data;
625
626         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt started cb");
627         
628         return 0;
629 }
630
631 int tts_unset_utterance_started_cb(tts_h tts)
632 {
633         if (NULL == tts) {
634                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : Input parameter is null");
635                 return TTS_ERROR_INVALID_PARAMETER;
636         }
637
638         tts_client_s* client = tts_client_get(tts);
639
640         if (NULL == client) {
641                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : A handle is not valid");
642                 return TTS_ERROR_INVALID_PARAMETER;
643         }
644
645         if (TTS_STATE_READY != client->current_state) {
646                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : Current state is not 'ready'."); 
647                 return TTS_ERROR_INVALID_STATE;
648         }
649
650         client->utt_started_cb = NULL;
651         client->utt_started_user_data = NULL;
652
653         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt started cb");
654         
655         return 0;
656 }
657
658 int tts_set_utterance_completed_cb(tts_h tts, tts_utterance_completed_cb callback, void* user_data)
659 {
660         if (NULL == tts || NULL == callback) {
661                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : Input parameter is null");
662                 return TTS_ERROR_INVALID_PARAMETER;
663         }
664
665         tts_client_s* client = tts_client_get(tts);
666
667         if (NULL == client) {
668                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : A handle is not valid");
669                 return TTS_ERROR_INVALID_PARAMETER;
670         }
671
672         if (TTS_STATE_READY != client->current_state) {
673                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : Current state is not 'ready'."); 
674                 return TTS_ERROR_INVALID_STATE;
675         }
676
677         client->utt_completeted_cb = callback;
678         client->utt_completed_user_data = user_data;
679
680         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt completed cb");
681         
682         return 0;
683 }
684
685 int tts_unset_utterance_completed_cb(tts_h tts)
686 {
687         if (NULL == tts) {
688                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : Input parameter is null");
689                 return TTS_ERROR_INVALID_PARAMETER;
690         }
691
692         tts_client_s* client = tts_client_get(tts);
693
694         if (NULL == client) {
695                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : A handle is not valid");
696                 return TTS_ERROR_INVALID_PARAMETER;
697         }
698
699         if (TTS_STATE_READY != client->current_state) {
700                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : Current state is not 'ready'."); 
701                 return TTS_ERROR_INVALID_STATE;
702         }
703
704         client->utt_completeted_cb = NULL;
705         client->utt_completed_user_data = NULL;
706
707         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt completed cb");
708         return 0;
709 }
710
711 int tts_set_error_cb(tts_h tts, tts_error_cb callback, void* user_data)
712 {
713         if (NULL == tts || NULL == callback) {
714                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : Input parameter is null");
715                 return TTS_ERROR_INVALID_PARAMETER;
716         }
717
718         tts_client_s* client = tts_client_get(tts);
719
720         if (NULL == client) {
721                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : A handle is not valid");
722                 return TTS_ERROR_INVALID_PARAMETER;
723         }
724
725         if (TTS_STATE_READY != client->current_state) {
726                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : Current state is not 'ready'."); 
727                 return TTS_ERROR_INVALID_STATE;
728         }
729
730         client->error_cb = callback;
731         client->error_user_data = user_data;
732
733         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set error cb");
734         
735         return 0;
736 }
737
738 int tts_unset_error_cb(tts_h tts)
739 {
740         if (NULL == tts) {
741                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : Input parameter is null");
742                 return TTS_ERROR_INVALID_PARAMETER;
743         }
744
745         tts_client_s* client = tts_client_get(tts);
746
747         if (NULL == client) {
748                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : A handle is not valid");
749                 return TTS_ERROR_INVALID_PARAMETER;
750         }
751         
752         if (TTS_STATE_READY != client->current_state) {
753                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : Current state is not 'ready'."); 
754                 return TTS_ERROR_INVALID_STATE;
755         }
756
757         client->error_cb = NULL;
758         client->error_user_data = NULL;
759
760         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset error cb");
761
762         return 0;
763 }
764
765 static bool _tts_is_alive()
766 {
767         FILE *fp = NULL;
768         char buff[256];
769         char cmd[256];
770         int i=0;
771
772         memset(buff, 0, sizeof(char));
773         memset(cmd, 0, sizeof(char));
774
775         if ((fp = popen("ps -eo \"cmd\"", "r")) == NULL) {
776                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] popen error \n");
777                 return FALSE;
778         }
779
780         while(fgets(buff, 255, fp)) {
781                 if (0 == i) {
782                         i++;
783                         continue;
784                 }
785
786                 sscanf(buff, "%s", cmd);
787
788                 if (0 == strncmp(cmd, "[tts-daemon]", strlen("[tts-daemon]")) ||
789                         0 == strncmp(cmd, "tts-daemon", strlen("tts-daemon")) ||
790                         0 == strncmp(cmd, "/usr/bin/tts-daemon", strlen("/usr/bin/tts-daemon"))) {
791                         SLOG(LOG_DEBUG, TAG_TTSC, "tts-daemon is ALIVE !! \n");
792                         fclose(fp);
793                         return TRUE;
794                 }
795
796                 i++;
797         }
798         fclose(fp);
799
800         return FALSE;
801 }
802
803
804 static void __my_sig_child(int signo, siginfo_t *info, void *data)
805 {
806         int status;
807         pid_t child_pid, child_pgid;
808
809         child_pgid = getpgid(info->si_pid);
810         SLOG(LOG_DEBUG, TAG_TTSC, "Signal handler: dead pid = %d, pgid = %d\n", info->si_pid, child_pgid);
811
812         while (0 < (child_pid = waitpid(-1, &status, WNOHANG))) {
813                 if(child_pid == child_pgid)
814                         killpg(child_pgid, SIGKILL);
815         }
816
817         return;
818 }
819
820 int __tts_check_tts_daemon()
821 {
822         if (TRUE == _tts_is_alive())
823                 return 0;
824         
825         /* fork-exec tts-daemom */
826         SLOG(LOG_DEBUG, TAG_TTSC, "THERE IS NO tts-daemon \n");
827         SLOG(LOG_DEBUG, TAG_TTSC, "START TTS-DAEMON \n");
828
829         int pid, i;
830         struct sigaction act, dummy;
831
832         act.sa_handler = NULL;
833         act.sa_sigaction = __my_sig_child;
834         sigemptyset(&act.sa_mask);
835         act.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
836         
837         if (sigaction(SIGCHLD, &act, &dummy) < 0) {
838                 SLOG(LOG_ERROR, TAG_TTSC, "Cannot make a signal handler");
839                 return -1;
840         }
841
842         pid = fork();
843
844         switch(pid) {
845         case -1:
846                 SLOG(LOG_ERROR, TAG_TTSC, "fail to create TTS-DAEMON \n");
847                 break;
848
849         case 0:
850                 setsid();
851                 for (i = 0;i < _NSIG;i++)
852                         signal(i, SIG_DFL);
853
854                 execl("/usr/bin/tts-daemon", "/usr/bin/tts-daemon", NULL);
855                 break;
856
857         default:
858                 sleep(1);
859                 break;
860         }
861
862         return 0;
863 }