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