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