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