Add restore logic and function to get nlp info and pre result
[platform/core/uifw/voice-control.git] / server / vcd_engine_agent.c
1 /*
2 * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18 #include <dlfcn.h>
19 #include <dirent.h>
20
21 #include "vcd_client_data.h"
22 #include "vcd_config.h"
23 #include "vcd_engine_agent.h"
24 #include "vcd_main.h"
25 #include "vcd_recorder.h"
26
27 /*
28 * Internal data structure
29 */
30 typedef struct {
31         /* engine info */
32         char*   engine_uuid;
33         char*   engine_name;
34         char*   engine_path;
35
36         /* engine load info */
37         bool    is_set;
38         bool    is_loaded;
39         bool    is_command_ready;
40         void    *handle;
41
42         vcpe_funcs_s*   pefuncs;
43         vcpd_funcs_s*   pdfuncs;
44
45         int (*vcp_load_engine)(vcpd_funcs_s* pdfuncs, vcpe_funcs_s* pefuncs);
46         int (*vcp_unload_engine)();
47 } vcengine_s;
48
49 typedef struct _vcengine_info {
50         char*   engine_uuid;
51         char*   engine_path;
52         char*   engine_name;
53 } vcengine_info_s;
54
55
56 /*
57 * static data
58 */
59
60 /** vc engine agent init */
61 static bool g_agent_init;
62
63 /** vc engine list */
64 static GList *g_engine_list;
65
66 /** current engine information */
67 static vcengine_s g_dynamic_engine;
68
69 static char* g_default_lang;
70
71 /** callback functions */
72 static pre_result_callback g_pre_result_cb;
73 static result_callback g_result_cb;
74
75 bool __supported_language_cb(const char* language, void* user_data);
76
77 void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* engine_setting, bool use_network, void* user_data);
78
79 bool __engine_setting_cb(const char* key, const char* value, void* user_data);
80
81 /** Free voice list */
82 void __free_language_list(GList* lang_list);
83
84
85 /*
86 * Internal Interfaces
87 */
88
89 /** check engine id */
90 int __internal_check_engine_id(const char* engine_uuid);
91
92 /** update engine list */
93 int __internal_update_engine_list();
94
95 /** get engine info */
96 int __internal_get_engine_info(const char* filepath, vcengine_info_s** info);
97
98 int __log_enginelist();
99
100 /*
101 * VCS Engine Agent Interfaces
102 */
103 int vcd_engine_agent_init(pre_result_callback pre_cb, result_callback result_cb)
104 {
105         if (NULL == pre_cb || NULL == result_cb) {
106                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Input parameter is NULL");
107                 return VCD_ERROR_OPERATION_FAILED;
108         }
109
110         /* init dynamic engine */
111         g_dynamic_engine.engine_uuid = NULL;
112         g_dynamic_engine.engine_name = NULL;
113         g_dynamic_engine.engine_path = NULL;
114
115         g_dynamic_engine.is_set = false;
116         g_dynamic_engine.is_loaded = false;
117         g_dynamic_engine.handle = NULL;
118         g_dynamic_engine.is_command_ready = false;
119         g_dynamic_engine.pefuncs = (vcpe_funcs_s*)calloc(1, sizeof(vcpe_funcs_s));
120         g_dynamic_engine.pdfuncs = (vcpd_funcs_s*)calloc(1, sizeof(vcpd_funcs_s));
121
122         g_agent_init = true;
123
124         g_pre_result_cb = pre_cb;
125         g_result_cb = result_cb;
126
127         if (0 != vcd_config_get_default_language(&g_default_lang)) {
128                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] There is No default voice in config");
129                 /* Set default voice */
130                 g_default_lang = strdup(VC_BASE_LANGUAGE);
131         }
132
133         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Engine Agent Initialize");
134
135         return 0;
136 }
137
138 int vcd_engine_agent_release()
139 {
140         if (false == g_agent_init) {
141                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
142                 return VCD_ERROR_OPERATION_FAILED;
143         }
144
145         /* unload current engine */
146         vcd_engine_agent_unload_current_engine();
147
148         /* release engine list */
149         GList *iter = NULL;
150         vcengine_s *data = NULL;
151
152         if (g_list_length(g_engine_list) > 0) {
153                 /* Get a first item */
154                 iter = g_list_first(g_engine_list);
155
156                 while (NULL != iter) {
157                         /* Get handle data from list */
158                         data = iter->data;
159                         iter = g_list_remove(iter, data);
160                 }
161         }
162
163         g_list_free(iter);
164
165         /* release current engine data */
166         if (NULL != g_dynamic_engine.pefuncs)   free(g_dynamic_engine.pefuncs);
167         if (NULL != g_dynamic_engine.pdfuncs)   free(g_dynamic_engine.pdfuncs);
168
169         g_agent_init = false;
170
171         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Engine Agent release");
172
173         return 0;
174 }
175
176 bool vcd_engine_is_available_engine()
177 {
178         if (true == g_dynamic_engine.is_loaded)
179                 return true;
180
181         return false;
182 }
183
184 int vcd_engine_agent_initialize_current_engine()
185 {
186         /* check agent init */
187         if (false == g_agent_init) {
188                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
189                 return VCD_ERROR_OPERATION_FAILED;
190         }
191
192         /* update engine list */
193         if (0 != __internal_update_engine_list()) {
194                 SLOG(LOG_ERROR, TAG_VCD, "[engine agent] vcd_engine_agent_init : __internal_update_engine_list : no engine error");
195                 return VCD_ERROR_ENGINE_NOT_FOUND;
196         }
197
198         /* check whether engine id is valid or not.*/
199         GList *iter = NULL;
200         vcengine_info_s *dynamic_engine = NULL;
201
202         if (g_list_length(g_engine_list) > 0) {
203                 /*Get a first item*/
204                 iter = g_list_first(g_engine_list);
205
206                 while (NULL != iter) {
207                         /*Get handle data from list*/
208                         dynamic_engine = iter->data;
209                         if (NULL != dynamic_engine) {
210                                 break;
211                         }
212
213                         /*Get next item*/
214                         iter = g_list_next(iter);
215                 }
216         } else {
217                 return VCD_ERROR_ENGINE_NOT_FOUND;
218         }
219
220         if (NULL == dynamic_engine) {
221                 return VCD_ERROR_ENGINE_NOT_FOUND;
222         } else {
223                 if (NULL != g_dynamic_engine.engine_uuid) {
224                         /* set data from g_engine_list */
225                         if (g_dynamic_engine.engine_uuid != NULL)       free(g_dynamic_engine.engine_uuid);
226                         if (g_dynamic_engine.engine_name != NULL)       free(g_dynamic_engine.engine_name);
227                         if (g_dynamic_engine.engine_path != NULL)       free(g_dynamic_engine.engine_path);
228                 }
229
230                 g_dynamic_engine.engine_uuid = g_strdup(dynamic_engine->engine_uuid);
231                 g_dynamic_engine.engine_name = g_strdup(dynamic_engine->engine_name);
232                 g_dynamic_engine.engine_path = g_strdup(dynamic_engine->engine_path);
233
234                 g_dynamic_engine.handle = NULL;
235                 g_dynamic_engine.is_loaded = false;
236                 g_dynamic_engine.is_set = true;
237
238                 SLOG(LOG_DEBUG, TAG_VCD, "-----");
239                 SLOG(LOG_DEBUG, TAG_VCD, " Dynamic engine uuid : %s", g_dynamic_engine.engine_uuid);
240                 SLOG(LOG_DEBUG, TAG_VCD, " Dynamic engine name : %s", g_dynamic_engine.engine_name);
241                 SLOG(LOG_DEBUG, TAG_VCD, " Dynamic engine path : %s", g_dynamic_engine.engine_path);
242                 SLOG(LOG_DEBUG, TAG_VCD, "-----");
243
244         }
245
246         return 0;
247 }
248
249 int __internal_check_engine_id(const char* engine_uuid)
250 {
251         if (NULL == engine_uuid) {
252                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
253                 return VCD_ERROR_INVALID_PARAMETER;
254         }
255
256         GList *iter = NULL;
257         vcengine_s *data = NULL;
258
259         if (0 < g_list_length(g_engine_list)) {
260                 /*Get a first item*/
261                 iter = g_list_first(g_engine_list);
262
263                 while (NULL != iter) {
264                         data = iter->data;
265
266                         if (0 == strncmp(engine_uuid, data->engine_uuid, strlen(data->engine_uuid))) {
267                                 return 0;
268                         }
269
270                         iter = g_list_next(iter);
271                 }
272         }
273
274         return -1;
275 }
276
277 void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* engine_setting, bool use_network, void* user_data)
278 {
279         vcengine_info_s* temp = (vcengine_info_s*)user_data;
280
281         temp->engine_uuid = g_strdup(engine_uuid);
282         temp->engine_name = g_strdup(engine_name);
283 }
284
285
286 int __internal_get_engine_info(const char* filepath, vcengine_info_s** info)
287 {
288         if (NULL == filepath || NULL == info) {
289                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
290                 return VCD_ERROR_INVALID_PARAMETER;
291         }
292
293         /* load engine */
294         char *error;
295         void* handle;
296
297         handle = dlopen(filepath, RTLD_LAZY);
298         if (!handle) {
299                 SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Invalid engine : %s", filepath);
300                 return -1;
301         }
302
303         /* link engine to daemon */
304         dlsym(handle, "vcp_load_engine");
305         if ((error = dlerror()) != NULL) {
306                 SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Invalid engine. Fail to open vcp_load_engine : %s", filepath);
307                 dlclose(handle);
308                 return -1;
309         }
310
311         dlsym(handle, "vcp_unload_engine");
312         if ((error = dlerror()) != NULL) {
313                 SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Invalid engine. Fail to open vcp_unload_engine : %s", filepath);
314                 dlclose(handle);
315                 return -1;
316         }
317
318         int (*get_engine_info)(vcpe_engine_info_cb callback, void* user_data);
319
320         get_engine_info = (int (*)(vcpe_engine_info_cb, void*))dlsym(handle, "vcp_get_engine_info");
321         if (NULL != (error = dlerror()) || NULL == get_engine_info) {
322                 SLOG(LOG_WARN, TAG_VCD, "[Engine Agent WARNING] Invalid engine. Fail to open vcp_get_engine_info : %s", filepath);
323                 dlclose(handle);
324                 return -1;
325         }
326
327         vcengine_info_s* temp;
328         temp = (vcengine_info_s*)calloc(1, sizeof(vcengine_info_s));
329         if (NULL == temp) {
330                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to allocate memory");
331                 dlclose(handle);
332                 return VCD_ERROR_OUT_OF_MEMORY;
333         }
334
335         /* get engine info */
336         if (0 != get_engine_info(__engine_info_cb, (void*)temp)) {
337                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get engine info from engine");
338                 dlclose(handle);
339                 free(temp);
340                 return -1;
341         }
342
343         /* close engine */
344         dlclose(handle);
345
346         temp->engine_path = g_strdup(filepath);
347
348         SLOG(LOG_DEBUG, TAG_VCD, "----- Valid Engine");
349         SLOG(LOG_DEBUG, TAG_VCD, "Engine uuid : %s", temp->engine_uuid);
350         SLOG(LOG_DEBUG, TAG_VCD, "Engine name : %s", temp->engine_name);
351         SLOG(LOG_DEBUG, TAG_VCD, "Engine path : %s", temp->engine_path);
352         SLOG(LOG_DEBUG, TAG_VCD, "-----");
353         SLOG(LOG_DEBUG, TAG_VCD, "  ");
354
355         *info = temp;
356
357         return 0;
358 }
359
360 int __internal_update_engine_list()
361 {
362         /* relsease engine list */
363         GList *iter = NULL;
364         vcengine_info_s *data = NULL;
365
366         if (0 < g_list_length(g_engine_list)) {
367                 /* Get a first item */
368                 iter = g_list_first(g_engine_list);
369
370                 while (NULL != iter) {
371                         /* Get handle data from list */
372                         data = iter->data;
373
374                         if (NULL != data) {
375                                 if (NULL != data->engine_uuid)          free(data->engine_uuid);
376                                 if (NULL != data->engine_path)          free(data->engine_path);
377                                 if (NULL != data->engine_name)          free(data->engine_name);
378
379                                 free(data);
380                         }
381
382                         g_engine_list = g_list_remove_link(g_engine_list, iter);
383                         iter = g_list_first(g_engine_list);
384                 }
385         }
386
387         /* Get file name from default engine directory */
388         DIR *dp = NULL;
389         int ret = -1;
390         struct dirent entry;
391         struct dirent *dirp = NULL;
392
393         dp  = opendir(VC_DEFAULT_ENGINE);
394         if (NULL != dp) {
395                 do {
396                         ret = readdir_r(dp, &entry, &dirp);
397                         if (0 != ret) {
398                                 SLOG(LOG_ERROR, TAG_VCD, "[File ERROR] Fail to read directory");
399                                 break;
400                         }
401
402                         if (NULL != dirp) {
403                                 vcengine_info_s* info = NULL;
404                                 char* filepath = NULL;
405                                 int filesize = 0;
406
407                                 filesize = strlen(VC_DEFAULT_ENGINE) + strlen(dirp->d_name) + 5;
408                                 filepath = (char*)calloc(filesize, sizeof(char));
409
410                                 if (NULL != filepath) {
411                                         snprintf(filepath, filesize, "%s/%s", VC_DEFAULT_ENGINE, dirp->d_name);
412                                 } else {
413                                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Memory not enough!!");
414                                         continue;
415                                 }
416
417                                 /* get its info and update engine list */
418                                 if (0 == __internal_get_engine_info(filepath, &info)) {
419                                         /* add engine info to g_engine_list */
420                                         g_engine_list = g_list_append(g_engine_list, info);
421                                 }
422
423                                 if (NULL != filepath) {
424                                         free(filepath);
425                                         filepath = NULL;
426                                 }
427                         }
428                 } while (NULL != dirp);
429
430                 closedir(dp);
431         } else {
432                 SLOG(LOG_WARN, TAG_VCD, "[Engine Agent WARNING] Fail to open default directory");
433         }
434
435         if (0 >= g_list_length(g_engine_list)) {
436                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] No Engine");
437                 return VCD_ERROR_ENGINE_NOT_FOUND;
438         }
439
440         __log_enginelist();
441
442         return 0;
443 }
444
445
446 int __foreach_command(vcp_cmd_h vc_command, vcpd_foreach_command_cb callback, void* user_data)
447 {
448         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request foreach command from engine");
449         return vcd_client_foreach_command((client_foreach_command_cb)callback, user_data);
450 }
451
452 int __command_get_length(vcp_cmd_h vc_command)
453 {
454         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request command length from engine");
455         return vcd_client_get_length();
456 }
457
458 int __get_audio_type(char** audio_type)
459 {
460         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request audio type");
461
462         return vcd_recorder_get(audio_type);
463 }
464
465 void __pre_result_cb(vcp_pre_result_event_e event, const char* pre_result, void* user_data)
466 {
467         SLOG(LOG_DEBUG, TAG_VCD, "[Engine agent] Pre result(%s)", pre_result);
468
469         if (NULL != g_pre_result_cb) {
470                 g_pre_result_cb(event, pre_result, user_data);
471         } else {
472                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent ERROR] Result callback function is NOT valid");
473         }
474
475         return;
476 }
477
478 void __result_cb(vcp_result_event_e event, int* result_id, int count, const char* all_result, const char* non_fixed, const char* msg, void *user_data)
479 {
480         SLOG(LOG_DEBUG, TAG_VCD, "[Engine agent] Event(%d), Count(%d) Text(%s) Nonfixed(%s) Msg(%s)", event, count, all_result, non_fixed, msg);
481
482         // Need to nlp info handle or true false value
483         int ret = 0;
484         char* temp_nlp = NULL;
485
486         if (true == g_dynamic_engine.is_loaded) {
487                 if (NULL != g_dynamic_engine.pefuncs->get_nlp_info) {
488                         ret = g_dynamic_engine.pefuncs->get_nlp_info(&temp_nlp);
489                         if (0 != ret) {
490                                 SLOG(LOG_WARN, TAG_VCD, "[Engine Agent ERROR] Fail to get nlp info : error(%d)", ret);
491                         } else {
492                                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Get nlp info : %s", temp_nlp);
493                         }
494                 } else {
495                         SLOG(LOG_WARN, TAG_VCD, "[Engine Agent ERROR] Not support to get nlp info");
496                 }
497         }
498
499         if (NULL == temp_nlp)
500                 temp_nlp = "null";
501
502         if (NULL != g_result_cb) {
503                 g_result_cb(event, result_id, count, all_result, non_fixed, msg, temp_nlp, user_data);
504         } else {
505                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent ERROR] Result callback function is NOT valid");
506         }
507
508         return;
509 }
510
511 int __load_engine(vcengine_s* engine)
512 {
513         /* check whether current engine is loaded or not */
514         if (true == engine->is_loaded) {
515                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Engine has already been loaded ");
516                 return 0;
517         }
518
519         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Current engine path : %s", engine->engine_path);
520
521         /* open engine */
522         char *error;
523         engine->handle = dlopen(engine->engine_path, RTLD_LAZY);
524
525         if ((error = dlerror()) != NULL || !engine->handle) {
526                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get engine handle");
527                 return VCD_ERROR_OPERATION_FAILED;
528         }
529
530         engine->vcp_unload_engine = (int (*)())dlsym(engine->handle, "vcp_unload_engine");
531         if ((error = dlerror()) != NULL) {
532                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to link daemon to vcp_unload_engine()");
533                 dlclose(engine->handle);
534                 return VCD_ERROR_OPERATION_FAILED;
535         }
536
537         engine->vcp_load_engine = (int (*)(vcpd_funcs_s*, vcpe_funcs_s*))dlsym(engine->handle, "vcp_load_engine");
538         if (NULL != (error = dlerror()) || NULL == engine->vcp_load_engine) {
539                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to link daemon to vcp_load_engine()");
540                 dlclose(engine->handle);
541                 return VCD_ERROR_OPERATION_FAILED;
542         }
543
544         /* load engine */
545         engine->pdfuncs->version = 1;
546         engine->pdfuncs->size = sizeof(vcpd_funcs_s);
547
548         engine->pdfuncs->foreach_command = __foreach_command;
549         engine->pdfuncs->get_command_count = __command_get_length;
550         engine->pdfuncs->get_audio_type = __get_audio_type;
551
552         if (0 != engine->vcp_load_engine(engine->pdfuncs, engine->pefuncs)) {
553                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail vcp_load_engine()");
554                 dlclose(engine->handle);
555                 return VCD_ERROR_OPERATION_FAILED;
556         }
557
558         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] engine info : version(%d), size(%d)", engine->pefuncs->version, engine->pefuncs->size);
559
560         /* engine error check */
561         if (engine->pefuncs->size != sizeof(vcpe_funcs_s)) {
562                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not valid");
563                 return VCD_ERROR_OPERATION_FAILED;
564         }
565
566         /* Check all engine functions */
567         if (NULL == engine->pefuncs->initialize ||
568                 NULL == engine->pefuncs->deinitialize ||
569                 NULL == engine->pefuncs->foreach_langs ||
570                 NULL == engine->pefuncs->is_lang_supported ||
571                 NULL == engine->pefuncs->set_result_cb ||
572                 NULL == engine->pefuncs->set_language ||
573                 NULL == engine->pefuncs->set_recording ||
574                 NULL == engine->pefuncs->stop ||
575                 NULL == engine->pefuncs->cancel) {
576                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] The current engine is NOT valid");
577                 return VCD_ERROR_OPERATION_FAILED;
578         }
579
580         /* initalize engine */
581         if (0 != engine->pefuncs->initialize()) {
582                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to initialize vc-engine");
583                 return VCD_ERROR_OPERATION_FAILED;
584         }
585
586         if (0 != engine->pefuncs->set_result_cb(__result_cb, NULL)) {
587                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set result callback of vc-engine");
588                 return VCD_ERROR_OPERATION_FAILED;
589         }
590
591         // temp
592         if (0 != engine->pefuncs->set_pre_result_cb(__pre_result_cb, NULL)) {
593                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set pre result callback of vc-engine");
594                 return VCD_ERROR_OPERATION_FAILED;
595         }
596
597         /* load engine */
598         if (true == engine->pefuncs->is_lang_supported(g_default_lang)) {
599                 if (0 != engine->pefuncs->set_language(g_default_lang)) {
600                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to load current engine");
601                         return VCD_ERROR_OPERATION_FAILED;
602                 }
603                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] The %s has been loaded !!!", engine->engine_name);
604                 engine->is_loaded = true;
605         } else {
606                 SLOG(LOG_WARN, TAG_VCD, "[Engine Agent WARNING] This engine do not support default language : lang(%s)", g_default_lang);
607                 engine->is_loaded = false;
608         }
609
610         return 0;
611 }
612
613 int vcd_engine_agent_load_current_engine()
614 {
615         if (false == g_agent_init) {
616                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
617                 return VCD_ERROR_OPERATION_FAILED;
618         }
619
620         if (true == g_dynamic_engine.is_set) {
621                 if (0 != __load_engine(&g_dynamic_engine)) {
622                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to load dynamic engine");
623
624                         /* need to initialize dynamic engine data */
625                         g_dynamic_engine.is_loaded = false;
626                 } else {
627                         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Load dynamic engine");
628                 }
629         }
630
631         return 0;
632 }
633
634 int vcd_engine_agent_unload_current_engine()
635 {
636         if (false == g_agent_init) {
637                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized ");
638                 return VCD_ERROR_OPERATION_FAILED;
639         }
640
641         if (true == g_dynamic_engine.is_set) {
642                 /* unload dynamic engine */
643                 if (true == g_dynamic_engine.is_loaded) {
644                         /* shutdown engine */
645                         g_dynamic_engine.pefuncs->deinitialize();
646                         g_dynamic_engine.vcp_unload_engine();
647                         dlclose(g_dynamic_engine.handle);
648                         g_dynamic_engine.handle = NULL;
649                         g_dynamic_engine.is_loaded = false;
650                 }
651         }
652         return 0;
653 }
654
655
656 /*
657 * VCS Engine Interfaces for client
658 */
659
660 int vcd_engine_set_commands()
661 {
662         if (false == g_agent_init) {
663                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
664                 return VCD_ERROR_OPERATION_FAILED;
665         }
666
667         int ret = -1;
668
669         if (true == g_dynamic_engine.is_loaded) {
670                 /* Set dynamic command */
671                 ret = g_dynamic_engine.pefuncs->set_commands((vcp_cmd_h)0);
672                 if (0 != ret) {
673                         SLOG(LOG_WARN, TAG_VCD, "[Engine Agent ERROR] Fail to set command of dynamic engine : error(%d)", ret);
674                         g_dynamic_engine.is_command_ready = false;
675                 } else {
676                         g_dynamic_engine.is_command_ready = true;
677                 }
678
679                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] set command");
680         } else {
681                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Dynamic engine is not available");
682         }
683
684         return 0;
685 }
686
687 int vcd_engine_recognize_start(bool silence)
688 {
689         if (false == g_agent_init) {
690                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
691                 return VCD_ERROR_OPERATION_FAILED;
692         }
693
694         int ret = -1;
695         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] silence is %s", silence ? "true" : "false");
696
697         if (true == g_dynamic_engine.is_loaded && true == g_dynamic_engine.is_command_ready) {
698                 ret = g_dynamic_engine.pefuncs->start(silence);
699                 if (0 != ret) {
700                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] Fail to start engine error(%d)", ret);
701                         return VCD_ERROR_OPERATION_FAILED;
702                 }
703         } else {
704                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Engine is not available (Cannot start)");
705                 return VCD_ERROR_OPERATION_FAILED;
706         }
707
708         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Engine start");
709         return 0;
710 }
711
712 int vcd_engine_recognize_audio(const void* data, unsigned int length, vcp_speech_detect_e* speech_detected)
713 {
714         if (false == g_agent_init) {
715                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
716                 return VCD_ERROR_OPERATION_FAILED;
717         }
718
719         if (NULL == data) {
720                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
721                 return VCD_ERROR_INVALID_PARAMETER;
722         }
723
724         int ret = -1;
725
726         if (true == g_dynamic_engine.is_loaded) {
727                 ret = g_dynamic_engine.pefuncs->set_recording(data, length, speech_detected);
728                 if (0 != ret) {
729                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set recording dynamic engine error(%d)", ret);
730                         if (VCP_ERROR_OUT_OF_NETWORK == ret) {
731                                 return VCD_ERROR_TIMED_OUT;
732                         }
733                         return VCD_ERROR_OPERATION_FAILED;
734                 }
735         }
736
737         return 0;
738 }
739
740 int vcd_engine_recognize_stop()
741 {
742         if (false == g_agent_init) {
743                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
744                 return VCD_ERROR_OPERATION_FAILED;
745         }
746
747         if (true == g_dynamic_engine.is_loaded) {
748                 int ret = -1;
749                 ret = g_dynamic_engine.pefuncs->stop();
750                 if (0 != ret) {
751                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to stop dynamic engine error(%d)", ret);
752                         return VCD_ERROR_OPERATION_FAILED;
753                 }
754         } else {
755                 SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Dynamic engine is not recording state");
756                 return VCD_ERROR_OPERATION_FAILED;
757         }
758
759         return 0;
760 }
761
762 int vcd_engine_recognize_cancel()
763 {
764         if (false == g_agent_init) {
765                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
766                 return VCD_ERROR_OPERATION_FAILED;
767         }
768
769         int ret = -1;
770         if (true == g_dynamic_engine.is_loaded) {
771                 ret = g_dynamic_engine.pefuncs->cancel();
772                 if (0 != ret) {
773                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to cancel dynamic engine error(%d)", ret);
774                 }
775         }
776
777         return 0;
778 }
779
780
781 /*
782 * VCS Engine Interfaces for client and setting
783 */
784
785 int vcd_engine_get_audio_format(const char* audio_id, vcp_audio_type_e* types, int* rate, int* channels)
786 {
787         if (false == g_agent_init) {
788                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
789                 return VCD_ERROR_OPERATION_FAILED;
790         }
791
792         if (true != g_dynamic_engine.is_loaded) {
793                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded");
794         }
795
796         if (NULL == g_dynamic_engine.pefuncs->get_recording_format) {
797                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] The function of engine is NULL!!");
798                 return VCD_ERROR_OPERATION_FAILED;
799         }
800
801         int ret = g_dynamic_engine.pefuncs->get_recording_format(audio_id, types, rate, channels);
802         if (0 != ret) {
803                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] get recording format(%d)", ret);
804                 return VCD_ERROR_OPERATION_FAILED;
805         }
806
807         return 0;
808 }
809
810 bool __supported_language_cb(const char* language, void* user_data)
811 {
812         GList** lang_list = (GList**)user_data;
813
814         if (NULL == language || NULL == lang_list) {
815                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Input parameter is NULL in callback!!!!");
816                 return false;
817         }
818
819         SLOG(LOG_DEBUG, TAG_VCD, "-- Language(%s)", language);
820
821         char* temp_lang = g_strdup(language);
822
823         *lang_list = g_list_append(*lang_list, temp_lang);
824
825         return true;
826 }
827
828 int vcd_engine_supported_langs(GList** lang_list)
829 {
830         if (false == g_agent_init) {
831                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
832                 return VCD_ERROR_OPERATION_FAILED;
833         }
834
835         if (true != g_dynamic_engine.is_loaded) {
836                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded");
837         }
838
839         if (NULL == g_dynamic_engine.pefuncs->foreach_langs) {
840                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] The function of engine is NULL!!");
841                 return VCD_ERROR_OPERATION_FAILED;
842         }
843
844         int ret = g_dynamic_engine.pefuncs->foreach_langs(__supported_language_cb, (void*)lang_list);
845         if (0 != ret) {
846                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] get language list error(%d)", ret);
847                 return VCD_ERROR_OPERATION_FAILED;
848         }
849
850         return 0;
851 }
852
853
854 int vcd_engine_get_current_language(char** lang)
855 {
856         if (false == g_agent_init) {
857                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
858                 return VCD_ERROR_OPERATION_FAILED;
859         }
860
861         if (NULL == lang) {
862                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
863                 return VCD_ERROR_INVALID_PARAMETER;
864         }
865
866         /* get default language */
867         *lang = g_strdup(g_default_lang);
868
869         return 0;
870 }
871
872 int vcd_engine_set_current_language(const char* language)
873 {
874         if (false == g_agent_init) {
875                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
876                 return VCD_ERROR_OPERATION_FAILED;
877         }
878
879         if (NULL == language) {
880                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
881                 return VCD_ERROR_INVALID_PARAMETER;
882         }
883
884         int ret;
885
886         if (true == g_dynamic_engine.is_loaded) {
887                 g_dynamic_engine.is_command_ready = false;
888
889                 ret = g_dynamic_engine.pefuncs->set_language(language);
890                 if (0 != ret) {
891                         SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Fail to set language of dynamic engine error(%d, %s)", ret, language);
892                 }
893         } else {
894                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Dynamic engine is not available (Cannot start)");
895         }
896
897         return 0;
898 }
899
900 void __free_language_list(GList* lang_list)
901 {
902         GList *iter = NULL;
903         char* data = NULL;
904
905         /* if list have item */
906         if (g_list_length(lang_list) > 0) {
907                 /* Get a first item */
908                 iter = g_list_first(lang_list);
909
910                 while (NULL != iter) {
911                         data = iter->data;
912
913                         if (NULL != data)
914                                 free(data);
915
916                         lang_list = g_list_remove_link(lang_list, iter);
917
918                         iter = g_list_first(lang_list);
919                 }
920         }
921 }
922
923 int __log_enginelist()
924 {
925         GList *iter = NULL;
926         vcengine_info_s *data = NULL;
927
928         if (0 < g_list_length(g_engine_list)) {
929
930                 /* Get a first item */
931                 iter = g_list_first(g_engine_list);
932
933                 SLOG(LOG_DEBUG, TAG_VCD, "--------------- engine list -------------------");
934
935                 int i = 1;
936                 while (NULL != iter) {
937                         /* Get handle data from list */
938                         data = iter->data;
939
940                         SLOG(LOG_DEBUG, TAG_VCD, "[%dth]", i);
941                         SLOG(LOG_DEBUG, TAG_VCD, "  engine uuid : %s", data->engine_uuid);
942                         SLOG(LOG_DEBUG, TAG_VCD, "  engine name : %s", data->engine_name);
943                         SLOG(LOG_DEBUG, TAG_VCD, "  engine path : %s", data->engine_path);
944                         iter = g_list_next(iter);
945                         i++;
946                 }
947                 SLOG(LOG_DEBUG, TAG_VCD, "----------------------------------------------");
948         } else {
949                 SLOG(LOG_DEBUG, TAG_VCD, "-------------- engine list -------------------");
950                 SLOG(LOG_DEBUG, TAG_VCD, "  No Engine in engine directory");
951                 SLOG(LOG_DEBUG, TAG_VCD, "----------------------------------------------");
952         }
953
954         return 0;
955 }
956
957
958
959