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