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