Fix error return value properly
[platform/core/uifw/stt.git] / server / sttd_engine_agent.c
1 /*
2 *  Copyright (c) 2011-2014 Samsung Electronics Co., Ltd All Rights Reserved
3 *  Licensed under the Apache License, Version 2.0 (the "License");
4 *  you may not use this file except in compliance with the License.
5 *  You may obtain a copy of the License at
6 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14
15 #include <dlfcn.h>
16 #include <dirent.h>
17
18 #include "stt_defs.h"
19 #include "stt_engine.h"
20 #include "sttd_main.h"
21 #include "sttd_client_data.h"
22 #include "sttd_config.h"
23 #include "sttd_recorder.h"
24 #include "sttd_engine_agent.h"
25
26
27 #define AUDIO_CREATE_ON_START
28
29 /*
30 * Internal data structure
31 */
32
33 typedef struct {
34         int     uid;
35         int     engine_id;
36         bool    use_default_engine;
37 } sttengine_client_s;
38
39 typedef struct _sttengine_info {
40         int     engine_id;
41
42         char*   engine_uuid;
43         char*   engine_path;
44         char*   engine_name;
45         char*   engine_setting_path;
46         bool    use_network;
47
48         bool    is_loaded;
49
50         /* engine base setting */
51         char*   first_lang;
52         bool    silence_detection;
53         bool    support_silence_detection;
54         bool    need_credential;
55 } sttengine_info_s;
56
57 /** stt engine agent init */
58 static bool     g_agent_init;
59
60 /** list */
61 static GSList*  g_engine_client_list;
62 static GSList*  g_engine_list;
63
64 /** default engine info */
65 static int      g_default_engine_id;
66 static char*    g_default_language;
67 static bool     g_default_silence_detected;
68
69 static int      g_engine_id_count;
70
71 /** current engine id */
72 static int      g_recording_engine_id;
73
74 /** callback functions */
75 static result_callback g_result_cb;
76 static result_time_callback g_result_time_cb;
77 static silence_dectection_callback g_silence_cb;
78
79
80 /** callback functions */
81 void __result_cb(sttp_result_event_e event, const char* type, const char** data, int data_count,
82                  const char* msg, void* time_info, void *user_data);
83
84 bool __result_time_cb(int index, sttp_result_time_event_e event, const char* text,
85                       long start_time, long end_time, void* user_data);
86
87 void __detect_silence_cb(sttp_silence_type_e type, void* user_data);
88
89 bool __supported_language_cb(const char* language, void* user_data);
90
91 void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* setting_ug_name,
92                       bool use_network, void* user_data);
93
94 /*
95 * Internal Interfaces
96 */
97
98 /** get engine info */
99 int __internal_get_engine_info(const char* filepath, sttengine_info_s** info);
100
101 int __log_enginelist();
102
103 /*
104 * STT Engine Agent Interfaces
105 */
106 int sttd_engine_agent_init(result_callback result_cb, result_time_callback time_cb,
107                            silence_dectection_callback silence_cb)
108 {
109         /* initialize static data */
110         if (NULL == result_cb || NULL == time_cb || NULL == silence_cb) {
111                 SLOG(LOG_ERROR, TAG_STTD, "[Engine agent ERROR] Invalid parameter");
112                 return STTD_ERROR_INVALID_PARAMETER;
113         }
114
115         g_result_cb = result_cb;
116         g_result_time_cb = time_cb;
117         g_silence_cb = silence_cb;
118
119         g_default_engine_id = -1;
120         g_default_language = NULL;
121         g_engine_id_count = 1;
122         g_recording_engine_id = -1;
123
124         if (0 != sttd_config_get_default_language(&(g_default_language))) {
125                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent WARNING] There is No default voice in config");
126                 /* Set default voice */
127                 g_default_language = strdup("en_US");
128         } else {
129                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Default language is %s", g_default_language);
130         }
131
132         int temp;
133         if (0 != sttd_config_get_default_silence_detection(&temp)) {
134                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] There is no silence detection in config");
135                 g_default_silence_detected = true;
136         } else {
137                 g_default_silence_detected = (bool)temp;
138         }
139
140         g_agent_init = false;
141
142         return 0;
143 }
144
145 int __engine_agent_clear_engine(sttengine_info_s *engine)
146 {
147         if (NULL != engine) {
148                 if (NULL != engine->engine_uuid)        free(engine->engine_uuid);
149                 if (NULL != engine->engine_path)        free(engine->engine_path);
150                 if (NULL != engine->engine_name)        free(engine->engine_name);
151                 if (NULL != engine->engine_setting_path)free(engine->engine_setting_path);
152                 if (NULL != engine->first_lang)         free(engine->first_lang);
153
154                 free(engine);
155         }
156
157         return 0;
158 }
159
160 int sttd_engine_agent_release()
161 {
162         /* Release client list */
163         GSList *iter = NULL;
164         sttengine_client_s *client = NULL;
165
166         if (g_slist_length(g_engine_client_list) > 0) {
167                 /* Get a first item */
168                 iter = g_slist_nth(g_engine_client_list, 0);
169
170                 while (NULL != iter) {
171                         /* Get handle data from list */
172                         client = iter->data;
173                         g_engine_client_list = g_slist_remove_link(g_engine_client_list, iter);
174
175                         if (NULL != client)
176                                 free(client);
177
178                         iter = g_slist_nth(g_engine_client_list, 0);
179                 }
180         }
181
182         g_slist_free(g_engine_client_list);
183
184         /* Release engine list */
185         sttengine_info_s *engine = NULL;
186
187         if (0 < g_slist_length(g_engine_list)) {
188                 /* Get a first item */
189                 iter = g_slist_nth(g_engine_list, 0);
190
191                 while (NULL != iter) {
192                         /* Get handle data from list */
193                         engine = iter->data;
194                         g_engine_list = g_slist_remove_link(g_engine_list, iter);
195
196                         /* Check engine unload */
197                         if (engine->is_loaded) {
198                                 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Unload engine id(%d)", engine->engine_id);
199
200                                 if (0 != stt_engine_deinitialize(engine->engine_id))
201                                         SECURE_SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to deinitialize engine id(%d)", engine->engine_id);
202
203                                 if (0 != stt_engine_unload(engine->engine_id))
204                                         SECURE_SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to unload engine id(%d)", engine->engine_id);
205
206                                 engine->is_loaded = false;
207                         }
208
209                         __engine_agent_clear_engine(engine);
210
211                         iter = g_slist_nth(g_engine_list, 0);
212                 }
213         }
214
215         g_result_cb = NULL;
216         g_silence_cb = NULL;
217
218         g_agent_init = false;
219         g_default_engine_id = -1;
220
221         return 0;
222 }
223
224 void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* setting_ug_name,
225                       bool use_network, void* user_data)
226 {
227         sttengine_info_s* temp = (sttengine_info_s*)user_data;
228
229         temp->engine_uuid = g_strdup(engine_uuid);
230         temp->engine_name = g_strdup(engine_name);
231         temp->engine_setting_path = g_strdup(setting_ug_name);
232         temp->use_network = use_network;
233 }
234
235 int __internal_get_engine_info(const char* filepath, sttengine_info_s** info)
236 {
237         if (NULL == filepath || NULL == info) {
238                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter");
239                 return STTD_ERROR_INVALID_PARAMETER;
240         }
241
242         /* load engine */
243         char *error;
244         void* handle;
245
246         handle = dlopen(filepath, RTLD_LAZY);
247
248         if (!handle) {
249                 SECURE_SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Invalid engine : %s, error(%s)", filepath, (NULL == dlerror()) ? "NULL" : dlerror());
250                 return STTD_ERROR_ENGINE_NOT_FOUND;
251         }
252
253         /* link engine to daemon */
254         dlsym(handle, "sttp_load_engine");
255         if ((error = dlerror()) != NULL) {
256                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Invalid engine. Fail to open sttp_load_engine : %s", error);
257                 dlclose(handle);
258                 return STTD_ERROR_ENGINE_NOT_FOUND;
259         }
260
261         dlsym(handle, "sttp_unload_engine");
262         if ((error = dlerror()) != NULL) {
263                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Invalid engine. Fail to open sttp_unload_engine : %s", error);
264                 dlclose(handle);
265                 return STTD_ERROR_ENGINE_NOT_FOUND;
266         }
267
268         int (*get_engine_info)(sttpe_engine_info_cb callback, void* user_data);
269
270         get_engine_info = (int (*)(sttpe_engine_info_cb, void*))dlsym(handle, "sttp_get_engine_info");
271         if ((error = dlerror()) != NULL || NULL == get_engine_info) {
272                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent WARNING] Invalid engine. Fail to open sttp_get_engine_info : %s", error);
273                 dlclose(handle);
274                 return STTD_ERROR_ENGINE_NOT_FOUND;
275         }
276
277         sttengine_info_s* temp;
278         temp = (sttengine_info_s*)calloc(1, sizeof(sttengine_info_s));
279         if (NULL == temp) {
280                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to allocate memory");
281                 dlclose(handle);
282                 return STTD_ERROR_OUT_OF_MEMORY;
283         }
284
285         /* get engine info */
286         if (0 != get_engine_info(__engine_info_cb, (void*)temp)) {
287                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get engine info from engine");
288                 dlclose(handle);
289                 free(temp);
290                 return STTD_ERROR_ENGINE_NOT_FOUND;
291         }
292
293         /* close engine */
294         dlclose(handle);
295
296         temp->engine_id = g_engine_id_count;
297         g_engine_id_count++;
298
299         temp->engine_path = g_strdup(filepath);
300         temp->is_loaded = false;
301
302         SLOG(LOG_DEBUG, TAG_STTD, "----- Valid Engine");
303         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "Engine id : %d", temp->engine_id);
304         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "Engine uuid : %s", temp->engine_uuid);
305         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "Engine name : %s", temp->engine_name);
306         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "Engine path : %s", temp->engine_path);
307         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "Engine setting path : %s", temp->engine_setting_path);
308         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "Use network : %s", temp->use_network ? "true" : "false");
309         SLOG(LOG_DEBUG, TAG_STTD, "-----");
310         SLOG(LOG_DEBUG, TAG_STTD, "  ");
311
312         *info = temp;
313
314         return STTD_ERROR_NONE;
315 }
316
317 bool __is_engine(const char* filepath)
318 {
319         GSList *iter = NULL;
320         sttengine_info_s *engine = NULL;
321
322         if (0 < g_slist_length(g_engine_list)) {
323                 /* Get a first item */
324                 iter = g_slist_nth(g_engine_list, 0);
325
326                 while (NULL != iter) {
327                         /* Get handle data from list */
328                         engine = iter->data;
329
330                         if (0 == strcmp(engine->engine_path, filepath)) {
331                                 return true;
332                         }
333
334                         iter = g_slist_next(iter);
335                 }
336         }
337
338         return false;
339 }
340
341 int sttd_engine_agent_initialize_engine_list()
342 {
343         /* Get file name from default engine directory */
344         DIR *dp = NULL;
345         int ret = -1;
346         struct dirent entry;
347         struct dirent *dirp = NULL;
348
349         dp  = opendir(STT_DEFAULT_ENGINE);
350         if (NULL != dp) {
351                 do {
352                         ret = readdir_r(dp, &entry, &dirp);
353                         if (0 != ret) {
354                                 SLOG(LOG_ERROR, TAG_STTD, "[File ERROR] Fail to read directory");
355                                 break;
356                         }
357
358                         if (NULL != dirp) {
359                                 sttengine_info_s* info;
360                                 char* filepath;
361                                 int filesize;
362
363                                 filesize = strlen(STT_DEFAULT_ENGINE) + strlen(dirp->d_name) + 5;
364                                 filepath = (char*)calloc(filesize, sizeof(char));
365
366                                 if (NULL != filepath) {
367                                         snprintf(filepath, filesize, "%s/%s", STT_DEFAULT_ENGINE, dirp->d_name);
368                                 } else {
369                                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Memory not enough!!");
370                                         continue;
371                                 }
372
373                                 if (false  == __is_engine(filepath)) {
374                                         /* get its info and update engine list */
375                                         if (0 == __internal_get_engine_info(filepath, &info)) {
376                                                 /* add engine info to g_engine_list */
377                                                 g_engine_list = g_slist_append(g_engine_list, info);
378                                         }
379                                 }
380
381                                 if (NULL != filepath)
382                                         free(filepath);
383                         }
384                 } while (NULL != dirp);
385
386                 closedir(dp);
387         } else {
388                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent WARNING] Fail to open default directory");
389         }
390
391         if (0 >= g_slist_length(g_engine_list)) {
392                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] No Engine");
393                 return STTD_ERROR_ENGINE_NOT_FOUND;
394         }
395
396         __log_enginelist();
397
398         /* Set default engine */
399         GSList *iter = NULL;
400         sttengine_info_s *engine = NULL;
401         char* cur_engine_uuid = NULL;
402         bool is_default_engine = false;
403
404         /* get current engine from config */
405         if (0 == sttd_config_get_default_engine(&cur_engine_uuid)) {
406                 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] current engine from config : %s", cur_engine_uuid);
407
408                 if (0 < g_slist_length(g_engine_list)) {
409                         /* Get a first item */
410                         iter = g_slist_nth(g_engine_list, 0);
411
412                         while (NULL != iter) {
413                                 /* Get handle data from list */
414                                 engine = iter->data;
415
416                                 if (0 == strcmp(engine->engine_uuid, cur_engine_uuid)) {
417                                         is_default_engine = true;
418                                         g_default_engine_id = engine->engine_id;
419                                         break;
420                                 }
421
422                                 iter = g_slist_next(iter);
423                         }
424                 }
425
426                 if (cur_engine_uuid != NULL)
427                         free(cur_engine_uuid);
428         } else {
429                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent WARNING] There is not current engine from config");
430         }
431
432         if (false == is_default_engine) {
433                 if (0 < g_slist_length(g_engine_list)) {
434                         /* Get a first item */
435                         iter = g_slist_nth(g_engine_list, 0);
436
437                         /* Get handle data from list */
438                         engine = iter->data;
439
440                         if (NULL != engine) {
441                                 is_default_engine = true;
442                                 g_default_engine_id = engine->engine_id;
443                         }
444                 }
445         }
446
447         if (NULL != engine) {
448                 if (NULL != engine->engine_uuid) {
449                         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Default engine Id(%d) uuid(%s)", engine->engine_id, engine->engine_uuid);
450
451                         if (false == is_default_engine) {
452                                 if (0 != sttd_config_set_default_engine(engine->engine_uuid))
453                                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set default engine ");
454                         }
455                 }
456         } else {
457                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Default engine is NULL");
458                 return STTD_ERROR_ENGINE_NOT_FOUND;
459         }
460
461         g_agent_init = true;
462
463         return 0;
464 }
465
466 sttengine_info_s* __engine_agent_get_engine_by_id(int engine_id)
467 {
468         GSList *iter = NULL;
469         sttengine_info_s *data = NULL;
470
471         iter = g_slist_nth(g_engine_list, 0);
472
473         while (NULL != iter) {
474
475                 data = iter->data;
476
477                 if (data->engine_id == engine_id)
478                         return data;
479
480                 iter = g_slist_next(iter);
481         }
482
483         return NULL;
484 }
485
486 sttengine_info_s* __engine_agent_get_engine_by_uuid(const char* engine_uuid)
487 {
488         GSList *iter = NULL;
489         sttengine_info_s *data = NULL;
490
491         iter = g_slist_nth(g_engine_list, 0);
492
493         while (NULL != iter) {
494
495                 data = iter->data;
496
497                 if (0 == strcmp(data->engine_uuid, engine_uuid))
498                         return data;
499
500                 iter = g_slist_next(iter);
501         }
502
503         return NULL;
504 }
505
506 sttengine_client_s* __engine_agent_get_client(int uid)
507 {
508         GSList *iter = NULL;
509         sttengine_client_s *data = NULL;
510
511         if (0 < g_slist_length(g_engine_client_list)) {
512                 iter = g_slist_nth(g_engine_client_list, 0);
513
514                 while (NULL != iter) {
515                         /* Get handle data from list */
516                         data = iter->data;
517
518                         if (uid == data->uid)
519                                 return data;
520
521                         iter = g_slist_next(iter);
522                 }
523         }
524
525         return NULL;
526 }
527
528 sttengine_info_s* __engine_agent_get_engine_by_uid(int uid)
529 {
530         sttengine_client_s *data;
531
532         data = __engine_agent_get_client(uid);
533         if (NULL != data)
534                 return __engine_agent_get_engine_by_id(data->engine_id);
535
536         return NULL;
537 }
538
539 int __engine_agent_check_engine_unload(int engine_id)
540 {
541         /* Check the count of client to use this engine */
542         GSList *iter = NULL;
543         int client_count = 0;
544         sttengine_client_s *data = NULL;
545
546         if (0 < g_slist_length(g_engine_client_list)) {
547                 iter = g_slist_nth(g_engine_client_list, 0);
548
549                 while (NULL != iter) {
550                         /* Get handle data from list */
551                         data = iter->data;
552
553                         if (data->engine_id == engine_id)
554                                 client_count++;
555
556                         iter = g_slist_next(iter);
557                 }
558         }
559
560         if (0 == client_count) {
561                 sttengine_info_s* engine = NULL;
562                 engine = __engine_agent_get_engine_by_id(engine_id);
563                 if (NULL == engine) {
564                         SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get engine from client(%d)", engine_id);
565                 } else {
566                         if (engine->is_loaded) {
567                                 /* unload engine */
568 #ifndef AUDIO_CREATE_ON_START
569                                 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Destroy recorder");
570                                 if (0 != sttd_recorder_destroy(engine->engine_id))
571                                         SECURE_SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to destroy recorder(%d)", engine->engine_id);
572 #endif
573                                 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Unload engine id(%d)", engine_id);
574                                 if (0 != stt_engine_deinitialize(engine->engine_id))
575                                         SECURE_SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to deinitialize engine id(%d)", engine->engine_id);
576
577                                 if (0 != stt_engine_unload(engine->engine_id))
578                                         SECURE_SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to unload engine id(%d)", engine->engine_id);
579
580                                 engine->is_loaded = false;
581                         }
582                 }
583         }
584
585         return 0;
586 }
587
588 int sttd_engine_agent_load_current_engine(int uid, const char* engine_uuid)
589 {
590         if (false == g_agent_init) {
591                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
592                 return STTD_ERROR_OPERATION_FAILED;
593         }
594
595         sttengine_client_s* client = NULL;
596         sttengine_info_s* engine = NULL;
597         int before_engine = -1;
598
599         client = __engine_agent_get_client(uid);
600
601         if (NULL == client) {
602                 client = (sttengine_client_s*)calloc(1, sizeof(sttengine_client_s));
603                 if (NULL == client) {
604                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to allocate memory");
605                         return STTD_ERROR_OUT_OF_MEMORY;
606                 }
607
608                 /* initialize */
609                 client->uid = uid;
610                 client->engine_id = -1;
611
612                 g_engine_client_list = g_slist_append(g_engine_client_list, client);
613
614                 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Registered client(%d)", uid);
615         }
616
617         if (NULL == engine_uuid) {
618                 /* Set default engine */
619                 engine = __engine_agent_get_engine_by_id(g_default_engine_id);
620
621                 if (NULL == engine) {
622                         SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get default engine : %d", g_default_engine_id);
623                         return STTD_ERROR_OPERATION_FAILED;
624                 }
625                 before_engine = client->engine_id;
626
627                 client->engine_id = engine->engine_id;
628                 client->use_default_engine = true;
629         } else {
630                 /* Set engine by uid */
631                 engine = __engine_agent_get_engine_by_uuid(engine_uuid);
632
633                 if (NULL == engine) {
634                         SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get engine : %s", engine_uuid);
635                         return STTD_ERROR_OPERATION_FAILED;
636                 }
637                 before_engine = client->engine_id;
638
639                 client->engine_id = engine->engine_id;
640                 client->use_default_engine = false;
641         }
642
643         if (-1 != before_engine) {
644                 /* Unload engine if reference count is 0 */
645                 __engine_agent_check_engine_unload(before_engine);
646         }
647
648         if (true == engine->is_loaded) {
649                 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine] engine id(%d) is already loaded", engine->engine_id);
650                 return 0;
651         }
652
653         /* Load engine */
654         int ret;
655         ret = stt_engine_load(engine->engine_id, engine->engine_path);
656         if (0 != ret) {
657                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to load engine : id(%d) path(%s)", engine->engine_id, engine->engine_path);
658                 return ret;
659         }
660
661         ret = stt_engine_initialize(engine->engine_id, __result_cb, __detect_silence_cb);
662         if (0 != ret) {
663                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to initialize engine : id(%d) path(%s)", engine->engine_id, engine->engine_path);
664                 return ret;
665         }
666
667         ret = stt_engine_set_silence_detection(engine->engine_id, g_default_silence_detected);
668         if (0 != ret) {
669                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent WARNING] Not support silence detection");
670                 engine->support_silence_detection = false;
671         } else {
672                 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Silence detection : %s", g_default_silence_detected ? "true" : "false");
673                 engine->support_silence_detection = true;
674                 engine->silence_detection = g_default_silence_detected;
675         }
676
677         /* Set first language */
678         char* tmp_lang = NULL;
679         ret = stt_engine_get_first_language(engine->engine_id, &tmp_lang);
680         if (0 == ret && NULL != tmp_lang) {
681                 engine->first_lang = strdup(tmp_lang);
682                 free(tmp_lang);
683         } else {
684                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get first language from engine : %d %s", engine->engine_id, engine->engine_name);
685                 return ret;
686         }
687
688 #ifndef AUDIO_CREATE_ON_START
689         /* Ready recorder */
690         sttp_audio_type_e atype;
691         int rate;
692         int channels;
693
694         ret = stt_engine_get_audio_type(engine->engine_id, &atype, &rate, &channels);
695         if (0 != ret) {
696                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get audio type : %d %s", engine->engine_id, engine->engine_name);
697                 return ret;
698         }
699
700         ret = sttd_recorder_create(engine->engine_id, uid, atype, channels, rate);
701         if (0 != ret) {
702                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to create recorder : %d %s", engine->engine_id, engine->engine_name);
703                 return ret;
704         }
705 #endif
706
707         engine->is_loaded = true;
708         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent SUCCESS] The %s(%d) has been loaded !!!", engine->engine_name, engine->engine_id);
709
710         return 0;
711 }
712
713 int sttd_engine_agent_unload_current_engine(int uid)
714 {
715         if (false == g_agent_init) {
716                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized ");
717                 return STTD_ERROR_OPERATION_FAILED;
718         }
719
720         /* Remove client */
721         int engine_id = -1;
722
723         GSList *iter = NULL;
724         sttengine_client_s *data = NULL;
725
726         if (0 < g_slist_length(g_engine_client_list)) {
727                 iter = g_slist_nth(g_engine_client_list, 0);
728
729                 while (NULL != iter) {
730                         /* Get handle data from list */
731                         data = iter->data;
732
733                         if (NULL != data) {
734                                 if (uid == data->uid) {
735                                         g_engine_client_list = g_slist_remove_link(g_engine_client_list, iter);
736                                         engine_id = data->engine_id;
737                                         free(data);
738                                         break;
739                                 }
740                         }
741
742                         iter = g_slist_next(iter);
743                 }
744         }
745
746         if (-1 != engine_id) {
747                 __engine_agent_check_engine_unload(engine_id);
748         }
749
750         return 0;
751 }
752
753 bool sttd_engine_agent_is_default_engine()
754 {
755         if (g_default_engine_id > 0)
756                 return true;
757
758         return false;
759 }
760
761 int sttd_engine_agent_get_engine_list(GSList** engine_list)
762 {
763         if (false == g_agent_init) {
764                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
765                 return STTD_ERROR_OPERATION_FAILED;
766         }
767
768         GSList *iter = NULL;
769         sttengine_info_s *data = NULL;
770
771         iter = g_slist_nth(g_engine_list, 0);
772
773         SLOG(LOG_DEBUG, TAG_STTD, "----- [Engine Agent] engine list -----");
774
775         while (NULL != iter) {
776                 engine_s* temp_engine;
777
778                 temp_engine = (engine_s*)calloc(1, sizeof(engine_s));
779                 if (NULL == temp_engine) {
780                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to allocate memory");
781                         return STTD_ERROR_OUT_OF_MEMORY;
782                 }
783
784                 data = iter->data;
785
786                 temp_engine->engine_id = strdup(data->engine_uuid);
787                 temp_engine->engine_name = strdup(data->engine_name);
788                 temp_engine->ug_name = strdup(data->engine_setting_path);
789
790                 *engine_list = g_slist_append(*engine_list, temp_engine);
791
792                 iter = g_slist_next(iter);
793
794                 SECURE_SLOG(LOG_DEBUG, TAG_STTD, " -- Engine id(%s)", temp_engine->engine_id);
795                 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "    Engine name(%s)", temp_engine->engine_name);
796                 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "    Engine ug name(%s)", temp_engine->ug_name);
797         }
798
799         SLOG(LOG_DEBUG, TAG_STTD, "--------------------------------------");
800
801         return 0;
802 }
803
804 int sttd_engine_agent_get_current_engine(int uid, char** engine_uuid)
805 {
806         if (false == g_agent_init) {
807                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
808                 return STTD_ERROR_OPERATION_FAILED;
809         }
810
811         if (NULL == engine_uuid) {
812                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid parameter");
813                 return STTD_ERROR_INVALID_PARAMETER;
814         }
815
816         sttengine_info_s* engine;
817         engine = __engine_agent_get_engine_by_uid(uid);
818
819         if (NULL == engine) {
820                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The engine of uid(%d) is not valid", uid);
821                 return STTD_ERROR_INVALID_PARAMETER;
822         }
823
824         if (false == engine->is_loaded) {
825                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
826                 return STTD_ERROR_OPERATION_FAILED;
827         }
828
829         *engine_uuid = strdup(engine->engine_uuid);
830
831         return 0;
832 }
833
834 bool sttd_engine_agent_need_network(int uid)
835 {
836         if (false == g_agent_init) {
837                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
838                 return STTD_ERROR_OPERATION_FAILED;
839         }
840
841         sttengine_info_s* engine;
842         engine = __engine_agent_get_engine_by_uid(uid);
843
844         if (NULL != engine)
845                 return engine->use_network;
846
847         return false;
848 }
849
850 int sttd_engine_agent_supported_langs(int uid, GSList** lang_list)
851 {
852         if (false == g_agent_init) {
853                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
854                 return STTD_ERROR_OPERATION_FAILED;
855         }
856
857         if (NULL == lang_list) {
858                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Input parameter is NULL");
859                 return STTD_ERROR_INVALID_PARAMETER;
860         }
861
862         sttengine_info_s* engine = NULL;
863         engine = __engine_agent_get_engine_by_uid(uid);
864
865         if (NULL == engine) {
866                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The engine of uid(%d) is not valid", uid);
867                 return STTD_ERROR_INVALID_PARAMETER;
868         }
869
870         if (false == engine->is_loaded) {
871                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
872                 return STTD_ERROR_OPERATION_FAILED;
873         }
874
875         int ret = stt_engine_get_supported_langs(engine->engine_id, lang_list);
876         if (0 != ret) {
877                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] get language list error(%d)", ret);
878                 return ret;
879         }
880
881         return 0;
882 }
883
884 int sttd_engine_agent_get_default_lang(int uid, char** lang)
885 {
886         if (false == g_agent_init) {
887                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
888                 return STTD_ERROR_OPERATION_FAILED;
889         }
890
891         if (NULL == lang) {
892                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter");
893                 return STTD_ERROR_INVALID_PARAMETER;
894         }
895
896         sttengine_info_s* engine = NULL;
897         engine = __engine_agent_get_engine_by_uid(uid);
898
899         if (NULL == engine) {
900                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The engine of uid(%d) is not valid", uid);
901                 return STTD_ERROR_INVALID_PARAMETER;
902         }
903
904         if (false == engine->is_loaded) {
905                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
906                 return STTD_ERROR_OPERATION_FAILED;
907         }
908
909         /* get default language */
910         bool is_valid = false;
911         int ret = -1;
912         ret = stt_engine_is_valid_language(engine->engine_id, g_default_language, &is_valid);
913         if (0 != ret) {
914                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to check valid language");
915                 return ret;
916         }
917
918         if (true == is_valid) {
919                 *lang = strdup(g_default_language);
920         } else
921                 *lang = strdup(engine->first_lang);
922
923         return 0;
924 }
925
926 int sttd_engine_agent_get_option_supported(int uid, bool* silence)
927 {
928         if (false == g_agent_init) {
929                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
930                 return STTD_ERROR_OPERATION_FAILED;
931         }
932
933         if (NULL == silence) {
934                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter");
935                 return STTD_ERROR_INVALID_PARAMETER;
936         }
937
938         sttengine_info_s* engine = NULL;
939         engine = __engine_agent_get_engine_by_uid(uid);
940
941         if (NULL == engine) {
942                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] uid(%d) is not valid", uid);
943                 return STTD_ERROR_INVALID_PARAMETER;
944         }
945
946         if (false == engine->is_loaded) {
947                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
948                 return STTD_ERROR_OPERATION_FAILED;
949         }
950
951         *silence = engine->support_silence_detection;
952
953         return 0;
954 }
955
956 int sttd_engine_agent_is_credential_needed(int uid, bool* credential)
957 {
958         if (false == g_agent_init) {
959                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
960                 return STTD_ERROR_OPERATION_FAILED;
961         }
962
963         if (NULL == credential) {
964                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter");
965                 return STTD_ERROR_INVALID_PARAMETER;
966         }
967
968         sttengine_info_s* engine = NULL;
969         engine = __engine_agent_get_engine_by_uid(uid);
970
971         if (NULL == engine) {
972                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] uid(%d) is not valid", uid);
973                 return STTD_ERROR_INVALID_PARAMETER;
974         }
975
976         if (false == engine->is_loaded) {
977                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
978                 return STTD_ERROR_OPERATION_FAILED;
979         }
980
981         bool temp = false;
982         int ret;
983
984         ret = stt_engine_need_app_credential(engine->engine_id, &temp);
985         if (0 != ret) {
986                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get to support recognition type : %d", ret);
987                 return ret;
988         }
989
990         *credential = temp;
991         return 0;
992 }
993
994 int sttd_engine_agent_is_recognition_type_supported(int uid, const char* type, bool* support)
995 {
996         if (false == g_agent_init) {
997                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
998                 return STTD_ERROR_OPERATION_FAILED;
999         }
1000
1001         if (NULL == type || NULL == support) {
1002                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter");
1003                 return STTD_ERROR_INVALID_PARAMETER;
1004         }
1005
1006         sttengine_info_s* engine = NULL;
1007         engine = __engine_agent_get_engine_by_uid(uid);
1008
1009         if (NULL == engine) {
1010                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The engine of uid(%d) is not valid", uid);
1011                 return STTD_ERROR_INVALID_PARAMETER;
1012         }
1013
1014         if (false == engine->is_loaded) {
1015                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
1016                 return STTD_ERROR_OPERATION_FAILED;
1017         }
1018
1019         bool temp = false;
1020         int ret;
1021
1022         ret = stt_engine_support_recognition_type(engine->engine_id, type, &temp);
1023         if (0 != ret) {
1024                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get to support recognition type : %d", ret);
1025                 return ret;
1026         }
1027
1028         *support = temp;
1029
1030         return 0;
1031 }
1032
1033 /*
1034 * STT Engine Interfaces for client
1035 */
1036
1037 int __set_option(sttengine_info_s* engine, int silence)
1038 {
1039         if (NULL == engine)
1040                 return -1;
1041
1042         /* Check silence detection */
1043         if (engine->support_silence_detection) {
1044                 if (2 == silence) {
1045                         /* default option set */
1046                         if (g_default_silence_detected != engine->silence_detection) {
1047                                 if (0 != stt_engine_set_silence_detection(engine->engine_id, g_default_silence_detected)) {
1048                                         SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set silence detection : %s", g_default_silence_detected ? "true" : "false");
1049                                 } else {
1050                                         engine->silence_detection = g_default_silence_detected;
1051                                         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Set silence detection : %s", g_default_silence_detected ? "true" : "false");
1052                                 }
1053                         }
1054                 } else {
1055                         if (silence != engine->silence_detection) {
1056                                 if (0 != stt_engine_set_silence_detection(engine->engine_id, silence)) {
1057                                         SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set silence detection : %s", silence ? "true" : "false");
1058                                 } else {
1059                                         engine->silence_detection = silence;
1060                                         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Set silence detection : %s", silence ? "true" : "false");
1061                                 }
1062                         }
1063                 }
1064         }
1065
1066         return 0;
1067 }
1068
1069 int sttd_engine_agent_recognize_start_engine(int uid, const char* lang, const char* recognition_type,
1070                                       int silence, const char* credential, void* user_param)
1071 {
1072         if (false == g_agent_init) {
1073                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
1074                 return STTD_ERROR_OPERATION_FAILED;
1075         }
1076
1077         if (NULL == lang || NULL == recognition_type) {
1078                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter");
1079                 return STTD_ERROR_INVALID_PARAMETER;
1080         }
1081
1082         sttengine_info_s* engine = NULL;
1083         engine = __engine_agent_get_engine_by_uid(uid);
1084
1085         if (NULL == engine) {
1086                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The engine of uid(%d) is not valid", uid);
1087                 return STTD_ERROR_INVALID_PARAMETER;
1088         }
1089
1090         if (false == engine->is_loaded) {
1091                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
1092                 return STTD_ERROR_OPERATION_FAILED;
1093         }
1094
1095         if (0 != __set_option(engine, silence)) {
1096                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set options");
1097                 return STTD_ERROR_OPERATION_FAILED;
1098         }
1099
1100         SLOG(LOG_DEBUG, TAG_STTD, "g_default_language %s", g_default_language);
1101
1102         int ret;
1103         char* temp = NULL;
1104         if (0 == strncmp(lang, "default", strlen("default"))) {
1105                 bool is_valid = false;
1106                 ret = stt_engine_is_valid_language(engine->engine_id, g_default_language, &is_valid);
1107                 if (0 != ret) {
1108                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to check valid language");
1109                         return ret;
1110                 }
1111
1112                 if (true == is_valid) {
1113                         temp = strdup(g_default_language);
1114                         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent DEBUG] Default language is %s", temp);
1115                 } else {
1116                         temp = strdup(engine->first_lang);
1117                         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent DEBUG] Default language is engine first lang : %s", temp);
1118                 }
1119         } else {
1120                 temp = strdup(lang);
1121         }
1122
1123         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Start engine");
1124
1125         ret = stt_engine_recognize_start(engine->engine_id, temp, recognition_type, credential, user_param);
1126         if (NULL != temp)       free(temp);
1127         if (0 != ret) {
1128                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Recognition start error(%d)", ret);
1129                 sttd_recorder_destroy(engine->engine_id);
1130                 return ret;
1131         }
1132
1133 #ifdef AUDIO_CREATE_ON_START
1134         /* Ready recorder */
1135         sttp_audio_type_e atype;
1136         int rate;
1137         int channels;
1138
1139         ret = stt_engine_get_audio_type(engine->engine_id, &atype, &rate, &channels);
1140         if (0 != ret) {
1141                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get audio type : %d %s", engine->engine_id, engine->engine_name);
1142                 return ret;
1143         }
1144
1145         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Create recorder");
1146
1147         ret = sttd_recorder_create(engine->engine_id, uid, atype, channels, rate);
1148         if (0 != ret) {
1149                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to create recorder : %d %s", engine->engine_id, engine->engine_name);
1150                 return ret;
1151         }
1152 #endif
1153
1154 #if 0
1155         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Start recorder");
1156
1157         ret = sttd_recorder_start(engine->engine_id);
1158         if (0 != ret) {
1159                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to start recorder : result(%d)", ret);
1160                 return ret;
1161         }
1162
1163         g_recording_engine_id = engine->engine_id;
1164         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] g_recording_engine_id : %d", g_recording_engine_id);
1165 #endif
1166
1167         return 0;
1168 }
1169
1170 int sttd_engine_agent_recognize_start_recorder(int uid)
1171 {
1172         sttengine_info_s* engine = NULL;
1173         engine = __engine_agent_get_engine_by_uid(uid);
1174
1175         if (NULL == engine) {
1176                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The engine of uid(%d) is not valid", uid);
1177                 return STTD_ERROR_INVALID_PARAMETER;
1178         }
1179
1180         if (false == engine->is_loaded) {
1181                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
1182                 return STTD_ERROR_OPERATION_FAILED;
1183         }
1184
1185         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Start recorder");
1186
1187         int ret;
1188         ret = sttd_recorder_start(engine->engine_id);
1189         if (0 != ret) {
1190                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to start recorder : result(%d)", ret);
1191                 stt_engine_recognize_cancel(engine->engine_id);
1192                 sttd_recorder_stop(engine->engine_id);
1193                 return ret;
1194         }
1195
1196         g_recording_engine_id = engine->engine_id;
1197         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] g_recording_engine_id : %d", g_recording_engine_id);
1198
1199         return 0;
1200 }
1201
1202 int sttd_engine_agent_set_recording_data(int uid, const void* data, unsigned int length)
1203 {
1204         if (false == g_agent_init) {
1205                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
1206                 return STTD_ERROR_OPERATION_FAILED;
1207         }
1208
1209         if (NULL == data || 0 == length) {
1210                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter");
1211                 return STTD_ERROR_INVALID_PARAMETER;
1212         }
1213
1214         sttengine_info_s* engine = NULL;
1215         engine = __engine_agent_get_engine_by_uid(uid);
1216
1217         if (NULL == engine) {
1218                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The engine of uid(%d) is not valid", uid);
1219                 return STTD_ERROR_INVALID_PARAMETER;
1220         }
1221
1222         if (false == engine->is_loaded) {
1223                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
1224                 return STTD_ERROR_OPERATION_FAILED;
1225         }
1226
1227         int ret = stt_engine_set_recording_data(engine->engine_id, data, length);
1228         if (0 != ret) {
1229                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent WARNING] set recording error(%d)", ret);
1230                 return ret;
1231         }
1232
1233         return 0;
1234 }
1235
1236 int sttd_engine_agent_recognize_stop_recorder(int uid)
1237 {
1238         if (false == g_agent_init) {
1239                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
1240                 return STTD_ERROR_OPERATION_FAILED;
1241         }
1242
1243         sttengine_info_s* engine = NULL;
1244         engine = __engine_agent_get_engine_by_uid(uid);
1245
1246         if (NULL == engine) {
1247                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The engine of uid(%d) is not valid", uid);
1248                 return STTD_ERROR_INVALID_PARAMETER;
1249         }
1250
1251         if (false == engine->is_loaded) {
1252                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
1253                 return STTD_ERROR_OPERATION_FAILED;
1254         }
1255
1256         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Stop recorder");
1257         int ret;
1258         ret = sttd_recorder_stop(engine->engine_id);
1259         if (0 != ret) {
1260                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to stop recorder : result(%d)", ret);
1261                 return ret;
1262         }
1263
1264 #ifdef AUDIO_CREATE_ON_START
1265         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Destroy recorder");
1266         if (0 != sttd_recorder_destroy(engine->engine_id))
1267                 SECURE_SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to destroy recorder(%d)", engine->engine_id);
1268 #endif
1269
1270         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent Success] Stop recorder");
1271         return 0;
1272 }
1273
1274 int sttd_engine_agent_recognize_stop_engine(int uid)
1275 {
1276         if (false == g_agent_init) {
1277                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
1278                 return STTD_ERROR_OPERATION_FAILED;
1279         }
1280
1281         sttengine_info_s* engine = NULL;
1282         engine = __engine_agent_get_engine_by_uid(uid);
1283
1284         if (NULL == engine) {
1285                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The engine of uid(%d) is not valid", uid);
1286                 return STTD_ERROR_INVALID_PARAMETER;
1287         }
1288
1289         if (false == engine->is_loaded) {
1290                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
1291                 return STTD_ERROR_OPERATION_FAILED;
1292         }
1293
1294         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Stop engine");
1295
1296         int ret;
1297         ret = stt_engine_recognize_stop(engine->engine_id);
1298         if (0 != ret) {
1299                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] stop recognition error(%d)", ret);
1300                 return ret;
1301         }
1302
1303         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent Success] Stop engine");
1304
1305         return 0;
1306 }
1307
1308 int sttd_engine_agent_recognize_cancel(int uid)
1309 {
1310         if (false == g_agent_init) {
1311                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
1312                 return STTD_ERROR_OPERATION_FAILED;
1313         }
1314
1315         sttengine_info_s* engine = NULL;
1316         engine = __engine_agent_get_engine_by_uid(uid);
1317
1318         if (NULL == engine) {
1319                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The engine of uid(%d) is not valid", uid);
1320                 return STTD_ERROR_INVALID_PARAMETER;
1321         }
1322
1323         if (false == engine->is_loaded) {
1324                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
1325                 return STTD_ERROR_OPERATION_FAILED;
1326         }
1327
1328         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Cancel engine");
1329
1330         int ret;
1331         ret = stt_engine_recognize_cancel(engine->engine_id);
1332         if (0 != ret) {
1333                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] cancel recognition error(%d)", ret);
1334                 return ret;
1335         }
1336
1337         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Stop recorder");
1338
1339         ret = sttd_recorder_stop(engine->engine_id);
1340         if (0 != ret) {
1341                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to stop recorder : result(%d)", ret);
1342                 return ret;
1343         }
1344
1345 #ifdef AUDIO_CREATE_ON_START
1346         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Destroy recorder");
1347         if (0 != sttd_recorder_destroy(engine->engine_id))
1348                 SECURE_SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to destroy recorder(%d)", engine->engine_id);
1349 #endif
1350
1351         g_recording_engine_id = -1;
1352
1353         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent Success] Cancel recognition");
1354
1355         return 0;
1356 }
1357
1358
1359 /*
1360 * STT Engine Interfaces for configure
1361 */
1362
1363 int sttd_engine_agent_set_default_engine(const char* engine_uuid)
1364 {
1365         if (false == g_agent_init) {
1366                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
1367                 return STTD_ERROR_OPERATION_FAILED;
1368         }
1369
1370         if (NULL == engine_uuid) {
1371                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter");
1372                 return STTD_ERROR_INVALID_PARAMETER;
1373         }
1374
1375         __log_enginelist();
1376
1377         sttengine_info_s* engine;
1378         engine = __engine_agent_get_engine_by_uuid(engine_uuid);
1379         if (NULL == engine) {
1380                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Default engine is not valid");
1381                 return STTD_ERROR_ENGINE_NOT_FOUND;
1382         }
1383
1384         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Default engine id(%d) engine uuid(%s)", engine->engine_id, engine->engine_uuid);
1385
1386         g_default_engine_id = engine->engine_id;
1387
1388         /* Update default engine of client */
1389         GSList *iter = NULL;
1390         sttengine_client_s *data = NULL;
1391
1392         if (0 < g_slist_length(g_engine_client_list)) {
1393                 iter = g_slist_nth(g_engine_client_list, 0);
1394
1395                 while (NULL != iter) {
1396                         /* Get handle data from list */
1397                         data = iter->data;
1398
1399                         if (true == data->use_default_engine) {
1400                                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] uid(%d) change engine from id(%d) to id(%d)",
1401                                         data->uid, data->engine_id, engine->engine_id);
1402
1403                                 if (0 != sttd_engine_agent_load_current_engine(data->uid, NULL)) {
1404                                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to load current engine : uid(%d)", data->uid);
1405                                 }
1406                         }
1407
1408                         iter = g_slist_next(iter);
1409                 }
1410         }
1411
1412         return 0;
1413 }
1414
1415 int sttd_engine_agent_set_default_language(const char* language)
1416 {
1417         if (false == g_agent_init) {
1418                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
1419                 return STTD_ERROR_OPERATION_FAILED;
1420         }
1421
1422         if (NULL == language) {
1423                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter");
1424                 return STTD_ERROR_INVALID_PARAMETER;
1425         }
1426
1427         if (NULL != g_default_language)
1428                 free(g_default_language);
1429
1430         g_default_language = strdup(language);
1431
1432         return 0;
1433 }
1434
1435 int sttd_engine_agent_set_silence_detection(bool value)
1436 {
1437         if (false == g_agent_init) {
1438                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
1439                 return STTD_ERROR_OPERATION_FAILED;
1440         }
1441
1442         g_default_silence_detected = value;
1443
1444         return 0;
1445 }
1446
1447 int sttd_engine_agent_check_app_agreed(int uid, const char* appid, bool* result)
1448 {
1449         if (false == g_agent_init) {
1450                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
1451                 return STTD_ERROR_OPERATION_FAILED;
1452         }
1453
1454         sttengine_info_s* engine = NULL;
1455         engine = __engine_agent_get_engine_by_uid(uid);
1456
1457         if (NULL == engine) {
1458                 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The engine of uid(%d) is not valid", uid);
1459                 return STTD_ERROR_INVALID_PARAMETER;
1460         }
1461
1462         if (false == engine->is_loaded) {
1463                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
1464                 return STTD_ERROR_OPERATION_FAILED;
1465         }
1466
1467         int ret;
1468         ret = stt_engine_check_app_agreed(engine->engine_id, appid, result);
1469         if (0 != ret) {
1470                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] cancel recognition error(%d)", ret);
1471                 return ret;
1472         }
1473
1474
1475         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Get engine right : %s", *result ? "true" : "false");
1476         return 0;
1477 }
1478
1479 /*
1480 * STT Engine Callback Functions                                                                                 `                                 *
1481 */
1482
1483 void __result_cb(sttp_result_event_e event, const char* type, const char** data, int data_count,
1484                  const char* msg, void* time_info, void *user_data)
1485 {
1486         if (false == g_agent_init) {
1487                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Result Callback : Not Initialized");
1488                 return;
1489         }
1490
1491         SLOG(LOG_DEBUG, TAG_STTD, "[Server] === Result time callback ===");
1492
1493         if (NULL != time_info) {
1494                 /* Get the time info */
1495                 int ret = stt_engine_foreach_result_time(g_recording_engine_id, time_info, __result_time_cb, NULL);
1496                 if (0 != ret) {
1497                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get time info : %d", ret);
1498                 }
1499         }
1500
1501         SLOG(LOG_DEBUG, TAG_STTD, "[Server] ============================");
1502
1503         g_result_cb(event, type, data, data_count, msg, user_data);
1504
1505 #ifdef AUDIO_CREATE_ON_START
1506         if (event == STTP_RESULT_EVENT_ERROR) {
1507                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Destroy recorder");
1508                 if (0 != sttd_recorder_destroy(g_recording_engine_id))
1509                         SECURE_SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to destroy recorder(%d)", g_recording_engine_id);
1510         }
1511 #endif
1512
1513         if (event == STTP_RESULT_EVENT_FINAL_RESULT || event == STTP_RESULT_EVENT_ERROR) {
1514                 g_recording_engine_id = -1;
1515         }
1516
1517         return;
1518 }
1519
1520 bool __result_time_cb(int index, sttp_result_time_event_e event, const char* text, long start_time, long end_time, void* user_data)
1521 {
1522         return g_result_time_cb(index, event, text, start_time, end_time, user_data);
1523 }
1524
1525 void __detect_silence_cb(sttp_silence_type_e type, void* user_data)
1526 {
1527         if (false == g_agent_init) {
1528                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Silence Callback : Not Initialized");
1529                 return;
1530         }
1531
1532         g_silence_cb(type, user_data);
1533         return;
1534 }
1535
1536 /* A function forging */
1537 int __log_enginelist()
1538 {
1539         GSList *iter = NULL;
1540         sttengine_info_s *data = NULL;
1541
1542         if (0 < g_slist_length(g_engine_list)) {
1543
1544                 /* Get a first item */
1545                 iter = g_slist_nth(g_engine_list, 0);
1546
1547                 SLOG(LOG_DEBUG, TAG_STTD, "--------------- engine list -------------------");
1548
1549                 int i = 1;
1550                 while (NULL != iter) {
1551                         /* Get handle data from list */
1552                         data = iter->data;
1553
1554                         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[%dth]", i);
1555                         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "  engine uuid : %s", data->engine_uuid);
1556                         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "  engine name : %s", data->engine_name);
1557                         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "  engine path : %s", data->engine_path);
1558                         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "  use network : %s", data->use_network ? "true" : "false");
1559                         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "  is loaded : %s", data->is_loaded ? "true" : "false");
1560                         if (NULL != data->first_lang)
1561                                 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "  default lang : %s", data->first_lang);
1562
1563                         iter = g_slist_next(iter);
1564                         i++;
1565                 }
1566                 SLOG(LOG_DEBUG, TAG_STTD, "----------------------------------------------");
1567         } else {
1568                 SLOG(LOG_DEBUG, TAG_STTD, "-------------- engine list -------------------");
1569                 SLOG(LOG_DEBUG, TAG_STTD, "  No Engine in engine directory");
1570                 SLOG(LOG_DEBUG, TAG_STTD, "----------------------------------------------");
1571         }
1572
1573         return 0;
1574 }