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