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