Add handler for player error
[platform/core/uifw/tts.git] / server / ttsd_server.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 #include <Ecore.h>
15 #include "ttsd_main.h"
16 #include "ttsd_player.h"
17 #include "ttsd_data.h"
18 #include "ttsd_engine_agent.h"
19 #include "ttsd_server.h"
20 #include "ttsd_dbus_server.h"
21 #include "ttsp.h"
22 #include "ttsd_dbus.h"
23 #include "ttsd_config.h"
24 #include "ttsd_network.h"
25
26 typedef enum {
27         TTSD_SYNTHESIS_CONTROL_DOING    = 0,
28         TTSD_SYNTHESIS_CONTROL_DONE     = 1,
29         TTSD_SYNTHESIS_CONTROL_EXPIRED  = 2
30 }ttsd_synthesis_control_e;
31
32 typedef struct {
33         int uid;
34         int uttid;
35 }utterance_t;
36
37 /* If current engine exist */
38 static bool     g_is_engine;
39
40 /* If engine is running */
41 static ttsd_synthesis_control_e g_synth_control;
42
43 static Ecore_Timer* g_wait_timer = NULL;
44
45 /* Function definitions */
46 int __server_next_synthesis(int uid);
47
48
49 int __server_set_synth_control(ttsd_synthesis_control_e control)
50 {
51         g_synth_control = control;
52         return 0;
53 }
54
55 ttsd_synthesis_control_e __server_get_synth_control()
56 {
57         return g_synth_control;
58 }
59
60 int __server_send_error(int uid, int utt_id, int error_code)
61 {
62         int pid = ttsd_data_get_pid(uid);
63
64         /* send error */
65         if ( 0 != ttsdc_send_error_message(pid, uid, utt_id, error_code)) {
66                 ttsd_data_delete_client(uid);                   
67         } 
68         
69         return 0;
70 }
71
72 Eina_Bool __wait_synthesis(void *data)
73 {
74         /* get current play */
75         int uid = ttsd_data_is_current_playing();
76
77         if (uid > 0) {
78                 if (TTSD_SYNTHESIS_CONTROL_DOING == __server_get_synth_control()) {
79                         return EINA_TRUE;
80                 } else {
81                         g_wait_timer = NULL;
82                         if (TTSD_SYNTHESIS_CONTROL_DONE == __server_get_synth_control()) {
83                                 /* Start next synthesis */
84                                 __server_next_synthesis(uid);
85                         }
86                 }       
87         } else {
88                 g_wait_timer = NULL;
89         }
90
91         return EINA_FALSE;
92 }
93
94 int __synthesis(int uid)
95 {
96         speak_data_s sdata;
97         if (0 == ttsd_data_get_speak_data(uid, &sdata)) {
98
99                 utterance_t* utt = (utterance_t*)g_malloc0(sizeof(utterance_t));
100
101                 if (NULL == utt) {
102                         SLOG(LOG_ERROR, get_tag(), "[Server ERROR][%s] fail to allocate memory : utterance ", __FUNCTION__);
103                         return TTSD_ERROR_OUT_OF_MEMORY;
104                 }
105
106                 utt->uid = uid;
107                 utt->uttid = sdata.utt_id;
108
109                 SLOG(LOG_DEBUG, get_tag(), "-----------------------------------------------------------");
110                 SLOG(LOG_DEBUG, get_tag(), "ID : uid (%d), uttid(%d) ", utt->uid, utt->uttid );
111                 SLOG(LOG_DEBUG, get_tag(), "Voice : langauge(%s), type(%d), speed(%d)", sdata.lang, sdata.vctype, sdata.speed);
112                 SLOG(LOG_DEBUG, get_tag(), "Text : %s", sdata.text);
113                 SLOG(LOG_DEBUG, get_tag(), "-----------------------------------------------------------");
114
115                 int ret = 0;
116                 __server_set_synth_control(TTSD_SYNTHESIS_CONTROL_DOING);
117                 ret = ttsd_engine_start_synthesis(sdata.lang, sdata.vctype, sdata.text, sdata.speed, (void*)utt);
118                 if (0 != ret) {
119                         SLOG(LOG_ERROR, get_tag(), "[Server ERROR][%s] * FAIL to start SYNTHESIS !!!! * ", __FUNCTION__);
120
121                         __server_set_synth_control(TTSD_SYNTHESIS_CONTROL_DONE);
122
123                         ttsd_config_save_error(utt->uid, utt->uttid, sdata.lang, sdata.vctype, sdata.text, __FUNCTION__, __LINE__, "fail to start synthesis");
124
125                         g_free(utt);
126
127                         ttsd_server_stop(uid);
128
129                         int pid = ttsd_data_get_pid(uid);
130                         ttsdc_send_set_state_message(pid, uid, APP_STATE_READY);
131                 } else {
132                         g_wait_timer = ecore_timer_add(0, __wait_synthesis, NULL);
133                 }
134
135                 if(sdata.text != NULL)  
136                         g_free(sdata.text);
137         } else {
138                 SLOG(LOG_DEBUG, get_tag(), "[Server] --------------------");
139                 SLOG(LOG_DEBUG, get_tag(), "[Server] Text queue is empty.");
140                 SLOG(LOG_DEBUG, get_tag(), "[Server] --------------------");
141         }
142
143         return 0;
144 }
145
146 int __server_next_synthesis(int uid)
147 {
148         SLOG(LOG_DEBUG, get_tag(), "===== NEXT SYNTHESIS & PLAY START");
149
150         /* get current playing client */
151         int current_uid = ttsd_data_get_current_playing();
152
153         if (0 > current_uid) {
154                 SLOG(LOG_WARN, get_tag(), "[Server WARNING] Current uid is not valid");
155                 SLOG(LOG_DEBUG, get_tag(), "=====");
156                 SLOG(LOG_DEBUG, get_tag(), "  ");
157                 return 0;
158         }
159
160         if (TTSD_SYNTHESIS_CONTROL_DOING == __server_get_synth_control()) {
161                 SLOG(LOG_WARN, get_tag(), "[Server WARNING] Engine has already been running. ");
162                 SLOG(LOG_DEBUG, get_tag(), "=====");
163                 SLOG(LOG_DEBUG, get_tag(), "  ");
164                 return 0;
165         }
166
167         __synthesis(current_uid);
168
169         if (0 != ttsd_player_play(current_uid)) {
170                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to play sound");
171
172                 int pid;
173                 int uid;
174                 int uttid;
175                 int reason;
176                 if (0 == ttsd_data_get_error_data(&uid, &uttid, &reason)) {
177                         if (current_uid == uid) {
178                                 /* Send error message */
179                                 pid = ttsd_data_get_pid(uid);
180                                 ttsdc_send_error_message(pid, uid, uttid, reason);
181                         } else {
182                                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Not matched uid : uid(%d) uttid(%d) reason(%d)", uid, uttid, reason);
183                         }
184                 }
185
186                 /* Change ready state */
187                 ttsd_server_stop(current_uid);
188                 
189                 pid = ttsd_data_get_pid(current_uid);
190                 ttsdc_send_set_state_message(pid, current_uid, APP_STATE_READY);
191         } else {
192                 /* success playing */
193                 SLOG(LOG_DEBUG, get_tag(), "[Server] Success to start player");
194         }
195
196         SLOG(LOG_DEBUG, get_tag(), "===== NEXT SYNTHESIS & PLAY END");
197         SLOG(LOG_DEBUG, get_tag(), "  ");
198
199         return 0;
200 }
201
202 /*
203 * TTS Server Callback Functions 
204 */
205
206 int __player_result_callback(player_event_e event, int uid, int utt_id)
207 {
208         switch(event) {
209         case PLAYER_ERROR:
210                 SLOG(LOG_ERROR, get_tag(), "[SERVER ERROR][%s] player result error", __FUNCTION__);
211                 ttsd_config_save_error(uid, utt_id, NULL, -1, NULL, __FUNCTION__, __LINE__, "PLAYER_ERROR");
212
213         case PLAYER_EMPTY_SOUND_QUEUE:
214                 /* check whether synthesis is running */
215                 if (TTSD_SYNTHESIS_CONTROL_DONE == __server_get_synth_control()) {
216                         /* check text queue is empty */
217                         if (0 == ttsd_data_get_speak_data_size(uid) && 0 == ttsd_data_get_sound_data_size(uid)) {
218                                 SLOG(LOG_DEBUG, get_tag(), "[SERVER Callback] all play completed ");
219                         }
220                 } 
221                 break;
222         
223         case PLAYER_END_OF_PLAYING:
224                 break;
225         }
226
227         return 0;
228 }
229
230 int __synthesis_result_callback(ttsp_result_event_e event, const void* data, unsigned int data_size, void *user_data)
231 {
232         SLOG(LOG_DEBUG, get_tag(), "===== SYNTHESIS RESULT CALLBACK START");
233
234         utterance_t* utt_get_param;
235         utt_get_param = (utterance_t*)user_data;
236
237         if (NULL == utt_get_param) {
238                 SLOG(LOG_ERROR, get_tag(), "[SERVER ERROR] User data is NULL " );
239                 SLOG(LOG_DEBUG, get_tag(), "=====");
240                 SLOG(LOG_DEBUG, get_tag(), "  ");
241                 return -1;
242         }
243
244         int uid = utt_get_param->uid;
245         int uttid = utt_get_param->uttid;
246
247         /* Synthesis is success */
248         if (TTSP_RESULT_EVENT_START == event || TTSP_RESULT_EVENT_CONTINUE == event || TTSP_RESULT_EVENT_FINISH == event) {
249                 
250                 if (TTSP_RESULT_EVENT_START == event)           SLOG(LOG_DEBUG, get_tag(), "[SERVER] Event : TTSP_RESULT_EVENT_START");
251                 if (TTSP_RESULT_EVENT_CONTINUE == event)        SLOG(LOG_DEBUG, get_tag(), "[SERVER] Event : TTSP_RESULT_EVENT_CONTINUE");
252                 if (TTSP_RESULT_EVENT_FINISH == event)          SLOG(LOG_DEBUG, get_tag(), "[SERVER] Event : TTSP_RESULT_EVENT_FINISH");
253
254                 if (false == ttsd_data_is_uttid_valid(uid, uttid)) {
255                         SLOG(LOG_ERROR, get_tag(), "[SERVER ERROR] uttid is NOT valid !!!! - uid(%d), uttid(%d)", uid, uttid);
256                         SLOG(LOG_DEBUG, get_tag(), "=====");
257                         SLOG(LOG_DEBUG, get_tag(), "  ");
258
259                         return 0;
260                 }
261
262                 SLOG(LOG_DEBUG, get_tag(), "[SERVER] Result Info : uid(%d), utt(%d), data(%p), data size(%d) ", 
263                         uid, uttid, data, data_size);
264
265                 /* add wav data */
266                 sound_data_s temp_data;
267                 temp_data.data = (char*)g_malloc0( sizeof(char) * data_size );
268                 memcpy(temp_data.data, data, data_size);
269
270                 temp_data.data_size = data_size;
271                 temp_data.utt_id = utt_get_param->uttid;
272                 temp_data.event = event;
273
274                 ttsp_audio_type_e audio_type;
275                 int rate;
276                 int channels;
277
278                 if (ttsd_engine_get_audio_format(&audio_type, &rate, &channels)) {
279                         SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to get audio format ");
280                         SLOG(LOG_DEBUG, get_tag(), "=====");
281                         SLOG(LOG_DEBUG, get_tag(), "  ");
282                         return -1;
283                 }
284                 
285                 temp_data.audio_type = audio_type;
286                 temp_data.rate = rate;
287                 temp_data.channels = channels;
288                 
289                 if (0 != ttsd_data_add_sound_data(uid, temp_data)) {
290                         SLOG(LOG_ERROR, get_tag(), "[SERVER ERROR] Fail to add sound data : uid(%d)", utt_get_param->uid);
291                 }
292
293                 if (event == TTSP_RESULT_EVENT_FINISH) {
294                         __server_set_synth_control(TTSD_SYNTHESIS_CONTROL_DONE);
295                 }
296         } else if (event == TTSP_RESULT_EVENT_CANCEL) {
297                 SLOG(LOG_DEBUG, get_tag(), "[SERVER] Event : TTSP_RESULT_EVENT_CANCEL");
298                 __server_set_synth_control(TTSD_SYNTHESIS_CONTROL_EXPIRED);
299         } else {
300                 SLOG(LOG_DEBUG, get_tag(), "[SERVER] Event : TTSP_RESULT_EVENT_ERROR");
301                 __server_set_synth_control(TTSD_SYNTHESIS_CONTROL_EXPIRED);
302         } 
303
304         if (TTSP_RESULT_EVENT_FINISH == event || TTSP_RESULT_EVENT_CANCEL == event || TTSP_RESULT_EVENT_FAIL == event) {
305                 if (NULL != utt_get_param)              
306                         free(utt_get_param);
307         }
308
309         SLOG(LOG_DEBUG, get_tag(), "===== SYNTHESIS RESULT CALLBACK END");
310         SLOG(LOG_DEBUG, get_tag(), "  ");
311
312 #if 0
313         if (true == __server_get_is_next_synthesis()) {
314                 __server_set_is_next_synthesis(false);
315
316                 /* Do NOT work ecore timer because of This function is thread callbacked */ 
317                 /* need to send dbus message event */
318                 ttsd_send_start_next_synthesis();
319         }
320 #endif
321
322         return 0;
323 }
324
325 bool __get_client_cb(int pid, int uid, app_state_e state, void* user_data)
326 {
327         /* clear client data */
328         ttsd_data_clear_data(uid);                      
329         ttsd_data_set_client_state(uid, APP_STATE_READY);
330
331         /* send message */
332         if ( 0 != ttsdc_send_set_state_message(pid, uid, APP_STATE_READY)) {
333                 /* remove client */
334                 ttsd_data_delete_client(uid);
335         } 
336
337         return true;
338 }
339
340 void __config_changed_cb(tts_config_type_e type, const char* str_param, int int_param)
341 {
342         switch(type) {
343         case TTS_CONFIG_TYPE_ENGINE:
344         {
345                 if (NULL == str_param) {
346                         SLOG(LOG_ERROR, get_tag(), "[Server] engine id from config is NULL");
347                         return;
348                 }
349
350                 if (true == ttsd_engine_agent_is_same_engine(str_param)) {
351                         SLOG(LOG_DEBUG, get_tag(), "[Server Setting] new engine is the same as current engine ");
352                         return;
353                 }
354
355                 /* stop all player */ 
356                 ttsd_player_all_stop();
357
358                 /* send interrupt message to  all clients */
359                 ttsd_data_foreach_clients(__get_client_cb, NULL);
360
361                 ttsd_engine_cancel_synthesis();
362
363                 /* set engine */
364                 int ret = 0;
365                 ret = ttsd_engine_setting_set_engine(str_param);
366                 if (0 != ret) {
367                         SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] fail to set current engine : result(%d) ", ret);
368                 }
369
370                 break;
371         }
372                 
373         case TTS_CONFIG_TYPE_VOICE:
374         {
375                 if (NULL == str_param) {
376                         SLOG(LOG_ERROR, get_tag(), "[Server] language from config is NULL");
377                         return;
378                 }
379
380                 char* out_lang;
381                 ttsp_voice_type_e out_type;
382                 int ret = -1;
383
384                 if (true == ttsd_engine_select_valid_voice(str_param, int_param, &out_lang, &out_type)) {
385                         SLOG(LOG_ERROR, get_tag(), "[Server] valid language : lang(%s), type(%d)", out_lang, out_type);
386                         ret = ttsd_engine_setting_set_default_voice(out_lang, out_type);
387                         if (0 != ret)
388                                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to set valid language : lang(%s), type(%d)", out_lang, out_type);
389
390                         if (NULL == out_lang)
391                                 free(out_lang);
392                 } else {
393                         /* Current language is not available */
394                         if (true == ttsd_engine_select_valid_voice("en_US", 2, &out_lang, &out_type)) {
395                                 ret = ttsd_engine_setting_set_default_voice(out_lang, out_type);
396                                 if (0 != ret) 
397                                         SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to set valid language : lang(%s), type(%d)", out_lang, out_type);
398
399                                 if (NULL == out_lang)
400                                         free(out_lang);
401                         }
402                 }
403                 break;
404         }
405         
406         case TTS_CONFIG_TYPE_SPEED:
407         {
408                 if (TTSP_SPEED_VERY_SLOW <= int_param && int_param <= TTSP_SPEED_VERY_FAST) {
409                         /* set default speed */
410                         int ret = 0;
411                         ret = ttsd_engine_setting_set_default_speed((ttsp_speed_e)int_param);
412                         if (0 != ret) {
413                                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] fail to set default speed : result(%d)", ret);
414                         }       
415                 }
416                 break;
417         }
418                 
419         default:
420                 break;
421         }
422         
423         return;
424 }
425
426
427 /*
428 * Server APIs
429 */
430
431 int ttsd_initialize()
432 {
433         if (ttsd_config_initialize(__config_changed_cb)) {
434                 SLOG(LOG_ERROR, get_tag(), "[Server WARNING] Fail to initialize config.");
435         }
436
437         /* player init */
438         if (ttsd_player_init(__player_result_callback)) {
439                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to initialize player init.");
440                 return TTSD_ERROR_OPERATION_FAILED;
441         }
442
443         /* Engine Agent initialize */
444         if (0 != ttsd_engine_agent_init(__synthesis_result_callback)) {
445                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to engine agent initialize.");
446                 return TTSD_ERROR_OPERATION_FAILED;
447         }
448
449         /* set current engine */
450         if (0 != ttsd_engine_agent_initialize_current_engine()) {
451                 SLOG(LOG_WARN, get_tag(), "[Server WARNING] No Engine !!!" );
452                 g_is_engine = false;
453         } else 
454                 g_is_engine = true;
455         
456         __server_set_synth_control(TTSD_SYNTHESIS_CONTROL_EXPIRED);
457
458         return TTSD_ERROR_NONE;
459 }
460
461 int ttsd_finalize()
462 {
463         ttsd_config_finalize();
464         
465         ttsd_player_release();
466
467         ttsd_engine_agent_release();
468
469         return TTSD_ERROR_NONE;
470 }
471
472 bool __get_client_for_clean_up(int pid, int uid, app_state_e state, void* user_data)
473 {
474         int result = 1;
475
476         result = ttsdc_send_hello(pid, uid);
477
478         if (0 == result) {
479                 SLOG(LOG_DEBUG, get_tag(), "[Server] uid(%d) should be removed.", uid); 
480                 ttsd_server_finalize(uid);
481         } else if (-1 == result) {
482                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Hello result has error"); 
483         }
484
485         return true;
486 }
487
488
489 Eina_Bool ttsd_cleanup_client(void *data)
490 {
491         SLOG(LOG_DEBUG, get_tag(), "===== CLEAN UP CLIENT START");
492         ttsd_data_foreach_clients(__get_client_for_clean_up, NULL);
493         SLOG(LOG_DEBUG, get_tag(), "=====");
494         SLOG(LOG_DEBUG, get_tag(), "  ");
495
496         return EINA_TRUE;
497 }
498
499 /*
500 * TTS Server Functions for Client
501 */
502
503 int ttsd_server_initialize(int pid, int uid)
504 {
505         if (false == g_is_engine) {
506                 if (0 != ttsd_engine_agent_initialize_current_engine()) {
507                         SLOG(LOG_WARN, get_tag(), "[Server WARNING] No Engine !!! " );
508                         g_is_engine = false;
509
510                         return TTSD_ERROR_ENGINE_NOT_FOUND;
511                 } else {
512                         g_is_engine = true;
513                 }
514         }
515
516         if (-1 != ttsd_data_is_client(uid)) {
517                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Uid has already been registered ");
518                 return TTSD_ERROR_INVALID_PARAMETER;
519         }
520
521         if (0 == ttsd_data_get_client_count()) {
522                 if (0 != ttsd_engine_agent_load_current_engine()) {
523                         SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to load current engine ");
524                         return TTSD_ERROR_OPERATION_FAILED;
525                 }
526                 /* Check system language */
527                 ttsd_config_update_language();
528         }
529
530         if (0 == ttsd_data_get_same_pid_client_count(pid)) {
531                 SLOG(LOG_DEBUG, get_tag(), "[Server] open file msg connection");
532                 if (0 != ttsd_file_msg_open_connection(pid)) {
533                         SLOG(LOG_ERROR, get_tag(), "[Server ERROR] fail to open file message connection");
534                         return TTSD_ERROR_OPERATION_FAILED;
535                 }
536         }
537
538         if (0 != ttsd_data_new_client(pid, uid)) {
539                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to add client info ");
540                 return TTSD_ERROR_OPERATION_FAILED;
541         }
542
543         if (0 != ttsd_player_create_instance(uid)) {
544                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to create player ");
545                 return TTSD_ERROR_OPERATION_FAILED;
546         }
547
548         return TTSD_ERROR_NONE;
549 }
550
551 static Eina_Bool __quit_ecore_loop(void *data)
552 {
553         ecore_main_loop_quit();
554         SLOG(LOG_DEBUG, get_tag(), "[Server] quit ecore main loop");
555         return EINA_FALSE;
556 }
557
558 int ttsd_server_finalize(int uid)
559 {
560         app_state_e state;
561         if (0 > ttsd_data_get_client_state(uid, &state)) {
562                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] ttsd_server_finalize : uid is not valid  ");
563                 return TTSD_ERROR_INVALID_PARAMETER;
564         }
565
566         ttsd_server_stop(uid);
567         
568         ttsd_player_destroy_instance(uid);
569
570         int pid = ttsd_data_get_pid(uid);
571
572         ttsd_data_delete_client(uid);
573
574         if (0 == ttsd_data_get_same_pid_client_count(pid)) {
575                 SLOG(LOG_DEBUG, get_tag(), "[Sever] File msg close connection");
576                 ttsd_file_msg_close_connection(pid);
577         }
578
579         /* unload engine, if ref count of client is 0 */
580         if (0 == ttsd_data_get_client_count()) {
581                 ecore_timer_add(0, __quit_ecore_loop, NULL);
582         }
583
584         return TTSD_ERROR_NONE;
585 }
586
587 int ttsd_server_add_queue(int uid, const char* text, const char* lang, int voice_type, int speed, int utt_id)
588 {
589         app_state_e state;
590         if (0 > ttsd_data_get_client_state(uid, &state)) {
591                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] ttsd_server_add_queue : uid is not valid  ");
592                 return TTSD_ERROR_INVALID_PARAMETER;
593         }
594
595         /* check valid voice */
596         char* temp_lang = NULL;
597         ttsp_voice_type_e temp_type;
598         if (true != ttsd_engine_select_valid_voice((const char*)lang, (const ttsp_voice_type_e)voice_type, &temp_lang, &temp_type)) {
599                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to select valid voice ");
600                 return TTSD_ERROR_INVALID_VOICE;
601         } else {                
602                 if (NULL == temp_lang)
603                         free(temp_lang);
604         }
605         
606         speak_data_s data;
607
608         data.lang = strdup(lang);
609         data.vctype = (ttsp_voice_type_e)voice_type;
610
611         data.speed = (ttsp_speed_e)speed;
612         data.utt_id = utt_id;
613                 
614         data.text = strdup(text);
615
616         /* if state is APP_STATE_READY , APP_STATE_PAUSED , only need to add speak data to queue*/
617         if (0 != ttsd_data_add_speak_data(uid, data)) {
618                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] ttsd_server_add_queue : Current state of uid is not 'ready' ");
619                 return TTSD_ERROR_OPERATION_FAILED;
620         }
621
622         if (APP_STATE_PLAYING == state) {
623                 /* check if engine use network */
624                 if (ttsd_engine_agent_need_network()) {
625                         if (false == ttsd_network_is_connected()) {
626                                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Disconnect network. Current engine needs network.");
627                                 return TTSD_ERROR_OPERATION_FAILED;
628                         }
629                 }
630
631                 /* Check whether tts-engine is running or not */
632                 if (TTSD_SYNTHESIS_CONTROL_DOING == __server_get_synth_control()) {
633                         SLOG(LOG_WARN, get_tag(), "[Server WARNING] Engine has already been running.");
634                 } else {
635                         __synthesis(uid);
636                 }
637         }
638
639         return TTSD_ERROR_NONE;
640 }
641
642 Eina_Bool __send_interrupt_client(void *data)
643 {
644         int* uid = (int*)data;
645         
646         if (NULL != uid) {
647                 int pid = ttsd_data_get_pid(*uid);
648
649                 if (TTSD_MODE_SCREEN_READER == ttsd_get_mode()) {
650                         /* send message to client about changing state */
651                         ttsdc_send_set_state_message (pid, *uid, APP_STATE_READY);
652                 } else {
653                         ttsdc_send_set_state_message (pid, *uid, APP_STATE_PAUSED);
654                 }
655                 free(uid);
656         }       
657         return EINA_FALSE;
658 }
659
660 int ttsd_server_play(int uid)
661 {
662         app_state_e state;
663         if (0 > ttsd_data_get_client_state(uid, &state)) {
664                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] uid(%d) is NOT valid  ", uid);
665                 return TTSD_ERROR_INVALID_PARAMETER;
666         }
667         
668         if (APP_STATE_PLAYING == state) {
669                 SLOG(LOG_WARN, get_tag(), "[Server WARNING] Current state(%d) is 'play' ", uid);
670                 return TTSD_ERROR_NONE;
671         }
672
673         /* check if engine use network */
674         if (ttsd_engine_agent_need_network()) {
675                 if (false == ttsd_network_is_connected()) {
676                         SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Disconnect network. Current engine needs network service!!!.");
677                         return TTSD_ERROR_OUT_OF_NETWORK;
678                 }
679         }
680
681         int current_uid = ttsd_data_get_current_playing();
682
683         if (uid != current_uid && -1 != current_uid) {
684                 if (TTSD_MODE_SCREEN_READER == ttsd_get_mode()) {
685                         /* Send interrupt message */
686                         SLOG(LOG_DEBUG, get_tag(), "[Server] Old uid(%d) will be interrupted into 'Stop' state ", current_uid);
687
688                         /* pause player */
689                         if (0 != ttsd_server_stop(current_uid)) {
690                                 SLOG(LOG_WARN, get_tag(), "[Server ERROR] fail to stop : uid (%d)", current_uid);
691                         } 
692                         
693                         int* temp_uid = (int*)malloc(sizeof(int));
694                         *temp_uid = current_uid;
695                         ecore_timer_add(0, __send_interrupt_client, temp_uid);
696                 } else {
697                         /* Send interrupt message */
698                         SLOG(LOG_DEBUG, get_tag(), "[Server] Old uid(%d) will be interrupted into 'Pause' state ", current_uid);
699
700                         /* pause player */
701                         if (0 != ttsd_player_pause(current_uid)) {
702                                 SLOG(LOG_WARN, get_tag(), "[Server ERROR] fail to ttsd_player_pause() : uid (%d)", current_uid);
703                         } 
704
705                         /* change state */
706                         ttsd_data_set_client_state(current_uid, APP_STATE_PAUSED);
707
708                         int* temp_uid = (int*)malloc(sizeof(int));
709                         *temp_uid = current_uid;
710                         ecore_timer_add(0, __send_interrupt_client, temp_uid);
711                 }
712         }
713         
714         /* Change current play */
715         if (0 != ttsd_data_set_client_state(uid, APP_STATE_PLAYING)) {
716                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to set state : uid(%d)", uid);
717                 return TTSD_ERROR_OPERATION_FAILED;
718         }
719
720         if (APP_STATE_PAUSED == state) {
721                 SLOG(LOG_DEBUG, get_tag(), "[Server] uid(%d) is 'Pause' state : Next step is resume player and start synthesis ", uid);
722
723                 ttsd_player_state_e state;
724                 if (0 != ttsd_player_get_state(uid, &state)) {
725                         SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to get player state : uid(%d)", uid);
726                         return TTSD_ERROR_OPERATION_FAILED;
727                 }
728
729                 if (TTSD_PLAYER_STATE_PAUSED == state) {
730                         /* Resume player */
731                         if (0 != ttsd_player_resume(uid)) {
732                                 SLOG(LOG_WARN, get_tag(), "[Server WARNING] fail to ttsd_player_resume()");
733                         }
734                 } else if (TTSD_PLAYER_STATE_NULL == state) {
735                         if (0 != ttsd_player_play(uid)) {
736                                 SLOG(LOG_WARN, get_tag(), "[Server WARNING] Fail ttsd_player_play() ");
737                                 
738                                 /* Need to wait synthesis */
739                                 if (NULL == g_wait_timer)
740                                         g_wait_timer = ecore_timer_add(0, __wait_synthesis, NULL);
741                         } else {
742                                 /* success playing */
743                                 SLOG(LOG_DEBUG, get_tag(), "[Server] Success to start player");
744                         }       
745                 } else {
746                         /* error */
747                 }
748         }
749
750         /* Check whether tts-engine is running or not */
751         if (TTSD_SYNTHESIS_CONTROL_DOING == __server_get_synth_control()) {
752                 SLOG(LOG_WARN, get_tag(), "[Server WARNING] Engine has already been running.");
753         } else {
754                 __synthesis(uid);
755         }
756
757         return TTSD_ERROR_NONE;
758 }
759
760
761 int ttsd_server_stop(int uid)
762 {
763         app_state_e state;
764         if (0 > ttsd_data_get_client_state(uid, &state)) {
765                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] uid is not valid  ");
766                 return TTSD_ERROR_INVALID_PARAMETER;
767         }
768
769         /* Reset all data */
770         ttsd_data_clear_data(uid);
771
772         if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
773                 ttsd_data_set_client_state(uid, APP_STATE_READY);
774
775                 if (0 != ttsd_player_stop(uid)) 
776                         SLOG(LOG_WARN, get_tag(), "[Server] Fail to ttsd_player_stop()");
777
778                 if (TTSD_SYNTHESIS_CONTROL_DOING == __server_get_synth_control()) {
779                         SLOG(LOG_DEBUG, get_tag(), "[Server] TTS-engine is running ");
780
781                         int ret = 0;
782                         ret = ttsd_engine_cancel_synthesis();
783                         if (0 != ret)
784                                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to cancel synthesis : ret(%d)", ret);
785                 }
786
787                 __server_set_synth_control(TTSD_SYNTHESIS_CONTROL_EXPIRED);
788         } else {
789                 SLOG(LOG_WARN, get_tag(), "[Server WARNING] Current state is 'ready' ");
790         }
791
792         return TTSD_ERROR_NONE;
793 }
794
795 int ttsd_server_pause(int uid, int* utt_id)
796 {
797         app_state_e state;
798         if (0 > ttsd_data_get_client_state(uid, &state)) {
799                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] ttsd_server_pause : uid is not valid  ");
800                 return TTSD_ERROR_INVALID_PARAMETER;
801         }
802
803         if (APP_STATE_PLAYING != state) {
804                 SLOG(LOG_WARN, get_tag(), "[Server WARNING] Current state is not 'play' ");
805                 return TTSD_ERROR_INVALID_STATE;
806         }
807
808         int ret = 0;
809         ret = ttsd_player_pause(uid);
810         if (0 != ret) {
811                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] fail player_pause() : ret(%d)", ret);
812                 return TTSD_ERROR_OPERATION_FAILED;
813         }
814
815         ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
816
817         return TTSD_ERROR_NONE;
818 }
819
820 int ttsd_server_get_support_voices(int uid, GList** voice_list)
821 {
822         app_state_e state;
823         if (0 > ttsd_data_get_client_state(uid, &state)) {
824                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] uid is not valid  ");
825                 return TTSD_ERROR_INVALID_PARAMETER;
826         }
827
828         /* get voice list*/
829         if (0 != ttsd_engine_get_voice_list(voice_list)) {
830                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail ttsd_server_get_support_voices() ");
831                 return TTSD_ERROR_OPERATION_FAILED;
832         }
833
834         SLOG(LOG_DEBUG, get_tag(), "[Server SUCCESS] Get supported voices ");
835
836         return TTSD_ERROR_NONE;
837 }
838
839 int ttsd_server_get_current_voice(int uid, char** language, int* voice_type)
840 {
841         app_state_e state;
842         if (0 > ttsd_data_get_client_state(uid, &state)) {
843                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] ttsd_server_get_current_voice : uid is not valid  ");
844                 return TTSD_ERROR_INVALID_PARAMETER;
845         }               
846
847         /* get current voice */
848         int ret = ttsd_engine_get_default_voice(language, (ttsp_voice_type_e*)voice_type);
849         if (0 != ret) {
850                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] fail ttsd_server_get_support_voices() ");
851                 return ret;
852         }
853
854         SLOG(LOG_DEBUG, get_tag(), "[Server] Get default language (%s), voice type(%d) ", *language, *voice_type); 
855
856         return TTSD_ERROR_NONE;
857 }
858
859 #if 0
860 /*
861 * Server API for Internal event
862 */
863 int ttsd_server_start_next_synthesis()
864 {
865         /* get current play */
866         int uid = ttsd_data_is_current_playing();
867
868         if (uid < 0) {
869                 return 0;
870         }
871
872         return __server_next_synthesis(uid);
873 }
874 #endif
875
876 /*
877 * TTS Server Functions for Setting                                                                                                                *
878 */
879
880 int ttsd_server_setting_initialize(int uid)
881 {
882         if (false == g_is_engine) {
883                 if (0 != ttsd_engine_agent_initialize_current_engine()) {
884                         SLOG(LOG_WARN, get_tag(), "[Server Setting WARNING] No Engine !!! " );
885                         g_is_engine = false;
886                         return TTSD_ERROR_ENGINE_NOT_FOUND;
887                 } else {
888                         g_is_engine = true;
889                 }
890         }
891
892         if (-1 != ttsd_setting_data_is_setting(uid)) {
893                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] pid has already been registered ");
894                 return TTSD_ERROR_INVALID_PARAMETER;
895         }
896
897         if (0 == ttsd_data_get_client_count()) {
898                 if( 0 != ttsd_engine_agent_load_current_engine() ) {
899                         SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] Fail to load current engine ");
900                         return TTSD_ERROR_OPERATION_FAILED;
901                 }
902         }
903
904         /* register pid */
905         if (0 != ttsd_setting_data_add(uid)) {
906                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] Fail to add client info ");
907                 return TTSD_ERROR_OPERATION_FAILED;
908         }
909
910         return TTSD_ERROR_NONE;
911 }
912
913 int ttsd_server_setting_finalize(int uid)
914 {
915         if (-1 == ttsd_setting_data_is_setting(uid)) {
916                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] uid is not valid  (%s)", uid);
917                 return TTSD_ERROR_INVALID_PARAMETER;
918         }
919
920         ttsd_setting_data_delete(uid);
921
922         /* unload engine, if ref count of client is 0 */
923         if (0 == ttsd_data_get_client_count()) {
924                 ecore_timer_add(0, __quit_ecore_loop, NULL);
925         }
926
927         return TTSD_ERROR_NONE;
928 }
929
930 int ttsd_server_setting_get_engine_list(int uid, GList** engine_list)
931 {
932         if (-1 == ttsd_setting_data_is_setting(uid)) {
933                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] uid is not valid  (%s)", uid);
934                 return TTSD_ERROR_INVALID_PARAMETER;
935         }
936
937         int ret = 0;
938         ret = ttsd_engine_setting_get_engine_list(engine_list);
939         if (0 != ret) {
940                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] fail to get engine list : result(%d)", ret);
941                 return ret;
942         }
943
944         return TTSD_ERROR_NONE;
945 }
946
947 int ttsd_server_setting_get_current_engine(int uid, char** engine_id)
948 {
949         if (-1 == ttsd_setting_data_is_setting(uid)) {
950                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] uid is not valid  (%s)", uid);
951                 return TTSD_ERROR_INVALID_PARAMETER;
952         }
953
954         int ret = 0;
955         ret = ttsd_engine_setting_get_engine(engine_id);
956         if (0 != ret) {
957                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] Fail to get current engine : result(%d) ", ret);
958                 return ret;
959         }
960
961         return TTSD_ERROR_NONE;
962 }
963
964 int ttsd_server_setting_set_current_engine(int uid, const char* engine_id)
965 {
966         /* check if uid is valid */
967         if (-1 == ttsd_setting_data_is_setting(uid)) {
968                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] uid is not valid  (%s)", uid);
969                 return TTSD_ERROR_INVALID_PARAMETER;
970         }
971
972         if (true == ttsd_engine_agent_is_same_engine(engine_id)) {
973                 SLOG(LOG_DEBUG, get_tag(), "[Server Setting] new engine is the same as current engine ");
974                 return TTSD_ERROR_NONE;
975         }
976
977         /* stop all player */ 
978         ttsd_player_all_stop();
979
980         /* send interrupt message to  all clients */
981         ttsd_data_foreach_clients(__get_client_cb, NULL);
982
983         ttsd_engine_cancel_synthesis();
984
985         /* set engine */
986         int ret = 0;
987         ret = ttsd_engine_setting_set_engine(engine_id);
988         if (0 != ret) {
989                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] fail to set current engine : result(%d) ", ret);
990                 return ret;
991         }
992
993         return TTSD_ERROR_NONE;
994 }
995
996 int ttsd_server_setting_get_voice_list(int uid, char** engine_id, GList** voice_list)
997 {
998         /* check if uid is valid */
999         if (-1 == ttsd_setting_data_is_setting(uid)) {
1000                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] uid is not valid  (%s)", uid);
1001                 return TTSD_ERROR_INVALID_PARAMETER;
1002         }
1003
1004         /* get language list from engine */
1005         int ret = 0;
1006         ret = ttsd_engine_setting_get_voice_list(engine_id, voice_list);
1007         if (0 != ret) {
1008                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] Fail to get voice list : result(%d)", ret);
1009                 return ret;
1010         }
1011
1012         return TTSD_ERROR_NONE;
1013 }
1014
1015 int ttsd_server_setting_get_default_voice(int uid, char** language, ttsp_voice_type_e* vctype)
1016 {
1017         /* check if uid is valid */
1018         if (-1 == ttsd_setting_data_is_setting(uid)) {
1019                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] uid is not valid  (%s)", uid);
1020                 return TTSD_ERROR_INVALID_PARAMETER;
1021         }
1022         
1023         int ret = 0;
1024         ret = ttsd_engine_setting_get_default_voice(language, vctype);
1025         if (0 != ret) {
1026                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] Fail to get default voice : result(%d) ", ret);
1027                 return ret;
1028         }
1029
1030         return TTSD_ERROR_NONE;
1031 }
1032
1033 int ttsd_server_setting_set_default_voice(int uid, const char* language, int vctype)
1034 {
1035         /* check if uid is valid */
1036         if (-1 == ttsd_setting_data_is_setting(uid)) {
1037                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] uid is not valid  (%s)", uid);
1038                 return TTSD_ERROR_INVALID_PARAMETER;
1039         }
1040
1041         /* set current language */
1042         int ret = 0;
1043         ret = ttsd_engine_setting_set_default_voice((const char*)language, (const ttsp_voice_type_e)vctype);
1044         if (0 != ret) {
1045                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] fail to set default voice : result(%d) ", ret);
1046                 return ret;
1047         }       
1048
1049         return TTSD_ERROR_NONE;
1050 }
1051
1052 int ttsd_server_setting_get_engine_setting(int uid, char** engine_id, GList** engine_setting_list)
1053 {
1054         /* check if uid is valid */
1055         if (-1 == ttsd_setting_data_is_setting(uid)) {
1056                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] uid is not valid  (%s)", uid);
1057                 return TTSD_ERROR_INVALID_PARAMETER;
1058         }
1059
1060         int ret = 0;
1061         ret = ttsd_engine_setting_get_engine_setting_info(engine_id, engine_setting_list);
1062         if (0 != ret) {
1063                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] fail to get engine setting info : result(%d)", ret);
1064                 return ret;
1065         }
1066
1067         return TTSD_ERROR_NONE;
1068 }
1069
1070 int ttsd_server_setting_set_engine_setting(int uid, const char* key, const char* value)
1071 {
1072         /* check if uid is valid */
1073         if (-1 == ttsd_setting_data_is_setting(uid)) {
1074                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] uid is not valid  (%s)", uid);
1075                 return TTSD_ERROR_INVALID_PARAMETER;
1076         }
1077
1078         int ret = 0;
1079         ret = ttsd_engine_setting_set_engine_setting(key, value);
1080         if (0 != ret) {
1081                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] fail to set engine setting info : result(%d)", ret);
1082                 return ret;
1083         }
1084
1085         return TTSD_ERROR_NONE;
1086 }
1087
1088 int ttsd_server_setting_get_default_speed(int uid, int* default_speed)
1089 {
1090         /* check if uid is valid */
1091         if (-1 == ttsd_setting_data_is_setting(uid)) {
1092                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] uid is not valid  (%s)", uid);
1093                 return TTSD_ERROR_INVALID_PARAMETER;
1094         }
1095
1096         /* get current speed */
1097         int ret = 0;
1098         ret = ttsd_engine_setting_get_default_speed((ttsp_speed_e*)default_speed);
1099         if (0 != ret) {
1100                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] fail to get default speed : result(%d)", ret);
1101                 return ret;
1102         }       
1103
1104         return TTSD_ERROR_NONE;
1105 }
1106
1107 int ttsd_server_setting_set_default_speed(int uid, int default_speed)
1108 {
1109         /* check if uid is valid */
1110         if (-1 == ttsd_setting_data_is_setting(uid)) {
1111                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] uid is not valid  (%s)", uid);
1112                 return TTSD_ERROR_INVALID_PARAMETER;
1113         }
1114
1115         /* set default speed */
1116         int ret = 0;
1117         ret = ttsd_engine_setting_set_default_speed((ttsp_speed_e)default_speed);
1118         if (0 != ret) {
1119                 SLOG(LOG_ERROR, get_tag(), "[Server Setting ERROR] fail to set default speed : result(%d)", ret);
1120                 return ret;
1121         }       
1122
1123         return TTSD_ERROR_NONE;
1124 }