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