Refactor sttd_server module according to review
[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_sound_done = 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
1223         app_state_e temp_app_state;
1224
1225         if (true == is_sound_done) {
1226                 SLOG(LOG_INFO, TAG_STTD, "[Server] No sound play");
1227
1228                 ret = sttd_engine_agent_recognize_start_recorder(uid, appid);
1229                 if (0 != ret) {
1230                         stt_client_unset_current_recognition();
1231                         sttd_recorder_unset_audio_session();
1232
1233                         sttd_engine_agent_recognize_cancel();
1234                         if (NULL != g_recording_timer)  {
1235                                 ecore_timer_del(g_recording_timer);
1236                                 g_recording_timer = NULL;
1237                         }
1238                         sttd_client_set_state(uid, APP_STATE_READY);
1239
1240                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
1241                         return ret;
1242                 }
1243
1244                 if (0 != sttd_client_get_state(uid, &temp_app_state)) {
1245                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid");
1246                         return STTD_ERROR_INVALID_PARAMETER;
1247                 }
1248                 if (APP_STATE_READY != temp_app_state && 0 != stt_client_get_current_recognition()) {
1249                         /* Notify uid state change */
1250                         sttdc_send_set_state(uid, APP_STATE_RECORDING);
1251                 }
1252
1253                 SLOG(LOG_INFO, TAG_STTD, "[Server SUCCESS] Start recognition");
1254         } else {
1255                 SLOG(LOG_INFO, TAG_STTD, "[Server] Wait sound finish");
1256         }
1257
1258         sttd_client_set_streaming(uid, false);
1259         return STTD_ERROR_NONE;
1260 }
1261
1262 static Eina_Bool __time_out_for_processing(void *data)
1263 {
1264         g_processing_timer = NULL;
1265         SLOG(LOG_INFO, TAG_STTD, "[Server INFO] Enter __time_out_for_processing");
1266
1267         /* current uid */
1268         unsigned int uid = stt_client_get_current_recognition();
1269         if (STT_INVALID_UID == uid)     return EINA_FALSE;
1270
1271         SLOG(LOG_INFO, TAG_STTD, "[Server Info] stt cancel is invoked by timeout for processing");
1272
1273         /* Cancel engine */
1274         int ret = sttd_engine_agent_recognize_cancel();
1275         if (0 != ret) {
1276                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1277         }
1278
1279         if (0 != sttdc_send_result(uid, STTE_RESULT_EVENT_FINAL_RESULT, NULL, 0, "Time out not to receive recognition result.")) {
1280                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
1281
1282                 /* send error msg */
1283                 int reason = (int)STTD_ERROR_TIMED_OUT;
1284                 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
1285                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
1286                 }
1287         }
1288
1289         /* Change uid state */
1290         sttd_client_set_state(uid, APP_STATE_READY);
1291
1292         stt_client_unset_current_recognition();
1293
1294         SLOG(LOG_INFO, TAG_STTD, "[Server INFO] End __time_out_for_processing");
1295
1296         return EINA_FALSE;
1297 }
1298
1299 static void __sttd_server_engine_stop(void* data)
1300 {
1301         uintptr_t puid = (uintptr_t)data;
1302         unsigned int uid = (unsigned int)puid;
1303         /* change uid state */
1304         sttd_client_set_state(uid, APP_STATE_PROCESSING);
1305
1306         /* Notify uid state change */
1307         sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1308
1309         /* Unset audio session */
1310         int ret = sttd_recorder_unset_audio_session();
1311         if (0 != ret) {
1312                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1313                 return;
1314         }
1315
1316         /* Stop engine */
1317         ret = sttd_engine_agent_recognize_stop_engine();
1318         if (0 != ret) {
1319                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1320                 return;
1321         }
1322
1323         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1324 }
1325
1326 static void __sttd_stop_sound_completed_cb(int id, void *user_data)
1327 {
1328         SLOG(LOG_INFO, TAG_STTD, "===== Stop sound completed");
1329
1330         /* After wav play callback, engine stop */
1331         ecore_main_loop_thread_safe_call_async(__sttd_server_engine_stop, user_data);
1332
1333         SLOG(LOG_DEBUG, TAG_STTD, "=====");
1334         SLOG(LOG_DEBUG, TAG_STTD, "  ");
1335         return;
1336 }
1337
1338 static bool play_stop_sound_for_uid(unsigned int uid)
1339 {
1340         char* sound = NULL;
1341         if (STTD_ERROR_NONE != sttd_client_get_stop_sound(uid, &sound)) {
1342                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start sound");
1343                 return false;
1344         }
1345
1346         if (NULL == sound) {
1347                 SLOG(LOG_INFO, TAG_STTD, "[Server] There is no start sound");
1348                 return false;
1349         }
1350
1351         SLOG(LOG_INFO, TAG_STTD, "[Server] stop sound : %s", sound);
1352
1353         uintptr_t puid = (uintptr_t)uid;
1354         bool ret = play_sound(sound, __sttd_stop_sound_completed_cb, (void*)puid);
1355         free(sound);
1356
1357         return ret;
1358 }
1359
1360 int sttd_server_stop(unsigned int uid)
1361 {
1362         /* check if uid is valid */
1363         app_state_e state;
1364         if (0 != sttd_client_get_state(uid, &state)) {
1365                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1366                 return STTD_ERROR_INVALID_PARAMETER;
1367         }
1368
1369         /* check uid state */
1370         if (APP_STATE_PROCESSING == state) {
1371                 SLOG(LOG_INFO, TAG_STTD, "[Server] State is already processing. Skip stop behavior");
1372                 return STTD_ERROR_NONE;
1373         }
1374
1375         if (APP_STATE_RECORDING != state) {
1376                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
1377                 return STTD_ERROR_INVALID_STATE;
1378         }
1379
1380         if (sttd_client_is_streaming(uid)) {
1381                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current client is not started as default");
1382                 return STTD_ERROR_OPERATION_FAILED;
1383         }
1384
1385         delete_timers_related_to_recording_session();
1386
1387         int ret;
1388         /* 1. Stop recorder */
1389         ret = sttd_engine_agent_recognize_stop_recorder();
1390         if (0 != ret) {
1391                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop recorder : result(%d)", ret);
1392                 if (0 != sttd_engine_agent_recognize_cancel()) {
1393                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognize");
1394                 }
1395                 return ret;
1396         }
1397
1398         /* 2. Request wav play */
1399         if (false == play_stop_sound_for_uid(uid)) {
1400                 SLOG(LOG_INFO, TAG_STTD, "[Server] No stop sound play");
1401
1402                 /* Unset audio session */
1403                 ret = sttd_recorder_unset_audio_session();
1404                 if (0 != ret) {
1405                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1406                         return ret;
1407                 }
1408
1409                 /* Stop engine */
1410                 ret = sttd_engine_agent_recognize_stop_engine();
1411                 if (0 != ret) {
1412                         stt_client_unset_current_recognition();
1413                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1414                         return ret;
1415                 }
1416
1417                 /* change uid state */
1418                 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1419
1420                 /* Notify uid state change */
1421                 sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1422
1423                 SLOG(LOG_INFO, TAG_STTD, "[Server SUCCESS] Stop recognition");
1424         }
1425
1426         SLOG(LOG_INFO, TAG_STTD, "[INFO] Add g_processing_timer");
1427         if (NULL == g_processing_timer) {
1428                 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1429         }
1430
1431         return STTD_ERROR_NONE;
1432 }
1433
1434 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)
1435 {
1436         if (NULL == lang || NULL == recognition_type) {
1437                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
1438                 return STTD_ERROR_INVALID_PARAMETER;
1439         }
1440
1441         int ret = __sttd_server_check_precondition_to_start(uid, appid);
1442         if (STTD_ERROR_NONE != ret) {
1443                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to satisfy preconditions, ret(0x%x)", ret);
1444                 return ret;
1445         }
1446
1447         if (STTD_ERROR_NONE != stt_client_set_current_recognition(uid)) {
1448                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
1449                 return STTD_ERROR_RECORDER_BUSY;
1450         }
1451
1452         delete_timers_related_to_recording_session();
1453
1454         ret = sttd_client_set_audio_id(uid, audio_id);
1455         if (STTD_ERROR_NONE != ret) {
1456                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set audio_id(%s)", audio_id);
1457                 return ret;
1458         }
1459
1460         /* engine start recognition */
1461         SLOG(LOG_INFO, TAG_STTD, "[Server] start : uid(%u), lang(%s), recog_type(%s)", uid, lang, recognition_type);
1462
1463         /* 3. Create recorder & engine initialize */
1464         ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, appid, credential, NULL);
1465         if (STTD_ERROR_NONE != ret) {
1466                 stt_client_unset_current_recognition();
1467                 sttd_recorder_unset_audio_session();
1468                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d/%s)", ret, get_error_message(ret));
1469                 return ret;
1470         }
1471
1472         if (STTD_ERROR_NONE != strncmp(STTE_RECOGNITION_TYPE_FREE_PARTIAL, recognition_type, STT_MAX_TYPE_LENGTH)) {
1473                 if (NULL == g_processing_timer) {
1474                         g_recording_timer = ecore_timer_add(g_recording_timeout, __stop_by_recording_timeout, NULL);
1475                 }
1476         }
1477
1478         /* change uid state */
1479         sttd_client_set_state(uid, APP_STATE_RECORDING);
1480
1481         g_recording_log_count = 0;
1482
1483         app_state_e temp_app_state = APP_STATE_CREATED;
1484         if (0 != sttd_client_get_state(uid, &temp_app_state)) {
1485                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid");
1486                 return STTD_ERROR_INVALID_PARAMETER;
1487         }
1488
1489         if (APP_STATE_READY != temp_app_state && 0 != stt_client_get_current_recognition()) {
1490                 /* Notify uid state change */
1491                 sttdc_send_set_state(uid, APP_STATE_RECORDING);
1492         }
1493
1494         SLOG(LOG_INFO, TAG_STTD, "[Server SUCCESS] Start recognition");
1495
1496         sttd_client_set_streaming(uid, true);
1497         return STTD_ERROR_NONE;
1498 }
1499
1500 int sttd_server_send_audio_streaming(unsigned int uid, const char *data, size_t data_size)
1501 {
1502         app_state_e state = APP_STATE_CREATED;
1503         if (0 != sttd_client_get_state(uid, &state)) {
1504                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1505                 return STTD_ERROR_INVALID_PARAMETER;
1506         }
1507
1508         /* check uid state */
1509         if (APP_STATE_PROCESSING == state) {
1510                 SLOG(LOG_INFO, TAG_STTD, "[Server] State is already processing. Skip stop behavior");
1511                 return STTD_ERROR_NONE;
1512         }
1513
1514         if (APP_STATE_RECORDING != state) {
1515                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
1516                 return STTD_ERROR_INVALID_STATE;
1517         }
1518
1519         if (false == sttd_client_is_streaming(uid)) {
1520                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current client is not started as audio streaming");
1521                 return STTD_ERROR_OPERATION_FAILED;
1522         }
1523
1524         int ret = __server_audio_recorder_callback(data, data_size);
1525         if (0 != ret) {
1526                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send audio data");
1527                 return STTD_ERROR_OPERATION_FAILED;
1528         }
1529
1530         return STTD_ERROR_NONE;
1531 }
1532
1533 int sttd_server_stop_audio_streaming(unsigned int uid)
1534 {
1535         /* check if uid is valid */
1536         app_state_e state = APP_STATE_CREATED;
1537         if (0 != sttd_client_get_state(uid, &state)) {
1538                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1539                 return STTD_ERROR_INVALID_PARAMETER;
1540         }
1541
1542         /* check uid state */
1543         if (APP_STATE_PROCESSING == state) {
1544                 SLOG(LOG_INFO, TAG_STTD, "[Server] State is already processing. Skip stop behavior");
1545                 return STTD_ERROR_NONE;
1546         }
1547
1548         if (APP_STATE_RECORDING != state) {
1549                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
1550                 return STTD_ERROR_INVALID_STATE;
1551         }
1552
1553         if (false == sttd_client_is_streaming(uid)) {
1554                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current client is not started as audio streaming");
1555                 return STTD_ERROR_OPERATION_FAILED;
1556         }
1557
1558         delete_timers_related_to_recording_session();
1559
1560         /* Stop engine */
1561         int ret = sttd_engine_agent_recognize_stop_engine();
1562         if (0 != ret) {
1563                 stt_client_unset_current_recognition();
1564                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1565                 return ret;
1566         }
1567
1568         /* change uid state */
1569         sttd_client_set_state(uid, APP_STATE_PROCESSING);
1570
1571         /* Notify uid state change */
1572         sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1573
1574         SLOG(LOG_INFO, TAG_STTD, "[Server SUCCESS] Stop recognition");
1575
1576         SLOG(LOG_INFO, TAG_STTD, "[INFO] Add g_processing_timer");
1577         if (NULL == g_processing_timer) {
1578                 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1579         }
1580
1581         sttd_client_set_streaming(uid, false);
1582         return STTD_ERROR_NONE;
1583 }
1584
1585 static int __sttd_server_cancel(unsigned int uid)
1586 {
1587         /* check if uid is valid */
1588         app_state_e state;
1589         if (0 != sttd_client_get_state(uid, &state)) {
1590                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1591                 return STTD_ERROR_INVALID_PARAMETER;
1592         }
1593
1594         /* check uid state */
1595         if (APP_STATE_READY == state) {
1596                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is ready");
1597                 return STTD_ERROR_NONE;
1598         }
1599
1600         stt_client_unset_current_recognition();
1601
1602         delete_timers_related_to_recording_session();
1603
1604         if (APP_STATE_RECORDING == state) {
1605                 /* Unset audio session */
1606                 int ret = sttd_recorder_unset_audio_session();
1607                 if (0 != ret) {
1608                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1609                         return ret;
1610                 }
1611         }
1612
1613         /* change uid state */
1614         sttd_client_set_state(uid, APP_STATE_READY);
1615
1616         SLOG(LOG_INFO, TAG_STTD, "[Server Info] stt cancel is invoked by app's request");
1617
1618         /* cancel engine recognition */
1619         int ret = sttd_engine_agent_recognize_cancel();
1620         if (0 != ret) {
1621                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1622                 return ret;
1623         }
1624
1625         /* Notify uid state change */
1626         sttdc_send_set_state(uid, APP_STATE_READY);
1627
1628         return ret;
1629 }
1630
1631 int sttd_server_cancel(unsigned int uid)
1632 {
1633         SLOG(LOG_INFO, TAG_STTD, "[Server INFO] Enter sttd_server_cancel");
1634
1635         int ret = __sttd_server_cancel(uid);
1636         if (0 != ret) {
1637                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(0x%x)", ret);
1638         }
1639
1640         SLOG(LOG_INFO, TAG_STTD, "[Server INFO] End sttd_server_cancel");
1641         return ret;
1642 }
1643
1644 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)
1645 {
1646         if (NULL == lang || NULL == recognition_type || NULL == filepath) {
1647                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
1648                 return STTD_ERROR_INVALID_PARAMETER;
1649         }
1650
1651         int ret = __sttd_server_check_precondition_to_start(uid, appid);
1652         if (0 != ret) {
1653                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to satisfy preconditions, ret(0x%x)", ret);
1654                 return ret;
1655         }
1656
1657         if (0 != stt_client_set_current_recognition(uid)) {
1658                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
1659                 return STTD_ERROR_RECORDER_BUSY;
1660         }
1661
1662         /* engine start recognition */
1663         SLOG(LOG_DEBUG, TAG_STTD, "[Server] start : uid(%u), lang(%s), recog_type(%s), appid(%s), file(%s)", uid, lang, recognition_type, appid, filepath);
1664
1665         /* 1. Set audio session */
1666         ret = sttd_recorder_set_audio_session();
1667         if (0 != ret) {
1668                 stt_client_unset_current_recognition();
1669                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set session : %d", ret);
1670                 return ret;
1671         }
1672
1673         /* 2. Start engine to recognize */
1674         ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, appid, credential, NULL);
1675         if (0 != ret) {
1676                 stt_client_unset_current_recognition();
1677                 sttd_recorder_unset_audio_session();
1678                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start engine : result(%d)", ret);
1679                 return ret;
1680         }
1681
1682         sttd_client_set_state(uid, APP_STATE_RECORDING);
1683         sttdc_send_set_state(uid, APP_STATE_RECORDING);
1684
1685         /* 3. Start to send pcm from file to engine */
1686         ret = sttd_engine_agent_recognize_start_file(uid, filepath);
1687         if (0 != ret) {
1688                 stt_client_unset_current_recognition();
1689                 sttd_recorder_unset_audio_session();
1690                 sttd_engine_agent_recognize_cancel();
1691                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start file : result(%d)", ret);
1692                 return ret;
1693         }
1694
1695         /* 4. Stop to send pcm from file  */
1696         ret = sttd_engine_agent_recognize_stop_file();
1697         if (0 != ret) {
1698                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop recorder : result(%d)", ret);
1699                 stt_client_unset_current_recognition();
1700                 sttd_recorder_unset_audio_session();
1701                 sttd_engine_agent_recognize_cancel();
1702                 return ret;
1703         }
1704
1705         /* 5. change & notify uid state */
1706         sttd_client_set_state(uid, APP_STATE_PROCESSING);
1707         sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1708
1709         /* 6. Unset audio session */
1710         ret = sttd_recorder_unset_audio_session();
1711         if (0 != ret) {
1712                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1713                 stt_client_unset_current_recognition();
1714                 return ret;
1715         }
1716
1717         /* 7. Stop engine */
1718         ret = sttd_engine_agent_recognize_stop_engine();
1719         if (0 != ret) {
1720                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1721                 stt_client_unset_current_recognition();
1722                 return ret;
1723         }
1724
1725         return STTD_ERROR_NONE;
1726 }
1727
1728 int sttd_server_cancel_file(unsigned int uid)
1729 {
1730         SLOG(LOG_INFO, TAG_STTD, "[Server INFO] Enter sttd_server_cancel_file");
1731
1732         int ret = __sttd_server_cancel(uid);
1733         if (0 != ret) {
1734                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel file : result(0x%x)", ret);
1735         }
1736
1737         SLOG(LOG_INFO, TAG_STTD, "[Server INFO] End sttd_server_cancel_file");
1738         return ret;
1739 }