merge with master
[platform/core/uifw/tts.git] / client / tts.c
1 /*
2 *  Copyright (c) 2012, 2013 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 #include <Ecore.h>
17 #include <sys/stat.h>
18 #include <sys/types.h> 
19 #include <dirent.h>
20
21 #include "tts_main.h"
22 #include "tts_client.h"
23 #include "tts_dbus.h"
24
25 #define MAX_TEXT_COUNT 1000
26
27 static bool g_is_daemon_started = false;
28
29 static bool g_is_noti_daemon_started = false;
30
31 static bool g_is_sr_daemon_started = false;
32
33 static Ecore_Timer* g_connect_timer = NULL;
34
35 /* Function definition */
36 static int __tts_check_tts_daemon(tts_mode_e mode);
37 static Eina_Bool __tts_notify_state_changed(void *data);
38 static Eina_Bool __tts_notify_error(void *data);
39
40 int tts_create(tts_h* tts)
41 {
42         SLOG(LOG_DEBUG, TAG_TTSC, "===== Create TTS");
43         
44         /* check param */
45         if (NULL == tts) {
46                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
47                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
48                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
49                 return TTS_ERROR_INVALID_PARAMETER;
50         }       
51
52         if (0 == tts_client_get_size()) {
53                 if (0 != tts_dbus_open_connection()) {
54                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to open dbus connection");
55                         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
56                         SLOG(LOG_DEBUG, TAG_TTSC, " ");
57                         return TTS_ERROR_OPERATION_FAILED;
58                 }
59         }
60
61         if (0 != tts_client_new(tts)) {
62                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create client!!!!!");
63                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
64                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
65                 return TTS_ERROR_OUT_OF_MEMORY;
66         }
67
68         g_is_daemon_started = false;
69         g_is_noti_daemon_started = false;
70         g_is_sr_daemon_started = false;
71
72         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
73         SLOG(LOG_DEBUG, TAG_TTSC, " ");
74
75         return TTS_ERROR_NONE;
76 }
77
78 int tts_destroy(tts_h tts)
79 {
80         SLOG(LOG_DEBUG, TAG_TTSC, "===== Destroy TTS");
81
82         if (NULL == tts) {
83                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
84                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
85                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
86                 return TTS_ERROR_INVALID_PARAMETER;
87         }
88
89         tts_client_s* client = tts_client_get(tts);
90
91         /* check handle */
92         if (NULL == client) {
93                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
94                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
95                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
96                 return TTS_ERROR_INVALID_PARAMETER;
97         }
98
99         /* check used callback */
100         if (0 != tts_client_get_use_callback(client)) {
101                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Cannot destroy in Callback function");
102                 return TTS_ERROR_OPERATION_FAILED;
103         }
104
105         int ret = -1;
106
107         /* check state */
108         switch (client->current_state) {
109         case TTS_STATE_PAUSED:
110         case TTS_STATE_PLAYING:
111         case TTS_STATE_READY:
112                 /* Request Finalize */
113                 ret = tts_dbus_request_finalize(client->uid);
114                 if (0 != ret) 
115                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request finalize");
116
117                 if (TTS_MODE_SCREEN_READER == client->mode) 
118                         g_is_sr_daemon_started = false;
119                 else if (TTS_MODE_NOTIFICATION == client->mode) 
120                         g_is_noti_daemon_started = false;
121                 else 
122                         g_is_daemon_started = false;
123
124         case TTS_STATE_CREATED:
125                 if (NULL != g_connect_timer) {
126                         SLOG(LOG_DEBUG, TAG_TTSC, "Connect Timer is deleted");
127                         ecore_timer_del(g_connect_timer);
128                 }
129                 /* Free resources */
130                 tts_client_destroy(tts);
131                 break;
132         }
133  
134         if (0 == tts_client_get_size()) {
135                 if (0 != tts_dbus_close_connection()) {
136                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to close connection");
137                 }
138         }
139
140         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
141         SLOG(LOG_DEBUG, TAG_TTSC, " ");
142
143         return TTS_ERROR_NONE;
144 }
145
146 int tts_set_mode(tts_h tts, tts_mode_e mode)
147 {
148         SLOG(LOG_DEBUG, TAG_TTSC, "===== Set TTS mode");
149
150         tts_client_s* client = tts_client_get(tts);
151
152         /* check handle */
153         if (NULL == client) {
154                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
155                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
156                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
157                 return TTS_ERROR_INVALID_PARAMETER;
158         }
159
160         /* check state */
161         if (client->current_state != TTS_STATE_CREATED) {
162                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'CREATED'"); 
163                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
164                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
165                 return TTS_ERROR_INVALID_STATE;
166         }
167
168         if (TTS_MODE_DEFAULT <= mode && mode <= TTS_MODE_SCREEN_READER) {
169                 client->mode = mode;
170         } else {
171                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] mode is not valid : %d", mode);
172                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
173                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
174                 return TTS_ERROR_INVALID_PARAMETER;
175         }
176
177         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
178         SLOG(LOG_DEBUG, TAG_TTSC, " ");
179
180         return TTS_ERROR_NONE;
181 }
182
183 int tts_get_mode(tts_h tts, tts_mode_e* mode)
184 {
185         SLOG(LOG_DEBUG, TAG_TTSC, "===== Get TTS mode");
186
187         tts_client_s* client = tts_client_get(tts);
188
189         /* check handle */
190         if (NULL == client) {
191                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
192                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
193                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
194                 return TTS_ERROR_INVALID_PARAMETER;
195         }
196
197         /* check state */
198         if (client->current_state != TTS_STATE_CREATED) {
199                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'CREATED'"); 
200                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
201                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
202                 return TTS_ERROR_INVALID_STATE;
203         }
204
205         if (NULL == mode) {
206                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter(mode) is NULL");
207                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
208                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
209                 return TTS_ERROR_INVALID_PARAMETER;
210         } 
211
212         *mode = client->mode;
213         
214         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
215         SLOG(LOG_DEBUG, TAG_TTSC, " ");
216
217         return TTS_ERROR_NONE;
218 }
219
220 static Eina_Bool __tts_connect_daemon(void *data)
221 {
222         tts_h tts = (tts_h)data;
223
224         tts_client_s* client = tts_client_get(tts);
225
226         /* check handle */
227         if (NULL == client) {
228                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
229                 return EINA_FALSE;
230         }
231
232         /* Send hello */
233         if (0 != tts_dbus_request_hello(client->uid)) {
234                 if (TTS_MODE_SCREEN_READER == client->mode) {
235                         if (false == g_is_sr_daemon_started) {
236                                 g_is_sr_daemon_started = true;
237                                 __tts_check_tts_daemon(client->mode);
238                         }
239                 } else if (TTS_MODE_NOTIFICATION == client->mode) {
240                         if (false == g_is_noti_daemon_started) {
241                                 g_is_noti_daemon_started = true;
242                                 __tts_check_tts_daemon(client->mode);
243                         }
244                 } else {
245                         if (false == g_is_daemon_started) {
246                                 g_is_daemon_started = true;
247                                 __tts_check_tts_daemon(client->mode);
248                         }
249                 }
250                 
251                 return EINA_TRUE;
252         }
253
254         SLOG(LOG_DEBUG, TAG_TTSC, "===== Connect daemon");
255
256         /* do request initialize */
257         int ret = -1;
258
259         ret = tts_dbus_request_initialize(client->uid);
260
261         if (TTS_ERROR_ENGINE_NOT_FOUND == ret) {
262                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Engine not found");
263                 
264                 client->reason = TTS_ERROR_ENGINE_NOT_FOUND;
265                 client->utt_id = -1;
266
267                 ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
268                 return EINA_FALSE;
269
270         } else if (TTS_ERROR_NONE != ret) {
271                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connection");
272
273                 client->reason = TTS_ERROR_TIMED_OUT;
274                 client->utt_id = -1;
275
276                 ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
277                 return EINA_FALSE;
278         } else {
279                 /* success to connect tts-daemon */
280         }
281
282         client->before_state = client->current_state;
283         client->current_state = TTS_STATE_READY;
284
285         ecore_timer_add(0, __tts_notify_state_changed, (void*)client->tts);
286
287         g_connect_timer = NULL;
288
289         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] uid(%d)", client->uid);
290
291         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
292         SLOG(LOG_DEBUG, TAG_TTSC, " ");
293
294         return EINA_FALSE;
295 }
296
297 int tts_prepare(tts_h tts)
298 {
299         SLOG(LOG_DEBUG, TAG_TTSC, "===== Prepare TTS");
300
301         tts_client_s* client = tts_client_get(tts);
302
303         /* check handle */
304         if (NULL == client) {
305                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
306                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
307                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
308                 return TTS_ERROR_INVALID_PARAMETER;
309         }
310
311         /* check state */
312         if (client->current_state != TTS_STATE_CREATED) {
313                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'CREATED'"); 
314                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
315                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
316                 return TTS_ERROR_INVALID_STATE;
317         }
318
319         g_connect_timer = ecore_timer_add(0, __tts_connect_daemon, (void*)tts);
320
321         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
322         SLOG(LOG_DEBUG, TAG_TTSC, " ");
323
324         return TTS_ERROR_NONE;
325 }
326
327 int tts_unprepare(tts_h tts)
328 {
329         SLOG(LOG_DEBUG, TAG_TTSC, "===== Unprepare TTS");
330
331         tts_client_s* client = tts_client_get(tts);
332
333         /* check handle */
334         if (NULL == client) {
335                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
336                 return TTS_ERROR_INVALID_PARAMETER;
337         }
338
339         /* check state */
340         if (client->current_state != TTS_STATE_READY) {
341                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'READY'"); 
342                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
343                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
344                 return TTS_ERROR_INVALID_STATE;
345         }
346
347         int ret = tts_dbus_request_finalize(client->uid);
348         if (0 != ret) {
349                 SLOG(LOG_WARN, TAG_TTSC, "[ERROR] Fail to request finalize");
350         }
351
352         if (TTS_MODE_SCREEN_READER == client->mode) 
353                 g_is_sr_daemon_started = false;
354         else if (TTS_MODE_NOTIFICATION == client->mode) 
355                 g_is_noti_daemon_started = false;
356         else 
357                 g_is_daemon_started = false;
358
359
360         client->before_state = client->current_state;
361         client->current_state = TTS_STATE_CREATED;
362
363         ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
364
365         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
366         SLOG(LOG_DEBUG, TAG_TTSC, " ");
367
368         return TTS_ERROR_NONE;
369 }
370
371 int tts_foreach_supported_voices(tts_h tts, tts_supported_voice_cb callback, void* user_data)
372 {
373         SLOG(LOG_DEBUG, TAG_TTSC, "===== Foreach supported voices");
374
375         if (NULL == tts || NULL == callback) {
376                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
377                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
378                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
379                 return TTS_ERROR_INVALID_PARAMETER;
380         }
381
382         tts_client_s* client = tts_client_get(tts);
383
384         /* check handle */
385         if (NULL == client) {
386                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
387                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
388                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
389                 return TTS_ERROR_INVALID_PARAMETER;
390         }
391
392         if (TTS_STATE_READY != client->current_state) {
393                 SLOG(LOG_ERROR, TAG_TTSC, "Current state is NOT 'READY'.");  
394                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
395                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
396                 return TTS_ERROR_INVALID_STATE;
397         }
398
399         int ret = 0;
400         ret = tts_dbus_request_get_support_voice(client->uid, client->tts, callback, user_data);
401         if (0 != ret) {
402                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
403         }    
404
405         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
406         SLOG(LOG_DEBUG, TAG_TTSC, " ");
407
408         return ret;
409 }
410
411 int tts_get_default_voice(tts_h tts, char** lang, tts_voice_type_e* vctype)
412 {
413         SLOG(LOG_DEBUG, TAG_TTSC, "===== Get default voice");
414
415         if (NULL == tts) {
416                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
417                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
418                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
419                 return TTS_ERROR_INVALID_PARAMETER;
420
421         }
422         tts_client_s* client = tts_client_get(tts);
423
424         if (NULL == client) {
425                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
426                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
427                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
428                 return TTS_ERROR_INVALID_PARAMETER;
429         }
430
431         if (TTS_STATE_READY != client->current_state) {
432                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is NOT 'READY'. ");
433                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
434                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
435                 return TTS_ERROR_INVALID_STATE;
436         }
437
438         /* Request call remote method */
439         int ret = 0;
440         ret = tts_dbus_request_get_default_voice(client->uid, lang, vctype );
441     
442         if (0 != ret) {
443                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
444         }
445         
446         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
447         SLOG(LOG_DEBUG, TAG_TTSC, " ");
448
449         return ret;
450 }
451
452 int tts_get_max_text_count(tts_h tts, int* count)
453 {
454         if (NULL == tts || NULL == count) {
455                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : Input parameter is null");
456                 return TTS_ERROR_INVALID_PARAMETER;
457         }
458
459         tts_client_s* client = tts_client_get(tts);
460
461         if (NULL == client) {
462                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : A handle is not valid");
463                 return TTS_ERROR_INVALID_PARAMETER;
464         }
465         
466         if (TTS_STATE_READY != client->current_state) {
467                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : Current state is NOT 'READY'."); 
468                 return TTS_ERROR_INVALID_STATE;
469         }
470
471         *count = MAX_TEXT_COUNT;
472
473         SLOG(LOG_DEBUG, TAG_TTSC, "[Suceess] Get max text count");
474         return TTS_ERROR_NONE;
475 }
476
477 int tts_get_state(tts_h tts, tts_state_e* state)
478 {
479         if (NULL == tts || NULL == state) {
480                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : Input parameter is null");
481                 return TTS_ERROR_INVALID_PARAMETER;
482         }
483
484         tts_client_s* client = tts_client_get(tts);
485
486         if (NULL == client) {
487                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : A handle is not valid");
488                 return TTS_ERROR_INVALID_PARAMETER;
489         }
490
491         *state = client->current_state;
492
493         switch(*state) {
494                 case TTS_STATE_CREATED: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Created'");        break;
495                 case TTS_STATE_READY:   SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Ready'");          break;
496                 case TTS_STATE_PLAYING: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Playing'");        break;
497                 case TTS_STATE_PAUSED:  SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Paused'");         break;
498         }
499
500         return TTS_ERROR_NONE;
501 }
502
503 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)
504 {
505         SLOG(LOG_DEBUG, TAG_TTSC, "===== Add text");
506
507         if (NULL == tts || NULL == utt_id) {
508                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
509                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
510                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
511                 return TTS_ERROR_INVALID_PARAMETER;
512         }
513
514         tts_client_s* client = tts_client_get(tts);
515
516         if (NULL == client) {
517                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
518                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
519                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
520                 return TTS_ERROR_INVALID_PARAMETER;
521         }
522
523         if (TTS_STATE_CREATED == client->current_state) {
524                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is 'CREATED'."); 
525                 return TTS_ERROR_INVALID_STATE;
526         }
527
528         if (MAX_TEXT_COUNT < strlen(text)) {
529                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input text size is too big.");
530                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
531                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
532                 return TTS_ERROR_INVALID_PARAMETER;
533         }
534
535         /* change default language value */
536         char* temp = NULL;
537
538         if (NULL == language)
539                 temp = strdup("default");
540         else 
541                 temp = strdup(language);
542
543         client->current_utt_id ++;
544         if (client->current_utt_id == 10000) {
545                 client->current_utt_id = 1;
546         }
547
548         /* do request */
549         int ret = 0;
550         ret = tts_dbus_request_add_text(client->uid, text, temp, voice_type, speed, client->current_utt_id);
551         if (0 != ret) {
552                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
553         } else {
554                 *utt_id = client->current_utt_id;
555         }
556
557         if (NULL != temp)
558                 free(temp);
559
560         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
561         SLOG(LOG_DEBUG, TAG_TTSC, " ");
562
563         return ret;
564 }
565
566 int tts_play(tts_h tts)
567 {
568         SLOG(LOG_DEBUG, TAG_TTSC, "===== Play tts");
569
570         if (NULL == tts) {
571                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null.");
572                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
573                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
574                 return TTS_ERROR_INVALID_PARAMETER;
575         }
576
577         tts_client_s* client = tts_client_get(tts);
578
579         if (NULL == client) {
580                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid.");
581                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
582                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
583                 return TTS_ERROR_INVALID_PARAMETER;
584         }
585
586         if (TTS_STATE_PLAYING == client->current_state || TTS_STATE_CREATED == client->current_state) {
587                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid."); 
588                 return TTS_ERROR_INVALID_STATE;
589         } 
590
591         int ret = 0;
592         ret = tts_dbus_request_play(client->uid);
593         if (0 != ret) {
594                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Request play : result(%d)", ret);
595                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
596                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
597                 return ret;
598         }
599
600         client->before_state = client->current_state;
601         client->current_state = TTS_STATE_PLAYING;
602
603         if (NULL != client->state_changed_cb) {
604                 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
605         } else {
606                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
607         }
608
609         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
610         SLOG(LOG_DEBUG, TAG_TTSC, " ");
611
612         return TTS_ERROR_NONE;
613 }
614
615
616 int tts_stop(tts_h tts)
617 {
618         SLOG(LOG_DEBUG, TAG_TTSC, "===== Stop tts");
619
620         if (NULL == tts) {
621                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
622                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
623                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
624                 return TTS_ERROR_INVALID_PARAMETER;
625         }
626
627         tts_client_s* client = tts_client_get(tts);
628
629         if (NULL == client) {
630                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
631                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
632                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
633                 return TTS_ERROR_INVALID_PARAMETER;
634         }
635
636         if (TTS_STATE_CREATED == client->current_state) {
637                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is 'CREATED'."); 
638                 return TTS_ERROR_INVALID_STATE;
639         }
640
641         int ret = 0;
642         ret = tts_dbus_request_stop(client->uid);
643         if (0 != ret) {
644                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
645                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
646                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
647                 return ret;
648         }       
649
650         client->before_state = client->current_state;
651         client->current_state = TTS_STATE_READY;
652
653         if (NULL != client->state_changed_cb) {
654                 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
655         } else {
656                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
657         }
658
659         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
660         SLOG(LOG_DEBUG, TAG_TTSC, " ");
661
662         return TTS_ERROR_NONE;
663 }
664
665
666 int tts_pause(tts_h tts)
667 {
668         SLOG(LOG_DEBUG, TAG_TTSC, "===== Pause tts");
669
670         if (NULL == tts) {
671                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
672                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
673                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
674                 return TTS_ERROR_INVALID_PARAMETER;
675         }
676
677         tts_client_s* client = tts_client_get(tts);
678
679         if (NULL == client) {
680                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
681                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
682                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
683                 return TTS_ERROR_INVALID_PARAMETER;
684         }
685
686         if (TTS_STATE_PLAYING != client->current_state) {
687                 SLOG(LOG_ERROR, TAG_TTSC, "[Error] The Current state is NOT 'playing'. So this request should be not running.");    
688                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
689                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
690                 return TTS_ERROR_INVALID_STATE;
691         }       
692         
693         int ret = 0;
694         ret = tts_dbus_request_pause(client->uid);
695         if (0 != ret) {
696                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Request pause : result(%d)", ret);
697                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
698                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
699                 return ret;
700         }
701
702         client->before_state = client->current_state;
703         client->current_state = TTS_STATE_PAUSED;
704
705         if (NULL != client->state_changed_cb) {
706                 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
707         } else {
708                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
709         }
710
711         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
712         SLOG(LOG_DEBUG, TAG_TTSC, " ");
713
714         return TTS_ERROR_NONE;
715 }
716
717 static Eina_Bool __tts_notify_error(void *data)
718 {
719         tts_h tts = (tts_h)data;
720
721         tts_client_s* client = tts_client_get(tts);
722
723         /* check handle */
724         if (NULL == client) {
725                 SLOG(LOG_WARN, TAG_TTSC, "Fail to notify error msg : A handle is not valid");
726                 return EINA_FALSE;
727         }
728
729         if (NULL != client->error_cb) {
730                 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of error");
731                 tts_client_use_callback(client);
732                 client->error_cb(client->tts, client->utt_id, client->reason, client->error_user_data );
733                 tts_client_not_use_callback(client);
734         } else {
735                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error ");
736         }
737
738         return EINA_FALSE;
739 }
740
741 int __tts_cb_error(int uid, tts_error_e reason, int utt_id)
742 {
743         tts_client_s* client = tts_client_get_by_uid(uid);
744
745         if (NULL == client) {
746                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
747                 return TTS_ERROR_INVALID_PARAMETER;
748         }
749
750         client->utt_id = utt_id;
751         client->reason = reason;
752
753         /* call callback function */
754         if (NULL != client->error_cb) {
755                 ecore_timer_add(0, __tts_notify_error, client->tts);
756         } else {
757                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error ");
758         }
759         
760         return 0;
761 }
762
763 static Eina_Bool __tts_notify_state_changed(void *data)
764 {
765         tts_h tts = (tts_h)data;
766
767         tts_client_s* client = tts_client_get(tts);
768
769         /* check handle */
770         if (NULL == client) {
771                 SLOG(LOG_WARN, TAG_TTSC, "Fail to notify state changed : A handle is not valid");
772                 return EINA_FALSE;
773         }
774
775         if (NULL != client->state_changed_cb) {
776                 tts_client_use_callback(client);
777                 client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data); 
778                 tts_client_not_use_callback(client);
779                 SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called");
780         } else {
781                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
782         }
783
784         return EINA_FALSE;
785 }
786
787 int __tts_cb_set_state(int uid, int state)
788 {
789         tts_client_s* client = tts_client_get_by_uid(uid);
790         if( NULL == client ) {
791                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] The handle is not valid");
792                 return -1;
793         }
794
795         tts_state_e state_from_daemon = (tts_state_e)state;
796
797         if (client->current_state == state_from_daemon) {
798                 SLOG(LOG_DEBUG, TAG_TTSC, "Current state has already been %d", client->current_state);
799                 return 0;
800         }
801
802         if (NULL != client->state_changed_cb) {
803                 ecore_timer_add(0, __tts_notify_state_changed, client->tts);
804         } else {
805                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
806         }
807
808         client->before_state = client->current_state;
809         client->current_state = state_from_daemon;
810
811         return 0;
812 }
813
814 static Eina_Bool __tts_notify_utt_started(void *data)
815 {
816         tts_h tts = (tts_h)data;
817
818         tts_client_s* client = tts_client_get(tts);
819
820         /* check handle */
821         if (NULL == client) {
822                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to notify utt started : A handle is not valid");
823                 return EINA_FALSE;
824         }
825         
826         if (NULL != client->utt_started_cb) {
827                 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of utterance started ");
828                 tts_client_use_callback(client);
829                 client->utt_started_cb(client->tts, client->utt_id, client->utt_started_user_data);
830                 tts_client_not_use_callback(client);
831         } else {
832                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance started ");
833         }
834
835         return EINA_FALSE;
836 }
837
838 int __tts_cb_utt_started(int uid, int utt_id)
839 {
840         tts_client_s* client = tts_client_get_by_uid(uid);
841
842         if (NULL == client) {
843                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
844                 return TTS_ERROR_INVALID_PARAMETER;
845         }
846
847         SLOG(LOG_DEBUG, TAG_TTSC, "utterance started : utt id(%d) ", utt_id);
848
849         client->utt_id = utt_id;
850
851         /* call callback function */
852         if (NULL != client->utt_started_cb) {
853                 ecore_timer_add(0, __tts_notify_utt_started, client->tts);
854         } else {
855                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance started ");
856         }
857
858         return 0;
859 }
860
861 static Eina_Bool __tts_notify_utt_completed(void *data)
862 {
863         tts_h tts = (tts_h)data;
864
865         tts_client_s* client = tts_client_get(tts);
866
867         /* check handle */
868         if (NULL == client) {
869                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to notify utt completed : A handle is not valid");
870                 return EINA_FALSE;
871         }
872
873         if (NULL != client->utt_completeted_cb) {
874                 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of utterance completed ");
875                 tts_client_use_callback(client);
876                 client->utt_completeted_cb(client->tts, client->utt_id, client->utt_completed_user_data);
877                 tts_client_not_use_callback(client);
878         } else {
879                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance completed ");
880         }
881
882         return EINA_FALSE;
883 }
884
885 int __tts_cb_utt_completed(int uid, int utt_id)
886 {
887         tts_client_s* client = tts_client_get_by_uid(uid);
888
889         if (NULL == client) {
890                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
891                 return TTS_ERROR_INVALID_PARAMETER;
892         }
893
894         SLOG(LOG_DEBUG, TAG_TTSC, "utterance completed : uttid(%d) ", utt_id);
895
896         client->utt_id = utt_id;
897
898         /* call callback function */
899         if (NULL != client->utt_completeted_cb) {
900                 ecore_timer_add(0, __tts_notify_utt_completed, client->tts);
901         } else {
902                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance completed ");
903         }
904
905         return 0;
906 }
907
908 int tts_set_state_changed_cb(tts_h tts, tts_state_changed_cb callback, void* user_data)
909 {
910         if (NULL == tts || NULL == callback) {
911                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : Input parameter is null");
912                 return TTS_ERROR_INVALID_PARAMETER;
913         }
914
915         tts_client_s* client = tts_client_get(tts);
916
917         if (NULL == client) {
918                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : A handle is not valid");
919                 return TTS_ERROR_INVALID_PARAMETER;
920         }
921
922         if (TTS_STATE_CREATED != client->current_state) {
923                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : Current state is not 'Created'."); 
924                 return TTS_ERROR_INVALID_STATE;
925         }
926
927         client->state_changed_cb = callback;
928         client->state_changed_user_data = user_data;
929
930         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set state changed cb");
931
932         return 0;
933 }
934
935 int tts_unset_state_changed_cb(tts_h tts)
936 {
937         if (NULL == tts) {
938                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : Input parameter is null");
939                 return TTS_ERROR_INVALID_PARAMETER;
940         }
941
942         tts_client_s* client = tts_client_get(tts);
943
944         if (NULL == client) {
945                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : A handle is not valid");
946                 return TTS_ERROR_INVALID_PARAMETER;
947         }
948
949         if (TTS_STATE_CREATED != client->current_state) {
950                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : Current state is not 'Created'."); 
951                 return TTS_ERROR_INVALID_STATE;
952         }
953
954         client->state_changed_cb = NULL;
955         client->state_changed_user_data = NULL;
956
957         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset state changed cb");
958
959         return 0;
960 }
961
962 int tts_set_utterance_started_cb(tts_h tts, tts_utterance_started_cb callback, void* user_data)
963 {
964         if (NULL == tts || NULL == callback) {
965                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : Input parameter is null");
966                 return TTS_ERROR_INVALID_PARAMETER;
967         }
968
969         tts_client_s* client = tts_client_get(tts);
970
971         if (NULL == client) {
972                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : A handle is not valid");
973                 return TTS_ERROR_INVALID_PARAMETER;
974         }
975
976         if (TTS_STATE_CREATED != client->current_state) {
977                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : Current state is not 'Created'."); 
978                 return TTS_ERROR_INVALID_STATE;
979         }
980
981         client->utt_started_cb = callback;
982         client->utt_started_user_data = user_data;
983
984         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt started cb");
985         
986         return 0;
987 }
988
989 int tts_unset_utterance_started_cb(tts_h tts)
990 {
991         if (NULL == tts) {
992                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : Input parameter is null");
993                 return TTS_ERROR_INVALID_PARAMETER;
994         }
995
996         tts_client_s* client = tts_client_get(tts);
997
998         if (NULL == client) {
999                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : A handle is not valid");
1000                 return TTS_ERROR_INVALID_PARAMETER;
1001         }
1002
1003         if (TTS_STATE_CREATED != client->current_state) {
1004                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : Current state is not 'Created'."); 
1005                 return TTS_ERROR_INVALID_STATE;
1006         }
1007
1008         client->utt_started_cb = NULL;
1009         client->utt_started_user_data = NULL;
1010
1011         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt started cb");
1012         
1013         return 0;
1014 }
1015
1016 int tts_set_utterance_completed_cb(tts_h tts, tts_utterance_completed_cb callback, void* user_data)
1017 {
1018         if (NULL == tts || NULL == callback) {
1019                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : Input parameter is null");
1020                 return TTS_ERROR_INVALID_PARAMETER;
1021         }
1022
1023         tts_client_s* client = tts_client_get(tts);
1024
1025         if (NULL == client) {
1026                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : A handle is not valid");
1027                 return TTS_ERROR_INVALID_PARAMETER;
1028         }
1029
1030         if (TTS_STATE_CREATED != client->current_state) {
1031                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : Current state is not 'Created'."); 
1032                 return TTS_ERROR_INVALID_STATE;
1033         }
1034
1035         client->utt_completeted_cb = callback;
1036         client->utt_completed_user_data = user_data;
1037
1038         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt completed cb");
1039         
1040         return 0;
1041 }
1042
1043 int tts_unset_utterance_completed_cb(tts_h tts)
1044 {
1045         if (NULL == tts) {
1046                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : Input parameter is null");
1047                 return TTS_ERROR_INVALID_PARAMETER;
1048         }
1049
1050         tts_client_s* client = tts_client_get(tts);
1051
1052         if (NULL == client) {
1053                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : A handle is not valid");
1054                 return TTS_ERROR_INVALID_PARAMETER;
1055         }
1056
1057         if (TTS_STATE_CREATED != client->current_state) {
1058                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : Current state is not 'Created'."); 
1059                 return TTS_ERROR_INVALID_STATE;
1060         }
1061
1062         client->utt_completeted_cb = NULL;
1063         client->utt_completed_user_data = NULL;
1064
1065         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt completed cb");
1066         return 0;
1067 }
1068
1069 int tts_set_error_cb(tts_h tts, tts_error_cb callback, void* user_data)
1070 {
1071         if (NULL == tts || NULL == callback) {
1072                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : Input parameter is null");
1073                 return TTS_ERROR_INVALID_PARAMETER;
1074         }
1075
1076         tts_client_s* client = tts_client_get(tts);
1077
1078         if (NULL == client) {
1079                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : A handle is not valid");
1080                 return TTS_ERROR_INVALID_PARAMETER;
1081         }
1082
1083         if (TTS_STATE_CREATED != client->current_state) {
1084                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : Current state is not 'Created'."); 
1085                 return TTS_ERROR_INVALID_STATE;
1086         }
1087
1088         client->error_cb = callback;
1089         client->error_user_data = user_data;
1090
1091         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set error cb");
1092         
1093         return 0;
1094 }
1095
1096 int tts_unset_error_cb(tts_h tts)
1097 {
1098         if (NULL == tts) {
1099                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : Input parameter is null");
1100                 return TTS_ERROR_INVALID_PARAMETER;
1101         }
1102
1103         tts_client_s* client = tts_client_get(tts);
1104
1105         if (NULL == client) {
1106                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : A handle is not valid");
1107                 return TTS_ERROR_INVALID_PARAMETER;
1108         }
1109         
1110         if (TTS_STATE_CREATED != client->current_state) {
1111                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : Current state is not 'Created'."); 
1112                 return TTS_ERROR_INVALID_STATE;
1113         }
1114
1115         client->error_cb = NULL;
1116         client->error_user_data = NULL;
1117
1118         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset error cb");
1119
1120         return 0;
1121 }
1122
1123 static int __get_cmd_line(char *file, char *buf) 
1124 {
1125         FILE *fp = NULL;
1126
1127         fp = fopen(file, "r");
1128         if (fp == NULL) {
1129                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get command line");
1130                 return -1;
1131         }
1132
1133         memset(buf, 0, 256);
1134         if (NULL == fgets(buf, 256, fp)) {
1135                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to fget command line");
1136                 fclose(fp);
1137                 return -1;
1138         }
1139         fclose(fp);
1140
1141         return 0;
1142 }
1143
1144 static bool __tts_is_alive(char* daemon_path)
1145 {
1146         DIR *dir;
1147         struct dirent *entry;
1148         struct stat filestat;
1149         
1150         int pid;
1151         char cmdLine[256] = {'\0',};
1152         char tempPath[256] = {'\0',};
1153
1154         dir  = opendir("/proc");
1155         if (NULL == dir) {
1156                 SLOG(LOG_ERROR, TAG_TTSC, "process checking is FAILED");
1157                 return FALSE;
1158         }
1159
1160         while ((entry = readdir(dir)) != NULL) {
1161                 if (0 != lstat(entry->d_name, &filestat)) {
1162                         continue;
1163                 }
1164
1165                 if (!S_ISDIR(filestat.st_mode)) {
1166                         continue;
1167                 }
1168
1169                 pid = atoi(entry->d_name);
1170                 if (pid <= 0) continue;
1171
1172                 sprintf(tempPath, "/proc/%d/cmdline", pid);
1173                 if (0 != __get_cmd_line(tempPath, cmdLine)) {
1174                         continue;
1175                 }
1176
1177                 if (0 == strncmp(cmdLine, daemon_path, strlen(daemon_path))) {
1178                         SLOG(LOG_DEBUG, TAG_TTSC, "%s is ALIVE !!", daemon_path);
1179                         closedir(dir);
1180                         return TRUE;
1181                 }
1182         }
1183
1184         SLOG(LOG_DEBUG, TAG_TTSC, "THERE IS NO %s !!", daemon_path);
1185
1186         closedir(dir);
1187         return FALSE;
1188 }
1189
1190 static int __tts_check_tts_daemon(tts_mode_e mode)
1191 {
1192         char daemon_path[64] = {'\0',};
1193         int pid, i;
1194
1195         if (TTS_MODE_DEFAULT == mode) {
1196                 strcpy(daemon_path, "/usr/bin/tts-daemon");
1197         } else if (TTS_MODE_NOTIFICATION == mode) {
1198                 strcpy(daemon_path, "/usr/bin/tts-daemon-noti");
1199         } else if (TTS_MODE_SCREEN_READER == mode) {
1200                 strcpy(daemon_path, "/usr/bin/tts-daemon-sr");
1201         } else {
1202                 SLOG(LOG_ERROR, TAG_TTSC, "mode is not valid");
1203                 return -1;
1204         }
1205
1206         if (TRUE == __tts_is_alive(daemon_path)) {
1207                 return 0;
1208         }
1209         
1210         /* fork-exec daemom */
1211         pid = fork();
1212
1213         switch(pid) {
1214         case -1:
1215                 SLOG(LOG_ERROR, TAG_TTSC, "Fail to create daemon");
1216                 break;
1217
1218         case 0:
1219                 setsid();
1220                 for (i = 0;i < _NSIG;i++)
1221                         signal(i, SIG_DFL);
1222
1223                 execl(daemon_path, daemon_path, NULL);
1224                 break;
1225
1226         default:
1227                 break;
1228         }
1229
1230         return 0;
1231 }