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