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