update directory path for migration
[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         if (!handle) {
297                 SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Invalid engine : %s", filepath);
298                 return -1;
299         }
300
301         /* link engine to daemon */
302         dlsym(handle, "vcp_load_engine");
303         if ((error = dlerror()) != NULL) {
304                 SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Invalid engine. Fail to open vcp_load_engine : %s", filepath);
305                 dlclose(handle);
306                 return -1;
307         }
308
309         dlsym(handle, "vcp_unload_engine");
310         if ((error = dlerror()) != NULL) {
311                 SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Invalid engine. Fail to open vcp_unload_engine : %s", filepath);
312                 dlclose(handle);
313                 return -1;
314         }
315
316         int (*get_engine_info)(vcpe_engine_info_cb callback, void* user_data);
317
318         get_engine_info = (int (*)(vcpe_engine_info_cb, void*))dlsym(handle, "vcp_get_engine_info");
319         if (NULL != (error = dlerror()) || NULL == get_engine_info) {
320                 SLOG(LOG_WARN, TAG_VCD, "[Engine Agent WARNING] Invalid engine. Fail to open vcp_get_engine_info : %s", filepath);
321                 dlclose(handle);
322                 return -1;
323         }
324
325         vcengine_info_s* temp;
326         temp = (vcengine_info_s*)calloc(1, sizeof(vcengine_info_s));
327         if (NULL == temp) {
328                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to allocate memory");
329                 dlclose(handle);
330                 return VCD_ERROR_OUT_OF_MEMORY;
331         }
332
333         /* get engine info */
334         if (0 != get_engine_info(__engine_info_cb, (void*)temp)) {
335                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get engine info from engine");
336                 dlclose(handle);
337                 free(temp);
338                 return -1;
339         }
340
341         /* close engine */
342         dlclose(handle);
343
344         temp->engine_path = g_strdup(filepath);
345
346         SLOG(LOG_DEBUG, TAG_VCD, "----- Valid Engine");
347         SLOG(LOG_DEBUG, TAG_VCD, "Engine uuid : %s", temp->engine_uuid);
348         SLOG(LOG_DEBUG, TAG_VCD, "Engine name : %s", temp->engine_name);
349         SLOG(LOG_DEBUG, TAG_VCD, "Engine path : %s", temp->engine_path);
350         SLOG(LOG_DEBUG, TAG_VCD, "-----");
351         SLOG(LOG_DEBUG, TAG_VCD, "  ");
352
353         *info = temp;
354
355         return 0;
356 }
357
358 int __internal_update_engine_list()
359 {
360         /* relsease engine list */
361         GList *iter = NULL;
362         vcengine_info_s *data = NULL;
363
364         if (0 < g_list_length(g_engine_list)) {
365                 /* Get a first item */
366                 iter = g_list_first(g_engine_list);
367
368                 while (NULL != iter) {
369                         /* Get handle data from list */
370                         data = iter->data;
371
372                         if (NULL != data) {
373                                 if (NULL != data->engine_uuid)          free(data->engine_uuid);
374                                 if (NULL != data->engine_path)          free(data->engine_path);
375                                 if (NULL != data->engine_name)          free(data->engine_name);
376
377                                 free(data);
378                         }
379
380                         g_engine_list = g_list_remove_link(g_engine_list, iter);
381                         iter = g_list_first(g_engine_list);
382                 }
383         }
384
385         /* Get file name from default engine directory */
386         DIR *dp = NULL;
387         int ret = -1;
388         struct dirent entry;
389         struct dirent *dirp = NULL;
390
391         dp  = opendir(VC_DEFAULT_ENGINE);
392         if (NULL != dp) {
393                 do {
394                         ret = readdir_r(dp, &entry, &dirp);
395                         if (0 != ret) {
396                                 SLOG(LOG_ERROR, TAG_VCD, "[File ERROR] Fail to read directory");
397                                 break;
398                         }
399
400                         if (NULL != dirp) {
401                                 vcengine_info_s* info = NULL;
402                                 char* filepath = NULL;
403                                 int filesize = 0;
404
405                                 filesize = strlen(VC_DEFAULT_ENGINE) + strlen(dirp->d_name) + 5;
406                                 filepath = (char*)calloc(filesize, sizeof(char));
407
408                                 if (NULL != filepath) {
409                                         snprintf(filepath, filesize, "%s/%s", VC_DEFAULT_ENGINE, dirp->d_name);
410                                 } else {
411                                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Memory not enough!!");
412                                         continue;
413                                 }
414
415                                 /* get its info and update engine list */
416                                 if (0 == __internal_get_engine_info(filepath, &info)) {
417                                         /* add engine info to g_engine_list */
418                                         g_engine_list = g_list_append(g_engine_list, info);
419                                 }
420
421                                 if (NULL != filepath) {
422                                         free(filepath);
423                                         filepath = NULL;
424                                 }
425                         }
426                 } while (NULL != dirp);
427
428                 closedir(dp);
429         } else {
430                 SLOG(LOG_WARN, TAG_VCD, "[Engine Agent WARNING] Fail to open default directory");
431         }
432
433         if (0 >= g_list_length(g_engine_list)) {
434                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] No Engine");
435                 return VCD_ERROR_ENGINE_NOT_FOUND;
436         }
437
438         __log_enginelist();
439
440         return 0;
441 }
442
443
444 int __foreach_command(vcp_cmd_h vc_command, vcpd_foreach_command_cb callback, void* user_data)
445 {
446         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request foreach command from engine");
447         return vcd_client_foreach_command((client_foreach_command_cb)callback, user_data);
448 }
449
450 int __command_get_length(vcp_cmd_h vc_command)
451 {
452         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request command length from engine");
453         return vcd_client_get_length();
454 }
455
456 int __get_audio_type(char** audio_type)
457 {
458         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request audio type");
459
460         return vcd_recorder_get(audio_type);
461 }
462
463 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)
464 {
465         SLOG(LOG_DEBUG, TAG_VCD, "[Engine agent] Event(%d), Count(%d) Text(%s) Nonfixed(%s) Msg(%s)", event, count, all_result, non_fixed, msg);
466
467         if (NULL != g_result_cb) {
468                 g_result_cb(event, result_id, count, all_result, non_fixed, msg, user_data);
469         } else {
470                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent ERROR] Result callback function is NOT valid");
471         }
472
473         return;
474 }
475
476 int __load_engine(vcengine_s* engine)
477 {
478         /* check whether current engine is loaded or not */
479         if (true == engine->is_loaded) {
480                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Engine has already been loaded ");
481                 return 0;
482         }
483
484         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Current engine path : %s", engine->engine_path);
485
486         /* open engine */
487         char *error;
488         engine->handle = dlopen(engine->engine_path, RTLD_LAZY);
489
490         if ((error = dlerror()) != NULL || !engine->handle) {
491                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get engine handle");
492                 return VCD_ERROR_OPERATION_FAILED;
493         }
494
495         engine->vcp_unload_engine = (int (*)())dlsym(engine->handle, "vcp_unload_engine");
496         if ((error = dlerror()) != NULL) {
497                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to link daemon to vcp_unload_engine()");
498                 dlclose(engine->handle);
499                 return VCD_ERROR_OPERATION_FAILED;
500         }
501
502         engine->vcp_load_engine = (int (*)(vcpd_funcs_s*, vcpe_funcs_s*))dlsym(engine->handle, "vcp_load_engine");
503         if (NULL != (error = dlerror()) || NULL == engine->vcp_load_engine) {
504                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to link daemon to vcp_load_engine()");
505                 dlclose(engine->handle);
506                 return VCD_ERROR_OPERATION_FAILED;
507         }
508
509         /* load engine */
510         engine->pdfuncs->version = 1;
511         engine->pdfuncs->size = sizeof(vcpd_funcs_s);
512
513         engine->pdfuncs->foreach_command = __foreach_command;
514         engine->pdfuncs->get_command_count = __command_get_length;
515         engine->pdfuncs->get_audio_type = __get_audio_type;
516
517         if (0 != engine->vcp_load_engine(engine->pdfuncs, engine->pefuncs)) {
518                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail vcp_load_engine()");
519                 dlclose(engine->handle);
520                 return VCD_ERROR_OPERATION_FAILED;
521         }
522
523         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] engine info : version(%d), size(%d)", engine->pefuncs->version, engine->pefuncs->size);
524
525         /* engine error check */
526         if (engine->pefuncs->size != sizeof(vcpe_funcs_s)) {
527                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not valid");
528                 return VCD_ERROR_OPERATION_FAILED;
529         }
530
531         /* Check all engine functions */
532         if (NULL == engine->pefuncs->initialize ||
533                 NULL == engine->pefuncs->deinitialize ||
534                 NULL == engine->pefuncs->foreach_langs ||
535                 NULL == engine->pefuncs->is_lang_supported ||
536                 NULL == engine->pefuncs->set_result_cb ||
537                 NULL == engine->pefuncs->set_language ||
538                 NULL == engine->pefuncs->set_recording ||
539                 NULL == engine->pefuncs->stop ||
540                 NULL == engine->pefuncs->cancel) {
541                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] The current engine is NOT valid");
542                 return VCD_ERROR_OPERATION_FAILED;
543         }
544
545         /* initalize engine */
546         if (0 != engine->pefuncs->initialize()) {
547                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to initialize vc-engine");
548                 return VCD_ERROR_OPERATION_FAILED;
549         }
550
551         if (0 != engine->pefuncs->set_result_cb(__result_cb, NULL)) {
552                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set result callback of vc-engine");
553                 return VCD_ERROR_OPERATION_FAILED;
554         }
555
556         /* load engine */
557         if (true == engine->pefuncs->is_lang_supported(g_default_lang)) {
558                 if (0 != engine->pefuncs->set_language(g_default_lang)) {
559                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to load current engine");
560                         return VCD_ERROR_OPERATION_FAILED;
561                 }
562                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] The %s has been loaded !!!", engine->engine_name);
563                 engine->is_loaded = true;
564         } else {
565                 SLOG(LOG_WARN, TAG_VCD, "[Engine Agent WARNING] This engine do not support default language : lang(%s)", g_default_lang);
566                 engine->is_loaded = false;
567         }
568
569         return 0;
570 }
571
572 int vcd_engine_agent_load_current_engine()
573 {
574         if (false == g_agent_init) {
575                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
576                 return VCD_ERROR_OPERATION_FAILED;
577         }
578
579         if (true == g_dynamic_engine.is_set) {
580                 if (0 != __load_engine(&g_dynamic_engine)) {
581                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to load dynamic engine");
582
583                         /* need to initialize dynamic engine data */
584                         g_dynamic_engine.is_loaded = false;
585                 } else {
586                         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Load dynamic engine");
587                 }
588         }
589
590         return 0;
591 }
592
593 int vcd_engine_agent_unload_current_engine()
594 {
595         if (false == g_agent_init) {
596                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized ");
597                 return VCD_ERROR_OPERATION_FAILED;
598         }
599
600         if (true == g_dynamic_engine.is_set) {
601                 /* unload dynamic engine */
602                 if (true == g_dynamic_engine.is_loaded) {
603                         /* shutdown engine */
604                         g_dynamic_engine.pefuncs->deinitialize();
605                         g_dynamic_engine.vcp_unload_engine();
606                         dlclose(g_dynamic_engine.handle);
607                         g_dynamic_engine.handle = NULL;
608                         g_dynamic_engine.is_loaded = false;
609                 }
610         }
611         return 0;
612 }
613
614
615 /*
616 * VCS Engine Interfaces for client
617 */
618
619 int vcd_engine_set_commands()
620 {
621         if (false == g_agent_init) {
622                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
623                 return VCD_ERROR_OPERATION_FAILED;
624         }
625
626         int ret = -1;
627
628         if (true == g_dynamic_engine.is_loaded) {
629                 /* Set dynamic command */
630                 ret = g_dynamic_engine.pefuncs->set_commands((vcp_cmd_h)0);
631                 if (0 != ret) {
632                         SLOG(LOG_WARN, TAG_VCD, "[Engine Agent ERROR] Fail to set command of dynamic engine : error(%d)", ret);
633                         g_dynamic_engine.is_command_ready = false;
634                 } else {
635                         g_dynamic_engine.is_command_ready = true;
636                 }
637
638                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] set command");
639         } else {
640                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Dynamic engine is not available");
641         }
642
643         return 0;
644 }
645
646 int vcd_engine_recognize_start(bool silence)
647 {
648         if (false == g_agent_init) {
649                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
650                 return VCD_ERROR_OPERATION_FAILED;
651         }
652
653         int ret = -1;
654         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] silence is %s", silence ? "true" : "false");
655
656         if (true == g_dynamic_engine.is_loaded && true == g_dynamic_engine.is_command_ready) {
657                 ret = g_dynamic_engine.pefuncs->start(silence);
658                 if (0 != ret) {
659                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] Fail to start engine error(%d)", ret);
660                         return VCD_ERROR_OPERATION_FAILED;
661                 }
662         } else {
663                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Engine is not available (Cannot start)");
664                 return VCD_ERROR_OPERATION_FAILED;
665         }
666
667         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Engine start");
668         return 0;
669 }
670
671 int vcd_engine_recognize_audio(const void* data, unsigned int length, vcp_speech_detect_e* speech_detected)
672 {
673         if (false == g_agent_init) {
674                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
675                 return VCD_ERROR_OPERATION_FAILED;
676         }
677
678         if (NULL == data) {
679                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
680                 return VCD_ERROR_INVALID_PARAMETER;
681         }
682
683         int ret = -1;
684
685         if (true == g_dynamic_engine.is_loaded) {
686                 ret = g_dynamic_engine.pefuncs->set_recording(data, length, speech_detected);
687                 if (0 != ret) {
688                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set recording dynamic engine error(%d)", ret);
689                         return VCD_ERROR_OPERATION_FAILED;
690                 }
691         }
692
693         return 0;
694 }
695
696 int vcd_engine_recognize_stop()
697 {
698         if (false == g_agent_init) {
699                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
700                 return VCD_ERROR_OPERATION_FAILED;
701         }
702
703         if (true == g_dynamic_engine.is_loaded) {
704                 int ret = -1;
705                 ret = g_dynamic_engine.pefuncs->stop();
706                 if (0 != ret) {
707                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to stop dynamic engine error(%d)", ret);
708                         return VCD_ERROR_OPERATION_FAILED;
709                 }
710         } else {
711                 SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Dynamic engine is not recording state");
712                 return VCD_ERROR_OPERATION_FAILED;
713         }
714
715         return 0;
716 }
717
718 int vcd_engine_recognize_cancel()
719 {
720         if (false == g_agent_init) {
721                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
722                 return VCD_ERROR_OPERATION_FAILED;
723         }
724
725         int ret = -1;
726         if (true == g_dynamic_engine.is_loaded) {
727                 ret = g_dynamic_engine.pefuncs->cancel();
728                 if (0 != ret) {
729                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to cancel dynamic engine error(%d)", ret);
730                 }
731         }
732
733         return 0;
734 }
735
736
737 /*
738 * VCS Engine Interfaces for client and setting
739 */
740
741 int vcd_engine_get_audio_format(const char* audio_id, vcp_audio_type_e* types, int* rate, int* channels)
742 {
743         if (false == g_agent_init) {
744                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
745                 return VCD_ERROR_OPERATION_FAILED;
746         }
747
748         if (true != g_dynamic_engine.is_loaded) {
749                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded");
750         }
751
752         if (NULL == g_dynamic_engine.pefuncs->get_recording_format) {
753                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] The function of engine is NULL!!");
754                 return VCD_ERROR_OPERATION_FAILED;
755         }
756
757         int ret = g_dynamic_engine.pefuncs->get_recording_format(audio_id, types, rate, channels);
758         if (0 != ret) {
759                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] get recording format(%d)", ret);
760                 return VCD_ERROR_OPERATION_FAILED;
761         }
762
763         return 0;
764 }
765
766 bool __supported_language_cb(const char* language, void* user_data)
767 {
768         GList** lang_list = (GList**)user_data;
769
770         if (NULL == language || NULL == lang_list) {
771                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Input parameter is NULL in callback!!!!");
772                 return false;
773         }
774
775         SLOG(LOG_DEBUG, TAG_VCD, "-- Language(%s)", language);
776
777         char* temp_lang = g_strdup(language);
778
779         *lang_list = g_list_append(*lang_list, temp_lang);
780
781         return true;
782 }
783
784 int vcd_engine_supported_langs(GList** lang_list)
785 {
786         if (false == g_agent_init) {
787                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
788                 return VCD_ERROR_OPERATION_FAILED;
789         }
790
791         if (true != g_dynamic_engine.is_loaded) {
792                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded");
793         }
794
795         if (NULL == g_dynamic_engine.pefuncs->foreach_langs) {
796                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] The function of engine is NULL!!");
797                 return VCD_ERROR_OPERATION_FAILED;
798         }
799
800         int ret = g_dynamic_engine.pefuncs->foreach_langs(__supported_language_cb, (void*)lang_list);
801         if (0 != ret) {
802                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] get language list error(%d)", ret);
803                 return VCD_ERROR_OPERATION_FAILED;
804         }
805
806         return 0;
807 }
808
809
810 int vcd_engine_get_current_language(char** lang)
811 {
812         if (false == g_agent_init) {
813                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
814                 return VCD_ERROR_OPERATION_FAILED;
815         }
816
817         if (NULL == lang) {
818                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
819                 return VCD_ERROR_INVALID_PARAMETER;
820         }
821
822         /* get default language */
823         *lang = g_strdup(g_default_lang);
824
825         return 0;
826 }
827
828 int vcd_engine_set_current_language(const char* language)
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 (NULL == language) {
836                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
837                 return VCD_ERROR_INVALID_PARAMETER;
838         }
839
840         int ret;
841
842         if (true == g_dynamic_engine.is_loaded) {
843                 g_dynamic_engine.is_command_ready = false;
844
845                 ret = g_dynamic_engine.pefuncs->set_language(language);
846                 if (0 != ret) {
847                         SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Fail to set language of dynamic engine error(%d, %s)", ret, language);
848                 }
849         } else {
850                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Dynamic engine is not available (Cannot start)");
851         }
852
853         return 0;
854 }
855
856 void __free_language_list(GList* lang_list)
857 {
858         GList *iter = NULL;
859         char* data = NULL;
860
861         /* if list have item */
862         if (g_list_length(lang_list) > 0) {
863                 /* Get a first item */
864                 iter = g_list_first(lang_list);
865
866                 while (NULL != iter) {
867                         data = iter->data;
868
869                         if (NULL != data)
870                                 free(data);
871
872                         lang_list = g_list_remove_link(lang_list, iter);
873
874                         iter = g_list_first(lang_list);
875                 }
876         }
877 }
878
879 int __log_enginelist()
880 {
881         GList *iter = NULL;
882         vcengine_info_s *data = NULL;
883
884         if (0 < g_list_length(g_engine_list)) {
885
886                 /* Get a first item */
887                 iter = g_list_first(g_engine_list);
888
889                 SLOG(LOG_DEBUG, TAG_VCD, "--------------- engine list -------------------");
890
891                 int i = 1;
892                 while (NULL != iter) {
893                         /* Get handle data from list */
894                         data = iter->data;
895
896                         SLOG(LOG_DEBUG, TAG_VCD, "[%dth]", i);
897                         SLOG(LOG_DEBUG, TAG_VCD, "  engine uuid : %s", data->engine_uuid);
898                         SLOG(LOG_DEBUG, TAG_VCD, "  engine name : %s", data->engine_name);
899                         SLOG(LOG_DEBUG, TAG_VCD, "  engine path : %s", data->engine_path);
900                         iter = g_list_next(iter);
901                         i++;
902                 }
903                 SLOG(LOG_DEBUG, TAG_VCD, "----------------------------------------------");
904         } else {
905                 SLOG(LOG_DEBUG, TAG_VCD, "-------------- engine list -------------------");
906                 SLOG(LOG_DEBUG, TAG_VCD, "  No Engine in engine directory");
907                 SLOG(LOG_DEBUG, TAG_VCD, "----------------------------------------------");
908         }
909
910         return 0;
911 }
912
913
914
915