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