fix merge duplication
[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_get_audio_format(unsigned int uid, stte_audio_type_e *type, int *rate, int *num_of_channels)
947 {
948         /* check if uid is valid */
949         app_state_e state = APP_STATE_CREATED;
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         if (NULL == type || NULL == rate || NULL == num_of_channels) {
956                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
957                 return STTD_ERROR_INVALID_PARAMETER;
958         }
959
960         int ret = sttd_engine_agent_get_audio_format(type, rate, num_of_channels);
961         if (0 != ret) {
962                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get recognition type supported : result(%d)", ret);
963                 return ret;
964         }
965
966         SLOG(LOG_INFO, TAG_STTD, "[Server SUCCESS] Audio format: type(%d), rate(%d), number of channels(%d)", *type, *rate, *num_of_channels);
967         return STTD_ERROR_NONE;
968 }
969
970 int sttd_server_set_start_sound(unsigned int uid, const char* file)
971 {
972         /* check if uid is valid */
973         app_state_e state;
974         if (0 != sttd_client_get_state(uid, &state)) {
975                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
976                 return STTD_ERROR_INVALID_PARAMETER;
977         }
978
979         int ret = sttd_client_set_start_sound(uid, file);
980         if (0 != ret) {
981                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
982                 return ret;
983         }
984
985         return 0;
986 }
987
988 int sttd_server_set_stop_sound(unsigned int uid, const char* file)
989 {
990         /* check if uid is valid */
991         app_state_e state;
992         if (0 != sttd_client_get_state(uid, &state)) {
993                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
994                 return STTD_ERROR_INVALID_PARAMETER;
995         }
996
997         int ret = sttd_client_set_stop_sound(uid, file);
998         if (0 != ret) {
999                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
1000                 return ret;
1001         }
1002
1003         return 0;
1004 }
1005
1006 static Eina_Bool __stop_by_recording_timeout(void *data)
1007 {
1008         SLOG(LOG_INFO, TAG_STTD, "===== Stop by timeout");
1009         g_recording_timer = NULL;
1010
1011         unsigned int uid = stt_client_get_current_recognition();
1012         if (STT_INVALID_UID != uid) {
1013                 /* cancel engine recognition */
1014                 int ret = sttd_server_stop(uid);
1015                 if (STTD_ERROR_NONE != ret) {
1016                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop : result(%d)", ret);
1017                 }
1018         }
1019
1020         SLOG(LOG_INFO, TAG_STTD, "=====");
1021         SLOG(LOG_DEBUG, TAG_STTD, "  ");
1022
1023         return EINA_FALSE;
1024 }
1025
1026 static void __sttd_server_recorder_start(void* data)
1027 {
1028         uintptr_t puid = (uintptr_t)data;
1029         unsigned int uid = (unsigned int)puid;
1030         int current_uid = stt_client_get_current_recognition();
1031
1032         if (uid != current_uid) {
1033                 stt_client_unset_current_recognition();
1034                 return;
1035         }
1036
1037         char appid[1024] = {0, };
1038         int pid = sttd_client_get_pid(uid);
1039         int ret = -1;
1040         ret = aul_app_get_appid_bypid(pid, appid, sizeof(appid) - 1);
1041         if ((AUL_R_OK != ret) || (0 == strlen(appid))) {
1042                 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to get application ID");
1043         } else {
1044                 SLOG(LOG_DEBUG, TAG_STTD, "[DEBUG] Current app id is %s", appid);
1045         }
1046
1047         ret = sttd_engine_agent_recognize_start_recorder(uid, appid);
1048         if (0 != ret) {
1049                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1050                 return;
1051         }
1052
1053         app_state_e temp_app_state;
1054         if (0 != sttd_client_get_state(uid, &temp_app_state)) {
1055                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1056                 return;
1057         }
1058         if (APP_STATE_READY != temp_app_state && 0 != stt_client_get_current_recognition()) {
1059                 /* Notify uid state change */
1060                 sttdc_send_set_state(uid, APP_STATE_RECORDING);
1061                 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
1062         }
1063 }
1064
1065 static void __sttd_start_sound_completed_cb(int id, void *user_data)
1066 {
1067         SLOG(LOG_INFO, TAG_STTD, "===== Start sound completed");
1068
1069         /* After wav play callback, recorder start */
1070         ecore_main_loop_thread_safe_call_async(__sttd_server_recorder_start, user_data);
1071
1072         SLOG(LOG_INFO, TAG_STTD, "=====");
1073         SLOG(LOG_DEBUG, TAG_STTD, "  ");
1074         return;
1075 }
1076
1077 static int __sttd_server_check_precondition_to_start(unsigned int uid, const char* appid)
1078 {
1079         /* check if uid is valid */
1080         app_state_e state;
1081         if (0 != sttd_client_get_state(uid, &state)) {
1082                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1083                 return STTD_ERROR_INVALID_PARAMETER;
1084         }
1085
1086         /* check uid state */
1087         if (APP_STATE_READY != state) {
1088                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] sttd_server_start : current state is not ready");
1089                 return STTD_ERROR_INVALID_STATE;
1090         }
1091
1092         int ret = STTD_ERROR_NONE;
1093         if (false == stt_client_get_app_agreed(uid)) {
1094                 bool temp = false;
1095                 ret = sttd_engine_agent_check_app_agreed(appid, &temp);
1096                 if (0 != ret) {
1097                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
1098                         return ret;
1099                 }
1100
1101                 if (false == temp) {
1102                         SLOG(LOG_ERROR, TAG_STTD, "[Server] App(%s) NOT confirmed that engine is available", appid);
1103                         return STTD_ERROR_PERMISSION_DENIED;
1104                 }
1105
1106                 stt_client_set_app_agreed(uid);
1107         }
1108
1109         /* check if engine use network */
1110         if (true == sttd_engine_agent_need_network()) {
1111                 if (false == stt_network_is_connected()) {
1112                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Disconnect network. Current engine needs to network connection.");
1113                         return STTD_ERROR_OUT_OF_NETWORK;
1114                 }
1115         }
1116         return ret;
1117 }
1118
1119 static bool play_sound(const char *path, wav_player_playback_completed_cb callback, void *user_data)
1120 {
1121         sound_stream_info_h wav_stream_info_h = NULL;
1122         if (SOUND_MANAGER_ERROR_NONE != sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, NULL, NULL, &wav_stream_info_h)) {
1123                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to create stream info for playing wav");
1124                 return false;
1125         }
1126
1127         int ret = wav_player_start_new(path, wav_stream_info_h, callback, user_data, NULL);
1128         if (SOUND_MANAGER_ERROR_NONE != sound_manager_destroy_stream_information(wav_stream_info_h)) {
1129                 SLOG(LOG_WARN, TAG_STTD, "[Server WARN] Fail to destroy stream info for playing wav");
1130         }
1131
1132         if (WAV_PLAYER_ERROR_NONE != ret) {
1133                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
1134                 return false;
1135         }
1136
1137         return true;
1138 }
1139
1140 static bool play_start_sound_for_uid(unsigned int uid)
1141 {
1142         char* sound = NULL;
1143         if (STTD_ERROR_NONE != sttd_client_get_start_sound(uid, &sound)) {
1144                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start sound");
1145                 return false;
1146         }
1147
1148         if (NULL == sound) {
1149                 SLOG(LOG_INFO, TAG_STTD, "[Server] There is no start sound");
1150                 return false;
1151         }
1152
1153         SLOG(LOG_INFO, TAG_STTD, "[Server] start sound : %s", sound);
1154
1155         uintptr_t puid = (uintptr_t)uid;
1156         bool ret = play_sound(sound, __sttd_start_sound_completed_cb, (void*)puid);
1157         free(sound);
1158
1159         return ret;
1160 }
1161
1162 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)
1163 {
1164         if (NULL == lang || NULL == recognition_type) {
1165                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
1166                 return STTD_ERROR_INVALID_PARAMETER;
1167         }
1168
1169         int ret = __sttd_server_check_precondition_to_start(uid, appid);
1170         if (0 != ret) {
1171                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to satisfy preconditions, ret(0x%x)", ret);
1172                 return ret;
1173         }
1174
1175         if (0 != stt_client_set_current_recognition(uid)) {
1176                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
1177                 return STTD_ERROR_RECORDER_BUSY;
1178         }
1179
1180         delete_timers_related_to_recording_session();
1181
1182         ret = sttd_client_set_audio_id(uid, audio_id);
1183         if (0 != ret) {
1184                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set audio_id(%s)", audio_id);
1185                 return ret;
1186         }
1187
1188         /* engine start recognition */
1189         SLOG(LOG_INFO, TAG_STTD, "[Server] start : uid(%u), lang(%s), recog_type(%s)",
1190                         uid, lang, recognition_type);
1191
1192         /* 1. Set audio session */
1193         ret = sttd_recorder_set_audio_session();
1194         if (0 != ret) {
1195                 stt_client_unset_current_recognition();
1196                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set session : %d", ret);
1197                 return ret;
1198         }
1199
1200         /* 2. Request wav play */
1201         bool is_playing = play_start_sound_for_uid(uid);
1202
1203         /* 3. Create recorder & engine initialize */
1204         ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, appid, credential, NULL);
1205         if (0 != ret) {
1206                 stt_client_unset_current_recognition();
1207                 sttd_recorder_unset_audio_session();
1208                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1209                 return ret;
1210         }
1211
1212         if (STTD_ERROR_NONE != strncmp(STTE_RECOGNITION_TYPE_FREE_PARTIAL, recognition_type, STT_MAX_TYPE_LENGTH)) {
1213                 if (NULL == g_processing_timer) {
1214                         g_recording_timer = ecore_timer_add(g_recording_timeout, __stop_by_recording_timeout, NULL);
1215                 }
1216         }
1217
1218         /* change uid state */
1219         sttd_client_set_state(uid, APP_STATE_RECORDING);
1220
1221         g_recording_log_count = 0;
1222         if (false == is_playing) {
1223                 SLOG(LOG_INFO, TAG_STTD, "[Server] No sound play");
1224
1225                 ret = sttd_engine_agent_recognize_start_recorder(uid, appid);
1226                 if (0 != ret) {
1227                         stt_client_unset_current_recognition();
1228                         sttd_recorder_unset_audio_session();
1229
1230                         sttd_engine_agent_recognize_cancel();
1231                         if (NULL != g_recording_timer)  {
1232                                 ecore_timer_del(g_recording_timer);
1233                                 g_recording_timer = NULL;
1234                         }
1235                         sttd_client_set_state(uid, APP_STATE_READY);
1236
1237                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
1238                         return ret;
1239                 }
1240
1241                 app_state_e temp_app_state;
1242                 if (0 != sttd_client_get_state(uid, &temp_app_state)) {
1243                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid");
1244                         return STTD_ERROR_INVALID_PARAMETER;
1245                 }
1246                 if (APP_STATE_READY != temp_app_state && 0 != stt_client_get_current_recognition()) {
1247                         /* Notify uid state change */
1248                         sttdc_send_set_state(uid, APP_STATE_RECORDING);
1249                 }
1250
1251                 SLOG(LOG_INFO, TAG_STTD, "[Server SUCCESS] Start recognition");
1252         } else {
1253                 SLOG(LOG_INFO, TAG_STTD, "[Server] Wait sound finish");
1254         }
1255
1256         sttd_client_set_streaming(uid, false);
1257         return STTD_ERROR_NONE;
1258 }
1259
1260 static Eina_Bool __time_out_for_processing(void *data)
1261 {
1262         g_processing_timer = NULL;
1263         SLOG(LOG_INFO, TAG_STTD, "[Server INFO] Enter __time_out_for_processing");
1264
1265         /* current uid */
1266         unsigned int uid = stt_client_get_current_recognition();
1267         if (STT_INVALID_UID == uid)     return EINA_FALSE;
1268
1269         SLOG(LOG_INFO, TAG_STTD, "[Server Info] stt cancel is invoked by timeout for processing");
1270
1271         /* Cancel engine */
1272         int ret = sttd_engine_agent_recognize_cancel();
1273         if (0 != ret) {
1274                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1275         }
1276
1277         if (0 != sttdc_send_result(uid, STTE_RESULT_EVENT_FINAL_RESULT, NULL, 0, "Time out not to receive recognition result.")) {
1278                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
1279
1280                 /* send error msg */
1281                 int reason = (int)STTD_ERROR_TIMED_OUT;
1282                 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
1283                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
1284                 }
1285         }
1286
1287         /* Change uid state */
1288         sttd_client_set_state(uid, APP_STATE_READY);
1289
1290         stt_client_unset_current_recognition();
1291
1292         SLOG(LOG_INFO, TAG_STTD, "[Server INFO] End __time_out_for_processing");
1293
1294         return EINA_FALSE;
1295 }
1296
1297 static void __sttd_server_engine_stop(void* data)
1298 {
1299         uintptr_t puid = (uintptr_t)data;
1300         unsigned int uid = (unsigned int)puid;
1301         /* change uid state */
1302         sttd_client_set_state(uid, APP_STATE_PROCESSING);
1303
1304         /* Notify uid state change */
1305         sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1306
1307         /* Unset audio session */
1308         int ret = sttd_recorder_unset_audio_session();
1309         if (0 != ret) {
1310                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1311                 return;
1312         }
1313
1314         /* Stop engine */
1315         ret = sttd_engine_agent_recognize_stop_engine();
1316         if (0 != ret) {
1317                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1318                 return;
1319         }
1320
1321         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1322 }
1323
1324 static void __sttd_stop_sound_completed_cb(int id, void *user_data)
1325 {
1326         SLOG(LOG_INFO, TAG_STTD, "===== Stop sound completed");
1327
1328         /* After wav play callback, engine stop */
1329         ecore_main_loop_thread_safe_call_async(__sttd_server_engine_stop, user_data);
1330
1331         SLOG(LOG_DEBUG, TAG_STTD, "=====");
1332         SLOG(LOG_DEBUG, TAG_STTD, "  ");
1333         return;
1334 }
1335
1336 static bool play_stop_sound_for_uid(unsigned int uid)
1337 {
1338         char* sound = NULL;
1339         if (STTD_ERROR_NONE != sttd_client_get_stop_sound(uid, &sound)) {
1340                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start sound");
1341                 return false;
1342         }
1343
1344         if (NULL == sound) {
1345                 SLOG(LOG_INFO, TAG_STTD, "[Server] There is no start sound");
1346                 return false;
1347         }
1348
1349         SLOG(LOG_INFO, TAG_STTD, "[Server] stop sound : %s", sound);
1350
1351         uintptr_t puid = (uintptr_t)uid;
1352         bool ret = play_sound(sound, __sttd_stop_sound_completed_cb, (void*)puid);
1353         free(sound);
1354
1355         return ret;
1356 }
1357
1358 int sttd_server_stop(unsigned int uid)
1359 {
1360         /* check if uid is valid */
1361         app_state_e state;
1362         if (0 != sttd_client_get_state(uid, &state)) {
1363                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1364                 return STTD_ERROR_INVALID_PARAMETER;
1365         }
1366
1367         /* check uid state */
1368         if (APP_STATE_PROCESSING == state) {
1369                 SLOG(LOG_INFO, TAG_STTD, "[Server] State is already processing. Skip stop behavior");
1370                 return STTD_ERROR_NONE;
1371         }
1372
1373         if (APP_STATE_RECORDING != state) {
1374                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
1375                 return STTD_ERROR_INVALID_STATE;
1376         }
1377
1378         if (sttd_client_is_streaming(uid)) {
1379                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current client is not started as default");
1380                 return STTD_ERROR_OPERATION_FAILED;
1381         }
1382
1383         delete_timers_related_to_recording_session();
1384
1385         int ret;
1386         /* 1. Stop recorder */
1387         ret = sttd_engine_agent_recognize_stop_recorder();
1388         if (0 != ret) {
1389                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop recorder : result(%d)", ret);
1390                 if (0 != sttd_engine_agent_recognize_cancel()) {
1391                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognize");
1392                 }
1393                 return ret;
1394         }
1395
1396         /* 2. Request wav play */
1397         if (false == play_stop_sound_for_uid(uid)) {
1398                 SLOG(LOG_INFO, TAG_STTD, "[Server] No stop 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();
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_INFO, TAG_STTD, "[Server SUCCESS] Stop recognition");
1422         }
1423
1424         SLOG(LOG_INFO, TAG_STTD, "[INFO] Add g_processing_timer");
1425         if (NULL == g_processing_timer) {
1426                 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1427         }
1428
1429         return STTD_ERROR_NONE;
1430 }
1431
1432 int sttd_server_start_audio_streaming(unsigned int uid, const char* lang, const char* recognition_type, int silence, const char* appid, const char* credential, const char* audio_id)
1433 {
1434         if (NULL == lang || NULL == recognition_type) {
1435                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
1436                 return STTD_ERROR_INVALID_PARAMETER;
1437         }
1438
1439         int ret = __sttd_server_check_precondition_to_start(uid, appid);
1440         if (STTD_ERROR_NONE != ret) {
1441                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to satisfy preconditions, ret(0x%x)", ret);
1442                 return ret;
1443         }
1444
1445         if (STTD_ERROR_NONE != stt_client_set_current_recognition(uid)) {
1446                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
1447                 return STTD_ERROR_RECORDER_BUSY;
1448         }
1449
1450         delete_timers_related_to_recording_session();
1451
1452         ret = sttd_client_set_audio_id(uid, audio_id);
1453         if (STTD_ERROR_NONE != ret) {
1454                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set audio_id(%s)", audio_id);
1455                 return ret;
1456         }
1457
1458         /* engine start recognition */
1459         SLOG(LOG_INFO, TAG_STTD, "[Server] start : uid(%u), lang(%s), recog_type(%s)", uid, lang, recognition_type);
1460
1461         /* 3. Create recorder & engine initialize */
1462         ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, appid, credential, NULL);
1463         if (STTD_ERROR_NONE != ret) {
1464                 stt_client_unset_current_recognition();
1465                 sttd_recorder_unset_audio_session();
1466                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d/%s)", ret, get_error_message(ret));
1467                 return ret;
1468         }
1469
1470         if (STTD_ERROR_NONE != strncmp(STTE_RECOGNITION_TYPE_FREE_PARTIAL, recognition_type, STT_MAX_TYPE_LENGTH)) {
1471                 if (NULL == g_processing_timer) {
1472                         g_recording_timer = ecore_timer_add(g_recording_timeout, __stop_by_recording_timeout, NULL);
1473                 }
1474         }
1475
1476         /* change uid state */
1477         sttd_client_set_state(uid, APP_STATE_RECORDING);
1478
1479         g_recording_log_count = 0;
1480
1481         app_state_e temp_app_state = APP_STATE_CREATED;
1482         if (0 != sttd_client_get_state(uid, &temp_app_state)) {
1483                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid");
1484                 return STTD_ERROR_INVALID_PARAMETER;
1485         }
1486
1487         if (APP_STATE_READY != temp_app_state && 0 != stt_client_get_current_recognition()) {
1488                 /* Notify uid state change */
1489                 sttdc_send_set_state(uid, APP_STATE_RECORDING);
1490         }
1491
1492         SLOG(LOG_INFO, TAG_STTD, "[Server SUCCESS] Start recognition");
1493
1494         sttd_client_set_streaming(uid, true);
1495         return STTD_ERROR_NONE;
1496 }
1497
1498 int sttd_server_send_audio_streaming(unsigned int uid, const char *data, size_t data_size)
1499 {
1500         app_state_e state = APP_STATE_CREATED;
1501         if (0 != sttd_client_get_state(uid, &state)) {
1502                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1503                 return STTD_ERROR_INVALID_PARAMETER;
1504         }
1505
1506         /* check uid state */
1507         if (APP_STATE_PROCESSING == state) {
1508                 SLOG(LOG_INFO, TAG_STTD, "[Server] State is already processing. Skip stop behavior");
1509                 return STTD_ERROR_NONE;
1510         }
1511
1512         if (APP_STATE_RECORDING != state) {
1513                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
1514                 return STTD_ERROR_INVALID_STATE;
1515         }
1516
1517         if (false == sttd_client_is_streaming(uid)) {
1518                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current client is not started as audio streaming");
1519                 return STTD_ERROR_OPERATION_FAILED;
1520         }
1521
1522         int ret = __server_audio_recorder_callback(data, data_size);
1523         if (0 != ret) {
1524                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send audio data");
1525                 return STTD_ERROR_OPERATION_FAILED;
1526         }
1527
1528         return STTD_ERROR_NONE;
1529 }
1530
1531 int sttd_server_stop_audio_streaming(unsigned int uid)
1532 {
1533         /* check if uid is valid */
1534         app_state_e state = APP_STATE_CREATED;
1535         if (0 != sttd_client_get_state(uid, &state)) {
1536                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1537                 return STTD_ERROR_INVALID_PARAMETER;
1538         }
1539
1540         /* check uid state */
1541         if (APP_STATE_PROCESSING == state) {
1542                 SLOG(LOG_INFO, TAG_STTD, "[Server] State is already processing. Skip stop behavior");
1543                 return STTD_ERROR_NONE;
1544         }
1545
1546         if (APP_STATE_RECORDING != state) {
1547                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
1548                 return STTD_ERROR_INVALID_STATE;
1549         }
1550
1551         if (false == sttd_client_is_streaming(uid)) {
1552                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current client is not started as audio streaming");
1553                 return STTD_ERROR_OPERATION_FAILED;
1554         }
1555
1556         delete_timers_related_to_recording_session();
1557
1558         /* Stop engine */
1559         int ret = sttd_engine_agent_recognize_stop_engine();
1560         if (0 != ret) {
1561                 stt_client_unset_current_recognition();
1562                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1563                 return ret;
1564         }
1565
1566         /* change uid state */
1567         sttd_client_set_state(uid, APP_STATE_PROCESSING);
1568
1569         /* Notify uid state change */
1570         sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1571
1572         SLOG(LOG_INFO, TAG_STTD, "[Server SUCCESS] Stop recognition");
1573
1574         SLOG(LOG_INFO, TAG_STTD, "[INFO] Add g_processing_timer");
1575         if (NULL == g_processing_timer) {
1576                 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1577         }
1578
1579         sttd_client_set_streaming(uid, false);
1580         return STTD_ERROR_NONE;
1581 }
1582
1583 static int __sttd_server_cancel(unsigned int uid)
1584 {
1585         /* check if uid is valid */
1586         app_state_e state;
1587         if (0 != sttd_client_get_state(uid, &state)) {
1588                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1589                 return STTD_ERROR_INVALID_PARAMETER;
1590         }
1591
1592         /* check uid state */
1593         if (APP_STATE_READY == state) {
1594                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is ready");
1595                 return STTD_ERROR_NONE;
1596         }
1597
1598         stt_client_unset_current_recognition();
1599
1600         delete_timers_related_to_recording_session();
1601
1602         if (APP_STATE_RECORDING == state) {
1603                 /* Unset audio session */
1604                 int ret = sttd_recorder_unset_audio_session();
1605                 if (0 != ret) {
1606                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1607                         return ret;
1608                 }
1609         }
1610
1611         /* change uid state */
1612         sttd_client_set_state(uid, APP_STATE_READY);
1613
1614         SLOG(LOG_INFO, TAG_STTD, "[Server Info] stt cancel is invoked by app's request");
1615
1616         /* cancel engine recognition */
1617         int ret = sttd_engine_agent_recognize_cancel();
1618         if (0 != ret) {
1619                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1620                 return ret;
1621         }
1622
1623         /* Notify uid state change */
1624         sttdc_send_set_state(uid, APP_STATE_READY);
1625
1626         return ret;
1627 }
1628
1629 int sttd_server_cancel(unsigned int uid)
1630 {
1631         SLOG(LOG_INFO, TAG_STTD, "[Server INFO] Enter sttd_server_cancel");
1632
1633         int ret = __sttd_server_cancel(uid);
1634         if (0 != ret) {
1635                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(0x%x)", ret);
1636         }
1637
1638         SLOG(LOG_INFO, TAG_STTD, "[Server INFO] End sttd_server_cancel");
1639         return ret;
1640 }
1641
1642 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)
1643 {
1644         if (NULL == lang || NULL == recognition_type || NULL == filepath) {
1645                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
1646                 return STTD_ERROR_INVALID_PARAMETER;
1647         }
1648
1649         int ret = __sttd_server_check_precondition_to_start(uid, appid);
1650         if (0 != ret) {
1651                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to satisfy preconditions, ret(0x%x)", ret);
1652                 return ret;
1653         }
1654
1655         if (0 != stt_client_set_current_recognition(uid)) {
1656                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
1657                 return STTD_ERROR_RECORDER_BUSY;
1658         }
1659
1660         /* engine start recognition */
1661         SLOG(LOG_DEBUG, TAG_STTD, "[Server] start : uid(%u), lang(%s), recog_type(%s), appid(%s), file(%s)", uid, lang, recognition_type, appid, filepath);
1662
1663         /* 1. Set audio session */
1664         ret = sttd_recorder_set_audio_session();
1665         if (0 != ret) {
1666                 stt_client_unset_current_recognition();
1667                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set session : %d", ret);
1668                 return ret;
1669         }
1670
1671         /* 2. Start engine to recognize */
1672         ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, appid, credential, NULL);
1673         if (0 != ret) {
1674                 stt_client_unset_current_recognition();
1675                 sttd_recorder_unset_audio_session();
1676                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start engine : result(%d)", ret);
1677                 return ret;
1678         }
1679
1680         sttd_client_set_state(uid, APP_STATE_RECORDING);
1681         sttdc_send_set_state(uid, APP_STATE_RECORDING);
1682
1683         /* 3. Start to send pcm from file to engine */
1684         ret = sttd_engine_agent_recognize_start_file(uid, filepath);
1685         if (0 != ret) {
1686                 stt_client_unset_current_recognition();
1687                 sttd_recorder_unset_audio_session();
1688                 sttd_engine_agent_recognize_cancel();
1689                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start file : result(%d)", ret);
1690                 return ret;
1691         }
1692
1693         /* 4. Stop to send pcm from file  */
1694         ret = sttd_engine_agent_recognize_stop_file();
1695         if (0 != ret) {
1696                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop recorder : result(%d)", ret);
1697                 stt_client_unset_current_recognition();
1698                 sttd_recorder_unset_audio_session();
1699                 sttd_engine_agent_recognize_cancel();
1700                 return ret;
1701         }
1702
1703         /* 5. change & notify uid state */
1704         sttd_client_set_state(uid, APP_STATE_PROCESSING);
1705         sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1706
1707         /* 6. Unset audio session */
1708         ret = sttd_recorder_unset_audio_session();
1709         if (0 != ret) {
1710                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1711                 stt_client_unset_current_recognition();
1712                 return ret;
1713         }
1714
1715         /* 7. Stop engine */
1716         ret = sttd_engine_agent_recognize_stop_engine();
1717         if (0 != ret) {
1718                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1719                 stt_client_unset_current_recognition();
1720                 return ret;
1721         }
1722
1723         return STTD_ERROR_NONE;
1724 }
1725
1726 int sttd_server_cancel_file(unsigned int uid)
1727 {
1728         SLOG(LOG_INFO, TAG_STTD, "[Server INFO] Enter sttd_server_cancel_file");
1729
1730         int ret = __sttd_server_cancel(uid);
1731         if (0 != ret) {
1732                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel file : result(0x%x)", ret);
1733         }
1734
1735         SLOG(LOG_INFO, TAG_STTD, "[Server INFO] End sttd_server_cancel_file");
1736         return ret;
1737 }