7a7d2b4d5f182ce6f7c4acee657a8499f8281a30
[platform/core/uifw/stt.git] / server / sttd_server.c
1 /*
2 *  Copyright (c) 2011-2016 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 <pthread.h>
15 #include <sound_manager.h>
16 #include <wav_player.h>
17
18 #include "stt_network.h"
19 #include "sttd_client_data.h"
20 #include "sttd_config.h"
21 #include "sttd_dbus.h"
22 #include "sttd_engine_agent.h"
23 #include "sttd_main.h"
24 #include "sttd_recorder.h"
25 #include "sttd_server.h"
26
27 static pthread_mutex_t sttpe_result_mutex = PTHREAD_MUTEX_INITIALIZER;
28 static pthread_mutex_t sttpe_result_time_mutex = PTHREAD_MUTEX_INITIALIZER;
29
30
31 /*
32 * STT Server static variable
33 */
34 static double g_processing_timeout = 30;
35
36 static double g_recording_timeout = 60;
37
38 Ecore_Timer*    g_recording_timer = NULL;
39 Ecore_Timer*    g_processing_timer = NULL;
40
41 static int g_recording_log_count = 0;
42
43 static GList *g_proc_list = NULL;
44
45 /*
46 * STT Server Callback Functions
47 */
48 void __stop_by_silence(void *data)
49 {
50         SLOG(LOG_DEBUG, TAG_STTD, "===== Stop by silence detection");
51
52         int uid = 0;
53
54         uid = stt_client_get_current_recognition();
55
56         int ret;
57         if (0 != uid) {
58                 ret = sttd_server_stop(uid);
59                 if (0 > ret) {
60                         return;
61                 }
62
63                 if (STTD_RESULT_STATE_DONE == ret) {
64                         ret = sttdc_send_set_state(uid, (int)APP_STATE_PROCESSING);
65                         if (0 != ret) {
66                                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send state : result(%d)", ret);
67
68                                 /* Remove client */
69                                 sttd_server_finalize(uid);
70                                 stt_client_unset_current_recognition();
71                         }
72                 }
73         } else {
74                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid is NOT valid");
75         }
76
77         SLOG(LOG_DEBUG, TAG_STTD, "=====");
78         SLOG(LOG_DEBUG, TAG_STTD, "  ");
79
80         return;
81 }
82
83 static void __cancel_recognition_internal()
84 {
85         if (NULL != g_recording_timer)  {
86                 ecore_timer_del(g_recording_timer);
87                 g_recording_timer = NULL;
88         }
89
90         int uid = 0;
91         uid = stt_client_get_current_recognition();
92
93         if (0 != uid) {
94                 /* cancel engine recognition */
95                 int ret = sttd_engine_agent_recognize_cancel(uid);
96                 if (0 != ret) {
97                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
98                 }
99
100                 /* change uid state */
101                 sttd_client_set_state(uid, APP_STATE_READY);
102                 stt_client_unset_current_recognition();
103
104                 ret = sttdc_send_set_state(uid, (int)APP_STATE_READY);
105                 if (0 != ret) {
106                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send state change : result(%d)", ret);
107                 }
108         } else {
109                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid is NOT valid");
110         }
111 }
112
113 static void __cancel_by_error(void *data)
114 {
115         SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by error");
116
117         __cancel_recognition_internal();
118
119         SLOG(LOG_DEBUG, TAG_STTD, "=====");
120         SLOG(LOG_DEBUG, TAG_STTD, "  ");
121
122         return;
123 }
124
125 int __server_audio_recorder_callback(const void* data, const unsigned int length)
126 {
127         int uid = -1;
128         int ret;
129
130         if (NULL == data || 0 == length) {
131                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Recording data is not valid");
132                 ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
133                 return -1;
134         }
135
136         uid = stt_client_get_current_recognition();
137         if (0 != uid) {
138                 ret = sttd_engine_agent_set_recording_data(uid, data, length);
139                 if (ret < 0) {
140                         ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
141                         return -1;
142                 }
143                 g_recording_log_count++;
144                 if (200 <= g_recording_log_count) {
145                         SLOG(LOG_DEBUG, TAG_STTD, "=== Set recording data ===");
146                         g_recording_log_count = 0;
147                 }
148         } else {
149                 if (NULL != g_recording_timer)  {
150                         ecore_timer_del(g_recording_timer);
151                         g_recording_timer = NULL;
152                 }
153                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current uid in recording is is not valid");
154                 return -1;
155         }
156
157         return 0;
158 }
159
160 void __server_audio_interrupt_callback()
161 {
162         SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by sound interrupt");
163
164         __cancel_recognition_internal();
165
166         SLOG(LOG_DEBUG, TAG_STTD, "=====");
167         SLOG(LOG_DEBUG, TAG_STTD, "  ");
168 }
169
170 void __cancel_by_no_record(void *data)
171 {
172         SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by no record");
173
174         __cancel_recognition_internal();
175
176         SLOG(LOG_DEBUG, TAG_STTD, "=====");
177         SLOG(LOG_DEBUG, TAG_STTD, "  ");
178
179         return;
180 }
181
182 void __server_recognition_result_callback(sttp_result_event_e event, const char* type,
183                                         const char** data, int data_count, const char* msg, void *user_data)
184 {
185         // critical section
186         pthread_mutex_lock(&sttpe_result_mutex);
187
188         SLOG(LOG_DEBUG, TAG_STTD, "===== RESULT event[%d] type[%s] data[%p] data_count[%d]", event, type, data, data_count);
189
190         /* check uid */
191         int uid = stt_client_get_current_recognition();
192
193         app_state_e state;
194         if (0 == uid || 0 != sttd_client_get_state(uid, &state)) {
195                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
196                 SLOG(LOG_DEBUG, TAG_STTD, "=====");
197                 SLOG(LOG_DEBUG, TAG_STTD, "  ");
198                 pthread_mutex_unlock(&sttpe_result_mutex);
199                 return;
200         }
201
202         SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid (%d), event(%d)", uid, event);
203
204         /* send result to client */
205         if (STTP_RESULT_EVENT_FINAL_RESULT == event) {
206                 if (APP_STATE_PROCESSING != state) {
207                         SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is NOT 'Processing'.");
208                 }
209                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] the size of result from engine is '%d'", data_count);
210
211                 /* Delete timer for processing time out */
212                 if (NULL != g_processing_timer) {
213                         ecore_timer_del(g_processing_timer);
214                         g_processing_timer = NULL;
215                 }
216
217                 sttd_config_time_save();
218                 sttd_config_time_reset();
219
220                 if (NULL == data || 0 == data_count) {
221                         if (0 != sttdc_send_result(uid, event, NULL, 0, msg)) {
222                                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
223                                 int reason = (int)STTD_ERROR_OPERATION_FAILED;
224
225                                 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
226                                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
227                                 }
228                         }
229                 } else {
230                         if (0 != sttdc_send_result(uid, event, data, data_count, msg)) {
231                                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
232                                 int reason = (int)STTD_ERROR_OPERATION_FAILED;
233
234                                 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
235                                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
236                                 }
237                         }
238                 }
239
240                 /* change state of uid */
241                 sttd_client_set_state(uid, APP_STATE_READY);
242                 stt_client_unset_current_recognition();
243
244         } else if (STTP_RESULT_EVENT_PARTIAL_RESULT == event) {
245                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The partial result from engine is event[%d] data_count[%d]", event,  data_count);
246
247                 sttd_config_time_save();
248                 sttd_config_time_reset();
249
250                 if (0 != sttdc_send_result(uid, event, data, data_count, msg)) {
251                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
252                         int reason = (int)STTD_ERROR_OPERATION_FAILED;
253
254                         if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
255                                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
256                         }
257                 }
258
259         } else if (STTP_RESULT_EVENT_ERROR == event) {
260                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The event of recognition result is ERROR");
261
262                 /* Delete timer for processing time out */
263                 if (NULL != g_processing_timer) {
264                         ecore_timer_del(g_processing_timer);
265                         g_processing_timer = NULL;
266                 }
267                 sttd_config_time_reset();
268
269                 if (0 != sttdc_send_result(uid, event, NULL, 0, msg)) {
270                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
271
272                         /* send error msg */
273                         int reason = (int)STTD_ERROR_INVALID_STATE;
274                         if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
275                                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
276                         }
277                 }
278
279                 /* change state of uid */
280                 sttd_client_set_state(uid, APP_STATE_READY);
281                 stt_client_unset_current_recognition();
282         } else {
283                 /* nothing */
284         }
285
286         SLOG(LOG_DEBUG, TAG_STTD, "=====");
287         SLOG(LOG_DEBUG, TAG_STTD, "  ");
288         pthread_mutex_unlock(&sttpe_result_mutex);
289
290         return;
291 }
292
293 bool __server_result_time_callback(int index, sttp_result_time_event_e event, const char* text, long start_time, long end_time, void* user_data)
294 {
295         pthread_mutex_lock(&sttpe_result_time_mutex);
296
297         SLOG(LOG_DEBUG, TAG_STTD, "[Server] index(%d) event(%d) text(%s) start(%ld) end(%ld)",
298                 index, event, text, start_time, end_time);
299
300         if (0 == index) {
301                 int ret;
302                 ret = sttd_config_time_add(index, (int)event, text, start_time, end_time);
303                 if (0 != ret) {
304                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add time info");
305                         pthread_mutex_unlock(&sttpe_result_time_mutex);
306                         return false;
307                 }
308         } else {
309                 pthread_mutex_unlock(&sttpe_result_time_mutex);
310                 return false;
311         }
312
313         pthread_mutex_unlock(&sttpe_result_time_mutex);
314
315         return true;
316 }
317
318 void __server_silence_dectection_callback(sttp_silence_type_e type, void *user_param)
319 {
320         SLOG(LOG_DEBUG, TAG_STTD, "===== Silence Detection Callback");
321
322         int uid = stt_client_get_current_recognition();
323         if (0 != uid) {
324                 app_state_e state;
325                 if (0 != sttd_client_get_state(uid, &state)) {
326                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is not valid ");
327                         return;
328                 }
329
330                 if (APP_STATE_RECORDING != state) {
331                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
332                         return;
333                 }
334
335                 if (STTP_SILENCE_TYPE_NO_RECORD_TIMEOUT == type) {
336                         SLOG(LOG_DEBUG, TAG_STTD, "Silence Detection type - No Record");
337                         ecore_main_loop_thread_safe_call_async(__cancel_by_no_record, NULL);
338                         if (0 != sttdc_send_error_signal(uid, STTP_ERROR_NO_SPEECH, "No speech while recording")) {
339                                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] No speech while recording");
340                         }
341                 } else if (STTP_SILENCE_TYPE_END_OF_SPEECH_DETECTED == type) {
342                         SLOG(LOG_DEBUG, TAG_STTD, "Silence Detection type - End of Speech");
343                         ecore_main_loop_thread_safe_call_async(__stop_by_silence, NULL);
344                 }
345         } else {
346                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current recogntion uid is not valid ");
347         }
348
349         SLOG(LOG_DEBUG, TAG_STTD, "=====");
350         SLOG(LOG_DEBUG, TAG_STTD, "  ");
351
352         return;
353 }
354
355 void __sttd_server_engine_changed_cb(const char* engine_id, const char* language, bool support_silence, bool need_credential, void* user_data)
356 {
357         if (NULL == engine_id) {
358                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Engine id is NULL");
359                 return;
360         } else {
361                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] New default engine : %s", engine_id);
362         }
363
364         /* need to change state of app to ready */
365         int uid;
366         uid = stt_client_get_current_recognition();
367
368         if (0 != uid) {
369                 SLOG(LOG_ERROR, TAG_STTD, "[Server] Set ready state of uid(%d)", uid);
370
371                 sttd_server_cancel(uid);
372                 sttdc_send_set_state(uid, (int)APP_STATE_READY);
373
374                 stt_client_unset_current_recognition();
375         }
376
377         /* set engine */
378         int ret = sttd_engine_agent_set_default_engine(engine_id);
379         if (0 != ret)
380                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : result(%d)", ret);
381
382         if (NULL != language) {
383                 ret = sttd_engine_agent_set_default_language(language);
384                 if (0 != ret)
385                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret);
386         }
387
388         ret = sttd_engine_agent_set_silence_detection(support_silence);
389         if (0 != ret)
390                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret);
391
392         return;
393 }
394
395 void __sttd_server_language_changed_cb(const char* language, void* user_data)
396 {
397         if (NULL == language) {
398                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] language is NULL");
399                 return;
400         } else {
401                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Get language changed : %s", language);
402         }
403
404         int ret = sttd_engine_agent_set_default_language(language);
405         if (0 != ret)
406                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret);
407
408         return;
409 }
410
411 void __sttd_server_silence_changed_cb(bool value, void* user_data)
412 {
413         SLOG(LOG_DEBUG, TAG_STTD, "[Server] Get silence detection changed : %s", value ? "on" : "off");
414
415         int ret = 0;
416         ret = sttd_engine_agent_set_silence_detection(value);
417         if (0 != ret)
418                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret);
419
420         return;
421 }
422
423 /*
424 * Daemon function
425 */
426
427 static void __sig_handler(int signo)
428 {
429         /* restore signal handler */
430         signal(signo, SIG_DFL);
431
432         /* Send error signal to clients */
433         int* client_list = NULL;
434         int client_count = 0;
435         int i = 0;
436         if (0 != sttd_client_get_list(&client_list, &client_count)) {
437                 if (NULL != client_list)
438                         free(client_list);
439         }
440
441         if (NULL != client_list) {
442                 for (i = 0; i < client_count; i++) {
443                         sttdc_send_error_signal(client_list[i], STTD_ERROR_SERVICE_RESET, "Service Reset");
444                 }
445                 free(client_list);
446         }
447
448         /* invoke signal again */
449         raise(signo);
450 }
451
452 static void __register_sig_handler()
453 {
454         signal(SIGSEGV, __sig_handler);
455         signal(SIGABRT, __sig_handler);
456         signal(SIGTERM, __sig_handler);
457         signal(SIGINT, __sig_handler);
458         signal(SIGQUIT, __sig_handler);
459 }
460
461 int sttd_initialize()
462 {
463         int ret = 0;
464
465         __register_sig_handler();
466
467         if (0 != pthread_mutex_init(&sttpe_result_mutex, NULL)) {
468                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize sttpe result mutex.");
469         }
470
471         if (0 != pthread_mutex_init(&sttpe_result_time_mutex, NULL)) {
472                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize sttpe sttpe_result_time_mutex.");
473         }
474
475         if (sttd_config_initialize(__sttd_server_engine_changed_cb, __sttd_server_language_changed_cb,
476                 __sttd_server_silence_changed_cb, NULL)) {
477                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize config.");
478         }
479
480         ret = sttd_recorder_initialize(__server_audio_recorder_callback, __server_audio_interrupt_callback);
481         if (0 != ret) {
482                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize recorder : result(%d)", ret);
483                 return ret;
484         }
485
486         /* Engine Agent initialize */
487         ret = sttd_engine_agent_init(__server_recognition_result_callback, __server_result_time_callback,
488                 __server_silence_dectection_callback);
489         if (0 != ret) {
490                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret);
491                 return ret;
492         }
493
494         /* Update engine list */
495         ret = sttd_engine_agent_initialize_engine_list();
496         if (0 != ret) {
497                 if (STTD_ERROR_ENGINE_NOT_FOUND == ret) {
498                         SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] There is no stt engine");
499                 } else {
500                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to update engine list : %d", ret);
501                         return ret;
502                 }
503         }
504
505         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] initialize");
506
507         return 0;
508 }
509
510 int sttd_finalize()
511 {
512         if (0 != pthread_mutex_destroy(&sttpe_result_mutex)) {
513                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy sttpe result mutex.");
514         }
515
516         if (0 != pthread_mutex_destroy(&sttpe_result_time_mutex)) {
517                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy sttpe_result_time_mutex.");
518         }
519
520         GList *iter = NULL;
521         if (0 < g_list_length(g_proc_list)) {
522                 iter = g_list_first(g_proc_list);
523                 while (NULL != iter) {
524                         g_proc_list = g_list_remove_link(g_proc_list, iter);
525                         iter = g_list_first(g_proc_list);
526                 }
527         }
528
529         sttd_recorder_deinitialize();
530
531         sttd_config_finalize();
532
533         sttd_engine_agent_release();
534
535         return STTD_ERROR_NONE;
536 }
537
538 static void __read_proc()
539 {
540         DIR *dp = NULL;
541         struct dirent entry;
542         struct dirent *dirp = NULL;
543         int ret = -1;
544         int tmp;
545
546         GList *iter = NULL;
547         if (0 < g_list_length(g_proc_list)) {
548                 iter = g_list_first(g_proc_list);
549                 while (NULL != iter) {
550                         g_proc_list = g_list_remove_link(g_proc_list, iter);
551                         iter = g_list_first(g_proc_list);
552                 }
553         }
554
555         dp = opendir("/proc");
556         if (NULL == dp) {
557                 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to open proc");
558         } else {
559                 do {
560                         ret = readdir_r(dp, &entry, &dirp);
561                         if (0 != ret) {
562                                 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to readdir");
563                                 break;
564                         }
565
566                         if (NULL != dirp) {
567                                 tmp = atoi(dirp->d_name);
568                                 if (0 >= tmp)   continue;
569                                 g_proc_list = g_list_append(g_proc_list, GINT_TO_POINTER(tmp));
570                         }
571                 } while (NULL != dirp);
572                 closedir(dp);
573         }
574         return;
575 }
576
577 Eina_Bool sttd_cleanup_client(void *data)
578 {
579         int* client_list = NULL;
580         int client_count = 0;
581         int i = 0;
582         int j = 0;
583         bool exist = false;
584
585         if (0 != sttd_client_get_list(&client_list, &client_count)) {
586                 if (NULL != client_list)
587                         free(client_list);
588
589                 return EINA_TRUE;
590         }
591
592         if (NULL != client_list) {
593                 SLOG(LOG_DEBUG, TAG_STTD, "===== Clean up client ");
594                 
595                 __read_proc();
596
597                 for (i = 0; i < client_count; i++) {
598                         int pid = sttd_client_get_pid(client_list[i]);
599                         if (0 > pid) {
600                                 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Invalid pid");
601                                 continue;
602                         }
603
604                         exist = false;
605                         GList *iter = NULL;
606                         for (j = 0; j < g_list_length(g_proc_list); j++) {
607                                 iter = g_list_nth(g_proc_list, j);
608                                 if (NULL != iter) {
609                                         if (pid == GPOINTER_TO_INT(iter->data)) {
610                                                 SLOG(LOG_DEBUG, TAG_STTD, "uid (%d) is running", client_list[i]);
611                                                 exist = true;
612                                                 break;
613                                         }
614                                 }
615                         }
616
617                         if (false == exist) {
618                                 SLOG(LOG_ERROR, TAG_STTD, "uid (%d) should be removed", client_list[i]);
619                                 sttd_server_finalize(client_list[i]);
620                         }
621 #if 0
622                         result = sttdc_send_hello(client_list[i]);
623
624                         if (0 == result) {
625                                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", client_list[i]);
626                                 sttd_server_finalize(client_list[i]);
627                         } else if (-1 == result) {
628                                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Hello result has error");
629                         }
630 #endif
631                 }
632
633                 SLOG(LOG_DEBUG, TAG_STTD, "=====");
634                 SLOG(LOG_DEBUG, TAG_STTD, "  ");
635
636                 free(client_list);
637         }
638
639         return EINA_TRUE;
640 }
641
642 /*
643 * STT Server Functions for Client
644 */
645
646 int sttd_server_initialize(int pid, int uid, bool* silence, bool* credential)
647 {
648         if (false == sttd_engine_agent_is_default_engine()) {
649                 /* Update installed engine */
650                 sttd_engine_agent_initialize_engine_list();
651
652                 if (false == sttd_engine_agent_is_default_engine()) {
653                         SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] No stt-engine");
654                         return STTD_ERROR_ENGINE_NOT_FOUND;
655                 }
656         }
657
658         int ret = STTD_ERROR_NONE;
659
660         /* check if uid is valid */
661         app_state_e state;
662         if (0 == sttd_client_get_state(uid, &state)) {
663                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid has already been registered");
664                 return STTD_ERROR_NONE;
665         }
666
667         /* load engine */
668         ret = sttd_engine_agent_load_current_engine(uid, NULL);
669         if (0 != ret) {
670                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to load default engine");
671                 return ret;
672         }
673
674         ret = sttd_engine_agent_get_option_supported(uid, silence);
675         if (0 != ret) {
676                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine options supported");
677                 return ret;
678         }
679
680         ret = sttd_engine_agent_is_credential_needed(uid, credential);
681         if (0 != ret) {
682                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get credential necessity");
683                 return ret;
684         }
685
686         /* Add client information to client manager */
687         ret = sttd_client_add(pid, uid);
688         if (0 != ret) {
689                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add client info");
690                 return ret;
691         }
692
693         return STTD_ERROR_NONE;
694 }
695
696 static Eina_Bool __quit_ecore_loop(void *data)
697 {
698         ecore_main_loop_quit();
699         return EINA_FALSE;
700 }
701
702 int sttd_server_finalize(int uid)
703 {
704         /* check if uid is valid */
705         app_state_e state;
706         if (0 != sttd_client_get_state(uid, &state)) {
707                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
708                 return STTD_ERROR_INVALID_PARAMETER;
709         }
710
711         /* release recorder */
712         if (APP_STATE_RECORDING == state || APP_STATE_PROCESSING == state) {
713                 if (APP_STATE_RECORDING == state) {
714                         if (NULL != g_recording_timer)  {
715                                 ecore_timer_del(g_recording_timer);
716                                 g_recording_timer = NULL;
717                         }
718                 }
719
720                 if (APP_STATE_PROCESSING == state) {
721                         if (NULL != g_processing_timer) {
722                                 ecore_timer_del(g_processing_timer);
723                                 g_processing_timer = NULL;
724                         }
725                 }
726
727                 if (0 != sttd_engine_agent_recognize_cancel(uid)) {
728                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognition");
729                 }
730
731                 stt_client_unset_current_recognition();
732         }
733
734         if (0 != sttd_engine_agent_unload_current_engine(uid)) {
735                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unload engine");
736         }
737
738         /* Remove client information */
739         if (0 != sttd_client_delete(uid)) {
740                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to delete client");
741         }
742
743         /* unload engine, if ref count of client is 0 */
744         if (0 == sttd_client_get_ref_count()) {
745 //              sttd_dbus_close_connection();
746                 ecore_timer_add(0, __quit_ecore_loop, NULL);
747         }
748
749         return STTD_ERROR_NONE;
750 }
751
752 int sttd_server_get_supported_engines(int uid, GSList** engine_list)
753 {
754         /* Check if uid is valid */
755         app_state_e state;
756         if (0 != sttd_client_get_state(uid, &state)) {
757                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
758                 return STTD_ERROR_INVALID_PARAMETER;
759         }
760
761         /* Check state of uid */
762         if (APP_STATE_READY != state) {
763                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
764                 return STTD_ERROR_INVALID_STATE;
765         }
766
767         int ret;
768         ret = sttd_engine_agent_get_engine_list(engine_list);
769         if (0 != ret) {
770                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine list");
771                 return ret;
772         }
773
774         return STTD_ERROR_NONE;
775 }
776
777 int sttd_server_set_current_engine(int uid, const char* engine_id, bool* silence, bool* credential)
778 {
779         /* Check if uid is valid */
780         app_state_e state;
781         if (0 != sttd_client_get_state(uid, &state)) {
782                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
783                 return STTD_ERROR_INVALID_PARAMETER;
784         }
785
786         /* Check state of uid */
787         if (APP_STATE_READY != state) {
788                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
789                 return STTD_ERROR_INVALID_STATE;
790         }
791
792         int ret;
793         ret = sttd_engine_agent_load_current_engine(uid, engine_id);
794         if (0 != ret) {
795                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : %d", ret);
796                 return ret;
797         }
798
799         ret = sttd_engine_agent_get_option_supported(uid, silence);
800         if (0 != ret) {
801                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine options : %d", ret);
802                 return ret;
803         }
804
805         if (0 != sttd_engine_agent_is_credential_needed(uid, credential)) {
806                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get credential necessity");
807                 return ret;
808         }
809
810         return STTD_ERROR_NONE;
811 }
812
813 int sttd_server_get_current_engine(int uid, char** engine_id)
814 {
815         /* Check if uid is valid */
816         app_state_e state;
817         if (0 != sttd_client_get_state(uid, &state)) {
818                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
819                 return STTD_ERROR_INVALID_PARAMETER;
820         }
821
822         /* Check state of uid */
823         if (APP_STATE_READY != state) {
824                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
825                 return STTD_ERROR_INVALID_STATE;
826         }
827
828         int ret;
829         ret = sttd_engine_agent_get_current_engine(uid, engine_id);
830         if (0 != ret) {
831                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine : %d", ret);
832                 return ret;
833         }
834
835         return STTD_ERROR_NONE;
836 }
837
838 int sttd_server_check_app_agreed(int uid, const char* appid, bool* available)
839 {
840         /* Check if uid is valid */
841         app_state_e state;
842         if (0 != sttd_client_get_state(uid, &state)) {
843                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
844                 return STTD_ERROR_INVALID_PARAMETER;
845         }
846
847         /* Check state of uid */
848         if (APP_STATE_READY != state) {
849                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
850                 return STTD_ERROR_INVALID_STATE;
851         }
852
853         /* Ask engine available */
854         int ret;
855         bool temp = false;
856         ret = sttd_engine_agent_check_app_agreed(uid, appid, &temp);
857         if (0 != ret) {
858                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
859                 return ret;
860         }
861
862         if (true == temp) {
863                 stt_client_set_app_agreed(uid);
864                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] App(%s) confirmed that engine is available", appid);
865         }
866
867         *available = temp;
868
869         return STTD_ERROR_NONE;
870 }
871
872
873 int sttd_server_get_supported_languages(int uid, GSList** lang_list)
874 {
875         /* check if uid is valid */
876         app_state_e state;
877         if (0 != sttd_client_get_state(uid, &state)) {
878                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
879                 return STTD_ERROR_INVALID_PARAMETER;
880         }
881
882         /* get language list from engine */
883         int ret = sttd_engine_agent_supported_langs(uid, lang_list);
884         if (0 != ret) {
885                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get supported languages");
886                 return ret;
887         }
888
889         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] sttd_server_get_supported_languages");
890
891         return STTD_ERROR_NONE;
892 }
893
894 int sttd_server_get_current_langauage(int uid, char** current_lang)
895 {
896         /* check if uid is valid */
897         app_state_e state;
898         if (0 != sttd_client_get_state(uid, &state)) {
899                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
900                 return STTD_ERROR_INVALID_PARAMETER;
901         }
902
903         if (NULL == current_lang) {
904                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
905                 return STTD_ERROR_INVALID_PARAMETER;
906         }
907
908         /*get current language from engine */
909         int ret = sttd_engine_agent_get_default_lang(uid, current_lang);
910         if (0 != ret) {
911                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get default language :result(%d)", ret);
912                 return ret;
913         }
914
915         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Get default language");
916
917         return STTD_ERROR_NONE;
918 }
919
920 int sttd_server_set_private_data(int uid, const char* key, const char* data)
921 {
922         /* check if uid is valid */
923         app_state_e state;
924         if (0 != sttd_client_get_state(uid, &state)) {
925                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
926                 return STTD_ERROR_INVALID_PARAMETER;
927         }
928
929         if (NULL == key || NULL == data) {
930                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
931                 return STTD_ERROR_INVALID_PARAMETER;
932         }
933
934         /* set private data to engine */
935         int ret = -1;
936         ret = sttd_engine_agent_set_private_data(uid, key, data);
937         if (0 != ret) {
938                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set private data :result(%d)", ret);
939                 return ret;
940         }
941
942         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Set private data");
943
944         return STTD_ERROR_NONE;
945 }
946
947 int sttd_server_get_private_data(int uid, const char* key, char** data)
948 {
949         /* check if uid is valid */
950         app_state_e state;
951         if (0 != sttd_client_get_state(uid, &state)) {
952                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
953                 return STTD_ERROR_INVALID_PARAMETER;
954         }
955
956         if (NULL == key || NULL == data) {
957                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
958                 return STTD_ERROR_INVALID_PARAMETER;
959         }
960
961         /* get private data to engine */
962         int ret = -1;
963         ret = sttd_engine_agent_get_private_data(uid, key, data);
964         if (0 != ret) {
965                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get private data :result(%d)", ret);
966                 return ret;
967         }
968
969         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Get private data");
970
971         return STTD_ERROR_NONE;
972 }
973
974 int sttd_server_is_recognition_type_supported(int uid, const char* type, int* support)
975 {
976         /* check if uid is valid */
977         app_state_e state;
978         if (0 != sttd_client_get_state(uid, &state)) {
979                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
980                 return STTD_ERROR_INVALID_PARAMETER;
981         }
982
983         if (NULL == type || NULL == support) {
984                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
985                 return STTD_ERROR_INVALID_PARAMETER;
986         }
987
988         bool temp;
989         int ret = sttd_engine_agent_is_recognition_type_supported(uid, type, &temp);
990         if (0 != ret) {
991                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get recognition type supported : result(%d)", ret);
992                 return ret;
993         }
994
995         *support = (int)temp;
996
997         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] recognition type supporting is %s", *support ? "true" : "false");
998
999         return STTD_ERROR_NONE;
1000 }
1001
1002 int sttd_server_set_start_sound(int uid, const char* file)
1003 {
1004         /* check if uid is valid */
1005         app_state_e state;
1006         if (0 != sttd_client_get_state(uid, &state)) {
1007                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1008                 return STTD_ERROR_INVALID_PARAMETER;
1009         }
1010
1011         int ret = sttd_client_set_start_sound(uid, file);
1012         if (0 != ret) {
1013                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
1014                 return ret;
1015         }
1016
1017         return 0;
1018 }
1019
1020 int sttd_server_set_stop_sound(int uid, const char* file)
1021 {
1022         /* check if uid is valid */
1023         app_state_e state;
1024         if (0 != sttd_client_get_state(uid, &state)) {
1025                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1026                 return STTD_ERROR_INVALID_PARAMETER;
1027         }
1028
1029         int ret = sttd_client_set_stop_sound(uid, file);
1030         if (0 != ret) {
1031                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
1032                 return ret;
1033         }
1034
1035         return 0;
1036 }
1037
1038 #if 0
1039 Eina_Bool __check_recording_state(void *data)
1040 {
1041         /* current uid */
1042         int uid = stt_client_get_current_recognition();
1043         if (0 == uid)
1044                 return EINA_FALSE;
1045
1046         app_state_e state;
1047         if (0 != sttdc_send_get_state(uid, (int*)&state)) {
1048                 /* client is removed */
1049                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", uid);
1050                 sttd_server_finalize(uid);
1051                 return EINA_FALSE;
1052         }
1053
1054         if (APP_STATE_READY == state) {
1055                 /* Cancel stt */
1056                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Ready'. The daemon should cancel recording", uid);
1057                 sttd_server_cancel(uid);
1058         } else if (APP_STATE_PROCESSING == state) {
1059                 /* Cancel stt and send change state */
1060                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Processing'. The daemon should cancel recording", uid);
1061                 sttd_server_cancel(uid);
1062                 sttdc_send_set_state(uid, (int)APP_STATE_READY);
1063         } else {
1064                 /* Normal state */
1065                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The states of daemon and client are identical");
1066                 return EINA_TRUE;
1067         }
1068
1069         return EINA_FALSE;
1070 }
1071 #endif
1072
1073 Eina_Bool __stop_by_recording_timeout(void *data)
1074 {
1075         SLOG(LOG_DEBUG, TAG_STTD, "===== Stop by timeout");
1076
1077         g_recording_timer = NULL;
1078
1079         int uid = 0;
1080         uid = stt_client_get_current_recognition();
1081         if (0 != uid) {
1082                 /* cancel engine recognition */
1083                 int ret = sttd_server_stop(uid);
1084                 if (0 != ret) {
1085                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop : result(%d)", ret);
1086                 }
1087         }
1088
1089         SLOG(LOG_DEBUG, TAG_STTD, "=====");
1090         SLOG(LOG_DEBUG, TAG_STTD, "  ");
1091
1092         return EINA_FALSE;
1093 }
1094
1095 void __sttd_server_recorder_start(void* data)
1096 {
1097         intptr_t puid = (intptr_t)data;
1098         int uid = (int)puid;
1099         int current_uid = stt_client_get_current_recognition();
1100
1101         if (uid != current_uid) {
1102                 stt_client_unset_current_recognition();
1103                 return;
1104         }
1105
1106         int ret = sttd_engine_agent_recognize_start_recorder(uid);
1107         if (0 != ret) {
1108                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1109                 return;
1110         }
1111
1112         /* Notify uid state change */
1113         sttdc_send_set_state(uid, APP_STATE_RECORDING);
1114
1115         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
1116 }
1117
1118 void __sttd_start_sound_completed_cb(int id, void *user_data)
1119 {
1120         SLOG(LOG_DEBUG, TAG_STTD, "===== Start sound completed");
1121
1122         /* After wav play callback, recorder start */
1123         ecore_main_loop_thread_safe_call_async(__sttd_server_recorder_start, user_data);
1124
1125         SLOG(LOG_DEBUG, TAG_STTD, "=====");
1126         SLOG(LOG_DEBUG, TAG_STTD, "  ");
1127         return;
1128 }
1129
1130 int sttd_server_start(int uid, const char* lang, const char* recognition_type, int silence, const char* appid, const char* credential)
1131 {
1132         if (NULL == lang || NULL == recognition_type) {
1133                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
1134                 return STTD_ERROR_INVALID_PARAMETER;
1135         }
1136
1137         /* check if uid is valid */
1138         app_state_e state;
1139         if (0 != sttd_client_get_state(uid, &state)) {
1140                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1141                 return STTD_ERROR_INVALID_PARAMETER;
1142         }
1143
1144         /* check uid state */
1145         if (APP_STATE_READY != state) {
1146                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] sttd_server_start : current state is not ready");
1147                 return STTD_ERROR_INVALID_STATE;
1148         }
1149
1150         int ret = 0;
1151         if (false == stt_client_get_app_agreed(uid)) {
1152                 bool temp = false;
1153                 ret = sttd_engine_agent_check_app_agreed(uid, appid, &temp);
1154                 if (0 != ret) {
1155                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
1156                         return ret;
1157                 }
1158
1159                 if (false == temp) {
1160                         SLOG(LOG_ERROR, TAG_STTD, "[Server] App(%s) NOT confirmed that engine is available", appid);
1161                         return STTD_ERROR_PERMISSION_DENIED;
1162                 }
1163
1164                 stt_client_set_app_agreed(uid);
1165         }
1166
1167         /* check if engine use network */
1168         if (true == sttd_engine_agent_need_network(uid)) {
1169                 if (false == stt_network_is_connected()) {
1170                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Disconnect network. Current engine needs to network connection.");
1171                         return STTD_ERROR_OUT_OF_NETWORK;
1172                 }
1173         }
1174
1175         char* sound = NULL;
1176         ret = sttd_client_get_start_sound(uid, &sound);
1177         if (0 != ret) {
1178                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
1179                 return ret;
1180         }
1181
1182         if (0 != stt_client_set_current_recognition(uid)) {
1183                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
1184                 if (NULL != sound)      free(sound);
1185                 return STTD_ERROR_RECORDER_BUSY;
1186         }
1187
1188         /* engine start recognition */
1189         SLOG(LOG_DEBUG, TAG_STTD, "[Server] start : uid(%d), lang(%s), recog_type(%s)",
1190                         uid, lang, recognition_type);
1191         if (NULL != sound)
1192                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] start sound : %s", sound);
1193
1194         /* 1. Set audio session */
1195         ret = sttd_recorder_set_audio_session();
1196         if (0 != ret) {
1197                 stt_client_unset_current_recognition();
1198                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set session : %d", ret);
1199                 if (NULL != sound)      free(sound);
1200                 return ret;
1201         }
1202
1203         bool is_sound_done = false;
1204
1205         /* 2. Request wav play */
1206         if (NULL != sound) {
1207                 int id = 0;
1208                 intptr_t puid = (intptr_t)uid;
1209                 ret = wav_player_start(sound, SOUND_TYPE_MEDIA, __sttd_start_sound_completed_cb, (void*)puid, &id);
1210                 if (WAV_PLAYER_ERROR_NONE != ret) {
1211                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
1212                         is_sound_done = true;
1213                 }
1214                 free(sound);
1215                 sound = NULL;
1216         } else {
1217                 is_sound_done = true;
1218         }
1219
1220         /* 3. Create recorder & engine initialize */
1221         ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, credential, NULL);
1222         if (0 != ret) {
1223                 stt_client_unset_current_recognition();
1224                 sttd_recorder_unset_audio_session();
1225                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1226                 return ret;
1227         }
1228
1229         if (0 != strcmp(STTP_RECOGNITION_TYPE_FREE_PARTIAL, recognition_type)) {
1230                 g_recording_timer = ecore_timer_add(g_recording_timeout, __stop_by_recording_timeout, NULL);
1231         }
1232
1233         /* change uid state */
1234         sttd_client_set_state(uid, APP_STATE_RECORDING);
1235
1236         g_recording_log_count = 0;
1237
1238         if (true == is_sound_done) {
1239                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1240
1241                 ret = sttd_engine_agent_recognize_start_recorder(uid);
1242                 if (0 != ret) {
1243                         stt_client_unset_current_recognition();
1244                         sttd_recorder_unset_audio_session();
1245
1246                         sttd_engine_agent_recognize_cancel(uid);
1247                         ecore_timer_del(g_recording_timer);
1248                         sttd_client_set_state(uid, APP_STATE_READY);
1249
1250                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
1251                         return ret;
1252                 }
1253
1254                 /* Notify uid state change */
1255                 sttdc_send_set_state(uid, APP_STATE_RECORDING);
1256
1257                 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
1258                 return STTD_RESULT_STATE_DONE;
1259         }
1260
1261         SLOG(LOG_DEBUG, TAG_STTD, "[Server] Wait sound finish");
1262
1263         return STTD_RESULT_STATE_NOT_DONE;
1264 }
1265
1266 Eina_Bool __time_out_for_processing(void *data)
1267 {
1268         g_processing_timer = NULL;
1269
1270         /* current uid */
1271         int uid = stt_client_get_current_recognition();
1272         if (0 == uid)   return EINA_FALSE;
1273
1274         /* Cancel engine */
1275         int ret = sttd_engine_agent_recognize_cancel(uid);
1276         if (0 != ret) {
1277                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1278         }
1279
1280         if (0 != sttdc_send_result(uid, STTP_RESULT_EVENT_FINAL_RESULT, NULL, 0, "Time out not to receive recognition result.")) {
1281                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
1282
1283                 /* send error msg */
1284                 int reason = (int)STTD_ERROR_TIMED_OUT;
1285                 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
1286                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
1287                 }
1288         }
1289
1290         /* Change uid state */
1291         sttd_client_set_state(uid, APP_STATE_READY);
1292
1293         stt_client_unset_current_recognition();
1294
1295         return EINA_FALSE;
1296 }
1297
1298 void __sttd_server_engine_stop(void* data)
1299 {
1300         intptr_t puid = (intptr_t)data;
1301         int uid = (int)puid;
1302         /* change uid state */
1303         sttd_client_set_state(uid, APP_STATE_PROCESSING);
1304
1305         /* Notify uid state change */
1306         sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1307
1308         /* Unset audio session */
1309         int ret = sttd_recorder_unset_audio_session();
1310         if (0 != ret) {
1311                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1312                 return;
1313         }
1314
1315         /* Stop engine */
1316         ret = sttd_engine_agent_recognize_stop_engine(uid);
1317         if (0 != ret) {
1318                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1319                 return;
1320         }
1321
1322         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1323 }
1324
1325 void __sttd_stop_sound_completed_cb(int id, void *user_data)
1326 {
1327         SLOG(LOG_DEBUG, TAG_STTD, "===== Stop sound completed");
1328
1329         /* After wav play callback, engine stop */
1330         ecore_main_loop_thread_safe_call_async(__sttd_server_engine_stop, user_data);
1331
1332         SLOG(LOG_DEBUG, TAG_STTD, "=====");
1333         SLOG(LOG_DEBUG, TAG_STTD, "  ");
1334         return;
1335 }
1336
1337 int sttd_server_stop(int uid)
1338 {
1339         /* check if uid is valid */
1340         app_state_e state;
1341         if (0 != sttd_client_get_state(uid, &state)) {
1342                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1343                 return STTD_ERROR_INVALID_PARAMETER;
1344         }
1345
1346         /* check uid state */
1347         if (APP_STATE_RECORDING != state) {
1348                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
1349                 return STTD_ERROR_INVALID_STATE;
1350         }
1351
1352         if (NULL != g_recording_timer)  {
1353                 ecore_timer_del(g_recording_timer);
1354                 g_recording_timer = NULL;
1355         }
1356
1357         char* sound = NULL;
1358         if (0 != sttd_client_get_stop_sound(uid, &sound)) {
1359                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
1360                 return STTD_ERROR_OPERATION_FAILED;
1361         }
1362
1363         SLOG(LOG_DEBUG, TAG_STTD, "[Server] stop sound path : %s", sound);
1364
1365         int ret;
1366         /* 1. Stop recorder */
1367         ret = sttd_engine_agent_recognize_stop_recorder(uid);
1368         if (0 != ret) {
1369                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop recorder : result(%d)", ret);
1370                 if (0 != sttd_engine_agent_recognize_cancel(uid)) {
1371                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognize");
1372                 }
1373                 if (NULL != sound)      free(sound);
1374                 return ret;
1375         }
1376
1377         /* 2. Request wav play */
1378         if (NULL != sound) {
1379                 int id = 0;
1380                 intptr_t puid = (intptr_t)uid;
1381                 ret = wav_player_start(sound, SOUND_TYPE_MEDIA, __sttd_stop_sound_completed_cb, (void*)puid, &id);
1382                 if (WAV_PLAYER_ERROR_NONE != ret) {
1383                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
1384                 } else {
1385                         SLOG(LOG_DEBUG, TAG_STTD, "[Server] Play wav : %s", sound);
1386                 }
1387
1388                 free(sound);
1389
1390                 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1391
1392                 return STTD_RESULT_STATE_NOT_DONE;
1393         } else {
1394                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1395
1396                 /* Unset audio session */
1397                 ret = sttd_recorder_unset_audio_session();
1398                 if (0 != ret) {
1399                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1400                         return ret;
1401                 }
1402
1403                 /* Stop engine */
1404                 ret = sttd_engine_agent_recognize_stop_engine(uid);
1405                 if (0 != ret) {
1406                         stt_client_unset_current_recognition();
1407                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1408                         return ret;
1409                 }
1410
1411                 /* change uid state */
1412                 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1413
1414                 /* Notify uid state change */
1415                 sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1416
1417                 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1418
1419                 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1420
1421                 return STTD_RESULT_STATE_DONE;
1422         }
1423
1424         return STTD_ERROR_NONE;
1425 }
1426
1427 int sttd_server_cancel(int uid)
1428 {
1429         /* check if uid is valid */
1430         app_state_e state;
1431         if (0 != sttd_client_get_state(uid, &state)) {
1432                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1433                 return STTD_ERROR_INVALID_PARAMETER;
1434         }
1435
1436         /* check uid state */
1437         if (APP_STATE_READY == state) {
1438                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is ready");
1439                 return STTD_ERROR_NONE;
1440         }
1441
1442         stt_client_unset_current_recognition();
1443
1444         if (NULL != g_recording_timer) {
1445                 ecore_timer_del(g_recording_timer);
1446                 g_recording_timer = NULL;
1447         }
1448
1449         if (NULL != g_processing_timer) {
1450                 ecore_timer_del(g_processing_timer);
1451                 g_processing_timer = NULL;
1452         }
1453
1454         if (APP_STATE_RECORDING == state) {
1455                 /* Unset audio session */
1456                 int ret = sttd_recorder_unset_audio_session();
1457                 if (0 != ret) {
1458                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1459                         return ret;
1460                 }
1461         }
1462
1463         /* change uid state */
1464         sttd_client_set_state(uid, APP_STATE_READY);
1465
1466         /* cancel engine recognition */
1467         int ret = sttd_engine_agent_recognize_cancel(uid);
1468         if (0 != ret) {
1469                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1470                 return ret;
1471         }
1472
1473         /* Notify uid state change */
1474         sttdc_send_set_state(uid, APP_STATE_READY);
1475
1476         return STTD_ERROR_NONE;
1477 }