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