check null before use when dbus close connection
[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 #include "vcd_dbus.h"
27
28 /*
29  * Internal data structure
30  */
31 typedef struct {
32         /* engine info */
33         char*   engine_uuid;
34         char*   engine_name;
35         char*   engine_path;
36
37         /* engine load info */
38         bool    is_set;
39         bool    is_loaded;
40         bool    is_command_ready;
41         void    *handle;
42
43         vc_engine_callback_s* callbacks;
44 } vcengine_s;
45
46 typedef struct _vcengine_info {
47         char*   engine_uuid;
48         char*   engine_path;
49         char*   engine_name;
50 } vcengine_info_s;
51
52
53 /*
54  * static data
55  */
56
57 /** vc engine agent init */
58 static bool g_agent_init;
59
60 /** current engine information */
61 static vcengine_s g_dynamic_engine;
62
63 static char* g_default_lang;
64
65 bool __supported_language_cb(const char* language, void* user_data);
66
67 /*
68  * Internal Interfaces
69  */
70
71 /** get engine info */
72 int __internal_get_engine_info(vce_request_callback_s* callback);
73
74 /*
75  * VCS Engine Agent Interfaces
76  */
77 int vcd_engine_agent_init()
78 {
79         if (true == g_agent_init) {
80                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Already initialized");
81                 return VCD_ERROR_NONE;
82         }
83
84         /* init dynamic engine */
85         g_dynamic_engine.engine_uuid = NULL;
86         g_dynamic_engine.engine_name = NULL;
87         g_dynamic_engine.engine_path = NULL;
88
89         g_dynamic_engine.is_set = false;
90         g_dynamic_engine.is_loaded = false;
91         g_dynamic_engine.handle = NULL;
92         g_dynamic_engine.is_command_ready = false;
93
94         g_dynamic_engine.callbacks = (vc_engine_callback_s*)calloc(1, sizeof(vc_engine_callback_s));
95         if (NULL == g_dynamic_engine.callbacks) {
96                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] Fail to allocate memory");
97                 return VCD_ERROR_OUT_OF_MEMORY;
98         }
99
100         g_agent_init = true;
101
102         if (0 != vcd_config_get_default_language(&g_default_lang)) {
103                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] There is No default voice in config");
104                 /* Set default voice */
105                 g_default_lang = strdup(VC_BASE_LANGUAGE);
106         }
107
108         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Engine Agent Initialize");
109
110         return 0;
111 }
112
113 int vcd_engine_agent_release()
114 {
115         if (false == g_agent_init) {
116                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
117                 return VCD_ERROR_OPERATION_FAILED;
118         }
119
120         /* unload current engine */
121         vcd_engine_agent_unload_current_engine();
122
123         /* release current engine data */
124         if (NULL != g_dynamic_engine.callbacks) {
125                 free(g_dynamic_engine.callbacks);
126                 g_dynamic_engine.callbacks = NULL;
127         }
128
129         g_agent_init = false;
130
131         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Engine Agent release");
132
133         return 0;
134 }
135
136 bool vcd_engine_is_available_engine()
137 {
138         if (true == g_dynamic_engine.is_loaded)
139                 return true;
140
141         return false;
142 }
143
144 int __internal_get_engine_info(vce_request_callback_s* callback)
145 {
146         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] inside __internal_get_engine_info");
147
148         if (NULL == callback) {
149                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid engine");
150                 return VCD_ERROR_ENGINE_NOT_FOUND;
151         }
152
153         if (NULL == callback->get_info) {
154                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid engine");
155                 return VCD_ERROR_ENGINE_NOT_FOUND;
156         }
157
158         if (0 != callback->get_info(&(g_dynamic_engine.engine_uuid), &(g_dynamic_engine.engine_name))) {
159                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get engine info");
160                 return VCD_ERROR_ENGINE_NOT_FOUND;
161         }
162
163         if (NULL != g_dynamic_engine.callbacks) {
164                 free(g_dynamic_engine.callbacks);
165                 g_dynamic_engine.callbacks = NULL;
166         }
167         g_dynamic_engine.callbacks = (vc_engine_callback_s*)calloc(1, sizeof(vc_engine_callback_s));
168         if (NULL == g_dynamic_engine.callbacks) {
169                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to allocate memory");
170                 return VCD_ERROR_OUT_OF_MEMORY;
171         }
172
173         g_dynamic_engine.callbacks->get_info = callback->get_info;
174         g_dynamic_engine.callbacks->get_recording_format = callback->get_recording_format;
175         g_dynamic_engine.callbacks->foreach_langs = callback->foreach_langs;
176         g_dynamic_engine.callbacks->is_lang_supported = callback->is_lang_supported;
177         g_dynamic_engine.callbacks->initialize = callback->initialize;
178         g_dynamic_engine.callbacks->deinitialize = callback->deinitialize;
179         g_dynamic_engine.callbacks->set_language = callback->set_language;
180         g_dynamic_engine.callbacks->set_commands = callback->set_commands;
181         g_dynamic_engine.callbacks->unset_commands = callback->unset_commands;
182
183         g_dynamic_engine.callbacks->start = callback->start;
184         g_dynamic_engine.callbacks->set_recording = callback->set_recording;
185         g_dynamic_engine.callbacks->stop = callback->stop;
186         g_dynamic_engine.callbacks->cancel = callback->cancel;
187         g_dynamic_engine.callbacks->set_domain = callback->set_domain;
188         g_dynamic_engine.callbacks->set_audio_type = callback->set_audio_type;
189         g_dynamic_engine.callbacks->process_text = callback->process_text;
190         g_dynamic_engine.callbacks->process_list_event = callback->process_list_event;
191         g_dynamic_engine.callbacks->process_haptic_event = callback->process_haptic_event;
192
193         g_dynamic_engine.callbacks->private_data_set = NULL;
194         g_dynamic_engine.callbacks->private_data_request = NULL;
195         g_dynamic_engine.callbacks->nlu_base_info_request = NULL;
196
197         SLOG(LOG_DEBUG, TAG_VCD, "@@@ Valid Engine");
198         SLOG(LOG_DEBUG, TAG_VCD, "Engine uuid : %s", g_dynamic_engine.engine_uuid);
199         SLOG(LOG_DEBUG, TAG_VCD, "Engine name : %s", g_dynamic_engine.engine_name);
200         SLOG(LOG_DEBUG, TAG_VCD, "@@@");
201
202         return 0;
203 }
204
205 int vcd_engine_agent_load_current_engine(vce_request_callback_s* callback)
206 {
207         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] load current engine START");
208
209         if (false == g_agent_init) {
210                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
211                 return VCD_ERROR_OPERATION_FAILED;
212         }
213
214         if (true == g_dynamic_engine.is_loaded) {
215                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] Engine has already been loaded");
216                 return 0;
217         }
218
219         if (NULL == callback) {
220                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid engine");
221                 return VCD_ERROR_ENGINE_NOT_FOUND;
222         }
223
224         /* Get current engine info */
225         int ret = __internal_get_engine_info(callback);
226         if (0 != ret) {
227                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get engine info");
228                 return ret;
229         }
230
231         /* Check all engine functions */
232         if (NULL == g_dynamic_engine.callbacks->get_info ||
233                         NULL == g_dynamic_engine.callbacks->get_recording_format ||
234                         NULL == g_dynamic_engine.callbacks->foreach_langs ||
235                         NULL == g_dynamic_engine.callbacks->is_lang_supported ||
236                         NULL == g_dynamic_engine.callbacks->initialize ||
237                         NULL == g_dynamic_engine.callbacks->deinitialize ||
238                         NULL == g_dynamic_engine.callbacks->set_language ||
239                         NULL == g_dynamic_engine.callbacks->set_commands ||
240                         NULL == g_dynamic_engine.callbacks->unset_commands ||
241                         NULL == g_dynamic_engine.callbacks->start ||
242                         NULL == g_dynamic_engine.callbacks->set_recording ||
243                         NULL == g_dynamic_engine.callbacks->stop ||
244                         NULL == g_dynamic_engine.callbacks->cancel ||
245                         NULL == g_dynamic_engine.callbacks->set_audio_type ||
246                         NULL == g_dynamic_engine.callbacks->set_domain ||
247                         NULL == g_dynamic_engine.callbacks->process_text ||
248                         NULL == g_dynamic_engine.callbacks->process_list_event ||
249                         NULL == g_dynamic_engine.callbacks->process_haptic_event) {
250                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] The current engine is NOT valid");
251                 return VCD_ERROR_ENGINE_NOT_FOUND;
252         }
253
254         /* initalize engine */
255         ret = g_dynamic_engine.callbacks->initialize();
256         if (0 != ret) {
257                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to initialize vc engine service");
258                 return ret;
259         }
260
261         /* set the supported language */
262         if (true == g_dynamic_engine.callbacks->is_lang_supported(g_default_lang)) {
263                 ret = g_dynamic_engine.callbacks->set_language(g_default_lang);
264                 if (0 != ret) {
265                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set the supported language");
266                         return ret;
267                 }
268
269                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] The %s has been loaded!!!", g_dynamic_engine.engine_name);
270                 g_dynamic_engine.is_loaded = true;
271         } else {
272                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent WARNING] This engine do not support default language : lang(%s)", g_default_lang);
273                 g_dynamic_engine.is_loaded = false;
274                 return VCD_ERROR_OPERATION_FAILED;
275         }
276
277         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] load current engine FINISH");
278
279         return 0;
280 }
281
282 int vcd_engine_agent_unload_current_engine()
283 {
284         if (false == g_agent_init) {
285                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
286                 return VCD_ERROR_OPERATION_FAILED;
287         }
288
289         if (false == g_dynamic_engine.is_loaded) {
290                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Engine has already been unloaded");
291                 return VCD_ERROR_NONE;
292         }
293
294         /* shut down engine */
295         int ret = 0;
296         ret = g_dynamic_engine.callbacks->deinitialize();
297         if (0 != ret) {
298                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to deinitialize");
299         }
300
301         /* reset current engine data */
302         g_dynamic_engine.is_loaded = false;
303
304         return 0;
305 }
306
307
308 /*
309  * VCS Engine Interfaces for client
310  */
311
312 int vcd_engine_set_commands()
313 {
314         if (false == g_agent_init) {
315                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
316                 return VCD_ERROR_OPERATION_FAILED;
317         }
318
319         int ret = -1;
320
321         if (true == g_dynamic_engine.is_loaded) {
322                 /* Set dynamic command */
323                 ret = g_dynamic_engine.callbacks->set_commands((vce_cmd_h)0);
324                 if (0 != ret) {
325                         SLOG(LOG_WARN, TAG_VCD, "[Engine Agent ERROR] Fail to set command of dynamic engine : error(%d)", ret);
326                         g_dynamic_engine.is_command_ready = false;
327                 } else {
328                         g_dynamic_engine.is_command_ready = true;
329                 }
330
331                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] set command");
332         } else {
333                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Dynamic engine is not available");
334         }
335
336         return 0;
337 }
338
339 int vcd_engine_recognize_start(bool silence)
340 {
341         if (false == g_agent_init) {
342                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
343                 return VCD_ERROR_OPERATION_FAILED;
344         }
345
346         int ret = -1;
347         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] silence is %s", silence ? "true" : "false");
348
349         if (true == g_dynamic_engine.is_loaded && true == g_dynamic_engine.is_command_ready) {
350                 ret = g_dynamic_engine.callbacks->start(silence);
351                 if (0 != ret) {
352                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] Fail to start engine error(%d)", ret);
353                         return VCD_ERROR_OPERATION_FAILED;
354                 }
355         } else {
356                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Engine is not available (Cannot start)");
357                 return VCD_ERROR_OPERATION_FAILED;
358         }
359
360         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Engine start");
361         return 0;
362 }
363
364 int vcd_engine_recognize_audio(const void* data, unsigned int length, vce_speech_detect_e* speech_detected)
365 {
366         if (false == g_agent_init) {
367                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
368                 return VCD_ERROR_OPERATION_FAILED;
369         }
370
371         if (NULL == data) {
372                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
373                 return VCD_ERROR_INVALID_PARAMETER;
374         }
375
376         int ret = -1;
377
378         if (true == g_dynamic_engine.is_loaded) {
379                 ret = g_dynamic_engine.callbacks->set_recording(data, length, speech_detected);
380                 if (0 != ret) {
381                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set recording dynamic engine error(%d)", ret);
382                         if (VCE_ERROR_OUT_OF_NETWORK == ret) {
383                                 return VCD_ERROR_TIMED_OUT;
384                         }
385                         return VCD_ERROR_OPERATION_FAILED;
386                 }
387         }
388
389         return 0;
390 }
391
392 int vcd_engine_recognize_stop()
393 {
394         if (false == g_agent_init) {
395                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
396                 return VCD_ERROR_OPERATION_FAILED;
397         }
398
399         if (true == g_dynamic_engine.is_loaded) {
400                 int ret = -1;
401                 ret = g_dynamic_engine.callbacks->stop();
402                 if (0 != ret) {
403                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to stop dynamic engine error(%d)", ret);
404                         return VCD_ERROR_OPERATION_FAILED;
405                 }
406         } else {
407                 SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Dynamic engine is not recording state");
408                 return VCD_ERROR_OPERATION_FAILED;
409         }
410
411         return 0;
412 }
413
414 int vcd_engine_recognize_cancel()
415 {
416         if (false == g_agent_init) {
417                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
418                 return VCD_ERROR_OPERATION_FAILED;
419         }
420
421         int ret = -1;
422         if (true == g_dynamic_engine.is_loaded) {
423                 ret = g_dynamic_engine.callbacks->cancel();
424                 if (0 != ret) {
425                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to cancel dynamic engine error(%d)", ret);
426                         return VCD_ERROR_OPERATION_FAILED;
427                 }
428         }
429
430         return 0;
431 }
432
433 int vcd_engine_set_audio_type(const char* audio)
434 {
435         if (false == g_agent_init) {
436                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
437                 return VCD_ERROR_OPERATION_FAILED;
438         }
439
440         int ret = -1;
441         if (true == g_dynamic_engine.is_loaded) {
442                 ret = g_dynamic_engine.callbacks->set_audio_type(audio);
443                 if (0 != ret) {
444                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set audio type(%d)", ret);
445                         return VCD_ERROR_OPERATION_FAILED;
446                 }
447         }
448
449         return 0;
450 }
451
452 int vcd_engine_set_domain(int pid, const char* domain)
453 {
454         if (false == g_agent_init) {
455                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
456                 return VCD_ERROR_OPERATION_FAILED;
457         }
458
459         int ret = -1;
460         if (true == g_dynamic_engine.is_loaded) {
461                 ret = g_dynamic_engine.callbacks->set_domain(domain);
462                 if (0 != ret) {
463                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set domain (%d)", ret);
464                         return VCD_ERROR_OPERATION_FAILED;
465                 }
466         }
467
468         return 0;
469 }
470
471 int vcd_engine_get_nlu_base_info(int pid, const char* key, char** value)
472 {
473         if (NULL == value) {
474                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
475                 return VCD_ERROR_INVALID_PARAMETER;
476         }
477
478         if (false == g_agent_init) {
479                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
480                 return VCD_ERROR_OPERATION_FAILED;
481         }
482
483         int ret = -1;
484         if (true == g_dynamic_engine.is_loaded && NULL != g_dynamic_engine.callbacks->nlu_base_info_request) {
485                 ret = g_dynamic_engine.callbacks->nlu_base_info_request(key, value);
486                 if (0 != ret) {
487                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get nlu base info (%d)", ret);
488                         return VCD_ERROR_OPERATION_FAILED;
489                 }
490         } else {
491                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded or There is no nlu_base_info_request callback");
492                 return VCD_ERROR_OPERATION_FAILED;
493         }
494
495         return 0;
496 }
497
498 int vcd_engine_set_private_data(int pid, const char* key, const char* data)
499 {
500         if (false == g_agent_init) {
501                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
502                 return VCD_ERROR_OPERATION_FAILED;
503         }
504
505         int ret = -1;
506         if (true == g_dynamic_engine.is_loaded && NULL != g_dynamic_engine.callbacks->private_data_set) {
507                 ret = g_dynamic_engine.callbacks->private_data_set(key, data);
508                 if (0 != ret) {
509                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set private data (%d)", ret);
510                         return VCD_ERROR_OPERATION_FAILED;
511                 }
512         } else {
513                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded or There is no private_data_set callback");
514                 return VCD_ERROR_OPERATION_FAILED;
515         }
516
517         return 0;
518 }
519
520 int vcd_engine_get_private_data(int pid, const char* key, char** data)
521 {
522         if (NULL == data) {
523                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
524                 return VCD_ERROR_INVALID_PARAMETER;
525         }
526
527         if (false == g_agent_init) {
528                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
529                 return VCD_ERROR_OPERATION_FAILED;
530         }
531
532         int ret = -1;
533         if (true == g_dynamic_engine.is_loaded && NULL != g_dynamic_engine.callbacks->private_data_request) {
534                 ret = g_dynamic_engine.callbacks->private_data_request(key, data);
535                 if (0 != ret) {
536                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get private data (%d)", ret);
537                         return VCD_ERROR_OPERATION_FAILED;
538                 }
539         } else {
540                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded or There is no private_data_request callback");
541                 return VCD_ERROR_OPERATION_FAILED;
542         }
543
544         return 0;
545 }
546
547 int vcd_engine_process_text(int pid, const char* text)
548 {
549         if (false == g_agent_init) {
550                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
551                 return VCD_ERROR_OPERATION_FAILED;
552         }
553
554         int ret = -1;
555         if (true == g_dynamic_engine.is_loaded) {
556                 ret = g_dynamic_engine.callbacks->process_text(text);
557                 if (0 != ret) {
558                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to process text (%d)", ret);
559                         return VCD_ERROR_OPERATION_FAILED;
560                 }
561         }
562
563         return 0;
564 }
565
566 int vcd_engine_process_list_event(int pid, const char* event)
567 {
568         if (false == g_agent_init) {
569                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
570                 return VCD_ERROR_OPERATION_FAILED;
571         }
572
573         int ret = -1;
574         if (true == g_dynamic_engine.is_loaded) {
575                 ret = g_dynamic_engine.callbacks->process_list_event(event);
576                 if (0 != ret) {
577                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to process list event (%d)", ret);
578                         return VCD_ERROR_OPERATION_FAILED;
579                 }
580         }
581
582         return 0;
583 }
584
585 int vcd_engine_process_haptic_event(int pid, const char* event)
586 {
587         if (false == g_agent_init) {
588                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
589                 return VCD_ERROR_OPERATION_FAILED;
590         }
591
592         int ret = -1;
593         if (true == g_dynamic_engine.is_loaded) {
594                 ret = g_dynamic_engine.callbacks->process_haptic_event(event);
595                 if (0 != ret) {
596                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to process haptic event (%d)", ret);
597                         return VCD_ERROR_OPERATION_FAILED;
598                 }
599         }
600
601         return 0;
602 }
603
604 /*
605  * VCS Engine Interfaces for client and setting
606  */
607
608 int vcd_engine_get_audio_format(const char* audio_id, vce_audio_type_e* types, int* rate, int* channels)
609 {
610         if (false == g_agent_init) {
611                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
612                 return VCD_ERROR_OPERATION_FAILED;
613         }
614
615         if (true != g_dynamic_engine.is_loaded) {
616                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded");
617         }
618
619         int ret = g_dynamic_engine.callbacks->get_recording_format(audio_id, types, rate, channels);
620         if (0 != ret) {
621                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] get recording format(%d)", ret);
622                 return VCD_ERROR_OPERATION_FAILED;
623         }
624
625         return 0;
626 }
627
628 bool __supported_language_cb(const char* language, void* user_data)
629 {
630         GList** lang_list = (GList**)user_data;
631
632         if (NULL == language || NULL == lang_list) {
633                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Input parameter is NULL in callback!!!!");
634                 return false;
635         }
636
637         SLOG(LOG_DEBUG, TAG_VCD, "-- Language(%s)", language);
638
639         char* temp_lang = g_strdup(language);
640
641         *lang_list = g_list_append(*lang_list, temp_lang);
642
643         return true;
644 }
645
646 int vcd_engine_supported_langs(GList** lang_list)
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         if (true != g_dynamic_engine.is_loaded) {
654                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded");
655         }
656
657         int ret = g_dynamic_engine.callbacks->foreach_langs(__supported_language_cb, (void*)lang_list);
658         if (0 != ret) {
659                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] get language list error(%d)", ret);
660                 return VCD_ERROR_OPERATION_FAILED;
661         }
662
663         return 0;
664 }
665
666
667 int vcd_engine_get_current_language(char** lang)
668 {
669         if (false == g_agent_init) {
670                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
671                 return VCD_ERROR_OPERATION_FAILED;
672         }
673
674         if (NULL == lang) {
675                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
676                 return VCD_ERROR_INVALID_PARAMETER;
677         }
678
679         /* get default language */
680         *lang = g_strdup(g_default_lang);
681
682         return 0;
683 }
684
685 int vcd_engine_set_current_language(const char* language)
686 {
687         if (false == g_agent_init) {
688                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
689                 return VCD_ERROR_OPERATION_FAILED;
690         }
691
692         if (NULL == language) {
693                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
694                 return VCD_ERROR_INVALID_PARAMETER;
695         }
696
697         int ret;
698
699         if (true == g_dynamic_engine.is_loaded) {
700                 g_dynamic_engine.is_command_ready = false;
701
702                 ret = g_dynamic_engine.callbacks->set_language(language);
703                 if (0 != ret) {
704                         SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Fail to set language of dynamic engine error(%d, %s)", ret, language);
705                 }
706         } else {
707                 SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Dynamic engine is not available (Cannot start)");
708         }
709
710         return 0;
711 }
712
713 int vcd_engine_agent_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void* user_data)
714 {
715         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request foreach command from engine");
716         return vcd_client_foreach_command((client_foreach_command_cb)callback, user_data);
717 }
718
719 int vcd_engine_agent_get_command_count(vce_cmd_h vce_command)
720 {
721         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request command length from engine");
722
723         return vcd_client_get_length();
724 }
725
726 int vcd_engine_agent_get_audio_type(char** audio_type)
727 {
728         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request audio type");
729
730         return vcd_recorder_get(audio_type);
731 }
732
733 int vcd_engine_agent_set_private_data(const char* key, const char* data)
734 {
735         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request set private data");
736         vcdc_send_request_set_private_data(vcd_client_manager_get_pid(), key, data);
737
738         return VCD_ERROR_NONE;
739 }
740
741 int vcd_engine_agent_get_private_data(const char* key, char** data)
742 {
743         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request get private data");
744         vcdc_send_request_get_private_data(vcd_client_manager_get_pid(), key, data);
745
746         return VCD_ERROR_NONE;
747 }
748
749 int vcd_engine_agent_start_recording()
750 {
751         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request start recording");
752
753         int ret = vcd_recorder_start();
754         if (0 != ret) {
755                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
756                 vcd_engine_recognize_cancel();
757                 /* Send error cb to manager */
758                 vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_engine.error.proc_fail");
759                 return ret;
760         }
761
762         return VCD_ERROR_NONE;
763 }
764
765 int vcd_engine_agent_stop_recording()
766 {
767         SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request stop recording");
768
769         return vcd_recorder_stop();
770 }
771
772 int vcd_engine_agent_set_private_data_set_cb(vce_private_data_set_cb callback_func)
773 {
774         if (false == g_agent_init) {
775                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
776                 return VCD_ERROR_OPERATION_FAILED;
777         }
778
779         if (false == g_dynamic_engine.is_loaded) {
780                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not loaded engine");
781                 return VCD_ERROR_OPERATION_FAILED;
782         }
783
784         g_dynamic_engine.callbacks->private_data_set = callback_func;
785
786         return VCD_ERROR_NONE;
787 }
788
789 int vcd_engine_agent_set_private_data_requested_cb(vce_private_data_requested_cb callback_func)
790 {
791         if (false == g_agent_init) {
792                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
793                 return VCD_ERROR_OPERATION_FAILED;
794         }
795
796         if (false == g_dynamic_engine.is_loaded) {
797                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not loaded engine");
798                 return VCD_ERROR_OPERATION_FAILED;
799         }
800
801         g_dynamic_engine.callbacks->private_data_request = callback_func;
802
803         return VCD_ERROR_NONE;
804 }
805
806 int vcd_engine_agent_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_func)
807 {
808         if (false == g_agent_init) {
809                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
810                 return VCD_ERROR_OPERATION_FAILED;
811         }
812
813         if (false == g_dynamic_engine.is_loaded) {
814                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not loaded engine");
815                 return VCD_ERROR_OPERATION_FAILED;
816         }
817
818         g_dynamic_engine.callbacks->nlu_base_info_request = callback_func;
819
820         return VCD_ERROR_NONE;
821 }
822