fix merge duplication
[platform/core/uifw/stt.git] / server / sttd_engine_agent.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
15 #include <dlfcn.h>
16 #include <dirent.h>
17 #include <stdatomic.h>
18
19 #include "stt_defs.h"
20 #include "stt_engine.h"
21 #include "sttd_main.h"
22 #include "sttd_client_data.h"
23 #include "sttd_config.h"
24 #include "sttd_dbus.h"
25 #include "sttd_recorder.h"
26 #include "sttd_engine_agent.h"
27 #include "stt_dlog.h"
28
29
30 #define AUDIO_CREATE_ON_START
31
32 /*
33 * Internal data structure
34 */
35
36 typedef struct _sttengine_info {
37         char*   engine_uuid;
38         char*   engine_path;
39         char*   engine_name;
40         char*   engine_setting_path;
41         bool    use_network;
42
43         bool    is_loaded;
44
45         /* engine base setting */
46         char*   first_lang;
47         bool    silence_detection;
48         bool    support_silence_detection;
49         bool    need_credential;
50 } sttengine_info_s;
51
52 /** stt engine agent init */
53 static atomic_bool g_agent_init;
54
55 static sttengine_info_s* g_engine_info = NULL;
56
57 /** default engine info */
58 static char*    g_default_language = NULL;
59 static bool     g_default_silence_detected;
60
61 /** callback functions */
62 static _Atomic result_callback g_result_cb = NULL;
63 static _Atomic result_time_callback g_result_time_cb = NULL;
64 static _Atomic speech_status_callback g_speech_status_cb = NULL;
65 static _Atomic error_callback g_error_cb = NULL;
66
67 /** callback functions */
68 static bool __result_time_cb(int index, stte_result_time_event_e event, const char* text,
69                       long start_time, long end_time, void* user_data);
70
71 /*
72 * Internal Interfaces
73 */
74
75 /** get engine info */
76 static int __internal_get_engine_info(stte_request_callback_s *callback, sttengine_info_s** info);
77
78 static int __log_enginelist();
79
80 /*
81 * STT Engine Agent Interfaces
82 */
83 int sttd_engine_agent_init(result_callback result_cb, result_time_callback time_cb,
84                            speech_status_callback speech_status_cb, error_callback error_cb)
85 {
86         /* initialize static data */
87         if (NULL == result_cb || NULL == time_cb || NULL == speech_status_cb || NULL == error_cb) {
88                 SLOG(LOG_ERROR, TAG_STTD, "[Engine agent ERROR] Invalid parameter");
89                 return STTD_ERROR_INVALID_PARAMETER;
90         }
91
92         g_result_cb = result_cb;
93         g_result_time_cb = time_cb;
94         g_speech_status_cb = speech_status_cb;
95         g_error_cb = error_cb;
96
97         g_default_language = NULL;
98
99         if (0 != sttd_config_get_default_language(&(g_default_language))) {
100                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent WARNING] There is No default voice in config");
101
102                 /* Set default voice */
103                 if (NULL != g_default_language) {
104                         free(g_default_language);
105                         g_default_language = NULL;
106                 }
107                 g_default_language = strdup("en_US");
108         } else {
109                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Default language is %s", g_default_language);
110         }
111
112         int temp;
113         if (0 != sttd_config_get_default_silence_detection(&temp)) {
114                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] There is no silence detection in config");
115                 g_default_silence_detected = true;
116         } else {
117                 g_default_silence_detected = (bool)temp;
118         }
119
120         g_agent_init = true;
121
122         return 0;
123 }
124
125 int __engine_agent_clear_engine(sttengine_info_s *engine)
126 {
127         if (NULL != engine) {
128                 if (NULL != engine->engine_uuid)        free(engine->engine_uuid);
129                 if (NULL != engine->engine_path)        free(engine->engine_path);
130                 if (NULL != engine->engine_name)        free(engine->engine_name);
131                 if (NULL != engine->engine_setting_path)free(engine->engine_setting_path);
132                 if (NULL != engine->first_lang)         free(engine->first_lang);
133
134                 free(engine);
135                 engine = NULL;
136         }
137
138         return 0;
139 }
140
141 int sttd_engine_agent_release()
142 {
143         if (NULL != g_engine_info) {
144                 if (g_engine_info->is_loaded) {
145                         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Unload engine");
146
147                         if (0 != stt_engine_deinitialize()) {
148                                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to deinitialize");
149                         }
150
151                         if (0 != stt_engine_unload()) {
152                                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to unload engine");
153                         }
154
155                         if (NULL != g_engine_info->engine_uuid) {
156                                 free(g_engine_info->engine_uuid);
157                                 g_engine_info->engine_uuid = NULL;
158                         }
159
160                         if (NULL != g_engine_info->engine_path) {
161                                 free(g_engine_info->engine_path);
162                                 g_engine_info->engine_path = NULL;
163                         }
164
165                         if (NULL != g_engine_info->engine_name) {
166                                 free(g_engine_info->engine_name);
167                                 g_engine_info->engine_name = NULL;
168                         }
169
170                         if (NULL != g_engine_info->engine_setting_path) {
171                                 free(g_engine_info->engine_setting_path);
172                                 g_engine_info->engine_setting_path = NULL;
173                         }
174
175                         if (NULL != g_engine_info->first_lang) {
176                                 free(g_engine_info->first_lang);
177                                 g_engine_info->first_lang = NULL;
178                         }
179
180                         g_engine_info->is_loaded = false;
181                 }
182
183                 __engine_agent_clear_engine(g_engine_info);
184         }
185
186         g_agent_init = false;
187
188         g_result_cb = NULL;
189         g_speech_status_cb = NULL;
190         g_error_cb = NULL;
191         g_result_time_cb = NULL;
192
193         return 0;
194 }
195
196 static int __internal_get_engine_info(stte_request_callback_s *callback, sttengine_info_s** info)
197 {
198         sttengine_info_s* temp;
199         temp = (sttengine_info_s*)calloc(1, sizeof(sttengine_info_s));
200         if (NULL == temp) {
201                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] fail to allocate memory");
202                 return STTD_ERROR_OUT_OF_MEMORY;
203         }
204
205         if (NULL == callback) {
206                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid engine");
207                 free(temp);
208                 return STTD_ERROR_ENGINE_NOT_FOUND;
209         }
210
211         if (NULL == callback->get_info) {
212                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid engine");
213                 free(temp);
214                 return STTD_ERROR_ENGINE_NOT_FOUND;
215         }
216
217         if (0 != callback->get_info(&(temp->engine_uuid), &(temp->engine_name), &(temp->engine_setting_path), &(temp->use_network))) {
218                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get engine info");
219                 free(temp);
220                 return STTD_ERROR_ENGINE_NOT_FOUND;
221         }
222
223         /* todo - removed? */
224         temp->engine_path = strdup("empty");
225         temp->is_loaded = false;
226
227         SLOG(LOG_DEBUG, TAG_STTD, "----- Valid Engine");
228         SLOG(LOG_DEBUG, TAG_STTD, "Engine uuid : %s", (NULL == temp->engine_uuid) ? "NULL" : temp->engine_uuid);
229         SLOG(LOG_DEBUG, TAG_STTD, "Engine name : %s", (NULL == temp->engine_name) ? "NULL" : temp->engine_name);
230         SLOG(LOG_DEBUG, TAG_STTD, "Engine path : %s", (NULL == temp->engine_path) ? "NULL" : temp->engine_path);
231         SLOG(LOG_DEBUG, TAG_STTD, "Engine setting path : %s", (NULL == temp->engine_setting_path) ? "NULL" : temp->engine_setting_path);
232         SLOG(LOG_DEBUG, TAG_STTD, "Use network : %s", temp->use_network ? "true" : "false");
233         SLOG(LOG_DEBUG, TAG_STTD, "-----");
234         SLOG(LOG_DEBUG, TAG_STTD, "  ");
235
236         *info = temp;
237
238         return STTD_ERROR_NONE;
239 }
240
241 bool __is_engine(const char* filepath)
242 {
243         if (NULL == filepath) {
244                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] No filepath");
245                 return false;
246         }
247
248         if (NULL != g_engine_info) {
249                 if (!strcmp(g_engine_info->engine_path, filepath)) {
250                         return true;
251                 }
252         }
253
254         return false;
255 }
256
257 int __engine_agent_check_engine_unload()
258 {
259         /* Check the count of client to use this engine */
260         if (NULL == g_engine_info) {
261                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] No engine");
262         } else {
263                 if (g_engine_info->is_loaded) {
264                         /* unload engine */
265 #ifndef AUDIO_CREATE_ON_START
266                         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Destroy recorder");
267                         if (0 != sttd_recorder_destroy())
268                                 SECURE_SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to destroy recorder");
269 #endif
270                         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Unload engine");
271                         if (0 != stt_engine_deinitialize())
272                                 SECURE_SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to deinitialize engine");
273
274                         if (0 != stt_engine_unload())
275                                 SECURE_SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to unload engine");
276
277                         g_engine_info->is_loaded = false;
278                 }
279         }
280
281         return 0;
282 }
283
284 int sttd_engine_agent_load_current_engine(stte_request_callback_s *callback)
285 {
286         RETVM_IF(false == g_agent_init, STTD_ERROR_OPERATION_FAILED, "[Engine Agent ERROR] Not Initialized");
287
288         /* Get current engine info */
289         sttengine_info_s* info;
290         int ret = __internal_get_engine_info(callback, &info);
291         if (0 != ret) {
292                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get engine info");
293                 return ret;
294         } else {
295                 g_engine_info = info;
296         }
297
298         __log_enginelist();
299
300         /* Set default engine */
301         char* cur_engine_uuid = NULL;
302         bool is_default_engine = false;
303
304         /* get current engine from config */
305         if (0 == sttd_config_get_default_engine(&cur_engine_uuid)) {
306                 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] current engine from config : %s", cur_engine_uuid);
307                 if (NULL != g_engine_info->engine_uuid && NULL != cur_engine_uuid) {
308                         if (!strcmp(g_engine_info->engine_uuid, cur_engine_uuid)) {
309                                 is_default_engine = true;
310                         }
311                 }
312                 if (NULL != cur_engine_uuid) {
313                         free(cur_engine_uuid);
314                         cur_engine_uuid = NULL;
315                 }
316         } else {
317                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent WARNING] There is not current engine from config");
318         }
319
320         if (false == is_default_engine) {
321                 SLOG(LOG_INFO, TAG_STTD, "[Engine Agent] Current engine is not Default engine");
322         } else {
323                 SLOG(LOG_INFO, TAG_STTD, "[Engine Agent] Current engine is Default engine");
324         }
325
326         /* Load engine */
327         ret = stt_engine_load(g_engine_info->engine_path, callback);
328         if (0 != ret) {
329                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to load engine : path(%s)", g_engine_info->engine_path);
330                 return ret;
331         }
332
333         ret = stt_engine_initialize(false);
334         if (0 != ret) {
335                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to initialize engine : path(%s)", g_engine_info->engine_path);
336                 return ret;
337         }
338
339         ret = stt_engine_set_silence_detection(g_default_silence_detected);
340         if (0 != ret) {
341                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent WARNING] Not support silence detection");
342                 g_engine_info->support_silence_detection = false;
343         } else {
344                 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Silence detection : %s", g_default_silence_detected ? "true" : "false");
345                 g_engine_info->support_silence_detection = true;
346                 g_engine_info->silence_detection = g_default_silence_detected;
347         }
348
349         /* Set first language */
350         char* tmp_lang = NULL;
351         ret = stt_engine_get_first_language(&tmp_lang);
352         if (0 == ret && NULL != tmp_lang) {
353                 g_engine_info->first_lang = strdup(tmp_lang);
354                 free(tmp_lang);
355         } else {
356                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get first language from engine : %s", g_engine_info->engine_name);
357                 return ret;
358         }
359
360 #ifndef AUDIO_CREATE_ON_START
361         /* Ready recorder */
362         stte_audio_type_e atype;
363         int rate;
364         int channels;
365
366         ret = stt_engine_get_audio_format(&atype, &rate, &channels);
367         if (0 != ret) {
368                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get audio type : %d %s", g_engine_info->engine_name);
369                 return ret;
370         }
371
372         ret = sttd_recorder_create(atype, channels, rate);
373         if (0 != ret) {
374                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to create recorder : %s", g_engine_info->engine_name);
375                 return ret;
376         }
377 #endif
378
379         g_engine_info->is_loaded = true;
380         SECURE_SLOG(LOG_INFO, TAG_STTD, "[Engine Agent SUCCESS] The %s has been loaded !!!", g_engine_info->engine_name);
381
382         return 0;
383 }
384
385 int sttd_engine_agent_unload_current_engine()
386 {
387         RETVM_IF(false == g_agent_init, STTD_ERROR_OPERATION_FAILED, "[Engine Agent ERROR] Not Initialized");
388
389         /* Remove client */
390         __engine_agent_check_engine_unload();
391
392         return 0;
393 }
394
395 bool sttd_engine_agent_is_default_engine()
396 {
397                 return true;
398 }
399
400 int sttd_engine_agent_get_engine_list(GSList** engine_list)
401 {
402         RETVM_IF(false == g_agent_init, STTD_ERROR_OPERATION_FAILED, "[Engine Agent ERROR] Not Initialized");
403
404         SLOG(LOG_DEBUG, TAG_STTD, "--------------------------------------");
405
406         return 0;
407 }
408
409 static int __sttd_engine_agent_check_precondition()
410 {
411         RETVM_IF(false == g_agent_init, STTD_ERROR_OPERATION_FAILED, "[Engine Agent ERROR] Not Initialized");
412         RETVM_IF(NULL == g_engine_info, STTD_ERROR_INVALID_PARAMETER, "[Engine Agent ERROR] The engine is not valid");
413         RETVM_IF(false == g_engine_info->is_loaded, STTD_ERROR_OPERATION_FAILED, "[Engine Agent ERROR] Not loaded engine");
414         return STTD_ERROR_NONE;
415 }
416
417 int sttd_engine_agent_get_current_engine(char** engine_uuid)
418 {
419         RETVM_IF(NULL == engine_uuid, STTD_ERROR_INVALID_PARAMETER,  "[Engine Agent ERROR] Invalid parameter");
420         int tmp = __sttd_engine_agent_check_precondition();
421         if (STTD_ERROR_NONE != tmp)
422                 return tmp;
423
424         *engine_uuid = strdup(g_engine_info->engine_uuid);
425
426         return 0;
427 }
428
429 bool sttd_engine_agent_need_network()
430 {
431         RETVM_IF(false == g_agent_init, STTD_ERROR_OPERATION_FAILED, "[Engine Agent ERROR] Not Initialized");
432         if (NULL != g_engine_info)
433                 return g_engine_info->use_network;
434
435         return false;
436 }
437
438 int sttd_engine_agent_supported_langs(GSList** lang_list)
439 {
440         RETVM_IF(NULL == lang_list, STTD_ERROR_INVALID_PARAMETER,  "[Engine Agent ERROR] Input parameter");
441         int tmp = __sttd_engine_agent_check_precondition();
442         if (STTD_ERROR_NONE != tmp)
443                 return tmp;
444
445         int ret = stt_engine_get_supported_langs(lang_list);
446         if (0 != ret) {
447                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] get language list error(%d)", ret);
448         }
449
450         return ret;
451 }
452
453 int sttd_engine_agent_get_default_lang(char** lang)
454 {
455         RETVM_IF(NULL == lang, STTD_ERROR_INVALID_PARAMETER,  "[Engine Agent ERROR] Input parameter");
456         int tmp = __sttd_engine_agent_check_precondition();
457         if (STTD_ERROR_NONE != tmp)
458                 return tmp;
459
460         /* get default language */
461         bool is_valid = false;
462         if (0 != stt_engine_is_valid_language(g_default_language, &is_valid)) {
463                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to check valid language");
464                 return STTD_ERROR_OPERATION_FAILED;
465         }
466
467         if (true == is_valid) {
468                 *lang = strdup(g_default_language);
469         } else
470                 *lang = strdup(g_engine_info->first_lang);
471
472         return 0;
473 }
474
475 int sttd_engine_agent_set_private_data(const char* key, const char* data)
476 {
477         RETVM_IF(NULL == key || NULL == data, STTD_ERROR_INVALID_PARAMETER,  "[Engine Agent ERROR] Input parameter");
478         int tmp = __sttd_engine_agent_check_precondition();
479         if (STTD_ERROR_NONE != tmp)
480                 return tmp;
481
482         /* set private data */
483         int ret = -1;
484         ret = stt_engine_set_private_data(key, data);
485         if (0 != ret) {
486                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set private data");
487         }
488
489         return ret;
490 }
491
492 int sttd_engine_agent_get_private_data(const char* key, char** data)
493 {
494         RETVM_IF(NULL == key || NULL == data, STTD_ERROR_INVALID_PARAMETER,  "[Engine Agent ERROR] Input parameter");
495         int tmp = __sttd_engine_agent_check_precondition();
496         if (STTD_ERROR_NONE != tmp)
497                 return tmp;
498
499         /* get default language */
500         int ret = -1;
501         ret = stt_engine_get_private_data(key, data);
502         if (0 != ret) {
503                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get private data");
504         }
505
506         return ret;
507 }
508
509 int sttd_engine_agent_get_option_supported(bool* silence)
510 {
511         RETVM_IF(NULL == silence, STTD_ERROR_INVALID_PARAMETER,  "[Engine Agent ERROR] Input parameter");
512         int tmp = __sttd_engine_agent_check_precondition();
513         if (STTD_ERROR_NONE != tmp)
514                 return tmp;
515
516         bool temp = false;
517         if (0 != stt_engine_support_silence(&temp)) {
518                 SLOG(LOG_WARN, TAG_STTD, "[WARNING] Fail to get support silence");
519         }
520
521         *silence = g_engine_info->support_silence_detection;
522         if (temp != *silence) {
523                 SLOG(LOG_WARN, TAG_STTD, "[WARNING] Metadata and Engine spec are different (engine:%d) (meta:%d)", temp, *silence);
524         }
525
526         return 0;
527 }
528
529 int sttd_engine_agent_is_credential_needed(unsigned int uid, bool* credential)
530 {
531         RETVM_IF(NULL == credential, STTD_ERROR_INVALID_PARAMETER,  "[Engine Agent ERROR] Input parameter");
532         int tmp = __sttd_engine_agent_check_precondition();
533         if (STTD_ERROR_NONE != tmp)
534                 return tmp;
535
536         bool temp = false;
537         int ret;
538
539         ret = stt_engine_need_app_credential(&temp);
540         if (0 != ret) {
541                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get to support recognition type : %d", ret);
542                 return ret;
543         }
544
545         *credential = temp;
546         return 0;
547 }
548
549 int sttd_engine_agent_is_recognition_type_supported(const char* type, bool* support)
550 {
551         RETVM_IF(NULL == type || NULL == support, STTD_ERROR_INVALID_PARAMETER,  "[Engine Agent ERROR] Input parameter");
552         int tmp = __sttd_engine_agent_check_precondition();
553         if (STTD_ERROR_NONE != tmp)
554                 return tmp;
555
556         bool temp = false;
557         int ret;
558
559         ret = stt_engine_support_recognition_type(type, &temp);
560         if (0 != ret) {
561                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get to support recognition type : %d", ret);
562                 return ret;
563         }
564
565         *support = temp;
566
567         return 0;
568 }
569
570 int sttd_engine_agent_get_audio_format(stte_audio_type_e* type, int* rate, int* num_of_channels)
571 {
572         RETVM_IF(NULL == type || NULL == rate || NULL == num_of_channels, STTD_ERROR_INVALID_PARAMETER,  "[Engine Agent ERROR] Input parameter");
573         int tmp = __sttd_engine_agent_check_precondition();
574         if (STTD_ERROR_NONE != tmp)
575                 return tmp;
576
577         int ret = stt_engine_get_audio_format(type, rate, num_of_channels);
578         if (0 != ret) {
579                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get to audio format : %d", ret);
580                 return ret;
581         }
582
583         return STTD_ERROR_NONE;
584 }
585
586 /*
587 * STT Engine Interfaces for client
588 */
589
590 int __set_option(sttengine_info_s* engine, int silence)
591 {
592         if (NULL == engine)
593                 return -1;
594
595         /* Check silence detection */
596         if (engine->support_silence_detection) {
597                 if (2 == silence) {
598                         /* default option set */
599 //                      if (g_default_silence_detected != engine->silence_detection) {
600                                 if (0 != stt_engine_set_silence_detection(g_default_silence_detected)) {
601                                         SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set silence detection : %s", g_default_silence_detected ? "true" : "false");
602                                 } else {
603                                         engine->silence_detection = g_default_silence_detected;
604                                         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Set silence detection : %s", g_default_silence_detected ? "true" : "false");
605                                 }
606 //                      }
607                 } else {
608                         if (silence != engine->silence_detection) {
609                                 if (0 != stt_engine_set_silence_detection(silence)) {
610                                         SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set silence detection : %s", silence ? "true" : "false");
611                                 } else {
612                                         engine->silence_detection = silence;
613                                         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Set silence detection : %s", silence ? "true" : "false");
614                                 }
615                         }
616                 }
617         }
618
619         return 0;
620 }
621
622 int sttd_engine_agent_recognize_start_engine(unsigned int uid, const char* lang, const char* recognition_type,
623                                       int silence, const char* appid, const char* credential, void* user_param)
624 {
625         RETVM_IF(NULL == lang || NULL == recognition_type, STTD_ERROR_INVALID_PARAMETER,  "[Engine Agent ERROR] Input parameter");
626         int tmp = __sttd_engine_agent_check_precondition();
627         if (STTD_ERROR_NONE != tmp)
628                 return tmp;
629
630         if (0 != __set_option(g_engine_info, silence)) {
631                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set options");
632                 return STTD_ERROR_OPERATION_FAILED;
633         }
634
635         SLOG(LOG_INFO, TAG_STTD, "g_default_language %s", g_default_language);
636
637         int ret;
638         char* temp = NULL;
639         if (0 == strncmp(lang, "default", strlen("default"))) {
640                 bool is_valid = false;
641                 ret = stt_engine_is_valid_language(g_default_language, &is_valid);
642                 if (0 != ret) {
643                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to check valid language");
644                         return ret;
645                 }
646
647                 if (true == is_valid) {
648                         temp = strdup(g_default_language);
649                         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent DEBUG] Default language is %s", temp);
650                 } else {
651                         temp = strdup(g_engine_info->first_lang);
652                         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent DEBUG] Default language is engine first lang : %s", temp);
653                 }
654         } else {
655                 temp = strdup(lang);
656         }
657
658         SLOG(LOG_INFO, TAG_STTD, "[Engine Agent] Start engine");
659
660         ret = stt_engine_recognize_start(temp, recognition_type, appid, credential, user_param);
661         if (NULL != temp)       free(temp);
662         if (0 != ret) {
663                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Recognition start error(%d)", ret);
664                 return ret;
665         }
666
667 #if 0
668         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Start recorder(%d)", uid);
669
670         ret = sttd_recorder_start(uid);
671         if (0 != ret) {
672                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to start recorder : result(%d)", ret);
673                 return ret;
674         }
675
676 #endif
677
678         return 0;
679 }
680
681 int sttd_engine_agent_recognize_start_recorder(unsigned int uid, const char* appid)
682 {
683         int tmp = __sttd_engine_agent_check_precondition();
684         if (STTD_ERROR_NONE != tmp)
685                 return tmp;
686
687         stte_audio_type_e atype;
688         int rate;
689         int channels;
690
691         int ret = stt_engine_get_audio_format(&atype, &rate, &channels);
692         if (STTE_ERROR_NONE != ret) {
693                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get audio format : %s", g_engine_info->engine_name);
694                 return ret;
695         }
696
697         SLOG(LOG_INFO, TAG_STTD, "[Engine Agent] Create recorder");
698         ret = sttd_recorder_create(atype, channels, rate);
699         if (STTD_ERROR_NONE != ret) {
700                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to create format : %s", g_engine_info->engine_name);
701                 return ret;
702         }
703
704         SLOG(LOG_INFO, TAG_STTD, "[Engine Agent] Start recorder");
705         ret = sttd_recorder_start(uid, appid);
706         if (STTD_ERROR_NONE != ret) {
707                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to start recorder : result(%d)", ret);
708                 stt_engine_recognize_cancel();
709                 sttd_recorder_stop();
710                 return ret;
711         }
712
713         return STTD_ERROR_NONE;
714 }
715
716 int sttd_engine_agent_recognize_start_file(unsigned int uid, const char* filepath)
717 {
718         int tmp = __sttd_engine_agent_check_precondition();
719         if (STTD_ERROR_NONE != tmp)
720                 return tmp;
721
722         SLOG(LOG_INFO, TAG_STTD, "[Engine Agent] Start recorder");
723
724         int ret;
725         ret = sttd_recorder_start_file(uid, filepath);
726         if (0 != ret) {
727                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to start recorder : result(%d)", ret);
728                 stt_engine_recognize_cancel();
729                 sttd_recorder_stop_file();
730                 return ret;
731         }
732
733         return 0;
734 }
735
736 int sttd_engine_agent_set_recording_data(const void* data, unsigned int length)
737 {
738         RETVM_IF(NULL == data || 0 == length, STTD_ERROR_INVALID_PARAMETER,  "[Engine Agent ERROR] Input parameter");
739         int tmp = __sttd_engine_agent_check_precondition();
740         if (STTD_ERROR_NONE != tmp)
741                 return tmp;
742
743         int ret = stt_engine_set_recording_data(data, length);
744         if (0 != ret) {
745                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent WARNING] set recording error(%d)", ret);
746         }
747
748         return ret;
749 }
750
751 int sttd_engine_agent_recognize_stop_file()
752 {
753         int tmp = __sttd_engine_agent_check_precondition();
754         if (STTD_ERROR_NONE != tmp)
755                 return tmp;
756
757         SLOG(LOG_INFO, TAG_STTD, "[Engine Agent] Stop recorder");
758         int ret;
759         ret = sttd_recorder_stop_file();
760         if (0 != ret) {
761                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to stop recorder : result(%d)", ret);
762                 return ret;
763         }
764
765 #ifdef AUDIO_CREATE_ON_START
766         SECURE_SLOG(LOG_INFO, TAG_STTD, "[Engine Agent] Destroy recorder");
767         if (0 != sttd_recorder_destroy())
768                 SECURE_SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to destroy recorder");
769 #endif
770
771         SLOG(LOG_INFO, TAG_STTD, "[Engine Agent Success] Stop recorder");
772         return 0;
773 }
774
775 int sttd_engine_agent_recognize_stop_recorder()
776 {
777         int tmp = __sttd_engine_agent_check_precondition();
778         if (STTD_ERROR_NONE != tmp)
779                 return tmp;
780
781         SLOG(LOG_INFO, TAG_STTD, "[Engine Agent] Stop recorder");
782         int ret;
783         ret = sttd_recorder_stop();
784         if (0 != ret) {
785                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to stop recorder : result(%d)", ret);
786                 return ret;
787         }
788
789 #ifdef AUDIO_CREATE_ON_START
790         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Destroy recorder");
791         if (0 != sttd_recorder_destroy())
792                 SECURE_SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to destroy recorder");
793 #endif
794
795         SLOG(LOG_INFO, TAG_STTD, "[Engine Agent Success] Stop recorder");
796         return 0;
797 }
798
799 int sttd_engine_agent_recognize_stop_engine()
800 {
801         int tmp = __sttd_engine_agent_check_precondition();
802         if (STTD_ERROR_NONE != tmp)
803                 return tmp;
804
805         SLOG(LOG_INFO, TAG_STTD, "[Engine Agent] Stop engine");
806
807         int ret;
808         ret = stt_engine_recognize_stop();
809         if (0 != ret) {
810                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] stop recognition error(%d)", ret);
811                 return ret;
812         }
813
814         SLOG(LOG_INFO, TAG_STTD, "[Engine Agent Success] Stop engine");
815
816         return 0;
817 }
818
819 int sttd_engine_agent_recognize_cancel()
820 {
821         int tmp = __sttd_engine_agent_check_precondition();
822         if (STTD_ERROR_NONE != tmp)
823                 return tmp;
824
825         SLOG(LOG_INFO, TAG_STTD, "[Engine Agent] Cancel engine");
826
827         int ret;
828         ret = stt_engine_recognize_cancel();
829         if (0 != ret) {
830                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] cancel recognition error(%d)", ret);
831                 return ret;
832         }
833
834         SLOG(LOG_INFO, TAG_STTD, "[Engine Agent] Stop recorder");
835
836         ret = sttd_recorder_stop();
837         if (0 != ret) {
838                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to stop recorder : result(%d)", ret);
839                 return ret;
840         }
841
842 #ifdef AUDIO_CREATE_ON_START
843         SLOG(LOG_INFO, TAG_STTD, "[Engine Agent] Destroy recorder");
844         if (0 != sttd_recorder_destroy())
845                 SECURE_SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to destroy recorder");
846 #endif
847
848         SLOG(LOG_INFO, TAG_STTD, "[Engine Agent Success] Cancel recognition");
849
850         return 0;
851 }
852
853
854 /*
855 * STT Engine Interfaces for configure
856 */
857
858 int sttd_engine_agent_set_default_engine(const char* engine_uuid)
859 {
860         RETVM_IF(false == g_agent_init, STTD_ERROR_OPERATION_FAILED, "[Engine Agent ERROR] Not Initialized");
861         RETVM_IF(NULL == engine_uuid, STTD_ERROR_INVALID_PARAMETER, "[Engine Agent ERROR] Invalid Parameter");
862
863         __log_enginelist();
864
865         RETVM_IF(NULL == g_engine_info, STTD_ERROR_INVALID_PARAMETER, "[Engine Agent ERROR] The Default engine is not valid");
866
867         SECURE_SLOG(LOG_INFO, TAG_STTD, "[Engine Agent] Default engine uuid(%s)", g_engine_info->engine_uuid);
868
869         return 0;
870 }
871
872 int sttd_engine_agent_set_default_language(const char* language)
873 {
874         RETVM_IF(NULL == language, STTD_ERROR_INVALID_PARAMETER,  "[Engine Agent ERROR] Input parameter");
875         RETVM_IF(false == g_agent_init, STTD_ERROR_OPERATION_FAILED, "[Engine Agent ERROR] Not Initialized");
876
877         if (NULL != g_default_language)
878                 free(g_default_language);
879
880         g_default_language = strdup(language);
881
882         return 0;
883 }
884
885 int sttd_engine_agent_set_silence_detection(bool value)
886 {
887         RETVM_IF(false == g_agent_init, STTD_ERROR_OPERATION_FAILED, "[Engine Agent ERROR] Not Initialized");
888
889         g_default_silence_detected = value;
890
891         return 0;
892 }
893
894 int sttd_engine_agent_check_app_agreed(const char* appid, bool* result)
895 {
896         int tmp = __sttd_engine_agent_check_precondition();
897         if (STTD_ERROR_NONE != tmp)
898                 return tmp;
899
900         int ret;
901         ret = stt_engine_check_app_agreed(appid, result);
902         if (0 != ret) {
903                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] cancel recognition error(%d)", ret);
904                 return ret;
905         }
906
907
908         SLOG(LOG_INFO, TAG_STTD, "[Engine Agent] Get engine right : %s", *result ? "true" : "false");
909         return 0;
910 }
911
912 static void __recorder_destroy_by_error_result(void *data)
913 {
914         SLOG(LOG_INFO, TAG_STTD, "[Engine Agent] Destroy recorder");
915         if (0 != sttd_recorder_destroy())
916                 SECURE_SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to destroy recorder");
917
918         return;
919 }
920
921 int sttd_engine_agent_send_result(stte_result_event_e event, const char* type, const char** result, int result_count,
922                  const char* msg, void* time_info, void *user_data)
923 {
924         int ret = -1;
925         RETVM_IF(false == g_agent_init, STTD_ERROR_OPERATION_FAILED, "[Engine Agent ERROR] Not Initialized");
926
927         SLOG(LOG_INFO, TAG_STTD, "[Server] === Result time callback ===");
928
929         if (NULL != time_info) {
930                 /* Get the time info */
931                 ret = stt_engine_foreach_result_time(time_info, __result_time_cb, NULL);
932                 if (0 != ret) {
933                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get time info : %d", ret);
934                         return ret;
935                 }
936         }
937
938         SLOG(LOG_INFO, TAG_STTD, "[Server] ============================");
939
940         RETVM_IF(NULL == g_result_cb, STTD_ERROR_OPERATION_FAILED, "[Server ERROR] Callback is not set.");
941
942         ret = g_result_cb(event, type, result, result_count, msg, user_data);
943
944 #ifdef AUDIO_CREATE_ON_START
945         if (event == STTE_RESULT_EVENT_ERROR) {
946                 ecore_main_loop_thread_safe_call_async(__recorder_destroy_by_error_result, NULL);
947         }
948 #endif
949
950         return ret;
951 }
952
953 int sttd_engine_agent_send_error(stte_error_e error, const char* msg)
954 {
955         RETVM_IF(false == g_agent_init, STTD_ERROR_OPERATION_FAILED, "[Engine Agent ERROR] Not Initialized");
956
957         /* check uid */
958         unsigned int uid = stt_client_get_current_recognition();
959
960         int ret = sttdc_send_error_signal(uid, error, msg);
961         if (0 != ret) {
962                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info. (%d/%s)", ret, get_error_message(ret));
963         }
964
965         RETVM_IF(NULL == g_error_cb, STTD_ERROR_OPERATION_FAILED, "[Server ERROR] Callback is not set.");
966
967         return g_error_cb(error, msg);
968 }
969
970 int sttd_engine_agent_send_speech_status(stte_speech_status_e status, void* user_data)
971 {
972         RETVM_IF(false == g_agent_init, STTD_ERROR_OPERATION_FAILED, "[Engine Agent ERROR] Not Initialized");
973         RETVM_IF(NULL == g_speech_status_cb, STTD_ERROR_OPERATION_FAILED, "[Server ERROR] Callback is not set.");
974
975         return g_speech_status_cb(status, user_data);
976 }
977
978 static bool __result_time_cb(int index, stte_result_time_event_e event, const char* text, long start_time, long end_time, void* user_data)
979 {
980         RETVM_IF(false == g_agent_init, false, "[Engine Agent ERROR] Not Initialized");
981         RETVM_IF(NULL == g_result_time_cb, false, "[Server ERROR] Callback is not set.");
982
983         return g_result_time_cb(index, event, text, start_time, end_time, user_data);
984 }
985
986 /* A function forging */
987 static int __log_enginelist()
988 {
989         if (NULL != g_engine_info) {
990                 SLOG(LOG_DEBUG, TAG_STTD, "------------------ engine -----------------------");
991                 SLOG(LOG_DEBUG, TAG_STTD, "engine uuid : %s", g_engine_info->engine_uuid);
992                 SLOG(LOG_DEBUG, TAG_STTD, "engine name : %s", g_engine_info->engine_name);
993                 SLOG(LOG_DEBUG, TAG_STTD, "engine path : %s", g_engine_info->engine_path);
994                 SLOG(LOG_DEBUG, TAG_STTD, "use network : %s", g_engine_info->use_network ? "true" : "false");
995                 SLOG(LOG_DEBUG, TAG_STTD, "is loaded   : %s", g_engine_info->is_loaded ? "true" : "false");
996                 if (NULL != g_engine_info->first_lang) {
997                         SLOG(LOG_DEBUG, TAG_STTD, "default lang : %s", g_engine_info->first_lang);
998                 }
999                 SLOG(LOG_DEBUG, TAG_STTD, "-------------------------------------------------");
1000         } else {
1001                 SLOG(LOG_DEBUG, TAG_STTD, "------------------ engine -----------------------");
1002                 SLOG(LOG_DEBUG, TAG_STTD, "     No engine");
1003                 SLOG(LOG_DEBUG, TAG_STTD, "-------------------------------------------------");
1004         }
1005
1006         return 0;
1007 }
1008
1009 int sttd_engine_agent_get_audio_type(char** audio_type)
1010 {
1011         int tmp = __sttd_engine_agent_check_precondition();
1012         if (STTD_ERROR_NONE != tmp)
1013                 return tmp;
1014
1015         SLOG(LOG_INFO, TAG_STTD, "[Server Info] Get audio type");
1016
1017         int ret = stt_engine_get_audio_type(audio_type);
1018         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent] get audio type(%s). ret(%d)", *audio_type, ret);
1019
1020         return ret;
1021 }
1022
1023 int sttd_engine_agent_set_audio_type(const char* audio_type)
1024 {
1025         int tmp = __sttd_engine_agent_check_precondition();
1026         if (STTD_ERROR_NONE != tmp)
1027                 return tmp;
1028
1029         SLOG(LOG_INFO, TAG_STTD, "[Server Info] Set audio type(%s)", audio_type);
1030
1031         int ret = stt_engine_set_audio_type(audio_type);
1032         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent] set audio type(%d)", ret);
1033
1034         return ret;
1035 }