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