Deallocate memory before setting new value
[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_tidl.h"
27 #include "vce_internal.h"
28
29 /*
30  * Internal data structure
31  */
32 typedef struct {
33         /* engine info */
34         char*   engine_uuid;
35         char*   engine_name;
36         char*   engine_path;
37         char*   engine_setting_path;
38
39         /* engine load info */
40         bool    is_set;
41         bool    is_loaded;
42         bool    is_command_ready;
43         bool    use_network;
44         void    *handle;
45
46         vce_request_callback_s* callbacks;
47         vce_internal_request_callback_s* internal_callbacks;
48 } vcengine_s;
49
50 typedef struct _vcengine_info {
51         char*   engine_uuid;
52         char*   engine_path;
53         char*   engine_name;
54 } vcengine_info_s;
55
56
57 /*
58  * static data
59  */
60
61 /** vc engine agent init */
62 static bool g_agent_init;
63
64 /** current engine information */
65 static vcengine_s g_dynamic_engine;
66
67 static char* g_default_lang;
68
69 static bool __supported_language_cb(const char* language, void* user_data);
70
71 /*
72  * Internal Interfaces
73  */
74
75 /** get engine info */
76 static int __internal_get_engine_info(vce_request_callback_s* callback);
77
78 /*
79  * VCS Engine Agent Interfaces
80  */
81 int vcd_engine_agent_init()
82 {
83         if (true == g_agent_init) {
84                 SLOG(LOG_INFO, TAG_VCD, "[Engine Agent] Already initialized");
85                 return VCD_ERROR_NONE;
86         }
87
88         /* init dynamic engine */
89         g_dynamic_engine.engine_uuid = NULL;
90         g_dynamic_engine.engine_name = NULL;
91         g_dynamic_engine.engine_setting_path = NULL;
92         g_dynamic_engine.engine_path = NULL;
93
94         g_dynamic_engine.is_set = false;
95         g_dynamic_engine.is_loaded = false;
96         g_dynamic_engine.handle = NULL;
97         g_dynamic_engine.is_command_ready = false;
98
99         g_dynamic_engine.callbacks = (vce_request_callback_s*)calloc(1, sizeof(vce_request_callback_s));
100         if (NULL == g_dynamic_engine.callbacks) {
101                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] Fail to allocate memory for callbacks");
102                 return VCD_ERROR_OUT_OF_MEMORY;
103         }
104
105         g_dynamic_engine.internal_callbacks = (vce_internal_request_callback_s*)calloc(1, sizeof(vce_internal_request_callback_s));
106         if (NULL == g_dynamic_engine.internal_callbacks) {
107                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] Fail to allocate memory for internal callbacks");
108                 return VCD_ERROR_OUT_OF_MEMORY;
109         }
110
111         g_agent_init = true;
112
113         if (0 != vcd_config_get_default_language(&g_default_lang)) {
114                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] There is No default voice in config");
115                 /* Set default voice */
116                 g_default_lang = strdup(VC_BASE_LANGUAGE);
117                 if (NULL == g_default_lang) {
118                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] Fail to allocate memory");
119                         return VCD_ERROR_OUT_OF_MEMORY;
120                 }
121         }
122
123         SLOG(LOG_INFO, TAG_VCD, "[Engine Agent SUCCESS] Engine Agent Initialize");
124
125         return VCD_ERROR_NONE;
126 }
127
128 int vcd_engine_agent_release()
129 {
130         if (false == g_agent_init) {
131                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
132                 return VCD_ERROR_OPERATION_FAILED;
133         }
134
135         /* unload current engine */
136         if (0 != vcd_engine_agent_unload_current_engine()) {
137                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to deinitialize");
138                 return VCD_ERROR_OPERATION_FAILED;
139         }
140
141         /* release current engine data */
142         if (NULL != g_dynamic_engine.callbacks) {
143                 free(g_dynamic_engine.callbacks);
144                 g_dynamic_engine.callbacks = NULL;
145         }
146         if (NULL != g_dynamic_engine.engine_uuid) {
147                 free(g_dynamic_engine.engine_uuid);
148                 g_dynamic_engine.engine_uuid = NULL;
149         }
150         if (NULL != g_dynamic_engine.engine_name) {
151                 free(g_dynamic_engine.engine_name);
152                 g_dynamic_engine.engine_name = NULL;
153         }
154         if (NULL != g_dynamic_engine.engine_setting_path) {
155                 free(g_dynamic_engine.engine_setting_path);
156                 g_dynamic_engine.engine_setting_path = NULL;
157         }
158
159         g_agent_init = false;
160
161         SLOG(LOG_INFO, TAG_VCD, "[Engine Agent SUCCESS] Engine Agent release");
162
163         return VCD_ERROR_NONE;
164 }
165
166 bool vcd_engine_is_available_engine()
167 {
168         if (true == g_dynamic_engine.is_loaded)
169                 return true;
170
171         return false;
172 }
173
174 static int __internal_get_engine_info(vce_request_callback_s* callback)
175 {
176         SLOG(LOG_INFO, TAG_VCD, "[Engine Agent] inside __internal_get_engine_info");
177
178         if (NULL == callback) {
179                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid engine");
180                 return VCD_ERROR_ENGINE_NOT_FOUND;
181         }
182
183         if (NULL == callback->get_info) {
184                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid engine");
185                 return VCD_ERROR_ENGINE_NOT_FOUND;
186         }
187
188         if (0 != callback->get_info(&(g_dynamic_engine.engine_uuid), &(g_dynamic_engine.engine_name), &(g_dynamic_engine.engine_setting_path), &(g_dynamic_engine.use_network))) {
189                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get engine info");
190                 return VCD_ERROR_ENGINE_NOT_FOUND;
191         }
192
193         if (NULL != g_dynamic_engine.callbacks) {
194                 free(g_dynamic_engine.callbacks);
195                 g_dynamic_engine.callbacks = NULL;
196         }
197         g_dynamic_engine.callbacks = (vce_request_callback_s*)calloc(1, sizeof(vce_request_callback_s));
198         if (NULL == g_dynamic_engine.callbacks) {
199                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to allocate memory for callbacks");
200                 return VCD_ERROR_OUT_OF_MEMORY;
201         }
202
203         if (NULL != g_dynamic_engine.internal_callbacks) {
204                 free(g_dynamic_engine.internal_callbacks);
205                 g_dynamic_engine.internal_callbacks = NULL;
206         }
207         g_dynamic_engine.internal_callbacks = (vce_internal_request_callback_s*)calloc(1, sizeof(vce_internal_request_callback_s));
208         if (NULL == g_dynamic_engine.internal_callbacks) {
209                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to allocate memory for internal callbacks");
210                 return VCD_ERROR_OUT_OF_MEMORY;
211         }
212
213         g_dynamic_engine.callbacks->get_info = callback->get_info;
214         g_dynamic_engine.callbacks->get_recording_format = callback->get_recording_format;
215         g_dynamic_engine.callbacks->foreach_langs = callback->foreach_langs;
216         g_dynamic_engine.callbacks->is_lang_supported = callback->is_lang_supported;
217         g_dynamic_engine.callbacks->initialize = callback->initialize;
218         g_dynamic_engine.callbacks->deinitialize = callback->deinitialize;
219         g_dynamic_engine.callbacks->set_language = callback->set_language;
220         g_dynamic_engine.callbacks->set_commands = callback->set_commands;
221         g_dynamic_engine.callbacks->unset_commands = callback->unset_commands;
222
223         g_dynamic_engine.callbacks->start = callback->start;
224         g_dynamic_engine.callbacks->set_recording = callback->set_recording;
225         g_dynamic_engine.callbacks->stop = callback->stop;
226         g_dynamic_engine.callbacks->cancel = callback->cancel;
227         g_dynamic_engine.callbacks->set_domain = callback->set_domain;
228         g_dynamic_engine.callbacks->set_audio_type = callback->set_audio_type;
229         g_dynamic_engine.callbacks->set_server_dialog = callback->set_server_dialog;
230         g_dynamic_engine.callbacks->process_text = callback->process_text;
231         g_dynamic_engine.callbacks->process_list_event = callback->process_list_event;
232         g_dynamic_engine.callbacks->process_haptic_event = callback->process_haptic_event;
233
234         g_dynamic_engine.internal_callbacks->private_data_set = NULL;
235         g_dynamic_engine.internal_callbacks->private_data_request = NULL;
236         g_dynamic_engine.internal_callbacks->nlu_base_info_request = NULL;
237         g_dynamic_engine.internal_callbacks->specific_engine_request = NULL;
238
239         g_dynamic_engine.internal_callbacks->request_tts = NULL;
240         g_dynamic_engine.internal_callbacks->request_tts_user_data = NULL;
241         g_dynamic_engine.internal_callbacks->cancel_tts = NULL;
242         g_dynamic_engine.internal_callbacks->cancel_tts_user_data = NULL;
243         g_dynamic_engine.internal_callbacks->get_tts_audio_format = NULL;
244         g_dynamic_engine.internal_callbacks->get_tts_audio_format_user_data = NULL;
245
246         SLOG(LOG_INFO, TAG_VCD, "@@@ Valid Engine");
247         SLOG(LOG_INFO, TAG_VCD, "Engine uuid : %s", g_dynamic_engine.engine_uuid);
248         SLOG(LOG_INFO, TAG_VCD, "Engine name : %s", g_dynamic_engine.engine_name);
249         SLOG(LOG_INFO, TAG_VCD, "Engine setting : %s", g_dynamic_engine.engine_setting_path);
250         SLOG(LOG_INFO, TAG_VCD, "@@@");
251
252         return VCD_ERROR_NONE;
253 }
254
255 int vcd_engine_agent_load_current_engine(vce_request_callback_s* callback)
256 {
257         SLOG(LOG_INFO, TAG_VCD, "[Engine Agent] load current engine START");
258
259         if (false == g_agent_init) {
260                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
261                 return VCD_ERROR_OPERATION_FAILED;
262         }
263
264         if (NULL == callback) {
265                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid engine");
266                 return VCD_ERROR_ENGINE_NOT_FOUND;
267         }
268
269         if (true == g_dynamic_engine.is_loaded) {
270                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] Engine has already been loaded");
271                 return VCD_ERROR_NONE;
272         }
273
274         /* Get current engine info */
275         int ret = __internal_get_engine_info(callback);
276         if (0 != ret) {
277                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get engine info");
278                 return ret;
279         }
280
281         /* Check all engine functions */
282         if (NULL == g_dynamic_engine.callbacks->get_info ||
283                         NULL == g_dynamic_engine.callbacks->get_recording_format ||
284                         NULL == g_dynamic_engine.callbacks->foreach_langs ||
285                         NULL == g_dynamic_engine.callbacks->is_lang_supported ||
286                         NULL == g_dynamic_engine.callbacks->initialize ||
287                         NULL == g_dynamic_engine.callbacks->deinitialize ||
288                         NULL == g_dynamic_engine.callbacks->set_language ||
289                         NULL == g_dynamic_engine.callbacks->set_commands ||
290                         NULL == g_dynamic_engine.callbacks->unset_commands ||
291                         NULL == g_dynamic_engine.callbacks->start ||
292                         NULL == g_dynamic_engine.callbacks->set_recording ||
293                         NULL == g_dynamic_engine.callbacks->stop ||
294                         NULL == g_dynamic_engine.callbacks->cancel ||
295                         NULL == g_dynamic_engine.callbacks->set_audio_type ||
296                         NULL == g_dynamic_engine.callbacks->set_server_dialog ||
297                         NULL == g_dynamic_engine.callbacks->set_domain ||
298                         NULL == g_dynamic_engine.callbacks->process_text ||
299                         NULL == g_dynamic_engine.callbacks->process_list_event ||
300                         NULL == g_dynamic_engine.callbacks->process_haptic_event) {
301                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] The current engine is NOT valid");
302                 return VCD_ERROR_ENGINE_NOT_FOUND;
303         }
304
305         /* initialize engine */
306         ret = g_dynamic_engine.callbacks->initialize();
307         if (0 != ret) {
308                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to initialize vc engine service");
309                 return ret;
310         }
311
312         /* set the supported language */
313         if (true == g_dynamic_engine.callbacks->is_lang_supported(g_default_lang)) {
314                 ret = g_dynamic_engine.callbacks->set_language(g_default_lang);
315                 if (0 != ret) {
316                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set the supported language");
317                         g_dynamic_engine.callbacks->deinitialize();
318                         return ret;
319                 }
320
321                 SLOG(LOG_INFO, TAG_VCD, "[Engine Agent SUCCESS] The %s has been loaded!!!", g_dynamic_engine.engine_name);
322                 g_dynamic_engine.is_loaded = true;
323         } else {
324                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent WARNING] This engine do not support default language : lang(%s)", g_default_lang);
325                 g_dynamic_engine.callbacks->deinitialize();
326                 g_dynamic_engine.is_loaded = false;
327                 return VCD_ERROR_OPERATION_FAILED;
328         }
329
330         SLOG(LOG_INFO, TAG_VCD, "[Engine Agent] load current engine FINISH");
331
332         return VCD_ERROR_NONE;
333 }
334
335 int vcd_engine_agent_unload_current_engine()
336 {
337         if (false == g_agent_init) {
338                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
339                 return VCD_ERROR_OPERATION_FAILED;
340         }
341
342         if (false == g_dynamic_engine.is_loaded) {
343                 SLOG(LOG_INFO, TAG_VCD, "[Engine Agent] Engine has already been unloaded");
344                 return VCD_ERROR_NONE;
345         }
346
347         /* shut down engine */
348         int ret = 0;
349         ret = g_dynamic_engine.callbacks->deinitialize();
350         if (0 != ret) {
351                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to deinitialize");
352         }
353
354         /* reset current engine data */
355         g_dynamic_engine.is_loaded = false;
356
357         return VCD_ERROR_NONE;
358 }
359
360
361 /*
362  * VCS Engine Interfaces for client
363  */
364
365 int vcd_engine_set_commands()
366 {
367         if (false == g_agent_init) {
368                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
369                 return VCD_ERROR_OPERATION_FAILED;
370         }
371
372         int ret = -1;
373
374         if (true == g_dynamic_engine.is_loaded) {
375                 /* Set dynamic command */
376                 ret = g_dynamic_engine.callbacks->set_commands((vce_cmd_h)0);
377                 if (0 != ret) {
378                         SLOG(LOG_WARN, TAG_VCD, "[Engine Agent ERROR] Fail to set command of dynamic engine : error(%d)", ret);
379                         g_dynamic_engine.is_command_ready = false;
380                 } else {
381                         g_dynamic_engine.is_command_ready = true;
382                 }
383
384                 SLOG(LOG_INFO, TAG_VCD, "[Engine Agent SUCCESS] set command");
385         } else {
386                 SLOG(LOG_INFO, TAG_VCD, "[Engine Agent] Dynamic engine is not available");
387         }
388
389         return VCD_ERROR_NONE;
390 }
391
392 int vcd_engine_recognize_start(bool silence)
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         int ret = -1;
400         SLOG(LOG_INFO, TAG_VCD, "[Engine Agent] silence is %s", silence ? "true" : "false");
401
402         if (true == g_dynamic_engine.is_loaded && true == g_dynamic_engine.is_command_ready) {
403                 ret = g_dynamic_engine.callbacks->start(silence);
404                 if (0 != ret) {
405                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] Fail to start engine error(%d)", ret);
406                         return ret;
407                 }
408         } else {
409                 SLOG(LOG_INFO, TAG_VCD, "[Engine Agent] Engine is not available (Cannot start)");
410                 return VCD_ERROR_OPERATION_FAILED;
411         }
412
413         SLOG(LOG_INFO, TAG_VCD, "[Engine Agent SUCCESS] Engine start");
414         return VCD_ERROR_NONE;
415 }
416
417 int vcd_engine_recognize_audio(const void* data, unsigned int length, vce_speech_detect_e* speech_detected)
418 {
419         if (false == g_agent_init) {
420                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
421                 return VCD_ERROR_OPERATION_FAILED;
422         }
423
424         if (NULL == data) {
425                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
426                 return VCD_ERROR_INVALID_PARAMETER;
427         }
428
429         int ret = -1;
430
431         if (true == g_dynamic_engine.is_loaded) {
432                 ret = g_dynamic_engine.callbacks->set_recording(data, length, speech_detected);
433                 if (0 != ret) {
434                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set recording dynamic engine error(%d)", ret);
435                         if (VCE_ERROR_OUT_OF_NETWORK == ret) {
436                                 return VCD_ERROR_TIMED_OUT;
437                         }
438                         return ret;
439                 }
440         }
441
442         return VCD_ERROR_NONE;
443 }
444
445 int vcd_engine_recognize_stop()
446 {
447         if (false == g_agent_init) {
448                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
449                 return VCD_ERROR_OPERATION_FAILED;
450         }
451
452         if (true == g_dynamic_engine.is_loaded) {
453                 int ret = -1;
454                 ret = g_dynamic_engine.callbacks->stop();
455                 if (0 != ret) {
456                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to stop dynamic engine error(%d)", ret);
457                         return ret;
458                 }
459         } else {
460                 SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Dynamic engine is not recording state");
461                 return VCD_ERROR_OPERATION_FAILED;
462         }
463
464         return VCD_ERROR_NONE;
465 }
466
467 int vcd_engine_recognize_cancel()
468 {
469         if (false == g_agent_init) {
470                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
471                 return VCD_ERROR_OPERATION_FAILED;
472         }
473
474         int ret = -1;
475         if (true == g_dynamic_engine.is_loaded) {
476                 ret = g_dynamic_engine.callbacks->cancel();
477                 if (0 != ret) {
478                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to cancel dynamic engine error(%d)", ret);
479                         return ret;
480                 }
481         }
482
483         return VCD_ERROR_NONE;
484 }
485
486 int vcd_engine_set_audio_type(const char* audio)
487 {
488         if (false == g_agent_init) {
489                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
490                 return VCD_ERROR_OPERATION_FAILED;
491         }
492
493         int ret = -1;
494         if (true == g_dynamic_engine.is_loaded) {
495                 ret = g_dynamic_engine.callbacks->set_audio_type(audio);
496                 if (0 != ret) {
497                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set audio type(%d)", ret);
498                         return ret;
499                 }
500         }
501
502         return VCD_ERROR_NONE;
503 }
504
505 int vcd_engine_set_server_dialog(const char* app_id, const char* credential)
506 {
507         if (false == g_agent_init) {
508                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
509                 return VCD_ERROR_OPERATION_FAILED;
510         }
511
512         int ret = -1;
513         if (true == g_dynamic_engine.is_loaded) {
514                 ret = g_dynamic_engine.callbacks->set_server_dialog(app_id, credential);
515                 if (0 != ret) {
516                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set server dialog (%d)", ret);
517                         return ret;
518                 }
519         }
520
521         return VCD_ERROR_NONE;
522 }
523
524 int vcd_engine_set_domain(int pid, const char* domain)
525 {
526         if (false == g_agent_init) {
527                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
528                 return VCD_ERROR_OPERATION_FAILED;
529         }
530
531         int ret = -1;
532         if (true == g_dynamic_engine.is_loaded) {
533                 ret = g_dynamic_engine.callbacks->set_domain(domain);
534                 if (0 != ret) {
535                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set domain (%d)", ret);
536                         return ret;
537                 }
538         }
539
540         return VCD_ERROR_NONE;
541 }
542
543 int vcd_engine_get_nlu_base_info(int pid, const char* key, char** value)
544 {
545         if (NULL == value) {
546                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
547                 return VCD_ERROR_INVALID_PARAMETER;
548         }
549
550         if (false == g_agent_init) {
551                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
552                 return VCD_ERROR_OPERATION_FAILED;
553         }
554
555         int ret = -1;
556         if (true == g_dynamic_engine.is_loaded && NULL != g_dynamic_engine.internal_callbacks->nlu_base_info_request) {
557                 ret = g_dynamic_engine.internal_callbacks->nlu_base_info_request(key, value);
558                 if (0 != ret) {
559                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get nlu base info (%d)", ret);
560                         return ret;
561                 }
562         } else {
563                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent INFO] Engine is not loaded or There is no nlu_base_info_request callback");
564                 return VCD_ERROR_NONE;
565         }
566
567         return VCD_ERROR_NONE;
568 }
569
570 int vcd_engine_set_private_data(int pid, const char* key, const char* data)
571 {
572         if (false == g_agent_init) {
573                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
574                 return VCD_ERROR_OPERATION_FAILED;
575         }
576
577         if (!strncmp(key, "##PpCcMmTestPath", 16))
578                 vcd_recorder_set_pcm_path(data);
579
580         int ret = -1;
581         if (true == g_dynamic_engine.is_loaded && NULL != g_dynamic_engine.internal_callbacks->private_data_set) {
582                 ret = g_dynamic_engine.internal_callbacks->private_data_set(key, data);
583                 if (0 != ret) {
584                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set private data (%d)", ret);
585                         return ret;
586                 }
587         } else {
588                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent INFO] Engine is not loaded or There is no private_data_set callback");
589                 return VCD_ERROR_NONE;
590         }
591
592         return VCD_ERROR_NONE;
593 }
594
595 int vcd_engine_get_private_data(int pid, const char* key, char** data)
596 {
597         if (NULL == data) {
598                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
599                 return VCD_ERROR_INVALID_PARAMETER;
600         }
601
602         if (false == g_agent_init) {
603                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
604                 return VCD_ERROR_OPERATION_FAILED;
605         }
606
607         int ret = -1;
608         if (true == g_dynamic_engine.is_loaded && NULL != g_dynamic_engine.internal_callbacks->private_data_request) {
609                 ret = g_dynamic_engine.internal_callbacks->private_data_request(key, data);
610                 if (0 != ret) {
611                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get private data (%d)", ret);
612                         return ret;
613                 }
614         } else {
615                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent INFO] Engine is not loaded or There is no private_data_request callback");
616                 return VCD_ERROR_NONE;
617         }
618
619         return VCD_ERROR_NONE;
620 }
621
622 int vcd_engine_send_specific_engine_request(const char* engine_app_id, const char* event, const char* request)
623 {
624         if (false == g_agent_init) {
625                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
626                 return VCD_ERROR_OPERATION_FAILED;
627         }
628
629         int ret = -1;
630         if (true == g_dynamic_engine.is_loaded && NULL != g_dynamic_engine.internal_callbacks->specific_engine_request) {
631                 ret = g_dynamic_engine.internal_callbacks->specific_engine_request(engine_app_id, event, request);
632                 if (0 != ret) {
633                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set specific engine request (%d)", ret);
634                         return ret;
635                 }
636         } else {
637                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent INFO] Engine is not loaded or There is no specific_engine_request callback");
638                 return VCD_ERROR_NONE;
639         }
640
641         return VCD_ERROR_NONE;
642 }
643
644 int vcd_engine_process_text(int pid, const char* text)
645 {
646         if (false == g_agent_init) {
647                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
648                 return VCD_ERROR_OPERATION_FAILED;
649         }
650
651         int ret = -1;
652         if (true == g_dynamic_engine.is_loaded) {
653                 ret = g_dynamic_engine.callbacks->process_text(text);
654                 if (0 != ret) {
655                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to process text (%d)", ret);
656                         return ret;
657                 }
658         }
659
660         return VCD_ERROR_NONE;
661 }
662
663 int vcd_engine_process_list_event(int pid, const char* event)
664 {
665         if (false == g_agent_init) {
666                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
667                 return VCD_ERROR_OPERATION_FAILED;
668         }
669
670         int ret = -1;
671         if (true == g_dynamic_engine.is_loaded) {
672                 ret = g_dynamic_engine.callbacks->process_list_event(event);
673                 if (0 != ret) {
674                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to process list event (%d)", ret);
675                         return ret;
676                 }
677         }
678
679         return VCD_ERROR_NONE;
680 }
681
682 int vcd_engine_process_haptic_event(int pid, const char* event)
683 {
684         if (false == g_agent_init) {
685                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
686                 return VCD_ERROR_OPERATION_FAILED;
687         }
688
689         int ret = -1;
690         if (true == g_dynamic_engine.is_loaded) {
691                 ret = g_dynamic_engine.callbacks->process_haptic_event(event);
692                 if (0 != ret) {
693                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to process haptic event (%d)", ret);
694                         return ret;
695                 }
696         }
697
698         return VCD_ERROR_NONE;
699 }
700
701 int vcd_engine_request_tts(int pid, int utt_id, const char* text, const char* language)
702 {
703         if (false == g_agent_init) {
704                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
705                 return VCD_ERROR_OPERATION_FAILED;
706         }
707
708         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] Request tts to engine");
709
710         int ret = -1;
711         if (true == g_dynamic_engine.is_loaded && NULL != g_dynamic_engine.internal_callbacks->request_tts) {
712                 ret = g_dynamic_engine.internal_callbacks->request_tts(pid, utt_id, text, language, g_dynamic_engine.internal_callbacks->request_tts_user_data);
713                 if (0 != ret) {
714                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set request tts (%d)", ret);
715                         return ret;
716                 }
717         } else {
718                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded or There is no request tts callback");
719                 return VCD_ERROR_OPERATION_FAILED;
720         }
721
722         return VCD_ERROR_NONE;
723 }
724
725 int vcd_engine_cancel_tts(int pid, int utt_id)
726 {
727         if (false == g_agent_init) {
728                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
729                 return VCD_ERROR_OPERATION_FAILED;
730         }
731
732         int ret = -1;
733         if (true == g_dynamic_engine.is_loaded && NULL != g_dynamic_engine.internal_callbacks->cancel_tts) {
734                 ret = g_dynamic_engine.internal_callbacks->cancel_tts(pid, utt_id, g_dynamic_engine.internal_callbacks->cancel_tts_user_data);
735                 if (0 != ret) {
736                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set cancel tts (%d)", ret);
737                         return ret;
738                 }
739         } else {
740                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded or There is no cancel tts callback");
741                 return VCD_ERROR_OPERATION_FAILED;
742         }
743
744         return VCD_ERROR_NONE;
745 }
746
747 int vcd_engine_get_tts_audio_format(int* rate, int* channel, int* audio_type)
748 {
749         if (false == g_agent_init) {
750                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
751                 return VCD_ERROR_OPERATION_FAILED;
752         }
753
754         int ret = -1;
755         if (true == g_dynamic_engine.is_loaded && NULL != g_dynamic_engine.internal_callbacks->get_tts_audio_format) {
756                 ret = g_dynamic_engine.internal_callbacks->get_tts_audio_format(rate, channel, audio_type, g_dynamic_engine.internal_callbacks->get_tts_audio_format_user_data);
757                 if (0 != ret) {
758                         SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get tts audio format(%d)", ret);
759                         return ret;
760                 }
761         } else {
762                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded or There is no get tts audio format callback");
763                 return VCD_ERROR_OPERATION_FAILED;
764         }
765
766         return VCD_ERROR_NONE;
767 }
768
769
770 /*
771  * VCS Engine Interfaces for client and setting
772  */
773
774 int vcd_engine_get_audio_format(const char* audio_id, vce_audio_type_e* types, int* rate, int* channels)
775 {
776         if (false == g_agent_init) {
777                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
778                 return VCD_ERROR_OPERATION_FAILED;
779         }
780
781         if (true != g_dynamic_engine.is_loaded) {
782                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded");
783         }
784
785         int ret = g_dynamic_engine.callbacks->get_recording_format(audio_id, types, rate, channels);
786         if (0 != ret) {
787                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] get recording format(%d)", ret);
788                 return ret;
789         }
790
791         return VCD_ERROR_NONE;
792 }
793
794 static bool __supported_language_cb(const char* language, void* user_data)
795 {
796         GList** lang_list = (GList**)user_data;
797
798         if (NULL == language || NULL == lang_list) {
799                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Input parameter is NULL in callback!!!!");
800                 return false;
801         }
802
803         SLOG(LOG_INFO, TAG_VCD, "-- Language(%s)", language);
804
805         char* temp_lang = g_strdup(language);
806
807         *lang_list = g_list_append(*lang_list, temp_lang);
808
809         return true;
810 }
811
812 int vcd_engine_supported_langs(GList** lang_list)
813 {
814         if (false == g_agent_init) {
815                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
816                 return VCD_ERROR_OPERATION_FAILED;
817         }
818
819         if (true != g_dynamic_engine.is_loaded) {
820                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded");
821         }
822
823         int ret = g_dynamic_engine.callbacks->foreach_langs(__supported_language_cb, (void*)lang_list);
824         if (0 != ret) {
825                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] get language list error(%d)", ret);
826                 return ret;
827         }
828
829         return VCD_ERROR_NONE;
830 }
831
832
833 int vcd_engine_get_current_language(char** lang)
834 {
835         if (false == g_agent_init) {
836                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
837                 return VCD_ERROR_OPERATION_FAILED;
838         }
839
840         if (NULL == lang) {
841                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
842                 return VCD_ERROR_INVALID_PARAMETER;
843         }
844
845         /* get default language */
846         *lang = g_strdup(g_default_lang);
847
848         return VCD_ERROR_NONE;
849 }
850
851 int vcd_engine_set_current_language(const char* language)
852 {
853         if (false == g_agent_init) {
854                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
855                 return VCD_ERROR_OPERATION_FAILED;
856         }
857
858         if (NULL == language) {
859                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
860                 return VCD_ERROR_INVALID_PARAMETER;
861         }
862
863         int ret;
864
865         if (true == g_dynamic_engine.is_loaded) {
866                 g_dynamic_engine.is_command_ready = false;
867
868                 ret = g_dynamic_engine.callbacks->set_language(language);
869                 if (0 != ret) {
870                         SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Fail to set language of dynamic engine error(%d, %s)", ret, language);
871                 }
872         } else {
873                 SLOG(LOG_INFO, TAG_VCD, "[Engine Agent] Dynamic engine is not available (Cannot start)");
874         }
875
876         return VCD_ERROR_NONE;
877 }
878
879 int vcd_engine_agent_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void* user_data)
880 {
881         SLOG(LOG_INFO, TAG_VCD, "[Engine Agent] Request foreach command from engine");
882         return vcd_client_foreach_command((client_foreach_command_cb)callback, user_data);
883 }
884
885 int vcd_engine_agent_get_command_count(vce_cmd_h vce_command, int* count)
886 {
887         SLOG(LOG_INFO, TAG_VCD, "[Engine Agent] Request command length from engine");
888
889         *count = vcd_client_get_length();
890         return VCD_ERROR_NONE;
891 }
892
893 int vcd_engine_agent_get_audio_type(char** audio_type)
894 {
895         SLOG(LOG_INFO, TAG_VCD, "[Engine Agent] Request audio type");
896
897         return vcd_recorder_get(audio_type);
898 }
899
900 int vcd_engine_agent_set_private_data(const char* key, const char* data)
901 {
902         SLOG(LOG_INFO, TAG_VCD, "[Engine Agent] Request set private data, key(%s), data(%s)", key, data);
903         vcdc_send_request_set_private_data(vcd_client_manager_get_pid(), key, data);
904
905         return VCD_ERROR_NONE;
906 }
907
908 int vcd_engine_agent_get_private_data(const char* key, char** data)
909 {
910         SLOG(LOG_INFO, TAG_VCD, "[Engine Agent] Request get private data, key(%s)", key);
911         vcdc_send_request_get_private_data(vcd_client_manager_get_pid(), key, data);
912
913         return VCD_ERROR_NONE;
914 }
915
916 int vcd_engine_agent_start_recording()
917 {
918         SLOG(LOG_INFO, TAG_VCD, "[Engine Agent] Request start recording");
919
920         int ret = vcd_recorder_start();
921         if (0 != ret) {
922                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
923                 vcd_engine_recognize_cancel();
924                 /* Send error cb to manager */
925                 vcdc_send_error_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_framework.error.vcfw.send_rc_fail");
926                 return ret;
927         }
928
929         return VCD_ERROR_NONE;
930 }
931
932 int vcd_engine_agent_stop_recording()
933 {
934         SLOG(LOG_INFO, TAG_VCD, "[Engine Agent] Request stop recording");
935
936         return vcd_recorder_stop();
937 }
938
939 int vcd_engine_agent_set_private_data_set_cb(vce_private_data_set_cb callback_func)
940 {
941         if (false == g_agent_init) {
942                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
943                 return VCD_ERROR_OPERATION_FAILED;
944         }
945
946         if (false == g_dynamic_engine.is_loaded) {
947                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not loaded engine");
948                 return VCD_ERROR_OPERATION_FAILED;
949         }
950
951         g_dynamic_engine.internal_callbacks->private_data_set = callback_func;
952
953         return VCD_ERROR_NONE;
954 }
955
956 int vcd_engine_agent_set_private_data_requested_cb(vce_private_data_requested_cb callback_func)
957 {
958         if (false == g_agent_init) {
959                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
960                 return VCD_ERROR_OPERATION_FAILED;
961         }
962
963         if (false == g_dynamic_engine.is_loaded) {
964                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not loaded engine");
965                 return VCD_ERROR_OPERATION_FAILED;
966         }
967
968         g_dynamic_engine.internal_callbacks->private_data_request = callback_func;
969
970         return VCD_ERROR_NONE;
971 }
972
973 int vcd_engine_agent_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_func)
974 {
975         if (false == g_agent_init) {
976                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
977                 return VCD_ERROR_OPERATION_FAILED;
978         }
979
980         if (false == g_dynamic_engine.is_loaded) {
981                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not loaded engine");
982                 return VCD_ERROR_OPERATION_FAILED;
983         }
984
985         g_dynamic_engine.internal_callbacks->nlu_base_info_request = callback_func;
986
987         return VCD_ERROR_NONE;
988 }
989
990 int vcd_engine_agent_set_specific_engine_request_cb(vce_specific_engine_request_cb callback_func)
991 {
992         if (false == g_agent_init) {
993                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
994                 return VCD_ERROR_OPERATION_FAILED;
995         }
996
997         if (false == g_dynamic_engine.is_loaded) {
998                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not loaded engine");
999                 return VCD_ERROR_OPERATION_FAILED;
1000         }
1001
1002         g_dynamic_engine.internal_callbacks->specific_engine_request = callback_func;
1003
1004         return VCD_ERROR_NONE;
1005 }
1006
1007 int vcd_engine_agent_set_request_tts_cb(vce_request_tts_cb callback_func, void* user_data)
1008 {
1009         if (false == g_agent_init) {
1010                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
1011                 return VCD_ERROR_OPERATION_FAILED;
1012         }
1013
1014         if (false == g_dynamic_engine.is_loaded) {
1015                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not loaded engine");
1016                 return VCD_ERROR_OPERATION_FAILED;
1017         }
1018
1019         g_dynamic_engine.internal_callbacks->request_tts = callback_func;
1020         g_dynamic_engine.internal_callbacks->request_tts_user_data = user_data;
1021
1022         return VCD_ERROR_NONE;
1023 }
1024
1025 int vcd_engine_agent_set_cancel_tts_cb(vce_cancel_tts_cb callback_func, void* user_data)
1026 {
1027         if (false == g_agent_init) {
1028                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
1029                 return VCD_ERROR_OPERATION_FAILED;
1030         }
1031
1032         if (false == g_dynamic_engine.is_loaded) {
1033                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not loaded engine");
1034                 return VCD_ERROR_OPERATION_FAILED;
1035         }
1036
1037         g_dynamic_engine.internal_callbacks->cancel_tts = callback_func;
1038         g_dynamic_engine.internal_callbacks->cancel_tts_user_data = user_data;
1039
1040         return VCD_ERROR_NONE;
1041 }
1042
1043 int vcd_engine_agent_set_get_tts_audio_format_cb(vce_tts_audio_format_request_cb callback_func, void* user_data)
1044 {
1045         if (false == g_agent_init) {
1046                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
1047                 return VCD_ERROR_OPERATION_FAILED;
1048         }
1049
1050         if (false == g_dynamic_engine.is_loaded) {
1051                 SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not loaded engine");
1052                 return VCD_ERROR_OPERATION_FAILED;
1053         }
1054
1055         g_dynamic_engine.internal_callbacks->get_tts_audio_format = callback_func;
1056         g_dynamic_engine.internal_callbacks->get_tts_audio_format_user_data = user_data;
1057
1058         return VCD_ERROR_NONE;
1059 }