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