Add multi-user support
[platform/core/uifw/stt.git] / server / sttd_engine_agent.c
1 /*
2 *  Copyright (c) 2012, 2013 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 "sttd_main.h"
19 #include "sttd_client_data.h"
20 #include "sttd_config.h"
21 #include "sttd_engine_agent.h"
22
23
24 /*
25 * Internal data structure
26 */
27
28 typedef struct {
29         /* engine info */
30         char*   engine_uuid;
31         char*   engine_name; 
32         char*   engine_path;
33
34         /* engine load info */
35         bool    is_set;
36         bool    is_loaded;      
37         bool    need_network;
38         bool    support_silence_detection;
39         bool    support_profanity_filter;
40         bool    support_punctuation_override;
41         void    *handle;
42
43         /* engine base setting */
44         char*   default_lang;
45         bool    profanity_filter;
46         bool    punctuation_override;
47         bool    silence_detection;
48
49         sttpe_funcs_s*  pefuncs;
50         sttpd_funcs_s*  pdfuncs;
51
52         int (*sttp_load_engine)(sttpd_funcs_s* pdfuncs, sttpe_funcs_s* pefuncs);
53         int (*sttp_unload_engine)();
54 } sttengine_s;
55
56 typedef struct _sttengine_info {
57         char*   engine_uuid;
58         char*   engine_path;
59         char*   engine_name;
60         char*   setting_ug_path;
61         bool    use_network;
62         bool    support_silence_detection;
63 } sttengine_info_s;
64
65
66 /*
67 * static data
68 */
69
70 /** stt engine agent init */
71 static bool g_agent_init;
72
73 /** stt engine list */
74 static GList *g_engine_list;            
75
76 /** current engine infomation */
77 static sttengine_s g_cur_engine;
78
79 /** default option value */
80 static bool g_default_profanity_filter;
81 static bool g_default_punctuation_override;
82 static bool g_default_silence_detected;
83
84 /** callback functions */
85 static result_callback g_result_cb;
86 static partial_result_callback g_partial_result_cb;
87 static silence_dectection_callback g_silence_cb;
88
89
90 /** callback functions */
91 void __result_cb(sttp_result_event_e event, const char* type, 
92                         const char** data, int data_count, const char* msg, void *user_data);
93
94 void __partial_result_cb(sttp_result_event_e event, const char* data, void *user_data);
95
96 void __detect_silence_cb(void* user_data);
97
98 bool __supported_language_cb(const char* language, void* user_data);
99
100 void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* setting_ug_name, 
101                       bool use_network, void* user_data);
102
103 bool __engine_setting_cb(const char* key, const char* value, void* user_data);
104
105 /** Free voice list */
106 void __free_language_list(GList* lang_list);
107
108
109 /*
110 * Internal Interfaces 
111 */
112  
113 /** Set current engine */
114 int __internal_set_current_engine(const char* engine_uuid);
115
116 /** check engine id */
117 int __internal_check_engine_id(const char* engine_uuid);
118
119 /** update engine list */
120 int __internal_update_engine_list();
121
122 /** get engine info */
123 int __internal_get_engine_info(const char* filepath, sttengine_info_s** info);
124
125 int __log_enginelist();
126
127 /*
128 * STT Engine Agent Interfaces
129 */
130 int sttd_engine_agent_init(result_callback result_cb, partial_result_callback partial_result_cb, silence_dectection_callback silence_cb)
131 {
132         /* initialize static data */
133         if (NULL == result_cb || NULL == silence_cb) {
134                 SLOG(LOG_ERROR, TAG_STTD, "[Engine agent ERROR] sttd_engine_agent_init : invalid parameter"); 
135                 return STTD_ERROR_INVALID_PARAMETER;
136         }
137
138         g_result_cb = result_cb;
139         g_partial_result_cb = partial_result_cb;
140         g_silence_cb = silence_cb;
141
142         g_cur_engine.engine_uuid = NULL;
143         g_cur_engine.engine_name = NULL;
144         g_cur_engine.engine_path = NULL;
145
146         g_cur_engine.is_set = false;
147         g_cur_engine.handle = NULL;
148         g_cur_engine.pefuncs = (sttpe_funcs_s*)malloc( sizeof(sttpe_funcs_s) );
149         g_cur_engine.pdfuncs = (sttpd_funcs_s*)malloc( sizeof(sttpd_funcs_s) );
150
151         g_agent_init = true;
152
153         if (0 != sttd_config_get_default_language(&(g_cur_engine.default_lang))) {
154                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] There is No default voice in config"); 
155                 /* Set default voice */
156                 g_cur_engine.default_lang = strdup("en_US");
157         }
158
159         int temp;
160         if (0 != sttd_config_get_default_silence_detection(&temp)) {
161                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] There is no silence detection in config"); 
162                 g_default_silence_detected = true;
163         } else {
164                 g_default_silence_detected = (bool)temp;
165         }
166
167         if (0 != sttd_config_get_default_profanity_filter(&temp)) {
168                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] There is no profanity filter in config"); 
169                 g_default_profanity_filter = false;
170         } else {
171                 g_default_profanity_filter = (bool)temp;
172         }
173
174         if (0 != sttd_config_get_default_punctuation_override(&temp)) {
175                 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] There is no punctuation override in config"); 
176                 g_default_punctuation_override = false;
177         } else {
178                 g_default_punctuation_override = (bool)temp;
179         }
180
181         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent SUCCESS] Engine Agent Initialize"); 
182
183         return 0;
184 }
185
186 int sttd_engine_agent_release()
187 {
188         if (false == g_agent_init) {
189                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
190                 return STTD_ERROR_OPERATION_FAILED;
191         }
192
193         /* unload current engine */
194         sttd_engine_agent_unload_current_engine();
195
196         /* release engine list */
197         GList *iter = NULL;
198         sttengine_s *data = NULL;
199
200         if (g_list_length(g_engine_list) > 0) {
201                 /* Get a first item */
202                 iter = g_list_first(g_engine_list);
203
204                 while (NULL != iter) {
205                         /* Get handle data from list */
206                         data = iter->data;
207
208                         iter = g_list_remove(iter, data);
209                 }
210         }
211
212         g_list_free(iter);
213         
214         /* release current engine data */
215         if( NULL != g_cur_engine.pefuncs )
216                 free(g_cur_engine.pefuncs);
217
218         if( NULL != g_cur_engine.pdfuncs )
219                 free(g_cur_engine.pdfuncs);
220
221         g_result_cb = NULL;
222         g_silence_cb = NULL;
223
224         g_agent_init = false;
225
226         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent SUCCESS] Engine Agent release"); 
227
228         return 0;
229 }
230
231 int sttd_engine_agent_initialize_current_engine()
232 {
233         /* check agent init */
234         if (false == g_agent_init ) {
235                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
236                 return STTD_ERROR_OPERATION_FAILED;
237         }
238
239         /* update engine list */
240         if (0 != __internal_update_engine_list()) {
241                 SLOG(LOG_ERROR, TAG_STTD, "[engine agent] sttd_engine_agent_init : __internal_update_engine_list : no engine error"); 
242                 return STTD_ERROR_ENGINE_NOT_FOUND;
243         }
244
245         /* get current engine from config */
246         char* cur_engine_uuid = NULL;
247         bool is_get_engineid_from_config = false;
248
249         if (0 != sttd_config_get_default_engine(&cur_engine_uuid)) {
250
251                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] There is not current engine from config"); 
252
253                 /* not set current engine */
254                 /* set system default engine */
255                 GList *iter = NULL;
256                 if (0 < g_list_length(g_engine_list)) {
257                         iter = g_list_first(g_engine_list);
258                 } else {
259                         SLOG(LOG_ERROR, TAG_STTD, "[engine agent ERROR] sttd_engine_agent_initialize_current_engine() : no engine error"); 
260                         return -1;      
261                 }
262
263                 sttengine_info_s *data = NULL;
264                 data = iter->data;
265
266                 cur_engine_uuid = g_strdup(data->engine_uuid);
267
268                 is_get_engineid_from_config = false;
269         } else {
270                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] current engine from config : %s", cur_engine_uuid); 
271
272                 is_get_engineid_from_config = true;
273         }
274
275         /* check whether cur engine uuid is valid or not. */
276         if (0 != __internal_check_engine_id(cur_engine_uuid)) {
277                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] It is not valid engine id and find other engine id");
278
279                 GList *iter = NULL;
280                 if (0 < g_list_length(g_engine_list)) {
281                         iter = g_list_first(g_engine_list);
282                 } else {
283                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] sttd_engine_agent_initialize_current_engine() : no engine error"); 
284                         return -1;      
285                 }
286
287                 if (NULL != cur_engine_uuid)    
288                         free(cur_engine_uuid);
289                 
290                 sttengine_info_s *data = NULL;
291                 data = iter->data;
292
293                 cur_engine_uuid = g_strdup(data->engine_uuid);
294                 
295                 is_get_engineid_from_config = false;
296         }
297
298         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Current Engine Id : %s", cur_engine_uuid);
299
300         /* set current engine */
301         if (0 != __internal_set_current_engine(cur_engine_uuid)) {
302                 SLOG(LOG_ERROR, TAG_STTD, "[engine agent ERROR] __internal_set_current_engine : no engine error"); 
303
304                 if( cur_engine_uuid != NULL)    
305                         free(cur_engine_uuid);
306
307                 return STTD_ERROR_ENGINE_NOT_FOUND;
308         }
309
310         if (false == is_get_engineid_from_config) {
311                 if (0 != sttd_config_set_default_engine(cur_engine_uuid))
312                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set default engine "); 
313         }
314
315         if( cur_engine_uuid != NULL )   
316                 free(cur_engine_uuid);
317
318         return 0;
319 }
320
321 int __internal_check_engine_id(const char* engine_uuid)
322 {
323         if (NULL == engine_uuid) {
324                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
325                 return STTD_ERROR_INVALID_PARAMETER;
326         }
327
328         GList *iter = NULL;
329         sttengine_s *data = NULL;
330
331         if (0 < g_list_length(g_engine_list)) {
332                 /*Get a first item*/
333                 iter = g_list_first(g_engine_list);
334
335                 while (NULL != iter) {
336                         data = iter->data;
337                         
338                         if (0 == strncmp(engine_uuid, data->engine_uuid, strlen(data->engine_uuid))) {
339                                 return 0;
340                         }
341
342                         iter = g_list_next(iter);
343                 }
344         }
345
346         return -1;
347 }
348
349 void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* setting_ug_name, 
350                       bool use_network, void* user_data)
351 {
352         sttengine_info_s* temp = (sttengine_info_s*)user_data; 
353
354         temp->engine_uuid = g_strdup(engine_uuid);
355         temp->engine_name = g_strdup(engine_name);
356         temp->setting_ug_path = g_strdup(setting_ug_name);
357         temp->use_network = use_network;
358 }
359
360
361 int __internal_get_engine_info(const char* filepath, sttengine_info_s** info)
362 {
363         if (NULL == filepath || NULL == info) {
364                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
365                 return STTD_ERROR_INVALID_PARAMETER;
366         }
367
368         /* load engine */
369         char *error;
370         void* handle;
371
372         handle = dlopen (filepath, RTLD_LAZY);
373
374         if (!handle) {
375                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Invalid engine : %s", filepath); 
376                 return -1;
377         }
378
379         /* link engine to daemon */
380         dlsym(handle, "sttp_load_engine");
381         if ((error = dlerror()) != NULL) {
382                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Invalid engine. Fail to open sttp_load_engine : %s", error); 
383                 dlclose(handle);
384                 return -1;
385         }
386
387         dlsym(handle, "sttp_unload_engine");
388         if ((error = dlerror()) != NULL) {
389                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Invalid engine. Fail to open sttp_unload_engine : %s", error); 
390                 dlclose(handle);
391                 return -1;
392         }
393
394         int (*get_engine_info)(sttpe_engine_info_cb callback, void* user_data);
395
396         get_engine_info = (int (*)(sttpe_engine_info_cb, void*))dlsym(handle, "sttp_get_engine_info");
397         if ((error = dlerror()) != NULL || NULL == get_engine_info) {
398                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent WARNING] Invalid engine. Fail to open sttp_get_engine_info : %s", error); 
399                 dlclose(handle);
400                 return -1;
401         }
402
403         sttengine_info_s* temp;
404         temp = (sttengine_info_s*)g_malloc0( sizeof(sttengine_info_s) );
405
406         /* get engine info */
407         if (0 != get_engine_info(__engine_info_cb, (void*)temp)) {
408                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get engine info from engine"); 
409                 dlclose(handle);
410                 g_free(temp);
411                 return -1;
412         }
413
414         /* close engine */
415         dlclose(handle);
416
417         temp->engine_path = g_strdup(filepath);
418
419         SLOG(LOG_DEBUG, TAG_STTD, "----- Valid Engine");
420         SLOG(LOG_DEBUG, TAG_STTD, "Engine uuid : %s", temp->engine_uuid);
421         SLOG(LOG_DEBUG, TAG_STTD, "Engine name : %s", temp->engine_name);
422         SLOG(LOG_DEBUG, TAG_STTD, "Setting ug path : %s", temp->setting_ug_path);
423         SLOG(LOG_DEBUG, TAG_STTD, "Engine path : %s", temp->engine_path);
424         SLOG(LOG_DEBUG, TAG_STTD, "Use network : %s", temp->use_network ? "true":"false");
425         SLOG(LOG_DEBUG, TAG_STTD, "-----");
426         SLOG(LOG_DEBUG, TAG_STTD, "  ");
427
428         *info = temp;
429
430         return 0;
431 }
432
433 int __internal_update_engine_list()
434 {
435         /* relsease engine list */
436         GList *iter = NULL;
437         sttengine_info_s *data = NULL;
438
439         if (0 < g_list_length(g_engine_list)) {
440                 /* Get a first item */
441                 iter = g_list_first(g_engine_list);
442
443                 while (NULL != iter) {
444                         /* Get handle data from list */
445                         data = iter->data;
446
447                         if (NULL != data) {
448                                 if (NULL != data->engine_uuid)          free(data->engine_uuid);
449                                 if (NULL != data->engine_path)          free(data->engine_path);
450                                 if (NULL != data->engine_name)          free(data->engine_name);
451                                 if (NULL != data->setting_ug_path)      free(data->setting_ug_path);
452                                 
453                                 free(data);
454                         }
455
456                         g_engine_list = g_list_remove_link(g_engine_list, iter);
457                         iter = g_list_first(g_engine_list);
458                 }
459         }
460
461         /* Get file name from default engine directory */
462         DIR *dp;
463         struct dirent *dirp;
464
465         dp  = opendir(ENGINE_DIRECTORY_DEFAULT);
466         if (NULL != dp) {
467                 while (NULL != (dirp = readdir(dp))) {
468                         sttengine_info_s* info;
469                         char* filepath;
470                         int filesize;
471
472                         filesize = strlen(ENGINE_DIRECTORY_DEFAULT) + strlen(dirp->d_name) + 5;
473                         filepath = (char*) g_malloc0(sizeof(char) * filesize);
474
475                         if (NULL != filepath) {
476                                 strncpy(filepath, ENGINE_DIRECTORY_DEFAULT, strlen(ENGINE_DIRECTORY_DEFAULT) );
477                                 strncat(filepath, "/", strlen("/") );
478                                 strncat(filepath, dirp->d_name, strlen(dirp->d_name) );
479                         } else {
480                                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Memory not enough!!" );
481                                 continue;       
482                         }
483
484                         /* get its info and update engine list */
485                         if (0 == __internal_get_engine_info(filepath, &info)) {
486                                 /* add engine info to g_engine_list */
487                                 g_engine_list = g_list_append(g_engine_list, info);
488                         }
489
490                         if (NULL != filepath)
491                                 g_free(filepath);
492                 }
493
494                 closedir(dp);
495         } else {
496                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent WARNING] Fail to open default directory"); 
497         }
498         
499         /* Get file name from downloadable engine directory */
500         dp  = opendir(ENGINE_DIRECTORY_DOWNLOAD);
501         if (NULL != dp) {
502                 while (NULL != (dirp = readdir(dp))) {
503                         sttengine_info_s* info;
504                         char* filepath;
505                         int filesize;
506
507                         filesize = strlen(ENGINE_DIRECTORY_DOWNLOAD) + strlen(dirp->d_name) + 5;
508                         filepath = (char*) g_malloc0(sizeof(char) * filesize);
509
510                         if (NULL != filepath) {
511                                 strncpy(filepath, ENGINE_DIRECTORY_DOWNLOAD, strlen(ENGINE_DIRECTORY_DOWNLOAD) );
512                                 strncat(filepath, "/", strlen("/") );
513                                 strncat(filepath, dirp->d_name, strlen(dirp->d_name) );
514                         } else {
515                                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Memory not enough!!" );
516                                 continue;
517                         }
518
519                         /* get its info and update engine list */
520                         if (0 == __internal_get_engine_info(filepath, &info)) {
521                                 /* add engine info to g_engine_list */
522                                 g_engine_list = g_list_append(g_engine_list, info);
523                         }
524
525                         if (NULL != filepath)
526                                 g_free(filepath);
527                 }
528
529                 closedir(dp);
530         } else {
531                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent WARNING] Fail to open downloadable directory"); 
532         }
533
534         if (0 >= g_list_length(g_engine_list)) {
535                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] No Engine"); 
536                 return STTD_ERROR_ENGINE_NOT_FOUND;     
537         }
538
539         __log_enginelist();
540         
541         return 0;
542 }
543
544 int __internal_set_current_engine(const char* engine_uuid)
545 {
546         if (NULL == engine_uuid) {
547                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
548                 return STTD_ERROR_INVALID_PARAMETER;
549         }
550
551         /* check whether engine id is valid or not.*/
552         GList *iter = NULL;
553         sttengine_info_s *data = NULL;
554
555         bool flag = false;
556         if (g_list_length(g_engine_list) > 0) {
557                 /*Get a first item*/
558                 iter = g_list_first(g_engine_list);
559
560                 while (NULL != iter) {
561                         /*Get handle data from list*/
562                         data = iter->data;
563
564                         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] engine_uuid(%s) engine list->uuid(%s)", engine_uuid, data->engine_uuid);
565
566                         if (0 == strncmp(data->engine_uuid, engine_uuid, strlen(engine_uuid))) {
567                                 flag = true;
568                                 break;
569                         }
570
571                         /*Get next item*/
572                         iter = g_list_next(iter);
573                 }
574         }
575
576         /* If current engine does not exist, return error */
577         if (false == flag) {
578                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] __internal_set_current_engine : Cannot find engine id"); 
579                 return STTD_ERROR_INVALID_PARAMETER;
580         } else {
581                 if (NULL != g_cur_engine.engine_uuid) {
582                         /*compare current engine uuid */
583                         if (0 == strncmp(g_cur_engine.engine_uuid, data->engine_uuid, strlen(engine_uuid))) {
584                                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent Check] stt engine has already been set");
585                                 return 0;
586                         }
587                 }
588         }
589
590         /* set data from g_engine_list */
591         if (g_cur_engine.engine_uuid != NULL)   free(g_cur_engine.engine_uuid);
592         if (g_cur_engine.engine_name != NULL)   free(g_cur_engine.engine_name);
593         if (g_cur_engine.engine_path != NULL)   free(g_cur_engine.engine_path);
594
595         g_cur_engine.engine_uuid = g_strdup(data->engine_uuid);
596         g_cur_engine.engine_name = g_strdup(data->engine_name);
597         g_cur_engine.engine_path = g_strdup(data->engine_path);
598
599         g_cur_engine.handle = NULL;
600         g_cur_engine.is_loaded = false;
601         g_cur_engine.is_set = true;
602         g_cur_engine.need_network = data->use_network;
603
604         g_cur_engine.profanity_filter = g_default_profanity_filter;
605         g_cur_engine.punctuation_override = g_default_punctuation_override;
606         g_cur_engine.silence_detection = g_default_silence_detected;
607
608         SLOG(LOG_DEBUG, TAG_STTD, "-----");
609         SLOG(LOG_DEBUG, TAG_STTD, " Current engine uuid : %s", g_cur_engine.engine_uuid);
610         SLOG(LOG_DEBUG, TAG_STTD, " Current engine name : %s", g_cur_engine.engine_name);
611         SLOG(LOG_DEBUG, TAG_STTD, " Current engine path : %s", g_cur_engine.engine_path);
612         SLOG(LOG_DEBUG, TAG_STTD, "-----");
613
614         return 0;
615 }
616
617 int sttd_engine_agent_load_current_engine()
618 {
619         if (false == g_agent_init) {
620                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
621                 return STTD_ERROR_OPERATION_FAILED;
622         }
623
624         if (false == g_cur_engine.is_set) {
625                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] sttd_engine_agent_load_current_engine : No Current Engine "); 
626                 return -1;
627         }
628
629         /* check whether current engine is loaded or not */
630         if (true == g_cur_engine.is_loaded) {
631                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] sttd_engine_agent_load_current_engine : Engine has already been loaded ");
632                 return 0;
633         }
634         
635         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Current engine path : %s", g_cur_engine.engine_path);
636
637         /* open engine */
638         char *error;
639         g_cur_engine.handle = dlopen(g_cur_engine.engine_path, RTLD_LAZY);
640
641         if (NULL != (error = dlerror()) || !g_cur_engine.handle) {
642                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to get engine handle"); 
643                 return STTD_ERROR_OPERATION_FAILED;
644         }
645         
646         g_cur_engine.sttp_unload_engine = (int (*)())dlsym(g_cur_engine.handle, "sttp_unload_engine");
647         if (NULL != (error = dlerror()) || NULL == g_cur_engine.sttp_unload_engine) {
648                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to link daemon to sttp_unload_engine() : %s", error); 
649                 return STTD_ERROR_OPERATION_FAILED;
650         }
651
652         g_cur_engine.sttp_load_engine = (int (*)(sttpd_funcs_s*, sttpe_funcs_s*) )dlsym(g_cur_engine.handle, "sttp_load_engine");
653         if (NULL != (error = dlerror()) || NULL == g_cur_engine.sttp_load_engine) {
654                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to link daemon to sttp_load_engine() : %s", error); 
655                 return STTD_ERROR_OPERATION_FAILED;
656         }
657
658         /* load engine */
659         g_cur_engine.pdfuncs->version = 1;
660         g_cur_engine.pdfuncs->size = sizeof(sttpd_funcs_s);
661
662         if (0 != g_cur_engine.sttp_load_engine(g_cur_engine.pdfuncs, g_cur_engine.pefuncs)) {
663                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail sttp_load_engine()"); 
664                 return STTD_ERROR_OPERATION_FAILED;
665         }
666
667         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] engine info : version(%d), size(%d)",g_cur_engine.pefuncs->version, g_cur_engine.pefuncs->size); 
668
669         /* engine error check */
670         if (g_cur_engine.pefuncs->size != sizeof(sttpe_funcs_s)) {
671                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] sttd_engine_agent_load_current_engine : engine is not valid"); 
672                 return STTD_ERROR_OPERATION_FAILED;
673         }
674
675         /* initalize engine */
676         if (0 != g_cur_engine.pefuncs->initialize(__result_cb, __partial_result_cb, __detect_silence_cb)) {
677                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to initialize stt-engine"); 
678                 return STTD_ERROR_OPERATION_FAILED;
679         }
680
681         /* set default setting */
682         int ret = 0;
683
684         if (NULL == g_cur_engine.pefuncs->set_profanity_filter) {
685                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] set_profanity_filter of engine is NULL!!");
686                 return STTD_ERROR_OPERATION_FAILED;
687         }
688         
689         /* check and set profanity filter */
690         ret = g_cur_engine.pefuncs->set_profanity_filter(g_cur_engine.profanity_filter);
691         if (0 != ret) {
692                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent] Not support profanity filter");
693                 g_cur_engine.support_profanity_filter = false;
694         } else {
695                 g_cur_engine.support_profanity_filter = true;
696         }
697         
698         /* check and set punctuation */
699         if (NULL == g_cur_engine.pefuncs->set_punctuation) {
700                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] set_punctuation of engine is NULL!!");
701                 return STTD_ERROR_OPERATION_FAILED;
702         }
703
704         ret = g_cur_engine.pefuncs->set_punctuation(g_cur_engine.punctuation_override);
705         if (0 != ret) {
706                 SLOG(LOG_ERROR, TAG_STTD, "[Engine ERROR] Not support punctuation override");
707                 g_cur_engine.support_punctuation_override = false;
708         } else {
709                 g_cur_engine.support_punctuation_override = true;
710         }
711
712         /* check and set silence detection */
713         if (NULL == g_cur_engine.pefuncs->set_silence_detection) {
714                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] set_silence_detection of engine is NULL!!");
715                 return STTD_ERROR_OPERATION_FAILED;
716         }
717
718         ret = g_cur_engine.pefuncs->set_silence_detection(g_cur_engine.silence_detection);
719         if (0 != ret) {
720                 SLOG(LOG_ERROR, TAG_STTD, "[Engine ERROR] Not support silence detection");
721                 g_cur_engine.support_silence_detection = false;
722         } else {
723                 g_cur_engine.support_silence_detection = true;
724         }
725         
726         /* select default language */
727         bool set_voice = false;
728         if (NULL != g_cur_engine.default_lang) {
729                 if (NULL == g_cur_engine.pefuncs->is_valid_lang) {
730                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] set_default_lang of engine is NULL!!");
731                         return STTD_ERROR_OPERATION_FAILED;
732                 }
733
734                 if (true == g_cur_engine.pefuncs->is_valid_lang(g_cur_engine.default_lang)) {
735                         set_voice = true;
736                         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent SUCCESS] Set origin default voice to current engine : lang(%s)", g_cur_engine.default_lang);
737                 } else {
738                         SLOG(LOG_WARN, TAG_STTD, "[Engine Agent WARNING] Fail set origin default language : lang(%s)", g_cur_engine.default_lang);
739                 }
740         }
741
742         if (false == set_voice) {
743                 if (NULL == g_cur_engine.pefuncs->foreach_langs) {
744                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] foreach_langs of engine is NULL!!");
745                         return STTD_ERROR_OPERATION_FAILED;
746                 }
747
748                 /* get language list */
749                 int ret;
750                 GList* lang_list = NULL;
751
752                 ret = g_cur_engine.pefuncs->foreach_langs(__supported_language_cb, &lang_list);
753
754                 if (0 == ret && 0 < g_list_length(lang_list)) {
755                         GList *iter = NULL;
756                         iter = g_list_first(lang_list);
757
758                         if (NULL != iter) {
759                                 char* temp_lang = iter->data;
760
761                                 if (true != g_cur_engine.pefuncs->is_valid_lang(temp_lang)) {
762                                         SLOG(LOG_ERROR, TAG_STTD, "[Engine ERROR] Fail voice is NOT valid");
763                                         return STTD_ERROR_OPERATION_FAILED;
764                                 }
765
766                                 sttd_config_set_default_language(temp_lang);
767
768                                 g_cur_engine.default_lang = g_strdup(temp_lang);
769                                 
770                                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent SUCCESS] Select default voice : lang(%s)", temp_lang);
771                         } else {
772                                 SLOG(LOG_ERROR, TAG_STTD, "[Engine ERROR] Fail to get language list : result(%d)\n", ret);
773                                 return STTD_ERROR_OPERATION_FAILED;
774                         }
775
776                         __free_language_list(lang_list);
777                 } else {
778                         SLOG(LOG_ERROR, TAG_STTD, "[Engine ERROR] Fail to get language list : result(%d)\n", ret);
779                         return STTD_ERROR_OPERATION_FAILED;
780                 }
781
782         } 
783
784         g_cur_engine.is_loaded = true;
785
786         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent SUCCESS] The %s has been loaded !!!", g_cur_engine.engine_name); 
787
788         return 0;
789 }
790
791 int sttd_engine_agent_unload_current_engine()
792 {
793         if (false == g_agent_init) {
794                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized "); 
795                 return STTD_ERROR_OPERATION_FAILED;
796         }
797
798         if (false == g_cur_engine.is_set) {
799                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] sttd_engine_agent_unload_current_engine : No Current Engine "); 
800                 return -1;
801         }
802
803         if (false == g_cur_engine.is_loaded) {
804                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent WARNING] Current engine has already been unloaded "); 
805                 return 0;
806         }
807
808         /* shutdown engine */
809         if (NULL == g_cur_engine.pefuncs->deinitialize) {
810                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] shutdown of engine is NULL!!");
811         } else {
812                 g_cur_engine.pefuncs->deinitialize();
813         }
814
815         /* unload engine */
816         if (0 != g_cur_engine.sttp_unload_engine()) {
817                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to unload engine"); 
818         }
819
820         dlclose(g_cur_engine.handle);
821
822         /* reset current engine data */
823         g_cur_engine.handle = NULL;
824         g_cur_engine.is_loaded = false;
825
826         return 0;
827 }
828
829 bool sttd_engine_agent_need_network()
830 {
831         if (false == g_agent_init) {
832                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized" );
833                 return STTD_ERROR_OPERATION_FAILED;
834         }
835
836         if (false == g_cur_engine.is_loaded) {
837                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
838                 return STTD_ERROR_OPERATION_FAILED;
839         }
840
841         return g_cur_engine.need_network;
842 }
843
844 int sttd_engine_get_option_supported(bool* silence, bool* profanity, bool* punctuation)
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 (false == g_cur_engine.is_loaded) {
852                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
853                 return STTD_ERROR_OPERATION_FAILED;
854         }
855
856         if (NULL == silence || NULL == profanity || NULL == punctuation) {
857                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
858                 return STTD_ERROR_INVALID_PARAMETER;
859         }
860
861         *silence = g_cur_engine.support_silence_detection;
862         *profanity = g_cur_engine.support_profanity_filter;
863         *punctuation = g_cur_engine.support_punctuation_override;
864
865         return 0;
866 }
867
868 /*
869 * STT Engine Interfaces for client
870 */
871
872 int __set_option(int profanity, int punctuation, int silence)
873 {
874         if (2 == profanity) {
875                 /* Default selection */
876                 if (g_default_profanity_filter != g_cur_engine.profanity_filter) {
877                         if (NULL != g_cur_engine.pefuncs->set_profanity_filter) {
878                                 if (0 != g_cur_engine.pefuncs->set_profanity_filter(g_default_profanity_filter)) {
879                                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set profanity filter");
880                                         return STTD_ERROR_OPERATION_FAILED;
881                                 }
882                                 g_cur_engine.profanity_filter = g_default_profanity_filter;
883                                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Set profanity filter : %s", g_cur_engine.profanity_filter ? "true" : "false");
884                         } else {
885                                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] profanity_filter() of engine is NULL!!");
886                                 return STTD_ERROR_OPERATION_FAILED;
887                         }
888                 }
889         } else {
890                 /* Client selection */
891                 if (g_cur_engine.profanity_filter != profanity) {
892                         if (NULL != g_cur_engine.pefuncs->set_profanity_filter) {
893                                 if (0 != g_cur_engine.pefuncs->set_profanity_filter((bool)profanity)) {
894                                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set profanity filter");
895                                         return STTD_ERROR_OPERATION_FAILED;
896                                 }
897
898                                 g_cur_engine.profanity_filter = (bool)profanity;
899                                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Set profanity filter : %s", g_cur_engine.profanity_filter ? "true" : "false");
900                         } else {
901                                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] profanity_filter() of engine is NULL!!");
902                                 return STTD_ERROR_OPERATION_FAILED;
903                         }
904                 }
905         }
906
907         if (2 == punctuation) {
908                 /* Default selection */
909                 if (g_default_punctuation_override != g_cur_engine.punctuation_override) {
910                         if (NULL != g_cur_engine.pefuncs->set_punctuation) {
911                                 if (0 != g_cur_engine.pefuncs->set_punctuation(g_default_punctuation_override)) {
912                                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set punctuation override");
913                                         return STTD_ERROR_OPERATION_FAILED;
914                                 }
915                                 g_cur_engine.punctuation_override = g_default_punctuation_override;
916                                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Set punctuation override : %s", g_cur_engine.punctuation_override ? "true" : "false");
917                         } else {
918                                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] set_punctuation() of engine is NULL!!");
919                                 return STTD_ERROR_OPERATION_FAILED;
920                         }
921                 }
922         } else {
923                 /* Client selection */
924                 if (g_cur_engine.punctuation_override != punctuation) {
925                         if (NULL != g_cur_engine.pefuncs->set_punctuation) {
926                                 if (0 != g_cur_engine.pefuncs->set_punctuation((bool)punctuation)) {
927                                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set punctuation override");
928                                         return STTD_ERROR_OPERATION_FAILED;
929                                 }
930
931                                 g_cur_engine.punctuation_override = (bool)punctuation;
932                                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Set punctuation override : %s", g_cur_engine.punctuation_override ? "true" : "false");
933                         } else {
934                                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] set_punctuation() of engine is NULL!!");
935                                 return STTD_ERROR_OPERATION_FAILED;
936                         }
937                 }
938         }
939
940         if (2 == silence) {
941                 /* Default selection */
942                 if (g_default_silence_detected != g_cur_engine.silence_detection) {
943                         if (NULL != g_cur_engine.pefuncs->set_silence_detection) {
944                                 if (0 != g_cur_engine.pefuncs->set_silence_detection(g_default_silence_detected)) {
945                                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set silence detection");
946                                         return STTD_ERROR_OPERATION_FAILED;
947                                 }
948                                 g_cur_engine.silence_detection = g_default_silence_detected;
949                                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Set silence detection : %s", g_cur_engine.silence_detection ? "true" : "false");
950                         } else {
951                                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] set_silence() of engine is NULL!!");
952                                 return STTD_ERROR_OPERATION_FAILED;
953                         }
954                 }
955         } else {
956                 /* Client selection */
957                 if (g_cur_engine.silence_detection != silence) {
958                         if (NULL != g_cur_engine.pefuncs->set_silence_detection) {
959                                 if (0 != g_cur_engine.pefuncs->set_silence_detection((bool)silence)) {
960                                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set silence detection");
961                                         return STTD_ERROR_OPERATION_FAILED;
962                                 }
963
964                                 g_cur_engine.silence_detection = (bool)silence;
965                                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Set silence detection : %s", g_cur_engine.silence_detection ? "true" : "false");
966                         } else {
967                                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] set_silence() of engine is NULL!!");
968                                 return STTD_ERROR_OPERATION_FAILED;
969                         }
970                 }
971         }
972         
973         return 0;
974 }
975
976 int sttd_engine_recognize_start(const char* lang, const char* recognition_type, 
977                                 int profanity, int punctuation, int silence, void* user_param)
978 {
979         if (false == g_agent_init) {
980                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
981                 return STTD_ERROR_OPERATION_FAILED;
982         }
983
984         if (false == g_cur_engine.is_loaded) {
985                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
986                 return STTD_ERROR_OPERATION_FAILED;
987         }
988
989         if (NULL == lang || NULL == recognition_type) {
990                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
991                 return STTD_ERROR_INVALID_PARAMETER;
992         }
993
994         if (0 != __set_option(profanity, punctuation, g_default_silence_detected)) {
995                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set options"); 
996                 return STTD_ERROR_OPERATION_FAILED;
997         }
998
999         if (NULL == g_cur_engine.pefuncs->start) {
1000                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] start() of engine is NULL!!");
1001                 return STTD_ERROR_OPERATION_FAILED;
1002         }
1003
1004         char* temp;
1005         if (0 == strncmp(lang, "default", strlen("default"))) {
1006                 temp = strdup(g_cur_engine.default_lang);
1007         } else {
1008                 temp = strdup(lang);
1009         }
1010
1011         int ret = g_cur_engine.pefuncs->start(temp, recognition_type, user_param);
1012         free(temp);
1013
1014         if (0 != ret) {
1015                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] sttd_engine_recognize_start : recognition start error(%d)", ret); 
1016                 return STTD_ERROR_OPERATION_FAILED;
1017         }
1018
1019         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent SUCCESS] sttd_engine_recognize_start");
1020
1021         return 0;
1022 }
1023
1024 int sttd_engine_recognize_audio(const void* data, unsigned int length)
1025 {
1026         if (false == g_agent_init) {
1027                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1028                 return STTD_ERROR_OPERATION_FAILED;
1029         }
1030
1031         if (false == g_cur_engine.is_loaded) {
1032                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1033                 return STTD_ERROR_OPERATION_FAILED;
1034         }
1035
1036         if (NULL == data) {
1037                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1038                 return STTD_ERROR_INVALID_PARAMETER;
1039         }
1040
1041         if (NULL == g_cur_engine.pefuncs->set_recording) {
1042                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The function of engine is NULL!!");
1043                 return STTD_ERROR_OPERATION_FAILED;
1044         }
1045
1046         int ret = g_cur_engine.pefuncs->set_recording(data, length);
1047         if (0 != ret) {
1048                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent WARNING] set recording error(%d)", ret); 
1049                 return ret;
1050         }
1051
1052         return 0;
1053 }
1054
1055 int sttd_engine_recognize_stop()
1056 {
1057         if (false == g_agent_init) {
1058                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1059                 return STTD_ERROR_OPERATION_FAILED;
1060         }
1061
1062         if (false == g_cur_engine.is_loaded) {
1063                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1064                 return STTD_ERROR_OPERATION_FAILED;
1065         }
1066
1067         if (NULL == g_cur_engine.pefuncs->stop) {
1068                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The function of engine is NULL!!");
1069                 return STTD_ERROR_OPERATION_FAILED;
1070         }
1071
1072         int ret = g_cur_engine.pefuncs->stop();
1073         if (0 != ret) {
1074                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] stop recognition error(%d)", ret); 
1075                 return STTD_ERROR_OPERATION_FAILED;
1076         }
1077
1078         return 0;
1079 }
1080
1081 int sttd_engine_recognize_cancel()
1082 {
1083         if (false == g_agent_init) {
1084                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1085                 return STTD_ERROR_OPERATION_FAILED;
1086         }
1087
1088         if (false == g_cur_engine.is_loaded) {
1089                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1090                 return STTD_ERROR_OPERATION_FAILED;
1091         }
1092         
1093         if (NULL == g_cur_engine.pefuncs->cancel) {
1094                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The function of engine is NULL!!");
1095                 return STTD_ERROR_OPERATION_FAILED;
1096         }
1097
1098         int ret = g_cur_engine.pefuncs->cancel();
1099         if (0 != ret) {
1100                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] cancel recognition error(%d)", ret); 
1101                 return STTD_ERROR_OPERATION_FAILED;
1102         }
1103
1104         return 0;
1105 }
1106
1107 int sttd_engine_get_audio_format(sttp_audio_type_e* types, int* rate, int* channels)
1108 {
1109         if (false == g_agent_init) {
1110                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1111                 return STTD_ERROR_OPERATION_FAILED;
1112         }
1113
1114         if (false == g_cur_engine.is_loaded) {
1115                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1116                 return STTD_ERROR_OPERATION_FAILED;
1117         }
1118
1119         if (NULL == g_cur_engine.pefuncs->get_audio_format) {
1120                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The function of engine is NULL!!");
1121                 return STTD_ERROR_OPERATION_FAILED;
1122         }
1123
1124         int ret = g_cur_engine.pefuncs->get_audio_format(types, rate, channels);
1125         if (0 != ret) {
1126                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] get audio format error(%d)", ret); 
1127                 return STTD_ERROR_OPERATION_FAILED;
1128         }
1129
1130         return 0;
1131 }
1132
1133 int sttd_engine_recognize_start_file(const char* filepath, const char* lang, const char* recognition_type, 
1134                                      int profanity, int punctuation, void* user_param)
1135 {
1136         if (false == g_agent_init) {
1137                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1138                 return STTD_ERROR_OPERATION_FAILED;
1139         }
1140
1141         if (false == g_cur_engine.is_loaded) {
1142                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1143                 return STTD_ERROR_OPERATION_FAILED;
1144         }
1145
1146         if (NULL == filepath || NULL == lang || NULL == recognition_type) {
1147                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1148                 return STTD_ERROR_INVALID_PARAMETER;
1149         }
1150
1151         if (0 != __set_option(profanity, punctuation, g_default_silence_detected)) {
1152                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set options"); 
1153                 return STTD_ERROR_OPERATION_FAILED;
1154         }
1155
1156         if (NULL == g_cur_engine.pefuncs->start_file_recognition) {
1157                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] start() of engine is NULL!!");
1158                 return STTD_ERROR_OPERATION_FAILED;
1159         }
1160
1161         char* temp;
1162         if (0 == strncmp(lang, "default", strlen("default"))) {
1163                 temp = strdup(g_cur_engine.default_lang);
1164         } else {
1165                 temp = strdup(lang);
1166         }
1167
1168         int ret = g_cur_engine.pefuncs->start_file_recognition(filepath, temp, recognition_type, user_param);
1169         free(temp);
1170
1171         if (0 != ret) {
1172                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to start file recognition(%d)", ret); 
1173                 return ret;
1174         }
1175
1176         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent SUCCESS] File recognition");
1177
1178         return 0;
1179 }
1180
1181 /*
1182 * STT Engine Interfaces for client and setting
1183 */
1184 bool __supported_language_cb(const char* language, void* user_data)
1185 {
1186         GList** lang_list = (GList**)user_data;
1187
1188         if (NULL == language || NULL == lang_list) {
1189                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Input parameter is NULL in callback!!!!");
1190                 return false;
1191         }
1192
1193         SLOG(LOG_DEBUG, TAG_STTD, "-- Language(%s)", language);
1194
1195         char* temp_lang = g_strdup(language);
1196
1197         *lang_list = g_list_append(*lang_list, temp_lang);
1198
1199         return true;
1200 }
1201
1202 int sttd_engine_supported_langs(GList** lang_list)
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 (false == g_cur_engine.is_loaded) {
1210                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1211                 return STTD_ERROR_OPERATION_FAILED;
1212         }
1213
1214         if (NULL == g_cur_engine.pefuncs->foreach_langs) {
1215                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The function of engine is NULL!!");
1216                 return STTD_ERROR_OPERATION_FAILED;
1217         }
1218
1219         int ret = g_cur_engine.pefuncs->foreach_langs(__supported_language_cb, (void*)lang_list);
1220         if (0 != ret) {
1221                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] get language list error(%d)", ret); 
1222                 return STTD_ERROR_OPERATION_FAILED;
1223         }
1224
1225         return 0;
1226 }
1227
1228
1229 int sttd_engine_get_default_lang(char** lang)
1230 {
1231         if (false == g_agent_init) {
1232                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1233                 return STTD_ERROR_OPERATION_FAILED;
1234         }
1235
1236         if (false == g_cur_engine.is_loaded) {
1237                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1238                 return STTD_ERROR_OPERATION_FAILED;
1239         }
1240
1241         if (NULL == lang) {
1242                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1243                 return STTD_ERROR_INVALID_PARAMETER;
1244         }
1245
1246         /* get default language */
1247         *lang = g_strdup(g_cur_engine.default_lang);
1248
1249         return 0;
1250 }
1251
1252 int sttd_engine_is_partial_result_supported(bool* partial_result)
1253 {
1254         if (false == g_agent_init) {
1255                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1256                 return STTD_ERROR_OPERATION_FAILED;
1257         }
1258
1259         if (false == g_cur_engine.is_loaded) {
1260                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1261                 return STTD_ERROR_OPERATION_FAILED;
1262         }
1263
1264         if (NULL == partial_result) {
1265                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1266                 return STTD_ERROR_INVALID_PARAMETER;
1267         }
1268
1269         if (NULL == g_cur_engine.pefuncs->support_partial_result) {
1270                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The function of engine is NULL!!");
1271                 return STTD_ERROR_OPERATION_FAILED;
1272         }
1273
1274         *partial_result = g_cur_engine.pefuncs->support_partial_result();
1275
1276         return 0;
1277 }
1278
1279
1280 /*
1281 * STT Engine Interfaces for setting
1282 */
1283
1284 int sttd_engine_setting_get_engine_list(GList** engine_list)
1285 {
1286         if (false == g_agent_init) {
1287                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1288                 return STTD_ERROR_OPERATION_FAILED;
1289         }
1290
1291         if (false == g_cur_engine.is_loaded) {
1292                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1293                 return STTD_ERROR_OPERATION_FAILED;
1294         }
1295
1296         /* update engine list */
1297         if (0 != __internal_update_engine_list()) {
1298                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] sttd_engine_setting_get_engine_list : __internal_update_engine_list()"); 
1299                 return -1;
1300         }
1301
1302         GList *iter = NULL;
1303         sttengine_info_s *data = NULL;
1304
1305         iter = g_list_first(g_engine_list);
1306
1307         SLOG(LOG_DEBUG, TAG_STTD, "----- [Engine Agent] engine list -----");
1308
1309         while (NULL != iter) {
1310                 engine_s* temp_engine;
1311
1312                 temp_engine = (engine_s*)g_malloc0(sizeof(engine_s));
1313
1314                 data = iter->data;
1315
1316                 temp_engine->engine_id = strdup(data->engine_uuid);
1317                 temp_engine->engine_name = strdup(data->engine_name);
1318                 temp_engine->ug_name = strdup(data->setting_ug_path);
1319
1320                 *engine_list = g_list_append(*engine_list, temp_engine);
1321
1322                 iter = g_list_next(iter);
1323
1324                 SLOG(LOG_DEBUG, TAG_STTD, " -- engine id(%s) engine name(%s) ug name(%s) \n", 
1325                         temp_engine->engine_id, temp_engine->engine_name, temp_engine->ug_name);
1326         }
1327
1328         SLOG(LOG_DEBUG, TAG_STTD, "--------------------------------------");
1329
1330         return 0;
1331 }
1332
1333 int sttd_engine_setting_get_engine(char** engine_id)
1334 {
1335         if (false == g_agent_init) {
1336                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized" );
1337                 return STTD_ERROR_OPERATION_FAILED;
1338         }
1339
1340         if (false == g_cur_engine.is_loaded) {
1341                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
1342                 return STTD_ERROR_ENGINE_NOT_FOUND;
1343         }
1344
1345         *engine_id = strdup(g_cur_engine.engine_uuid);
1346
1347         return 0;
1348 }
1349
1350 int sttd_engine_setting_set_engine(const char* engine_id)
1351 {
1352         if (false == g_agent_init) {
1353                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1354                 return STTD_ERROR_OPERATION_FAILED;
1355         }
1356
1357         if (NULL == engine_id) {
1358                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1359                 return STTD_ERROR_INVALID_PARAMETER;
1360         }
1361
1362         /* compare current engine and new engine. */
1363         if (NULL != g_cur_engine.engine_uuid) {
1364                 if (0 == strncmp(g_cur_engine.engine_uuid, engine_id, strlen(g_cur_engine.engine_uuid))) {
1365                         SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] New engine is the same as current engine"); 
1366                         return 0;
1367                 }
1368         }
1369
1370         char* tmp_uuid = NULL;
1371         tmp_uuid = g_strdup(g_cur_engine.engine_uuid);
1372         if (NULL == tmp_uuid) {
1373                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not enough memory!!"); 
1374                 return STTD_ERROR_OUT_OF_MEMORY;
1375         }
1376
1377         /* unload engine */
1378         if (0 != sttd_engine_agent_unload_current_engine()) 
1379                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to unload current engine"); 
1380         else
1381                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent SUCCESS] unload current engine");
1382
1383         /* change current engine */
1384         if (0 != __internal_set_current_engine(engine_id)) {
1385                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] __internal_set_current_engine : no engine error"); 
1386                 
1387                 /* roll back to old current engine. */
1388                 __internal_set_current_engine(tmp_uuid);
1389                 sttd_engine_agent_load_current_engine();
1390
1391                 if (NULL != tmp_uuid)   
1392                         free(tmp_uuid);
1393
1394                 return STTD_ERROR_OPERATION_FAILED;
1395         }
1396
1397         if (0 != sttd_engine_agent_load_current_engine()) {
1398                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to load new engine"); 
1399
1400                 if (NULL != tmp_uuid)   
1401                         free(tmp_uuid);
1402
1403                 return STTD_ERROR_OPERATION_FAILED;
1404         }
1405
1406         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent SUCCESS] sttd_engine_setting_set_engine() : Load new engine");
1407
1408         if( tmp_uuid != NULL )  
1409                 free(tmp_uuid);
1410
1411         /* set engine id to config */
1412         if (0 != sttd_config_set_default_engine(engine_id)) {
1413                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set engine id"); 
1414         }
1415
1416         return 0;
1417 }
1418
1419 int sttd_engine_setting_get_lang_list(char** engine_id, GList** lang_list)
1420 {
1421         if (false == g_agent_init) {
1422                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1423                 return STTD_ERROR_OPERATION_FAILED;
1424         }
1425
1426         if (false == g_cur_engine.is_loaded) {
1427                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1428                 return STTD_ERROR_OPERATION_FAILED;
1429         }
1430
1431         if (NULL == lang_list || NULL == engine_id) {
1432                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1433                 return STTD_ERROR_INVALID_PARAMETER;
1434         }
1435
1436         /* get language list from engine */
1437         int ret = sttd_engine_supported_langs(lang_list); 
1438         if (0 != ret) {
1439                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail get lang list (%d)", ret); 
1440                 return STTD_ERROR_OPERATION_FAILED;
1441         }
1442
1443         *engine_id = strdup(g_cur_engine.engine_uuid);
1444
1445         return 0;
1446 }
1447
1448 int sttd_engine_setting_get_default_lang(char** language)
1449 {
1450         if (false == g_agent_init) {
1451                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1452                 return STTD_ERROR_OPERATION_FAILED;
1453         }
1454
1455         if (false == g_cur_engine.is_loaded) {
1456                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1457                 return STTD_ERROR_OPERATION_FAILED;
1458         }
1459
1460         if (NULL == language) {
1461                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1462                 return STTD_ERROR_INVALID_PARAMETER;
1463         }
1464
1465         if (NULL != g_cur_engine.default_lang) {
1466                 *language = strdup(g_cur_engine.default_lang);
1467
1468                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent SUCCESS] Get default lanaguae : language(%s)", *language);
1469         } else {
1470                 if (NULL == g_cur_engine.pefuncs->foreach_langs) {
1471                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] foreach_langs of engine is NULL!!");
1472                         return STTD_ERROR_OPERATION_FAILED;
1473                 }
1474
1475                 /* get language list */
1476                 int ret;
1477                 GList* lang_list = NULL;
1478
1479                 ret = g_cur_engine.pefuncs->foreach_langs(__supported_language_cb, &lang_list);
1480
1481                 if (0 == ret && 0 < g_list_length(lang_list)) {
1482                         GList *iter = NULL;
1483                         iter = g_list_first(lang_list);
1484
1485                         if (NULL != iter) {
1486                                 char* temp_lang = iter->data;
1487
1488                                 if (true != g_cur_engine.pefuncs->is_valid_lang(temp_lang)) {
1489                                         SLOG(LOG_ERROR, TAG_STTD, "[Engine ERROR] Fail voice is NOT valid");
1490                                         return STTD_ERROR_OPERATION_FAILED;
1491                                 }
1492
1493                                 sttd_config_set_default_language(temp_lang);
1494
1495                                 g_cur_engine.default_lang = g_strdup(temp_lang);
1496
1497                                 *language = strdup(g_cur_engine.default_lang);
1498
1499                                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent SUCCESS] Select default voice : lang(%s)", temp_lang);
1500                         } else {
1501                                 SLOG(LOG_ERROR, TAG_STTD, "[Engine ERROR] Fail to get language list : result(%d)\n", ret);
1502                                 return STTD_ERROR_OPERATION_FAILED;
1503                         }
1504
1505                         __free_language_list(lang_list);
1506                 } else {
1507                         SLOG(LOG_ERROR, TAG_STTD, "[Engine ERROR] Fail to get language list : result(%d)\n", ret);
1508                         return STTD_ERROR_OPERATION_FAILED;
1509                 }
1510         }
1511         
1512         return 0;
1513 }
1514
1515 int sttd_engine_setting_set_default_lang(const char* language)
1516 {
1517         if (false == g_agent_init) {
1518                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1519                 return STTD_ERROR_OPERATION_FAILED;
1520         }
1521
1522         if (false == g_cur_engine.is_loaded) {
1523                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1524                 return STTD_ERROR_OPERATION_FAILED;
1525         }
1526
1527         if (NULL == g_cur_engine.pefuncs->is_valid_lang) {
1528                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] get_voice_list() of engine is NULL!!");
1529                 return STTD_ERROR_OPERATION_FAILED;
1530         }
1531
1532         int ret = -1;
1533         if(false == g_cur_engine.pefuncs->is_valid_lang(language)) {
1534                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Language is NOT valid !!");
1535                 return STTD_ERROR_INVALID_LANGUAGE;
1536         }
1537
1538         if (NULL != g_cur_engine.default_lang)
1539                 g_free(g_cur_engine.default_lang);
1540
1541         g_cur_engine.default_lang = strdup(language);
1542
1543         ret = sttd_config_set_default_language(language);
1544         if (0 != ret) {
1545                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set default lang (%d)", ret); 
1546         }
1547
1548         return 0;
1549 }
1550
1551 int sttd_engine_setting_get_profanity_filter(bool* value)
1552 {
1553         if (false == g_agent_init) {
1554                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1555                 return STTD_ERROR_OPERATION_FAILED;
1556         }
1557
1558         if (false == g_cur_engine.is_loaded) {
1559                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1560                 return STTD_ERROR_OPERATION_FAILED;
1561         }
1562
1563         if (NULL == value) {
1564                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1565                 return STTD_ERROR_INVALID_PARAMETER;
1566         }
1567
1568         *value = g_default_profanity_filter;    
1569
1570         return 0;
1571 }
1572
1573 int sttd_engine_setting_set_profanity_filter(bool value)
1574 {
1575         if (false == g_agent_init) {
1576                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1577                 return STTD_ERROR_OPERATION_FAILED;
1578         }
1579
1580         if (false == g_cur_engine.is_loaded) {
1581                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1582                 return STTD_ERROR_OPERATION_FAILED;
1583         }
1584
1585         if (NULL == g_cur_engine.pefuncs->set_profanity_filter) {
1586                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The function of engine is NULL!!");
1587                 return STTD_ERROR_OPERATION_FAILED;
1588         }
1589
1590         int ret = g_cur_engine.pefuncs->set_profanity_filter(value);
1591         if (0 != ret) {
1592                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail set profanity filter : result(%d)", ret); 
1593                 return STTD_ERROR_OPERATION_FAILED;
1594         }
1595
1596         g_default_profanity_filter = value;
1597
1598         ret = sttd_config_set_default_profanity_filter((int)value);
1599         if (0 != ret) {
1600                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set default lang (%d)", ret); 
1601         }
1602
1603         return 0;
1604 }
1605
1606 int sttd_engine_setting_get_punctuation_override(bool* value)
1607 {
1608         if (false == g_agent_init) {
1609                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1610                 return STTD_ERROR_OPERATION_FAILED;
1611         }
1612
1613         if (false == g_cur_engine.is_loaded) {
1614                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1615                 return STTD_ERROR_OPERATION_FAILED;
1616         }
1617
1618         if (NULL == value) {
1619                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1620                 return STTD_ERROR_INVALID_PARAMETER;
1621         }
1622
1623         *value = g_default_punctuation_override;
1624
1625         return 0;
1626 }
1627
1628 int sttd_engine_setting_set_punctuation_override(bool value)
1629 {
1630         if (false == g_agent_init) {
1631                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1632                 return STTD_ERROR_OPERATION_FAILED;
1633         }
1634
1635         if (false == g_cur_engine.is_loaded) {
1636                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1637                 return STTD_ERROR_OPERATION_FAILED;
1638         }
1639
1640         if (NULL == g_cur_engine.pefuncs->set_punctuation) {
1641                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The function of engine is NULL!!");
1642                 return STTD_ERROR_OPERATION_FAILED;
1643         }
1644
1645         int ret = g_cur_engine.pefuncs->set_punctuation(value);
1646         if (0 != ret) {
1647                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail set punctuation override : result(%d)", ret); 
1648                 return STTD_ERROR_OPERATION_FAILED;
1649         }
1650         g_default_punctuation_override = value;
1651
1652         ret = sttd_config_set_default_punctuation_override((int)value);
1653         if (0 != ret) {
1654                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set punctuation override (%d)", ret); 
1655         }
1656
1657         return 0;
1658 }
1659
1660 int sttd_engine_setting_get_silence_detection(bool* value)
1661 {
1662         if (false == g_agent_init) {
1663                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1664                 return STTD_ERROR_OPERATION_FAILED;
1665         }
1666
1667         if (false == g_cur_engine.is_loaded) {
1668                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1669                 return STTD_ERROR_OPERATION_FAILED;
1670         }
1671
1672         if (NULL == value) {
1673                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1674                 return STTD_ERROR_INVALID_PARAMETER;
1675         }
1676
1677         *value = g_default_silence_detected;
1678
1679         return 0;
1680 }
1681
1682 int sttd_engine_setting_set_silence_detection(bool value)
1683 {
1684         if (false == g_agent_init) {
1685                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1686                 return STTD_ERROR_OPERATION_FAILED;
1687         }
1688
1689         if (false == g_cur_engine.is_loaded) {
1690                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1691                 return STTD_ERROR_OPERATION_FAILED;
1692         }
1693
1694         int ret = g_cur_engine.pefuncs->set_silence_detection(value);
1695         if (0 != ret) {
1696                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail set silence detection : result(%d)", ret); 
1697                 return STTD_ERROR_OPERATION_FAILED;
1698         }
1699         
1700         g_default_silence_detected = value;
1701
1702         ret = sttd_config_set_default_silence_detection((int)value);
1703         if (0 != ret) {
1704                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set silence detection (%d)", ret); 
1705         }
1706         
1707         return 0;
1708 }
1709
1710 bool __engine_setting_cb(const char* key, const char* value, void* user_data)
1711 {
1712         GList** engine_setting_list = (GList**)user_data;
1713
1714         if (NULL == engine_setting_list || NULL == key || NULL == value) {
1715                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Input parameter is NULL in engine setting callback!!!!");
1716                 return false;
1717         }
1718
1719         engine_setting_s* temp = g_malloc0(sizeof(engine_setting_s));
1720         temp->key = g_strdup(key);
1721         temp->value = g_strdup(value);
1722
1723         *engine_setting_list = g_list_append(*engine_setting_list, temp);
1724
1725         return true;
1726 }
1727
1728 int sttd_engine_setting_get_engine_setting_info(char** engine_id, GList** setting_list)
1729 {
1730         if (false == g_agent_init) {
1731                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1732                 return STTD_ERROR_OPERATION_FAILED;
1733         }
1734
1735         if (false == g_cur_engine.is_loaded) {
1736                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1737                 return STTD_ERROR_OPERATION_FAILED;
1738         }
1739
1740         if (NULL == setting_list) {
1741                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Input parameter is NULL");
1742                 return STTD_ERROR_INVALID_PARAMETER;
1743         }
1744
1745         if (NULL == g_cur_engine.pefuncs->foreach_engine_settings) {
1746                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] foreach_engine_settings() of engine is NULL!!");
1747                 return STTD_ERROR_OPERATION_FAILED;
1748         }
1749
1750         /* get setting info and move setting info to input parameter */
1751         int result = 0;
1752
1753         result = g_cur_engine.pefuncs->foreach_engine_settings(__engine_setting_cb, setting_list);
1754
1755         if (0 == result && 0 < g_list_length(*setting_list)) {
1756                 *engine_id = strdup(g_cur_engine.engine_uuid);
1757         } else {
1758                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] fail to get setting info : result(%d)\n", result);
1759                 result = STTD_ERROR_OPERATION_FAILED;
1760         }
1761
1762         return result;
1763 }
1764
1765 int sttd_engine_setting_set_engine_setting(const char* key, const char* value)
1766 {
1767         if (false == g_agent_init) {
1768                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1769                 return STTD_ERROR_OPERATION_FAILED;
1770         }
1771
1772         if (false == g_cur_engine.is_loaded) {
1773                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1774                 return STTD_ERROR_OPERATION_FAILED;
1775         }
1776
1777         if (NULL == key || NULL == value) {
1778                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1779                 return STTD_ERROR_INVALID_PARAMETER;
1780         }
1781
1782         if (NULL == g_cur_engine.pefuncs->set_engine_setting) {
1783                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] set_engine_setting() of engine is NULL!!");
1784                 return STTD_ERROR_OPERATION_FAILED;
1785         }
1786
1787         /* get setting info and move setting info to input parameter */
1788         int ret = g_cur_engine.pefuncs->set_engine_setting(key, value);
1789         if (0 != ret) {
1790                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail set setting info (%d) ", ret); 
1791                 return STTD_ERROR_OPERATION_FAILED;
1792         }
1793
1794         return 0;
1795 }
1796
1797 /*
1798 * STT Engine Callback Functions                                                                                 `                                 *
1799 */
1800
1801 void __result_cb(sttp_result_event_e event, const char* type, 
1802                                         const char** data, int data_count, const char* msg, void *user_data)
1803 {
1804         if (false == g_agent_init) {
1805                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Result Callback : Not Initialized"); 
1806                 return;
1807         }
1808
1809         if (false == g_cur_engine.is_loaded) {
1810                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Result Callback : Not loaded engine"); 
1811                 return;
1812         }
1813
1814         return g_result_cb(event, type, data, data_count, msg, user_data);
1815 }
1816
1817 void __partial_result_cb(sttp_result_event_e event, const char* data, void *user_data)
1818 {
1819         if (false == g_agent_init) {
1820                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Partial Result Callback : Not Initialized"); 
1821                 return;
1822         }
1823
1824         if (false == g_cur_engine.is_loaded) {
1825                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Partial Result Callback : Not loaded engine"); 
1826                 return;
1827         }
1828
1829         return g_partial_result_cb(event, data, user_data);
1830 }
1831
1832 void __detect_silence_cb(void* user_data)
1833 {
1834         if (false == g_agent_init) {
1835                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Silence Callback : Not Initialized"); 
1836                 return;
1837         }
1838
1839         if (false == g_cur_engine.is_loaded) {
1840                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Silence Callback : Not loaded engine"); 
1841                 return;
1842         }
1843
1844         if (true == g_cur_engine.silence_detection) {
1845                 g_silence_cb(user_data);
1846         } else {
1847                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Silence detection callback is blocked because option value is false.");
1848         }
1849 }
1850
1851 void __free_language_list(GList* lang_list)
1852 {
1853         GList *iter = NULL;
1854         char* data = NULL;
1855
1856         /* if list have item */
1857         if (g_list_length(lang_list) > 0) {
1858                 /* Get a first item */
1859                 iter = g_list_first(lang_list);
1860
1861                 while (NULL != iter) {
1862                         data = iter->data;
1863
1864                         if (NULL != data)
1865                                 g_free(data);
1866                         
1867                         lang_list = g_list_remove_link(lang_list, iter);
1868
1869                         iter = g_list_first(lang_list);
1870                 }
1871         }
1872 }
1873
1874 /* A function forging */
1875 int __log_enginelist()
1876 {
1877         GList *iter = NULL;
1878         sttengine_info_s *data = NULL;
1879
1880         if (0 < g_list_length(g_engine_list)) {
1881
1882                 /* Get a first item */
1883                 iter = g_list_first(g_engine_list);
1884
1885                 SLOG(LOG_DEBUG, TAG_STTD, "--------------- engine list -------------------");
1886
1887                 int i = 1;      
1888                 while (NULL != iter) {
1889                         /* Get handle data from list */
1890                         data = iter->data;
1891
1892                         SLOG(LOG_DEBUG, TAG_STTD, "[%dth]", i);
1893                         SLOG(LOG_DEBUG, TAG_STTD, "  engine uuid : %s", data->engine_uuid);
1894                         SLOG(LOG_DEBUG, TAG_STTD, "  engine name : %s", data->engine_name);
1895                         SLOG(LOG_DEBUG, TAG_STTD, "  engine path : %s", data->engine_path);
1896                         SLOG(LOG_DEBUG, TAG_STTD, "  setting ug path : %s", data->setting_ug_path);
1897
1898                         iter = g_list_next(iter);
1899                         i++;
1900                 }
1901                 SLOG(LOG_DEBUG, TAG_STTD, "----------------------------------------------");
1902         } else {
1903                 SLOG(LOG_DEBUG, TAG_STTD, "-------------- engine list -------------------");
1904                 SLOG(LOG_DEBUG, TAG_STTD, "  No Engine in engine directory");
1905                 SLOG(LOG_DEBUG, TAG_STTD, "----------------------------------------------");
1906         }
1907
1908         return 0;
1909 }
1910
1911
1912