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