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