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