Add functions to set credential
[platform/core/uifw/stt.git] / server / sttd_server.c
1 /*
2 *  Copyright (c) 2011-2014 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 static pthread_mutex_t sttpe_result_mutex = PTHREAD_MUTEX_INITIALIZER;
28 static pthread_mutex_t sttpe_result_time_mutex = PTHREAD_MUTEX_INITIALIZER;
29
30
31 /*
32 * STT Server static variable
33 */
34 static double g_processing_timeout = 30;
35
36 static double g_recording_timeout = 60;
37
38 Ecore_Timer*    g_recording_timer = NULL;
39 Ecore_Timer*    g_processing_timer = NULL;
40
41 static int g_recording_log_count = 0;
42
43 static GList *g_proc_list = NULL;
44
45 /*
46 * STT Server Callback Functions
47 */
48 void __stop_by_silence(void *data)
49 {
50         SLOG(LOG_DEBUG, TAG_STTD, "===== Stop by silence detection");
51
52         int uid = 0;
53
54         uid = stt_client_get_current_recognition();
55
56         int ret;
57         if (0 != uid) {
58                 ret = sttd_server_stop(uid);
59                 if (0 > ret) {
60                         return;
61                 }
62
63                 if (STTD_RESULT_STATE_DONE == ret) {
64                         ret = sttdc_send_set_state(uid, (int)APP_STATE_PROCESSING);
65                         if (0 != ret) {
66                                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send state : result(%d)", ret);
67
68                                 /* Remove client */
69                                 sttd_server_finalize(uid);
70                                 stt_client_unset_current_recognition();
71                         }
72                 }
73         } else {
74                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid is NOT valid");
75         }
76
77         SLOG(LOG_DEBUG, TAG_STTD, "=====");
78         SLOG(LOG_DEBUG, TAG_STTD, "  ");
79
80         return;
81 }
82
83 static void __cancel_recognition_internal()
84 {
85         if (NULL != g_recording_timer)  {
86                 ecore_timer_del(g_recording_timer);
87                 g_recording_timer = NULL;
88         }
89
90         int uid = 0;
91         uid = stt_client_get_current_recognition();
92
93         if (0 != uid) {
94                 /* cancel engine recognition */
95                 int ret = sttd_engine_agent_recognize_cancel(uid);
96                 if (0 != ret) {
97                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
98                 }
99
100                 /* change uid state */
101                 sttd_client_set_state(uid, APP_STATE_READY);
102                 stt_client_unset_current_recognition();
103
104                 ret = sttdc_send_set_state(uid, (int)APP_STATE_READY);
105                 if (0 != ret) {
106                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send state change : result(%d)", ret);
107                 }
108         } else {
109                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid is NOT valid");
110         }
111 }
112
113 static void __cancel_by_error(void *data)
114 {
115         SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by error");
116
117         __cancel_recognition_internal();
118
119         SLOG(LOG_DEBUG, TAG_STTD, "=====");
120         SLOG(LOG_DEBUG, TAG_STTD, "  ");
121
122         return;
123 }
124
125 int __server_audio_recorder_callback(const void* data, const unsigned int length)
126 {
127         int uid = -1;
128         int ret;
129
130         if (NULL == data || 0 == length) {
131                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Recording data is not valid");
132                 ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
133                 return -1;
134         }
135
136         uid = stt_client_get_current_recognition();
137         if (0 != uid) {
138                 ret = sttd_engine_agent_set_recording_data(uid, data, length);
139                 if (ret < 0) {
140                         ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
141                         return -1;
142                 }
143                 g_recording_log_count++;
144                 if (200 <= g_recording_log_count) {
145                         SLOG(LOG_DEBUG, TAG_STTD, "=== Set recording data ===");
146                         g_recording_log_count = 0;
147                 }
148         } else {
149                 if (NULL != g_recording_timer)  {
150                         ecore_timer_del(g_recording_timer);
151                         g_recording_timer = NULL;
152                 }
153                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current uid in recording is is not valid");
154                 return -1;
155         }
156
157         return 0;
158 }
159
160 void __server_audio_interrupt_callback()
161 {
162         SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by sound interrupt");
163
164         __cancel_recognition_internal();
165
166         SLOG(LOG_DEBUG, TAG_STTD, "=====");
167         SLOG(LOG_DEBUG, TAG_STTD, "  ");
168 }
169
170 void __cancel_by_no_record(void *data)
171 {
172         SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by no record");
173
174         __cancel_recognition_internal();
175
176         SLOG(LOG_DEBUG, TAG_STTD, "=====");
177         SLOG(LOG_DEBUG, TAG_STTD, "  ");
178
179         return;
180 }
181
182 void __server_recognition_result_callback(sttp_result_event_e event, const char* type,
183                                         const char** data, int data_count, const char* msg, void *user_data)
184 {
185         // critical section
186         pthread_mutex_lock(&sttpe_result_mutex);
187
188         SLOG(LOG_DEBUG, TAG_STTD, "===== RESULT event[%d] type[%s] data[%p] data_count[%d]", event, type, data, data_count);
189
190         /* check uid */
191         int uid = stt_client_get_current_recognition();
192
193         app_state_e state;
194         if (0 == uid || 0 != sttd_client_get_state(uid, &state)) {
195                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
196                 SLOG(LOG_DEBUG, TAG_STTD, "=====");
197                 SLOG(LOG_DEBUG, TAG_STTD, "  ");
198                 pthread_mutex_unlock(&sttpe_result_mutex);
199                 return;
200         }
201
202         SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid (%d), event(%d)", uid, event);
203
204         /* send result to client */
205         if (STTP_RESULT_EVENT_FINAL_RESULT == event) {
206                 if (APP_STATE_PROCESSING != state) {
207                         SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is NOT 'Processing'.");
208                 }
209                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] the size of result from engine is '%d'", data_count);
210
211                 /* Delete timer for processing time out */
212                 if (NULL != g_processing_timer) {
213                         ecore_timer_del(g_processing_timer);
214                         g_processing_timer = NULL;
215                 }
216
217                 sttd_config_time_save();
218                 sttd_config_time_reset();
219
220                 if (NULL == data || 0 == data_count) {
221                         if (0 != sttdc_send_result(uid, event, NULL, 0, msg)) {
222                                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
223                                 int reason = (int)STTD_ERROR_OPERATION_FAILED;
224
225                                 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
226                                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
227                                 }
228                         }
229                 } else {
230                         if (0 != sttdc_send_result(uid, event, data, data_count, msg)) {
231                                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
232                                 int reason = (int)STTD_ERROR_OPERATION_FAILED;
233
234                                 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
235                                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
236                                 }
237                         }
238                 }
239
240                 /* change state of uid */
241                 sttd_client_set_state(uid, APP_STATE_READY);
242                 stt_client_unset_current_recognition();
243
244         } else if (STTP_RESULT_EVENT_PARTIAL_RESULT == event) {
245                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The partial result from engine is event[%d] data_count[%d]", event,  data_count);
246
247                 sttd_config_time_save();
248                 sttd_config_time_reset();
249
250                 if (0 != sttdc_send_result(uid, event, data, data_count, msg)) {
251                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
252                         int reason = (int)STTD_ERROR_OPERATION_FAILED;
253
254                         if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
255                                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
256                         }
257                 }
258
259         } else if (STTP_RESULT_EVENT_ERROR == event) {
260                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The event of recognition result is ERROR");
261
262                 /* Delete timer for processing time out */
263                 if (NULL != g_processing_timer) {
264                         ecore_timer_del(g_processing_timer);
265                         g_processing_timer = NULL;
266                 }
267                 sttd_config_time_reset();
268
269                 if (0 != sttdc_send_result(uid, event, NULL, 0, msg)) {
270                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
271
272                         /* send error msg */
273                         int reason = (int)STTD_ERROR_INVALID_STATE;
274                         if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
275                                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
276                         }
277                 }
278
279                 /* change state of uid */
280                 sttd_client_set_state(uid, APP_STATE_READY);
281                 stt_client_unset_current_recognition();
282         } else {
283                 /* nothing */
284         }
285
286         SLOG(LOG_DEBUG, TAG_STTD, "=====");
287         SLOG(LOG_DEBUG, TAG_STTD, "  ");
288         pthread_mutex_unlock(&sttpe_result_mutex);
289
290         return;
291 }
292
293 bool __server_result_time_callback(int index, sttp_result_time_event_e event, const char* text, long start_time, long end_time, void* user_data)
294 {
295         pthread_mutex_lock(&sttpe_result_time_mutex);
296
297         SLOG(LOG_DEBUG, TAG_STTD, "[Server] index(%d) event(%d) text(%s) start(%ld) end(%ld)",
298                 index, event, text, start_time, end_time);
299
300         if (0 == index) {
301                 int ret;
302                 ret = sttd_config_time_add(index, (int)event, text, start_time, end_time);
303                 if (0 != ret) {
304                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add time info");
305                         pthread_mutex_unlock(&sttpe_result_time_mutex);
306                         return false;
307                 }
308         } else {
309                 pthread_mutex_unlock(&sttpe_result_time_mutex);
310                 return false;
311         }
312
313         pthread_mutex_unlock(&sttpe_result_time_mutex);
314
315         return true;
316 }
317
318 void __server_silence_dectection_callback(sttp_silence_type_e type, void *user_param)
319 {
320         SLOG(LOG_DEBUG, TAG_STTD, "===== Silence Detection Callback");
321
322         int uid = stt_client_get_current_recognition();
323         if (0 != uid) {
324                 app_state_e state;
325                 if (0 != sttd_client_get_state(uid, &state)) {
326                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is not valid ");
327                         return;
328                 }
329
330                 if (APP_STATE_RECORDING != state) {
331                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
332                         return;
333                 }
334
335                 if (STTP_SILENCE_TYPE_NO_RECORD_TIMEOUT == type) {
336                         SLOG(LOG_DEBUG, TAG_STTD, "Silence Detection type - No Record");
337                         ecore_main_loop_thread_safe_call_async(__cancel_by_no_record, NULL);
338                 } else if (STTP_SILENCE_TYPE_END_OF_SPEECH_DETECTED == type) {
339                         SLOG(LOG_DEBUG, TAG_STTD, "Silence Detection type - End of Speech");
340                         ecore_main_loop_thread_safe_call_async(__stop_by_silence, NULL);
341                 }
342         } else {
343                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current recogntion uid is not valid ");
344         }
345
346         SLOG(LOG_DEBUG, TAG_STTD, "=====");
347         SLOG(LOG_DEBUG, TAG_STTD, "  ");
348
349         return;
350 }
351
352 void __sttd_server_engine_changed_cb(const char* engine_id, const char* language, bool support_silence, bool need_credential, void* user_data)
353 {
354         if (NULL == engine_id) {
355                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Engine id is NULL");
356                 return;
357         } else {
358                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] New default engine : %s", engine_id);
359         }
360
361         /* need to change state of app to ready */
362         int uid;
363         uid = stt_client_get_current_recognition();
364
365         if (0 != uid) {
366                 SLOG(LOG_ERROR, TAG_STTD, "[Server] Set ready state of uid(%d)", uid);
367
368                 sttd_server_cancel(uid);
369                 sttdc_send_set_state(uid, (int)APP_STATE_READY);
370
371                 stt_client_unset_current_recognition();
372         }
373
374         /* set engine */
375         int ret = sttd_engine_agent_set_default_engine(engine_id);
376         if (0 != ret)
377                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : result(%d)", ret);
378
379         if (NULL != language) {
380                 ret = sttd_engine_agent_set_default_language(language);
381                 if (0 != ret)
382                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret);
383         }
384
385         ret = sttd_engine_agent_set_silence_detection(support_silence);
386         if (0 != ret)
387                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret);
388
389         return;
390 }
391
392 void __sttd_server_language_changed_cb(const char* language, void* user_data)
393 {
394         if (NULL == language) {
395                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] language is NULL");
396                 return;
397         } else {
398                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Get language changed : %s", language);
399         }
400
401         int ret = sttd_engine_agent_set_default_language(language);
402         if (0 != ret)
403                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret);
404
405         return;
406 }
407
408 void __sttd_server_silence_changed_cb(bool value, void* user_data)
409 {
410         SLOG(LOG_DEBUG, TAG_STTD, "[Server] Get silence detection changed : %s", value ? "on" : "off");
411
412         int ret = 0;
413         ret = sttd_engine_agent_set_silence_detection(value);
414         if (0 != ret)
415                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret);
416
417         return;
418 }
419
420 /*
421 * Daemon function
422 */
423
424 int sttd_initialize()
425 {
426         int ret = 0;
427
428         if (0 != pthread_mutex_init(&sttpe_result_mutex, NULL)) {
429                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize sttpe result mutex.");
430         }
431
432         if (0 != pthread_mutex_init(&sttpe_result_time_mutex, NULL)) {
433                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize sttpe sttpe_result_time_mutex.");
434         }
435
436         if (sttd_config_initialize(__sttd_server_engine_changed_cb, __sttd_server_language_changed_cb,
437                 __sttd_server_silence_changed_cb, NULL)) {
438                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize config.");
439         }
440
441         ret = sttd_recorder_initialize(__server_audio_recorder_callback, __server_audio_interrupt_callback);
442         if (0 != ret) {
443                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize recorder : result(%d)", ret);
444         }
445
446         /* Engine Agent initialize */
447         ret = sttd_engine_agent_init(__server_recognition_result_callback, __server_result_time_callback,
448                 __server_silence_dectection_callback);
449         if (0 != ret) {
450                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret);
451                 return ret;
452         }
453
454         /* Update engine list */
455         ret = sttd_engine_agent_initialize_engine_list();
456         if (0 != ret) {
457                 if (STTD_ERROR_ENGINE_NOT_FOUND == ret) {
458                         SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] There is no stt engine");
459                 } else {
460                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to update engine list : %d", ret);
461                         return ret;
462                 }
463         }
464
465         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] initialize");
466
467         return 0;
468 }
469
470 int sttd_finalize()
471 {
472         if (0 != pthread_mutex_destroy(&sttpe_result_mutex)) {
473                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy sttpe result mutex.");
474         }
475
476         if (0 != pthread_mutex_destroy(&sttpe_result_time_mutex)) {
477                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy sttpe_result_time_mutex.");
478         }
479
480         GList *iter = NULL;
481         if (0 < g_list_length(g_proc_list)) {
482                 iter = g_list_first(g_proc_list);
483                 while (NULL != iter) {
484                         g_proc_list = g_list_remove_link(g_proc_list, iter);
485                         iter = g_list_first(g_proc_list);
486                 }
487         }
488
489         sttd_recorder_deinitialize();
490
491         sttd_config_finalize();
492
493         sttd_engine_agent_release();
494
495         return STTD_ERROR_NONE;
496 }
497
498 static void __read_proc()
499 {
500         DIR *dp = NULL;
501         struct dirent entry;
502         struct dirent *dirp = NULL;
503         int ret = -1;
504         int tmp;
505
506         GList *iter = NULL;
507         if (0 < g_list_length(g_proc_list)) {
508                 iter = g_list_first(g_proc_list);
509                 while (NULL != iter) {
510                         g_proc_list = g_list_remove_link(g_proc_list, iter);
511                         iter = g_list_first(g_proc_list);
512                 }
513         }
514
515         dp = opendir("/proc");
516         if (NULL == dp) {
517                 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to open proc");
518         } else {
519                 do {
520                         ret = readdir_r(dp, &entry, &dirp);
521                         if (0 != ret) {
522                                 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to readdir");
523                                 break;
524                         }
525
526                         if (NULL != dirp) {
527                                 tmp = atoi(dirp->d_name);
528                                 if (0 >= tmp)   continue;
529                                 g_proc_list = g_list_append(g_proc_list, GINT_TO_POINTER(tmp));
530                         }
531                 } while (NULL != dirp);
532                 closedir(dp);
533         }
534         return;
535 }
536
537 Eina_Bool sttd_cleanup_client(void *data)
538 {
539         int* client_list = NULL;
540         int client_count = 0;
541         int i = 0;
542         int j = 0;
543         bool exist = false;
544
545         if (0 != sttd_client_get_list(&client_list, &client_count)) {
546                 if (NULL != client_list)
547                         free(client_list);
548
549                 return EINA_TRUE;
550         }
551
552         if (NULL != client_list) {
553                 SLOG(LOG_DEBUG, TAG_STTD, "===== Clean up client ");
554                 
555                 __read_proc();
556
557                 for (i = 0; i < client_count; i++) {
558                         int pid = sttd_client_get_pid(client_list[i]);
559                         if (0 > pid) {
560                                 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Invalid pid");
561                                 continue;
562                         }
563
564                         exist = false;
565                         GList *iter = NULL;
566                         for (j = 0; j < g_list_length(g_proc_list); j++) {
567                                 iter = g_list_nth(g_proc_list, j);
568                                 if (NULL != iter) {
569                                         if (pid == GPOINTER_TO_INT(iter->data)) {
570                                                 SLOG(LOG_DEBUG, TAG_STTD, "uid (%d) is running", client_list[i]);
571                                                 exist = true;
572                                                 break;
573                                         }
574                                 }
575                         }
576
577                         if (false == exist) {
578                                 SLOG(LOG_ERROR, TAG_STTD, "uid (%d) should be removed", client_list[i]);
579                                 sttd_server_finalize(client_list[i]);
580                         }
581 #if 0
582                         result = sttdc_send_hello(client_list[i]);
583
584                         if (0 == result) {
585                                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", client_list[i]);
586                                 sttd_server_finalize(client_list[i]);
587                         } else if (-1 == result) {
588                                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Hello result has error");
589                         }
590 #endif
591                 }
592
593                 SLOG(LOG_DEBUG, TAG_STTD, "=====");
594                 SLOG(LOG_DEBUG, TAG_STTD, "  ");
595
596                 free(client_list);
597         }
598
599         return EINA_TRUE;
600 }
601
602 /*
603 * STT Server Functions for Client
604 */
605
606 int sttd_server_initialize(int pid, int uid, bool* silence, bool* credential)
607 {
608         if (false == sttd_engine_agent_is_default_engine()) {
609                 /* Update installed engine */
610                 sttd_engine_agent_initialize_engine_list();
611
612                 if (false == sttd_engine_agent_is_default_engine()) {
613                         SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] No stt-engine");
614                         return STTD_ERROR_ENGINE_NOT_FOUND;
615                 }
616         }
617
618         /* check if uid is valid */
619         app_state_e state;
620         if (0 == sttd_client_get_state(uid, &state)) {
621                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid has already been registered");
622                 return STTD_ERROR_NONE;
623         }
624
625         /* load engine */
626         if (0 != sttd_engine_agent_load_current_engine(uid, NULL)) {
627                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to load default engine");
628                 return STTD_ERROR_OPERATION_FAILED;
629         }
630
631         if (0 != sttd_engine_agent_get_option_supported(uid, silence)) {
632                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine options supported");
633                 return STTD_ERROR_OPERATION_FAILED;
634         }
635
636         if (0 != sttd_engine_agent_is_credential_needed(uid, credential)) {
637                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get credential necessity");
638                 return STTD_ERROR_OPERATION_FAILED;
639         }
640
641         /* Add client information to client manager */
642         if (0 != sttd_client_add(pid, uid)) {
643                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add client info");
644                 return STTD_ERROR_OPERATION_FAILED;
645         }
646
647         return STTD_ERROR_NONE;
648 }
649
650 static Eina_Bool __quit_ecore_loop(void *data)
651 {
652         ecore_main_loop_quit();
653         return EINA_FALSE;
654 }
655
656 int sttd_server_finalize(int uid)
657 {
658         /* check if uid is valid */
659         app_state_e state;
660         if (0 != sttd_client_get_state(uid, &state)) {
661                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
662                 return STTD_ERROR_INVALID_PARAMETER;
663         }
664
665         /* release recorder */
666         if (APP_STATE_RECORDING == state || APP_STATE_PROCESSING == state) {
667                 if (APP_STATE_RECORDING == state) {
668                         if (NULL != g_recording_timer)  {
669                                 ecore_timer_del(g_recording_timer);
670                                 g_recording_timer = NULL;
671                         }
672                 }
673
674                 if (APP_STATE_PROCESSING == state) {
675                         if (NULL != g_processing_timer) {
676                                 ecore_timer_del(g_processing_timer);
677                                 g_processing_timer = NULL;
678                         }
679                 }
680
681                 if (0 != sttd_engine_agent_recognize_cancel(uid)) {
682                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognition");
683                 }
684
685                 stt_client_unset_current_recognition();
686         }
687
688         if (0 != sttd_engine_agent_unload_current_engine(uid)) {
689                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unload engine");
690         }
691
692         /* Remove client information */
693         if (0 != sttd_client_delete(uid)) {
694                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to delete client");
695         }
696
697         /* unload engine, if ref count of client is 0 */
698         if (0 == sttd_client_get_ref_count()) {
699                 sttd_dbus_close_connection();
700                 ecore_timer_add(0, __quit_ecore_loop, NULL);
701         }
702
703         return STTD_ERROR_NONE;
704 }
705
706 int sttd_server_get_supported_engines(int uid, GSList** engine_list)
707 {
708         /* Check if uid is valid */
709         app_state_e state;
710         if (0 != sttd_client_get_state(uid, &state)) {
711                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
712                 return STTD_ERROR_INVALID_PARAMETER;
713         }
714
715         /* Check state of uid */
716         if (APP_STATE_READY != state) {
717                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
718                 return STTD_ERROR_INVALID_STATE;
719         }
720
721         int ret;
722         ret = sttd_engine_agent_get_engine_list(engine_list);
723         if (0 != ret) {
724                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine list");
725                 return STTD_ERROR_OPERATION_FAILED;
726         }
727
728         return STTD_ERROR_NONE;
729 }
730
731 int sttd_server_set_current_engine(int uid, const char* engine_id, bool* silence, bool* credential)
732 {
733         /* Check if uid is valid */
734         app_state_e state;
735         if (0 != sttd_client_get_state(uid, &state)) {
736                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
737                 return STTD_ERROR_INVALID_PARAMETER;
738         }
739
740         /* Check state of uid */
741         if (APP_STATE_READY != state) {
742                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
743                 return STTD_ERROR_INVALID_STATE;
744         }
745
746         int ret;
747         ret = sttd_engine_agent_load_current_engine(uid, engine_id);
748         if (0 != ret) {
749                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : %d", ret);
750                 return STTD_ERROR_OPERATION_FAILED;
751         }
752
753         ret = sttd_engine_agent_get_option_supported(uid, silence);
754         if (0 != ret) {
755                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine options : %d", ret);
756                 return STTD_ERROR_OPERATION_FAILED;
757         }
758
759         if (0 != sttd_engine_agent_is_credential_needed(uid, credential)) {
760                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get credential necessity");
761                 return STTD_ERROR_OPERATION_FAILED;
762         }
763
764         return STTD_ERROR_NONE;
765 }
766
767 int sttd_server_get_current_engine(int uid, char** engine_id)
768 {
769         /* Check if uid is valid */
770         app_state_e state;
771         if (0 != sttd_client_get_state(uid, &state)) {
772                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
773                 return STTD_ERROR_INVALID_PARAMETER;
774         }
775
776         /* Check state of uid */
777         if (APP_STATE_READY != state) {
778                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
779                 return STTD_ERROR_INVALID_STATE;
780         }
781
782         int ret;
783         ret = sttd_engine_agent_get_current_engine(uid, engine_id);
784         if (0 != ret) {
785                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine : %d", ret);
786                 return STTD_ERROR_OPERATION_FAILED;
787         }
788
789         return STTD_ERROR_NONE;
790 }
791
792 int sttd_server_check_app_agreed(int uid, const char* appid, bool* available)
793 {
794         /* Check if uid is valid */
795         app_state_e state;
796         if (0 != sttd_client_get_state(uid, &state)) {
797                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
798                 return STTD_ERROR_INVALID_PARAMETER;
799         }
800
801         /* Check state of uid */
802         if (APP_STATE_READY != state) {
803                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
804                 return STTD_ERROR_INVALID_STATE;
805         }
806
807         /* Ask engine available */
808         int ret;
809         bool temp = false;
810         ret = sttd_engine_agent_check_app_agreed(uid, appid, &temp);
811         if (0 != ret) {
812                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
813                 return STTD_ERROR_OPERATION_FAILED;
814         }
815
816         if (true == temp) {
817                 stt_client_set_app_agreed(uid);
818                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] App(%s) confirmed that engine is available", appid);
819         }
820
821         *available = temp;
822
823         return STTD_ERROR_NONE;
824 }
825
826
827 int sttd_server_get_supported_languages(int uid, GSList** lang_list)
828 {
829         /* check if uid is valid */
830         app_state_e state;
831         if (0 != sttd_client_get_state(uid, &state)) {
832                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
833                 return STTD_ERROR_INVALID_PARAMETER;
834         }
835
836         /* get language list from engine */
837         int ret = sttd_engine_agent_supported_langs(uid, lang_list);
838         if (0 != ret) {
839                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get supported languages");
840                 return STTD_ERROR_OPERATION_FAILED;
841         }
842
843         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] sttd_server_get_supported_languages");
844
845         return STTD_ERROR_NONE;
846 }
847
848 int sttd_server_get_current_langauage(int uid, char** current_lang)
849 {
850         /* check if uid is valid */
851         app_state_e state;
852         if (0 != sttd_client_get_state(uid, &state)) {
853                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
854                 return STTD_ERROR_INVALID_PARAMETER;
855         }
856
857         if (NULL == current_lang) {
858                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
859                 return STTD_ERROR_INVALID_PARAMETER;
860         }
861
862         /*get current language from engine */
863         int ret = sttd_engine_agent_get_default_lang(uid, current_lang);
864         if (0 != ret) {
865                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get default language :result(%d)", ret);
866                 return STTD_ERROR_OPERATION_FAILED;
867         }
868
869         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Get default language");
870
871         return STTD_ERROR_NONE;
872 }
873
874 int sttd_server_is_recognition_type_supported(int uid, const char* type, int* support)
875 {
876         /* check if uid is valid */
877         app_state_e state;
878         if (0 != sttd_client_get_state(uid, &state)) {
879                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
880                 return STTD_ERROR_INVALID_PARAMETER;
881         }
882
883         if (NULL == type || NULL == support) {
884                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
885                 return STTD_ERROR_INVALID_PARAMETER;
886         }
887
888         bool temp;
889         int ret = sttd_engine_agent_is_recognition_type_supported(uid, type, &temp);
890         if (0 != ret) {
891                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get recognition type supported : result(%d)", ret);
892                 return STTD_ERROR_OPERATION_FAILED;
893         }
894
895         *support = (int)temp;
896
897         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] recognition type supporting is %s", *support ? "true" : "false");
898
899         return STTD_ERROR_NONE;
900 }
901
902 int sttd_server_set_start_sound(int uid, const char* file)
903 {
904         /* check if uid is valid */
905         app_state_e state;
906         if (0 != sttd_client_get_state(uid, &state)) {
907                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
908                 return STTD_ERROR_INVALID_PARAMETER;
909         }
910
911         int ret = sttd_client_set_start_sound(uid, file);
912         if (0 != ret) {
913                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
914                 return STTD_ERROR_OPERATION_FAILED;
915         }
916
917         return 0;
918 }
919
920 int sttd_server_set_stop_sound(int uid, const char* file)
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         int ret = sttd_client_set_stop_sound(uid, file);
930         if (0 != ret) {
931                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
932                 return STTD_ERROR_OPERATION_FAILED;
933         }
934
935         return 0;
936 }
937
938 #if 0
939 Eina_Bool __check_recording_state(void *data)
940 {
941         /* current uid */
942         int uid = stt_client_get_current_recognition();
943         if (0 == uid)
944                 return EINA_FALSE;
945
946         app_state_e state;
947         if (0 != sttdc_send_get_state(uid, (int*)&state)) {
948                 /* client is removed */
949                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", uid);
950                 sttd_server_finalize(uid);
951                 return EINA_FALSE;
952         }
953
954         if (APP_STATE_READY == state) {
955                 /* Cancel stt */
956                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Ready'. The daemon should cancel recording", uid);
957                 sttd_server_cancel(uid);
958         } else if (APP_STATE_PROCESSING == state) {
959                 /* Cancel stt and send change state */
960                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Processing'. The daemon should cancel recording", uid);
961                 sttd_server_cancel(uid);
962                 sttdc_send_set_state(uid, (int)APP_STATE_READY);
963         } else {
964                 /* Normal state */
965                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The states of daemon and client are identical");
966                 return EINA_TRUE;
967         }
968
969         return EINA_FALSE;
970 }
971 #endif
972
973 Eina_Bool __stop_by_recording_timeout(void *data)
974 {
975         SLOG(LOG_DEBUG, TAG_STTD, "===== Stop by timeout");
976
977         g_recording_timer = NULL;
978
979         int uid = 0;
980         uid = stt_client_get_current_recognition();
981         if (0 != uid) {
982                 /* cancel engine recognition */
983                 int ret = sttd_server_stop(uid);
984                 if (0 != ret) {
985                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop : result(%d)", ret);
986                 }
987         }
988
989         SLOG(LOG_DEBUG, TAG_STTD, "=====");
990         SLOG(LOG_DEBUG, TAG_STTD, "  ");
991
992         return EINA_FALSE;
993 }
994
995 void __sttd_server_recorder_start(void* data)
996 {
997         intptr_t puid = (intptr_t)data;
998         int uid = (int)puid;
999         int current_uid = stt_client_get_current_recognition();
1000
1001         if (uid != current_uid) {
1002                 stt_client_unset_current_recognition();
1003                 return;
1004         }
1005
1006         int ret = sttd_engine_agent_recognize_start_recorder(uid);
1007         if (0 != ret) {
1008                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1009                 return;
1010         }
1011
1012         /* Notify uid state change */
1013         sttdc_send_set_state(uid, APP_STATE_RECORDING);
1014
1015         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
1016 }
1017
1018 void __sttd_start_sound_completed_cb(int id, void *user_data)
1019 {
1020         SLOG(LOG_DEBUG, TAG_STTD, "===== Start sound completed");
1021
1022         /* After wav play callback, recorder start */
1023         ecore_main_loop_thread_safe_call_async(__sttd_server_recorder_start, user_data);
1024
1025         SLOG(LOG_DEBUG, TAG_STTD, "=====");
1026         SLOG(LOG_DEBUG, TAG_STTD, "  ");
1027         return;
1028 }
1029
1030 int sttd_server_start(int uid, const char* lang, const char* recognition_type, int silence, const char* appid, const char* credential)
1031 {
1032         if (NULL == lang || NULL == recognition_type) {
1033                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
1034                 return STTD_ERROR_INVALID_PARAMETER;
1035         }
1036
1037         /* check if uid is valid */
1038         app_state_e state;
1039         if (0 != sttd_client_get_state(uid, &state)) {
1040                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1041                 return STTD_ERROR_INVALID_PARAMETER;
1042         }
1043
1044         /* check uid state */
1045         if (APP_STATE_READY != state) {
1046                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] sttd_server_start : current state is not ready");
1047                 return STTD_ERROR_INVALID_STATE;
1048         }
1049
1050         int ret = 0;
1051         if (false == stt_client_get_app_agreed(uid)) {
1052                 bool temp = false;
1053                 ret = sttd_engine_agent_check_app_agreed(uid, appid, &temp);
1054                 if (0 != ret) {
1055                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
1056                         return STTD_ERROR_OPERATION_FAILED;
1057                 }
1058
1059                 if (false == temp) {
1060                         SLOG(LOG_ERROR, TAG_STTD, "[Server] App(%s) NOT confirmed that engine is available", appid);
1061                         return STTD_ERROR_PERMISSION_DENIED;
1062                 }
1063
1064                 stt_client_set_app_agreed(uid);
1065         }
1066
1067         /* check if engine use network */
1068         if (true == sttd_engine_agent_need_network(uid)) {
1069                 if (false == stt_network_is_connected()) {
1070                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Disconnect network. Current engine needs to network connection.");
1071                         return STTD_ERROR_OUT_OF_NETWORK;
1072                 }
1073         }
1074
1075         char* sound = NULL;
1076         if (0 != sttd_client_get_start_sound(uid, &sound)) {
1077                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
1078                 return STTD_ERROR_OPERATION_FAILED;
1079         }
1080
1081         if (0 != stt_client_set_current_recognition(uid)) {
1082                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
1083                 if (NULL != sound)      free(sound);
1084                 return STTD_ERROR_RECORDER_BUSY;
1085         }
1086
1087         /* engine start recognition */
1088         SLOG(LOG_DEBUG, TAG_STTD, "[Server] start : uid(%d), lang(%s), recog_type(%s)",
1089                         uid, lang, recognition_type);
1090         if (NULL != sound)
1091                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] start sound : %s", sound);
1092
1093         /* 1. Set audio session */
1094         ret = sttd_recorder_set_audio_session();
1095         if (0 != ret) {
1096                 stt_client_unset_current_recognition();
1097                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set session : %d", ret);
1098                 if (NULL != sound)      free(sound);
1099                 return ret;
1100         }
1101
1102         bool is_sound_done = false;
1103
1104         /* 2. Request wav play */
1105         if (NULL != sound) {
1106                 int id = 0;
1107                 intptr_t puid = (intptr_t)uid;
1108                 ret = wav_player_start(sound, SOUND_TYPE_MEDIA, __sttd_start_sound_completed_cb, (void*)puid, &id);
1109                 if (WAV_PLAYER_ERROR_NONE != ret) {
1110                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
1111                         is_sound_done = true;
1112                 }
1113                 free(sound);
1114                 sound = NULL;
1115         } else {
1116                 is_sound_done = true;
1117         }
1118
1119         /* 3. Create recorder & engine initialize */
1120         ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, credential, NULL);
1121         if (0 != ret) {
1122                 stt_client_unset_current_recognition();
1123                 sttd_recorder_unset_audio_session();
1124                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1125                 return ret;
1126         }
1127
1128         if (0 != strcmp(STTP_RECOGNITION_TYPE_FREE_PARTIAL, recognition_type)) {
1129                 g_recording_timer = ecore_timer_add(g_recording_timeout, __stop_by_recording_timeout, NULL);
1130         }
1131
1132         /* change uid state */
1133         sttd_client_set_state(uid, APP_STATE_RECORDING);
1134
1135         g_recording_log_count = 0;
1136
1137         if (true == is_sound_done) {
1138                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1139
1140                 ret = sttd_engine_agent_recognize_start_recorder(uid);
1141                 if (0 != ret) {
1142                         stt_client_unset_current_recognition();
1143                         sttd_recorder_unset_audio_session();
1144
1145                         sttd_engine_agent_recognize_cancel(uid);
1146                         ecore_timer_del(g_recording_timer);
1147                         sttd_client_set_state(uid, APP_STATE_READY);
1148
1149                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
1150                         return STTD_ERROR_OPERATION_FAILED;
1151                 }
1152
1153                 /* Notify uid state change */
1154                 sttdc_send_set_state(uid, APP_STATE_RECORDING);
1155
1156                 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
1157                 return STTD_RESULT_STATE_DONE;
1158         }
1159
1160         SLOG(LOG_DEBUG, TAG_STTD, "[Server] Wait sound finish");
1161
1162         return STTD_RESULT_STATE_NOT_DONE;
1163 }
1164
1165 Eina_Bool __time_out_for_processing(void *data)
1166 {
1167         g_processing_timer = NULL;
1168
1169         /* current uid */
1170         int uid = stt_client_get_current_recognition();
1171         if (0 == uid)   return EINA_FALSE;
1172
1173         /* Cancel engine */
1174         int ret = sttd_engine_agent_recognize_cancel(uid);
1175         if (0 != ret) {
1176                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1177         }
1178
1179         if (0 != sttdc_send_result(uid, STTP_RESULT_EVENT_FINAL_RESULT, NULL, 0, "Time out not to receive recognition result.")) {
1180                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
1181
1182                 /* send error msg */
1183                 int reason = (int)STTD_ERROR_TIMED_OUT;
1184                 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
1185                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
1186                 }
1187         }
1188
1189         /* Change uid state */
1190         sttd_client_set_state(uid, APP_STATE_READY);
1191
1192         stt_client_unset_current_recognition();
1193
1194         return EINA_FALSE;
1195 }
1196
1197 void __sttd_server_engine_stop(void* data)
1198 {
1199         intptr_t puid = (intptr_t)data;
1200         int uid = (int)puid;
1201         /* change uid state */
1202         sttd_client_set_state(uid, APP_STATE_PROCESSING);
1203
1204         /* Notify uid state change */
1205         sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1206
1207         /* Unset audio session */
1208         int ret = sttd_recorder_unset_audio_session();
1209         if (0 != ret) {
1210                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1211                 return;
1212         }
1213
1214         /* Stop engine */
1215         ret = sttd_engine_agent_recognize_stop_engine(uid);
1216         if (0 != ret) {
1217                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1218                 return;
1219         }
1220
1221         SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1222 }
1223
1224 void __sttd_stop_sound_completed_cb(int id, void *user_data)
1225 {
1226         SLOG(LOG_DEBUG, TAG_STTD, "===== Stop sound completed");
1227
1228         /* After wav play callback, engine stop */
1229         ecore_main_loop_thread_safe_call_async(__sttd_server_engine_stop, user_data);
1230
1231         SLOG(LOG_DEBUG, TAG_STTD, "=====");
1232         SLOG(LOG_DEBUG, TAG_STTD, "  ");
1233         return;
1234 }
1235
1236 int sttd_server_stop(int uid)
1237 {
1238         /* check if uid is valid */
1239         app_state_e state;
1240         if (0 != sttd_client_get_state(uid, &state)) {
1241                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1242                 return STTD_ERROR_INVALID_PARAMETER;
1243         }
1244
1245         /* check uid state */
1246         if (APP_STATE_RECORDING != state) {
1247                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
1248                 return STTD_ERROR_INVALID_STATE;
1249         }
1250
1251         if (NULL != g_recording_timer)  {
1252                 ecore_timer_del(g_recording_timer);
1253                 g_recording_timer = NULL;
1254         }
1255
1256         char* sound = NULL;
1257         if (0 != sttd_client_get_stop_sound(uid, &sound)) {
1258                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
1259                 return STTD_ERROR_OPERATION_FAILED;
1260         }
1261
1262         SLOG(LOG_DEBUG, TAG_STTD, "[Server] stop sound path : %s", sound);
1263
1264         int ret;
1265         /* 1. Stop recorder */
1266         ret = sttd_engine_agent_recognize_stop_recorder(uid);
1267         if (0 != ret) {
1268                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop recorder : result(%d)", ret);
1269                 if (0 != sttd_engine_agent_recognize_cancel(uid)) {
1270                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognize");
1271                 }
1272                 if (NULL != sound)      free(sound);
1273                 return STTD_ERROR_OPERATION_FAILED;
1274         }
1275
1276         /* 2. Request wav play */
1277         if (NULL != sound) {
1278                 int id = 0;
1279                 intptr_t puid = (intptr_t)uid;
1280                 ret = wav_player_start(sound, SOUND_TYPE_MEDIA, __sttd_stop_sound_completed_cb, (void*)puid, &id);
1281                 if (WAV_PLAYER_ERROR_NONE != ret) {
1282                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
1283                 } else {
1284                         SLOG(LOG_DEBUG, TAG_STTD, "[Server] Play wav : %s", sound);
1285                 }
1286
1287                 free(sound);
1288
1289                 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1290
1291                 return STTD_RESULT_STATE_NOT_DONE;
1292         } else {
1293                 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1294
1295                 /* Unset audio session */
1296                 ret = sttd_recorder_unset_audio_session();
1297                 if (0 != ret) {
1298                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1299                         return STTD_ERROR_OPERATION_FAILED;
1300                 }
1301
1302                 /* Stop engine */
1303                 ret = sttd_engine_agent_recognize_stop_engine(uid);
1304                 if (0 != ret) {
1305                         stt_client_unset_current_recognition();
1306                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1307                         return STTD_ERROR_OPERATION_FAILED;
1308                 }
1309
1310                 /* change uid state */
1311                 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1312
1313                 /* Notify uid state change */
1314                 sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1315
1316                 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1317
1318                 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1319
1320                 return STTD_RESULT_STATE_DONE;
1321         }
1322
1323         return STTD_ERROR_NONE;
1324 }
1325
1326 int sttd_server_cancel(int uid)
1327 {
1328         /* check if uid is valid */
1329         app_state_e state;
1330         if (0 != sttd_client_get_state(uid, &state)) {
1331                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1332                 return STTD_ERROR_INVALID_PARAMETER;
1333         }
1334
1335         /* check uid state */
1336         if (APP_STATE_READY == state) {
1337                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is ready");
1338                 return STTD_ERROR_NONE;
1339         }
1340
1341         stt_client_unset_current_recognition();
1342
1343         if (NULL != g_recording_timer) {
1344                 ecore_timer_del(g_recording_timer);
1345                 g_recording_timer = NULL;
1346         }
1347
1348         if (NULL != g_processing_timer) {
1349                 ecore_timer_del(g_processing_timer);
1350                 g_processing_timer = NULL;
1351         }
1352
1353         if (APP_STATE_RECORDING == state) {
1354                 /* Unset audio session */
1355                 int ret = sttd_recorder_unset_audio_session();
1356                 if (0 != ret) {
1357                         SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1358                         return STTD_ERROR_OPERATION_FAILED;
1359                 }
1360         }
1361
1362         /* change uid state */
1363         sttd_client_set_state(uid, APP_STATE_READY);
1364
1365         /* cancel engine recognition */
1366         int ret = sttd_engine_agent_recognize_cancel(uid);
1367         if (0 != ret) {
1368                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1369                 return STTD_ERROR_OPERATION_FAILED;
1370         }
1371
1372         /* Notify uid state change */
1373         sttdc_send_set_state(uid, APP_STATE_READY);
1374
1375         return STTD_ERROR_NONE;
1376 }