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