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