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