merge with master
[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, silence)) {
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
1134 /*
1135 * STT Engine Interfaces for client and setting
1136 */
1137 bool __supported_language_cb(const char* language, void* user_data)
1138 {
1139         GList** lang_list = (GList**)user_data;
1140
1141         if (NULL == language || NULL == lang_list) {
1142                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Input parameter is NULL in callback!!!!");
1143                 return false;
1144         }
1145
1146         SLOG(LOG_DEBUG, TAG_STTD, "-- Language(%s)", language);
1147
1148         char* temp_lang = g_strdup(language);
1149
1150         *lang_list = g_list_append(*lang_list, temp_lang);
1151
1152         return true;
1153 }
1154
1155 int sttd_engine_supported_langs(GList** lang_list)
1156 {
1157         if (false == g_agent_init) {
1158                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1159                 return STTD_ERROR_OPERATION_FAILED;
1160         }
1161
1162         if (false == g_cur_engine.is_loaded) {
1163                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1164                 return STTD_ERROR_OPERATION_FAILED;
1165         }
1166
1167         if (NULL == g_cur_engine.pefuncs->foreach_langs) {
1168                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The function of engine is NULL!!");
1169                 return STTD_ERROR_OPERATION_FAILED;
1170         }
1171
1172         int ret = g_cur_engine.pefuncs->foreach_langs(__supported_language_cb, (void*)lang_list);
1173         if (0 != ret) {
1174                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] get language list error(%d)", ret); 
1175                 return STTD_ERROR_OPERATION_FAILED;
1176         }
1177
1178         return 0;
1179 }
1180
1181
1182 int sttd_engine_get_default_lang(char** lang)
1183 {
1184         if (false == g_agent_init) {
1185                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1186                 return STTD_ERROR_OPERATION_FAILED;
1187         }
1188
1189         if (false == g_cur_engine.is_loaded) {
1190                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1191                 return STTD_ERROR_OPERATION_FAILED;
1192         }
1193
1194         if (NULL == lang) {
1195                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1196                 return STTD_ERROR_INVALID_PARAMETER;
1197         }
1198
1199         /* get default language */
1200         *lang = g_strdup(g_cur_engine.default_lang);
1201
1202         return 0;
1203 }
1204
1205 int sttd_engine_is_partial_result_supported(bool* partial_result)
1206 {
1207         if (false == g_agent_init) {
1208                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1209                 return STTD_ERROR_OPERATION_FAILED;
1210         }
1211
1212         if (false == g_cur_engine.is_loaded) {
1213                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1214                 return STTD_ERROR_OPERATION_FAILED;
1215         }
1216
1217         if (NULL == partial_result) {
1218                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1219                 return STTD_ERROR_INVALID_PARAMETER;
1220         }
1221
1222         if (NULL == g_cur_engine.pefuncs->support_partial_result) {
1223                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The function of engine is NULL!!");
1224                 return STTD_ERROR_OPERATION_FAILED;
1225         }
1226
1227         *partial_result = g_cur_engine.pefuncs->support_partial_result();
1228
1229         return 0;
1230 }
1231
1232
1233 /*
1234 * STT Engine Interfaces for setting
1235 */
1236
1237 int sttd_engine_setting_get_engine_list(GList** engine_list)
1238 {
1239         if (false == g_agent_init) {
1240                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1241                 return STTD_ERROR_OPERATION_FAILED;
1242         }
1243
1244         if (false == g_cur_engine.is_loaded) {
1245                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1246                 return STTD_ERROR_OPERATION_FAILED;
1247         }
1248
1249         /* update engine list */
1250         if (0 != __internal_update_engine_list()) {
1251                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] sttd_engine_setting_get_engine_list : __internal_update_engine_list()"); 
1252                 return -1;
1253         }
1254
1255         GList *iter = NULL;
1256         sttengine_info_s *data = NULL;
1257
1258         iter = g_list_first(g_engine_list);
1259
1260         SLOG(LOG_DEBUG, TAG_STTD, "----- [Engine Agent] engine list -----");
1261
1262         while (NULL != iter) {
1263                 engine_s* temp_engine;
1264
1265                 temp_engine = (engine_s*)g_malloc0(sizeof(engine_s));
1266
1267                 data = iter->data;
1268
1269                 temp_engine->engine_id = strdup(data->engine_uuid);
1270                 temp_engine->engine_name = strdup(data->engine_name);
1271                 temp_engine->ug_name = strdup(data->setting_ug_path);
1272
1273                 *engine_list = g_list_append(*engine_list, temp_engine);
1274
1275                 iter = g_list_next(iter);
1276
1277                 SLOG(LOG_DEBUG, TAG_STTD, " -- engine id(%s) engine name(%s) ug name(%s) \n", 
1278                         temp_engine->engine_id, temp_engine->engine_name, temp_engine->ug_name);
1279         }
1280
1281         SLOG(LOG_DEBUG, TAG_STTD, "--------------------------------------");
1282
1283         return 0;
1284 }
1285
1286 int sttd_engine_setting_get_engine(char** engine_id)
1287 {
1288         if (false == g_agent_init) {
1289                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized" );
1290                 return STTD_ERROR_OPERATION_FAILED;
1291         }
1292
1293         if (false == g_cur_engine.is_loaded) {
1294                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
1295                 return STTD_ERROR_ENGINE_NOT_FOUND;
1296         }
1297
1298         *engine_id = strdup(g_cur_engine.engine_uuid);
1299
1300         return 0;
1301 }
1302
1303 int sttd_engine_setting_set_engine(const char* engine_id)
1304 {
1305         if (false == g_agent_init) {
1306                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1307                 return STTD_ERROR_OPERATION_FAILED;
1308         }
1309
1310         if (NULL == engine_id) {
1311                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1312                 return STTD_ERROR_INVALID_PARAMETER;
1313         }
1314
1315         /* compare current engine and new engine. */
1316         if (NULL != g_cur_engine.engine_uuid) {
1317                 if (0 == strncmp(g_cur_engine.engine_uuid, engine_id, strlen(g_cur_engine.engine_uuid))) {
1318                         SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] New engine is the same as current engine"); 
1319                         return 0;
1320                 }
1321         }
1322
1323         char* tmp_uuid = NULL;
1324         tmp_uuid = g_strdup(g_cur_engine.engine_uuid);
1325         if (NULL == tmp_uuid) {
1326                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not enough memory!!"); 
1327                 return STTD_ERROR_OUT_OF_MEMORY;
1328         }
1329
1330         /* unload engine */
1331         if (0 != sttd_engine_agent_unload_current_engine()) 
1332                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to unload current engine"); 
1333         else
1334                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent SUCCESS] unload current engine");
1335
1336         /* change current engine */
1337         if (0 != __internal_set_current_engine(engine_id)) {
1338                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] __internal_set_current_engine : no engine error"); 
1339                 
1340                 /* roll back to old current engine. */
1341                 __internal_set_current_engine(tmp_uuid);
1342                 sttd_engine_agent_load_current_engine();
1343
1344                 if (NULL != tmp_uuid)   
1345                         free(tmp_uuid);
1346
1347                 return STTD_ERROR_OPERATION_FAILED;
1348         }
1349
1350         if (0 != sttd_engine_agent_load_current_engine()) {
1351                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to load new engine"); 
1352
1353                 if (NULL != tmp_uuid)   
1354                         free(tmp_uuid);
1355
1356                 return STTD_ERROR_OPERATION_FAILED;
1357         }
1358
1359         SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent SUCCESS] sttd_engine_setting_set_engine() : Load new engine");
1360
1361         if( tmp_uuid != NULL )  
1362                 free(tmp_uuid);
1363
1364         /* set engine id to config */
1365         if (0 != sttd_config_set_default_engine(engine_id)) {
1366                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set engine id"); 
1367         }
1368
1369         return 0;
1370 }
1371
1372 int sttd_engine_setting_get_lang_list(char** engine_id, GList** lang_list)
1373 {
1374         if (false == g_agent_init) {
1375                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1376                 return STTD_ERROR_OPERATION_FAILED;
1377         }
1378
1379         if (false == g_cur_engine.is_loaded) {
1380                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1381                 return STTD_ERROR_OPERATION_FAILED;
1382         }
1383
1384         if (NULL == lang_list || NULL == engine_id) {
1385                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1386                 return STTD_ERROR_INVALID_PARAMETER;
1387         }
1388
1389         /* get language list from engine */
1390         int ret = sttd_engine_supported_langs(lang_list); 
1391         if (0 != ret) {
1392                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail get lang list (%d)", ret); 
1393                 return STTD_ERROR_OPERATION_FAILED;
1394         }
1395
1396         *engine_id = strdup(g_cur_engine.engine_uuid);
1397
1398         return 0;
1399 }
1400
1401 int sttd_engine_setting_get_default_lang(char** language)
1402 {
1403         if (false == g_agent_init) {
1404                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1405                 return STTD_ERROR_OPERATION_FAILED;
1406         }
1407
1408         if (false == g_cur_engine.is_loaded) {
1409                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1410                 return STTD_ERROR_OPERATION_FAILED;
1411         }
1412
1413         if (NULL == language) {
1414                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1415                 return STTD_ERROR_INVALID_PARAMETER;
1416         }
1417
1418         if (NULL != g_cur_engine.default_lang) {
1419                 *language = strdup(g_cur_engine.default_lang);
1420
1421                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent SUCCESS] Get default lanaguae : language(%s)", *language);
1422         } else {
1423                 if (NULL == g_cur_engine.pefuncs->foreach_langs) {
1424                         SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] foreach_langs of engine is NULL!!");
1425                         return STTD_ERROR_OPERATION_FAILED;
1426                 }
1427
1428                 /* get language list */
1429                 int ret;
1430                 GList* lang_list = NULL;
1431
1432                 ret = g_cur_engine.pefuncs->foreach_langs(__supported_language_cb, &lang_list);
1433
1434                 if (0 == ret && 0 < g_list_length(lang_list)) {
1435                         GList *iter = NULL;
1436                         iter = g_list_first(lang_list);
1437
1438                         if (NULL != iter) {
1439                                 char* temp_lang = iter->data;
1440
1441                                 if (true != g_cur_engine.pefuncs->is_valid_lang(temp_lang)) {
1442                                         SLOG(LOG_ERROR, TAG_STTD, "[Engine ERROR] Fail voice is NOT valid");
1443                                         return STTD_ERROR_OPERATION_FAILED;
1444                                 }
1445
1446                                 sttd_config_set_default_language(temp_lang);
1447
1448                                 g_cur_engine.default_lang = g_strdup(temp_lang);
1449
1450                                 *language = strdup(g_cur_engine.default_lang);
1451
1452                                 SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent SUCCESS] Select default voice : lang(%s)", temp_lang);
1453                         } else {
1454                                 SLOG(LOG_ERROR, TAG_STTD, "[Engine ERROR] Fail to get language list : result(%d)\n", ret);
1455                                 return STTD_ERROR_OPERATION_FAILED;
1456                         }
1457
1458                         __free_language_list(lang_list);
1459                 } else {
1460                         SLOG(LOG_ERROR, TAG_STTD, "[Engine ERROR] Fail to get language list : result(%d)\n", ret);
1461                         return STTD_ERROR_OPERATION_FAILED;
1462                 }
1463         }
1464         
1465         return 0;
1466 }
1467
1468 int sttd_engine_setting_set_default_lang(const char* language)
1469 {
1470         if (false == g_agent_init) {
1471                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1472                 return STTD_ERROR_OPERATION_FAILED;
1473         }
1474
1475         if (false == g_cur_engine.is_loaded) {
1476                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1477                 return STTD_ERROR_OPERATION_FAILED;
1478         }
1479
1480         if (NULL == g_cur_engine.pefuncs->is_valid_lang) {
1481                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] get_voice_list() of engine is NULL!!");
1482                 return STTD_ERROR_OPERATION_FAILED;
1483         }
1484
1485         int ret = -1;
1486         if(false == g_cur_engine.pefuncs->is_valid_lang(language)) {
1487                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Language is NOT valid !!");
1488                 return STTD_ERROR_INVALID_LANGUAGE;
1489         }
1490
1491         if (NULL != g_cur_engine.default_lang)
1492                 g_free(g_cur_engine.default_lang);
1493
1494         g_cur_engine.default_lang = strdup(language);
1495
1496         ret = sttd_config_set_default_language(language);
1497         if (0 != ret) {
1498                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set default lang (%d)", ret); 
1499         }
1500
1501         return 0;
1502 }
1503
1504 int sttd_engine_setting_get_profanity_filter(bool* value)
1505 {
1506         if (false == g_agent_init) {
1507                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1508                 return STTD_ERROR_OPERATION_FAILED;
1509         }
1510
1511         if (false == g_cur_engine.is_loaded) {
1512                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1513                 return STTD_ERROR_OPERATION_FAILED;
1514         }
1515
1516         if (NULL == value) {
1517                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1518                 return STTD_ERROR_INVALID_PARAMETER;
1519         }
1520
1521         *value = g_default_profanity_filter;    
1522
1523         return 0;
1524 }
1525
1526 int sttd_engine_setting_set_profanity_filter(bool value)
1527 {
1528         if (false == g_agent_init) {
1529                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1530                 return STTD_ERROR_OPERATION_FAILED;
1531         }
1532
1533         if (false == g_cur_engine.is_loaded) {
1534                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1535                 return STTD_ERROR_OPERATION_FAILED;
1536         }
1537
1538         if (NULL == g_cur_engine.pefuncs->set_profanity_filter) {
1539                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The function of engine is NULL!!");
1540                 return STTD_ERROR_OPERATION_FAILED;
1541         }
1542
1543         int ret = g_cur_engine.pefuncs->set_profanity_filter(value);
1544         if (0 != ret) {
1545                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail set profanity filter : result(%d)", ret); 
1546                 return STTD_ERROR_OPERATION_FAILED;
1547         }
1548
1549         g_default_profanity_filter = value;
1550
1551         ret = sttd_config_set_default_profanity_filter((int)value);
1552         if (0 != ret) {
1553                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set default lang (%d)", ret); 
1554         }
1555
1556         return 0;
1557 }
1558
1559 int sttd_engine_setting_get_punctuation_override(bool* value)
1560 {
1561         if (false == g_agent_init) {
1562                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1563                 return STTD_ERROR_OPERATION_FAILED;
1564         }
1565
1566         if (false == g_cur_engine.is_loaded) {
1567                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1568                 return STTD_ERROR_OPERATION_FAILED;
1569         }
1570
1571         if (NULL == value) {
1572                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1573                 return STTD_ERROR_INVALID_PARAMETER;
1574         }
1575
1576         *value = g_default_punctuation_override;
1577
1578         return 0;
1579 }
1580
1581 int sttd_engine_setting_set_punctuation_override(bool value)
1582 {
1583         if (false == g_agent_init) {
1584                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1585                 return STTD_ERROR_OPERATION_FAILED;
1586         }
1587
1588         if (false == g_cur_engine.is_loaded) {
1589                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1590                 return STTD_ERROR_OPERATION_FAILED;
1591         }
1592
1593         if (NULL == g_cur_engine.pefuncs->set_punctuation) {
1594                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The function of engine is NULL!!");
1595                 return STTD_ERROR_OPERATION_FAILED;
1596         }
1597
1598         int ret = g_cur_engine.pefuncs->set_punctuation(value);
1599         if (0 != ret) {
1600                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail set punctuation override : result(%d)", ret); 
1601                 return STTD_ERROR_OPERATION_FAILED;
1602         }
1603         g_default_punctuation_override = value;
1604
1605         ret = sttd_config_set_default_punctuation_override((int)value);
1606         if (0 != ret) {
1607                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set punctuation override (%d)", ret); 
1608         }
1609
1610         return 0;
1611 }
1612
1613 int sttd_engine_setting_get_silence_detection(bool* value)
1614 {
1615         if (false == g_agent_init) {
1616                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1617                 return STTD_ERROR_OPERATION_FAILED;
1618         }
1619
1620         if (false == g_cur_engine.is_loaded) {
1621                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1622                 return STTD_ERROR_OPERATION_FAILED;
1623         }
1624
1625         if (NULL == value) {
1626                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1627                 return STTD_ERROR_INVALID_PARAMETER;
1628         }
1629
1630         *value = g_default_silence_detected;
1631
1632         return 0;
1633 }
1634
1635 int sttd_engine_setting_set_silence_detection(bool value)
1636 {
1637         if (false == g_agent_init) {
1638                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1639                 return STTD_ERROR_OPERATION_FAILED;
1640         }
1641
1642         if (false == g_cur_engine.is_loaded) {
1643                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1644                 return STTD_ERROR_OPERATION_FAILED;
1645         }
1646
1647         int ret = g_cur_engine.pefuncs->set_silence_detection(value);
1648         if (0 != ret) {
1649                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail set silence detection : result(%d)", ret); 
1650                 return STTD_ERROR_OPERATION_FAILED;
1651         }
1652         
1653         g_default_silence_detected = value;
1654
1655         ret = sttd_config_set_default_silence_detection((int)value);
1656         if (0 != ret) {
1657                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to set silence detection (%d)", ret); 
1658         }
1659         
1660         return 0;
1661 }
1662
1663 bool __engine_setting_cb(const char* key, const char* value, void* user_data)
1664 {
1665         GList** engine_setting_list = (GList**)user_data;
1666
1667         if (NULL == engine_setting_list || NULL == key || NULL == value) {
1668                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Input parameter is NULL in engine setting callback!!!!");
1669                 return false;
1670         }
1671
1672         engine_setting_s* temp = g_malloc0(sizeof(engine_setting_s));
1673         temp->key = g_strdup(key);
1674         temp->value = g_strdup(value);
1675
1676         *engine_setting_list = g_list_append(*engine_setting_list, temp);
1677
1678         return true;
1679 }
1680
1681 int sttd_engine_setting_get_engine_setting_info(char** engine_id, GList** setting_list)
1682 {
1683         if (false == g_agent_init) {
1684                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1685                 return STTD_ERROR_OPERATION_FAILED;
1686         }
1687
1688         if (false == g_cur_engine.is_loaded) {
1689                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1690                 return STTD_ERROR_OPERATION_FAILED;
1691         }
1692
1693         if (NULL == setting_list) {
1694                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Input parameter is NULL");
1695                 return STTD_ERROR_INVALID_PARAMETER;
1696         }
1697
1698         if (NULL == g_cur_engine.pefuncs->foreach_engine_settings) {
1699                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] foreach_engine_settings() of engine is NULL!!");
1700                 return STTD_ERROR_OPERATION_FAILED;
1701         }
1702
1703         /* get setting info and move setting info to input parameter */
1704         int result = 0;
1705
1706         result = g_cur_engine.pefuncs->foreach_engine_settings(__engine_setting_cb, setting_list);
1707
1708         if (0 == result && 0 < g_list_length(*setting_list)) {
1709                 *engine_id = strdup(g_cur_engine.engine_uuid);
1710         } else {
1711                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] fail to get setting info : result(%d)\n", result);
1712                 result = STTD_ERROR_OPERATION_FAILED;
1713         }
1714
1715         return result;
1716 }
1717
1718 int sttd_engine_setting_set_engine_setting(const char* key, const char* value)
1719 {
1720         if (false == g_agent_init) {
1721                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized"); 
1722                 return STTD_ERROR_OPERATION_FAILED;
1723         }
1724
1725         if (false == g_cur_engine.is_loaded) {
1726                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine"); 
1727                 return STTD_ERROR_OPERATION_FAILED;
1728         }
1729
1730         if (NULL == key || NULL == value) {
1731                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Invalid Parameter"); 
1732                 return STTD_ERROR_INVALID_PARAMETER;
1733         }
1734
1735         if (NULL == g_cur_engine.pefuncs->set_engine_setting) {
1736                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] set_engine_setting() of engine is NULL!!");
1737                 return STTD_ERROR_OPERATION_FAILED;
1738         }
1739
1740         /* get setting info and move setting info to input parameter */
1741         int ret = g_cur_engine.pefuncs->set_engine_setting(key, value);
1742         if (0 != ret) {
1743                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail set setting info (%d) ", ret); 
1744                 return STTD_ERROR_OPERATION_FAILED;
1745         }
1746
1747         return 0;
1748 }
1749
1750 /*
1751 * STT Engine Callback Functions                                                                                 `                                 *
1752 */
1753
1754 void __result_cb(sttp_result_event_e event, const char* type, 
1755                                         const char** data, int data_count, const char* msg, void *user_data)
1756 {
1757         if (false == g_agent_init) {
1758                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Result Callback : Not Initialized"); 
1759                 return;
1760         }
1761
1762         if (false == g_cur_engine.is_loaded) {
1763                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Result Callback : Not loaded engine"); 
1764                 return;
1765         }
1766
1767         return g_result_cb(event, type, data, data_count, msg, user_data);
1768 }
1769
1770 void __partial_result_cb(sttp_result_event_e event, const char* data, void *user_data)
1771 {
1772         if (false == g_agent_init) {
1773                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Partial Result Callback : Not Initialized"); 
1774                 return;
1775         }
1776
1777         if (false == g_cur_engine.is_loaded) {
1778                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Partial Result Callback : Not loaded engine"); 
1779                 return;
1780         }
1781
1782         return g_partial_result_cb(event, data, user_data);
1783 }
1784
1785 void __detect_silence_cb(void* user_data)
1786 {
1787         if (false == g_agent_init) {
1788                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Silence Callback : Not Initialized"); 
1789                 return;
1790         }
1791
1792         if (false == g_cur_engine.is_loaded) {
1793                 SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Silence Callback : Not loaded engine"); 
1794                 return;
1795         }
1796
1797         if (true == g_cur_engine.silence_detection) {
1798                 g_silence_cb(user_data);
1799         } else {
1800                 SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Silence detection callback is blocked because option value is false.");
1801         }
1802 }
1803
1804 void __free_language_list(GList* lang_list)
1805 {
1806         GList *iter = NULL;
1807         char* data = NULL;
1808
1809         /* if list have item */
1810         if (g_list_length(lang_list) > 0) {
1811                 /* Get a first item */
1812                 iter = g_list_first(lang_list);
1813
1814                 while (NULL != iter) {
1815                         data = iter->data;
1816
1817                         if (NULL != data)
1818                                 g_free(data);
1819                         
1820                         lang_list = g_list_remove_link(lang_list, iter);
1821
1822                         iter = g_list_first(lang_list);
1823                 }
1824         }
1825 }
1826
1827 /* A function forging */
1828 int __log_enginelist()
1829 {
1830         GList *iter = NULL;
1831         sttengine_info_s *data = NULL;
1832
1833         if (0 < g_list_length(g_engine_list)) {
1834
1835                 /* Get a first item */
1836                 iter = g_list_first(g_engine_list);
1837
1838                 SLOG(LOG_DEBUG, TAG_STTD, "--------------- engine list -------------------");
1839
1840                 int i = 1;      
1841                 while (NULL != iter) {
1842                         /* Get handle data from list */
1843                         data = iter->data;
1844
1845                         SLOG(LOG_DEBUG, TAG_STTD, "[%dth]", i);
1846                         SLOG(LOG_DEBUG, TAG_STTD, "  engine uuid : %s", data->engine_uuid);
1847                         SLOG(LOG_DEBUG, TAG_STTD, "  engine name : %s", data->engine_name);
1848                         SLOG(LOG_DEBUG, TAG_STTD, "  engine path : %s", data->engine_path);
1849                         SLOG(LOG_DEBUG, TAG_STTD, "  setting ug path : %s", data->setting_ug_path);
1850
1851                         iter = g_list_next(iter);
1852                         i++;
1853                 }
1854                 SLOG(LOG_DEBUG, TAG_STTD, "----------------------------------------------");
1855         } else {
1856                 SLOG(LOG_DEBUG, TAG_STTD, "-------------- engine list -------------------");
1857                 SLOG(LOG_DEBUG, TAG_STTD, "  No Engine in engine directory");
1858                 SLOG(LOG_DEBUG, TAG_STTD, "----------------------------------------------");
1859         }
1860
1861         return 0;
1862 }
1863
1864
1865