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