From fd608e0cbada622b6384752a2a929373a8f3a66b Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Mon, 11 Sep 2017 10:18:27 +0900 Subject: [PATCH 01/16] Remove to start recorder when bt data received cb is called Change-Id: I01f7b09f752051088821b0772bfd7f3d44fa6ad1 Signed-off-by: Wonnam Jang --- server/vcd_recorder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index 88a654f..1d69fff 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -166,7 +166,7 @@ static void _bt_hid_audio_data_receive_cb(bt_hid_voice_data_s *voice_data, void if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) { SLOG(LOG_WARN, TAG_VCD, "[Recorder] Not start yet, but send audio data vi Bluetooth"); - vcd_recorder_start(); +// vcd_recorder_start(); } if (NULL != g_audio_cb) { -- 2.7.4 From dd4bd25c5dc09658e6cbe31d960a76ed1be9c197 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Wed, 13 Sep 2017 14:15:10 +0900 Subject: [PATCH 02/16] Fix unintended recording cancel by changing language Change-Id: Ib0c14671d7e57ed9e0aad208a3ec2a29dda2460e Signed-off-by: Suyeon Hwang --- client/CMakeLists.txt | 1 + client/vc_dbus.c | 5 +- client/vc_dbus.h | 1 - client/vc_setting.c | 18 ++- client/vc_setting_dbus.c | 381 +++++++++++++++++++++++++++++++++++++++++++++++ client/vc_setting_dbus.h | 38 +++++ common/vc_defs.h | 10 ++ server/vcd_config.c | 23 ++- server/vcd_config.h | 2 + server/vcd_dbus.c | 3 + server/vcd_dbus_server.c | 48 ++++++ server/vcd_dbus_server.h | 2 + server/vcd_server.c | 19 +++ server/vcd_server.h | 2 + 14 files changed, 544 insertions(+), 9 deletions(-) mode change 100644 => 100755 client/vc_setting.c create mode 100755 client/vc_setting_dbus.c create mode 100755 client/vc_setting_dbus.h mode change 100644 => 100755 common/vc_defs.h mode change 100644 => 100755 server/vcd_config.c mode change 100644 => 100755 server/vcd_config.h mode change 100644 => 100755 server/vcd_dbus.c mode change 100644 => 100755 server/vcd_dbus_server.c mode change 100644 => 100755 server/vcd_server.c diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 0103780..074d790 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -11,6 +11,7 @@ SET(SRCS ) SET(SETTING_SRCS + vc_setting_dbus.c vc_setting.c ../common/vc_config_mgr.c ../common/vc_config_parser.c diff --git a/client/vc_dbus.c b/client/vc_dbus.c index 6bbfdf0..245ea13 100644 --- a/client/vc_dbus.c +++ b/client/vc_dbus.c @@ -14,8 +14,7 @@ * limitations under the License. */ - -#include "vc_client.h" +#include "vc_command.h" #include "vc_dbus.h" #include "vc_main.h" @@ -1571,4 +1570,4 @@ int vc_dbus_request_auth_cancel(int pid, int mgr_pid) } return result; -} +} \ No newline at end of file diff --git a/client/vc_dbus.h b/client/vc_dbus.h index a3fd996..b5db90b 100644 --- a/client/vc_dbus.h +++ b/client/vc_dbus.h @@ -65,7 +65,6 @@ int vc_dbus_request_auth_stop(int pid, int mgr_pid); int vc_dbus_request_auth_cancel(int pid, int mgr_pid); - #ifdef __cplusplus } #endif diff --git a/client/vc_setting.c b/client/vc_setting.c old mode 100644 new mode 100755 index 82826a0..8fe5496 --- a/client/vc_setting.c +++ b/client/vc_setting.c @@ -17,6 +17,7 @@ #include "vc_config_mgr.h" #include "vc_main.h" +#include "vc_setting_dbus.h" #include "voice_control_common.h" #include "voice_control_setting.h" @@ -202,7 +203,22 @@ int vc_setting_set_language(const char* language) if (0 != ret) { SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Result : %d", ret); } else { - SLOG(LOG_DEBUG, TAG_VCS, "[SUCCESS] Set default language"); + if (0 != vc_setting_dbus_open_connection()) { + SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Fail to open connection"); + return VC_ERROR_OPERATION_FAILED; + } + + if (0 != vc_setting_dbus_request_hello()) { + SLOG(LOG_DEBUG, TAG_VCS, "[DEBUG] Daemon is not available"); + } else { + ret = vc_setting_dbus_request_set_language(getpid(), language); + SLOG(LOG_DEBUG, TAG_VCS, "[DEBUG] Set default language (%d)", ret); + } + + if (0 != vc_setting_dbus_close_connection()) { + SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Fail to close connection"); + return VC_ERROR_OPERATION_FAILED; + } } SLOG(LOG_DEBUG, TAG_VCS, "@@@"); diff --git a/client/vc_setting_dbus.c b/client/vc_setting_dbus.c new file mode 100755 index 0000000..7f6b7d8 --- /dev/null +++ b/client/vc_setting_dbus.c @@ -0,0 +1,381 @@ +/* +* Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the License); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an AS IS BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "vc_setting_dbus.h" +#include "vc_main.h" + + +static int g_s_waiting_time = 3000; + +static Ecore_Fd_Handler* g_s_fd_handler = NULL; + +static DBusConnection* g_s_conn_sender = NULL; +static DBusConnection* g_s_conn_listener = NULL; + + +static Eina_Bool listener_setting_event_callback(void* data, Ecore_Fd_Handler *fd_handler) +{ + if (NULL == g_s_conn_listener) return ECORE_CALLBACK_RENEW; + + dbus_connection_read_write_dispatch(g_s_conn_listener, 50); + + while (1) { + DBusMessage* msg = NULL; + msg = dbus_connection_pop_message(g_s_conn_listener); + + /* loop again if we haven't read a message */ + if (NULL == msg) { + break; + } + + DBusError err; + dbus_error_init(&err); + + char if_name[64] = {0, }; + snprintf(if_name, 64, "%s", VC_SETTING_SERVICE_INTERFACE); + + if (dbus_message_is_method_call(msg, if_name, VCD_METHOD_HELLO)) { + SLOG(LOG_DEBUG, TAG_VCS, "@@@ Get Hello"); + int pid = 0; + int response = -1; + + dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Dbus Error (%s)", err.message); + dbus_error_free(&err); + } + + if (pid > 0) { + SLOG(LOG_DEBUG, TAG_VCS, "@@ vc get hello : pid(%d) ", pid); + response = 1; + } else { + SLOG(LOG_ERROR, TAG_VCS, "@@ vc get hello : invalid pid "); + } + + DBusMessage* reply = NULL; + reply = dbus_message_new_method_return(msg); + + if (NULL != reply) { + dbus_message_append_args(reply, DBUS_TYPE_INT32, &response, DBUS_TYPE_INVALID); + + if (!dbus_connection_send(g_s_conn_listener, reply, NULL)) + SLOG(LOG_ERROR, TAG_VCS, "@@ vc get hello : fail to send reply"); + else + SLOG(LOG_DEBUG, TAG_VCS, "@@ vc get hello : result(%d)", response); + + dbus_connection_flush(g_s_conn_listener); + dbus_message_unref(reply); + } else { + SLOG(LOG_ERROR, TAG_VCS, "@@ vc get hello : fail to create reply message"); + } + + SLOG(LOG_DEBUG, TAG_VCS, "@@@"); + } /* VCD_METHOD_HELLO */ + + else { + SLOG(LOG_DEBUG, TAG_VCS, "Message is NOT valid"); + dbus_message_unref(msg); + break; + } + + /* free the message */ + dbus_message_unref(msg); + } /* while(1) */ + + return ECORE_CALLBACK_PASS_ON; +} + +static void __vc_setting_dbus_connection_free() +{ + if (NULL != g_s_conn_listener) { + dbus_connection_close(g_s_conn_listener); + dbus_connection_unref(g_s_conn_listener); + g_s_conn_listener = NULL; + } + if (NULL != g_s_conn_sender) { + dbus_connection_close(g_s_conn_sender); + dbus_connection_unref(g_s_conn_sender); + g_s_conn_sender = NULL; + } +} + +int vc_setting_dbus_open_connection() +{ + if (NULL != g_s_conn_sender && NULL != g_s_conn_listener) { + SLOG(LOG_WARN, TAG_VCS, "already existed connection "); + return 0; + } + + DBusError err; + int ret; + + /* initialise the error value */ + dbus_error_init(&err); + + /* connect to the DBUS system bus, and check for errors */ + g_s_conn_sender = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCS, "Dbus Connection Error (%s)", err.message); + dbus_error_free(&err); + } + + if (NULL == g_s_conn_sender) { + SLOG(LOG_ERROR, TAG_VCS, "Fail to get dbus connection "); + return VC_ERROR_OPERATION_FAILED; + } + + g_s_conn_listener = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCS, "Dbus Connection Error (%s)", err.message); + dbus_error_free(&err); + } + + if (NULL == g_s_conn_listener) { + SLOG(LOG_ERROR, TAG_VCS, "Fail to get dbus connection "); + __vc_setting_dbus_connection_free(); + return VC_ERROR_OPERATION_FAILED; + } + + int pid = getpid(); + + char service_name[64]; + memset(service_name, '\0', 64); + snprintf(service_name, 64, "%s%d", VC_SETTING_SERVICE_NAME, pid); + + SLOG(LOG_DEBUG, TAG_VCS, "service name is %s", service_name); + + /* register our name on the bus, and check for errors */ + ret = dbus_bus_request_name(g_s_conn_listener, service_name, DBUS_NAME_FLAG_REPLACE_EXISTING, &err); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCS, "Name Error (%s)", err.message); + dbus_error_free(&err); + } + + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { + SLOG(LOG_ERROR, TAG_VCS, "fail dbus_bus_request_name()"); + __vc_setting_dbus_connection_free(); + return -2; + } + + if (NULL != g_s_fd_handler) { + SLOG(LOG_WARN, TAG_VCS, "The handler already exists."); + __vc_setting_dbus_connection_free(); + return 0; + } + + char rule[128] = {0, }; + snprintf(rule, 128, "type='signal',interface='%s'", VC_SETTING_SERVICE_INTERFACE); + + /* add a rule for which messages we want to see */ + dbus_bus_add_match(g_s_conn_listener, rule, &err); + dbus_connection_flush(g_s_conn_listener); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCS, "Match Error (%s)", err.message); + dbus_error_free(&err); + __vc_setting_dbus_connection_free(); + return VC_ERROR_OPERATION_FAILED; + } + + int fd = 0; + if (1 != dbus_connection_get_unix_fd(g_s_conn_listener, &fd)) { + SLOG(LOG_ERROR, TAG_VCS, "fail to get fd from dbus "); + __vc_setting_dbus_connection_free(); + return VC_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCS, "Get fd from dbus : %d", fd); + } + + g_s_fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)listener_setting_event_callback, g_s_conn_listener, NULL, NULL); + if (NULL == g_s_fd_handler) { + SLOG(LOG_ERROR, TAG_VCS, "fail to get fd handler from ecore "); + __vc_setting_dbus_connection_free(); + return VC_ERROR_OPERATION_FAILED; + } + + return 0; +} + +int vc_setting_dbus_close_connection() +{ + DBusError err; + dbus_error_init(&err); + + if (NULL != g_s_fd_handler) { + ecore_main_fd_handler_del(g_s_fd_handler); + g_s_fd_handler = NULL; + } + + int pid = getpid(); + + char service_name[64]; + memset(service_name, '\0', 64); + snprintf(service_name, 64, "%s%d", VC_SETTING_SERVICE_NAME, pid); + + dbus_bus_release_name(g_s_conn_listener, service_name, &err); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Dbus Error (%s)", err.message); + dbus_error_free(&err); + } + + __vc_setting_dbus_connection_free(); + + return 0; +} + +int vc_setting_dbus_reconnect() +{ + if (!g_s_conn_sender || !g_s_conn_listener) { + vc_setting_dbus_close_connection(); + + if (0 != vc_setting_dbus_open_connection()) { + SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Fail to reconnect"); + return -1; + } + + SLOG(LOG_DEBUG, TAG_VCS, "[DBUS] Reconnect"); + return 0; + } + + bool sender_connected = dbus_connection_get_is_connected(g_s_conn_sender); + bool listener_connected = dbus_connection_get_is_connected(g_s_conn_listener); + SLOG(LOG_WARN, TAG_VCS, "[DBUS] Sender(%s) Listener(%s)", + sender_connected ? "Connected" : "Not connected", listener_connected ? "Connected" : "Not connected"); + + if (false == sender_connected || false == listener_connected) { + vc_setting_dbus_close_connection(); + + if (0 != vc_setting_dbus_open_connection()) { + SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Fail to reconnect"); + return -1; + } + + SLOG(LOG_DEBUG, TAG_VCS, "[DBUS] Reconnect"); + } + + return 0; +} + +int vc_setting_dbus_request_hello() +{ + if (NULL == g_s_conn_sender) { + return VC_ERROR_OPERATION_FAILED; + } + + DBusMessage* msg; + + msg = dbus_message_new_method_call( + VC_SERVER_SERVICE_NAME, + VC_SERVER_SERVICE_OBJECT_PATH, + VC_SERVER_SERVICE_INTERFACE, + VC_METHOD_HELLO); + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_VCS, "@@ Request vc hello : Fail to make message"); + return VC_ERROR_OPERATION_FAILED; + } + + DBusError err; + dbus_error_init(&err); + + DBusMessage* result_msg = NULL; + int result = 0; + + result_msg = dbus_connection_send_with_reply_and_block(g_s_conn_sender, msg, 500, &err); + + if (dbus_error_is_set(&err)) { + dbus_error_free(&err); + } + + dbus_message_unref(msg); + + if (NULL != result_msg) { + dbus_message_unref(result_msg); + result = 0; + } else { + result = VC_ERROR_TIMED_OUT; + } + + return result; +} + +int vc_setting_dbus_request_set_language(int pid, const char* language) +{ + if (NULL == g_s_conn_sender) { + SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Dbus does not open"); + return VC_ERROR_OPERATION_FAILED; + } + + DBusMessage* msg; + + msg = dbus_message_new_method_call( + VC_SERVER_SERVICE_NAME, + VC_SERVER_SERVICE_OBJECT_PATH, + VC_SERVER_SERVICE_INTERFACE, + VC_SETTING_METHOD_SET_LANGUAGE); + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_VCS, "@@ vc set language : Fail to make message"); + return VC_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCS, "@@ vc set language : pid(%d)", pid); + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_STRING, &language, + DBUS_TYPE_INVALID); + + DBusError err; + dbus_error_init(&err); + + DBusMessage* result_msg; + int result = VC_ERROR_OPERATION_FAILED; + + result_msg = dbus_connection_send_with_reply_and_block(g_s_conn_sender, msg, g_s_waiting_time, &err); + dbus_message_unref(msg); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Dbus Error (%s)", err.message); + dbus_error_free(&err); + } + + if (NULL != result_msg) { + dbus_message_get_args(result_msg, &err, + DBUS_TYPE_INT32, &result, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCS, "@@ Get arguments error (%s)", err.message); + dbus_error_free(&err); + result = VC_ERROR_OPERATION_FAILED; + } + dbus_message_unref(result_msg); + + SLOG(LOG_DEBUG, TAG_VCS, "@@ vcd set language : result = %d", result); + } else { + SLOG(LOG_ERROR, TAG_VCS, "@@ Result message is NULL"); + vc_setting_dbus_reconnect(); + result = VC_ERROR_TIMED_OUT; + } + + return result; +} \ No newline at end of file diff --git a/client/vc_setting_dbus.h b/client/vc_setting_dbus.h new file mode 100755 index 0000000..3404d4f --- /dev/null +++ b/client/vc_setting_dbus.h @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the License); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an AS IS BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __VC_SETTING_DBUS_H_ +#define __VC_SETTING_DBUS_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +int vc_setting_dbus_open_connection(); + +int vc_setting_dbus_close_connection(); + +int vc_setting_dbus_request_hello(); + +int vc_setting_dbus_request_set_language(int pid, const char* language); + +#ifdef __cplusplus +} +#endif + +#endif /* __VC_SETTING_DBUS_H_ */ diff --git a/common/vc_defs.h b/common/vc_defs.h old mode 100644 new mode 100755 index 60e0aa4..31d4725 --- a/common/vc_defs.h +++ b/common/vc_defs.h @@ -45,6 +45,9 @@ extern "C" { #define VC_SERVER_SERVICE_OBJECT_PATH "/org/tizen/voice/vcserver" #define VC_SERVER_SERVICE_INTERFACE "org.tizen.voice.vcserver" +#define VC_SETTING_SERVICE_NAME "org.tizen.voice.vcsetting" +#define VC_SETTING_SERVICE_OBJECT_PATH "/org/tize/voice/vcsetting" +#define VC_SETTING_SERVICE_INTERFACE "org.tizen.voice.vcsetting" /****************************************************************************************** * Message Definition for all @@ -155,6 +158,13 @@ extern "C" { /****************************************************************************************** +* Message Definitions for setting +*******************************************************************************************/ + +#define VC_SETTING_METHOD_SET_LANGUAGE "vc_setting_method_set_language" + + +/****************************************************************************************** * Definitions for configuration *******************************************************************************************/ diff --git a/server/vcd_config.c b/server/vcd_config.c old mode 100644 new mode 100755 index 287ba23..8d707b7 --- a/server/vcd_config.c +++ b/server/vcd_config.c @@ -41,10 +41,12 @@ static int g_enabled_command_type[COMMAND_TYPE_MAX] = { void __vcd_config_lang_changed_cb(const char* before_lang, const char* current_lang) { - if (NULL != g_lang_cb) - g_lang_cb(current_lang, g_user_data); - else - SLOG(LOG_ERROR, TAG_VCD, "Language changed callback is NULL"); + if (NULL != before_lang && NULL != current_lang && strncmp(before_lang, current_lang, strlen(before_lang))) { + if (NULL != g_lang_cb) + g_lang_cb(current_lang, g_user_data); + else + SLOG(LOG_ERROR, TAG_VCD, "Language changed callback is NULL"); + } } @@ -107,6 +109,19 @@ int vcd_config_get_default_language(char** language) return 0; } +int vcd_config_set_default_language(const char* language) +{ + if (NULL == language) + return VCD_ERROR_INVALID_PARAMETER; + + if (0 != vc_config_mgr_set_default_language(language)) { + SLOG(LOG_ERROR, TAG_VCD, "[Config ERROR] Fail to get language"); + return VCD_ERROR_OPERATION_FAILED; + } + + return 0; +} + int vcd_config_set_service_state(vcd_state_e state) { g_state = state; diff --git a/server/vcd_config.h b/server/vcd_config.h old mode 100644 new mode 100755 index 047d6d6..de6589d --- a/server/vcd_config.h +++ b/server/vcd_config.h @@ -35,6 +35,8 @@ int vcd_config_finalize(); int vcd_config_get_default_language(char** language); +int vcd_config_set_default_language(const char* language); + int vcd_config_set_service_state(vcd_state_e state); vcd_state_e vcd_config_get_service_state(); diff --git a/server/vcd_dbus.c b/server/vcd_dbus.c old mode 100644 new mode 100755 index 186abf4..3493459 --- a/server/vcd_dbus.c +++ b/server/vcd_dbus.c @@ -1053,6 +1053,9 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_WIDGET_METHOD_ENABLE_ASR_RESULT)) vcd_dbus_server_widget_enable_asr_result(g_conn_listener, msg); + else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_SETTING_METHOD_SET_LANGUAGE)) + vcd_dbus_server_set_language(g_conn_listener, msg); + else { SLOG(LOG_DEBUG, TAG_VCD, "Message is NOT valid"); dbus_message_unref(msg); diff --git a/server/vcd_dbus_server.c b/server/vcd_dbus_server.c old mode 100644 new mode 100755 index 5a72d01..6a6a15d --- a/server/vcd_dbus_server.c +++ b/server/vcd_dbus_server.c @@ -1944,3 +1944,51 @@ int vcd_dbus_server_widget_enable_asr_result(DBusConnection* conn, DBusMessage* return 0; } + +int vcd_dbus_server_set_language(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int pid; + char* language; + int ret = VCD_ERROR_OPERATION_FAILED; + dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_STRING, &language, DBUS_TYPE_INVALID); + + SLOG(LOG_DEBUG, TAG_VCD, "@@@ VCD server set language"); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd server set language : get arguments error (%s)", err.message); + dbus_error_free(&err); + ret = VCD_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd server set language : language(%s)", language); + ret = vcd_server_set_language(language); + } + + DBusMessage* reply; + reply = dbus_message_new_method_return(msg); + + if (NULL != reply) { + dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID); + + if (0 == ret) { + SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret); + } + + if (!dbus_connection_send(conn, reply, NULL)) { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!"); + } + + dbus_connection_flush(conn); + dbus_message_unref(reply); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!"); + } + + SLOG(LOG_DEBUG, TAG_VCD, "@@@"); + + return 0; +} \ No newline at end of file diff --git a/server/vcd_dbus_server.h b/server/vcd_dbus_server.h index 626d415..caa87df 100644 --- a/server/vcd_dbus_server.h +++ b/server/vcd_dbus_server.h @@ -114,6 +114,8 @@ int vcd_dbus_server_widget_cancel(DBusConnection* conn, DBusMessage* msg); int vcd_dbus_server_widget_enable_asr_result(DBusConnection* conn, DBusMessage* msg); +int vcd_dbus_server_set_language(DBusConnection* conn, DBusMessage* msg); + #ifdef __cplusplus } #endif diff --git a/server/vcd_server.c b/server/vcd_server.c old mode 100644 new mode 100755 index c8e3304..0129914 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -2346,3 +2346,22 @@ int vcd_server_widget_enable_asr_result(int pid, bool enable) return ret; } + +int vcd_server_set_language(const char* language) +{ + int ret = VCD_ERROR_NONE; + + ret = vcd_config_set_default_language(language); + if (0 != ret) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to set language : %d", ret); + return ret; + } + + ret = vcd_engine_set_current_language(language); + if (0 != ret) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to set language : %d", ret); + return ret; + } + + return ret; +} \ No newline at end of file diff --git a/server/vcd_server.h b/server/vcd_server.h index b97589d..14fcbd2 100644 --- a/server/vcd_server.h +++ b/server/vcd_server.h @@ -122,6 +122,8 @@ int vcd_server_widget_cancel(int pid); int vcd_server_widget_enable_asr_result(int pid, bool enable); +int vcd_server_set_language(const char* language); + #ifdef __cplusplus } #endif -- 2.7.4 From 7717f835c9b0f4bc4d30cd65ebe7fa1e388c65b7 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Mon, 18 Sep 2017 20:02:29 +0900 Subject: [PATCH 03/16] Add synchronous prepare function for web API Change-Id: Ie70180121c1569d602d439cd9a295d2ec617be36 Signed-off-by: Suyeon Hwang --- client/vc.c | 38 +++++++++++++++++++++++++++++++++++--- include/voice_control_internal.h | 2 ++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/client/vc.c b/client/vc.c index e5bb5c6..7fe220e 100644 --- a/client/vc.c +++ b/client/vc.c @@ -310,13 +310,13 @@ int vc_initialize(void) /* check handle */ if (true == vc_client_is_valid(g_vc)) { - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Already initialized"); - return VC_ERROR_INVALID_STATE; + SLOG(LOG_DEBUG, TAG_VCC, "[DEBUG] Already initialized"); + return VC_ERROR_NONE; } if (0 < vc_client_get_count()) { SLOG(LOG_DEBUG, TAG_VCC, "[DEBUG] Already initialized"); - return VC_ERROR_INVALID_STATE; + return VC_ERROR_NONE; } if (0 != vc_dbus_open_connection()) { @@ -572,6 +572,38 @@ int vc_prepare(void) return VC_ERROR_NONE; } +int vc_prepare_sync(void) +{ + if (0 != __vc_get_feature_enabled()) { + return VC_ERROR_NOT_SUPPORTED; + } + if (0 != __vc_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + + SLOG(LOG_DEBUG, TAG_VCC, "@@@ [Client] Prepare"); + + vc_state_e state; + if (0 != vc_client_get_client_state(g_vc, &state)) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available"); + SLOG(LOG_DEBUG, TAG_VCC, "@@@"); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != VC_STATE_INITIALIZED) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state is not 'CREATED'"); + SLOG(LOG_DEBUG, TAG_VCC, "@@@"); + return VC_ERROR_INVALID_STATE; + } + + while (EINA_TRUE == __vc_connect_daemon(NULL)); + + SLOG(LOG_DEBUG, TAG_VCC, "@@@"); + + return VC_ERROR_NONE; +} + int vc_unprepare(void) { if (0 != __vc_get_feature_enabled()) { diff --git a/include/voice_control_internal.h b/include/voice_control_internal.h index 8465e9e..d73dcfb 100644 --- a/include/voice_control_internal.h +++ b/include/voice_control_internal.h @@ -68,6 +68,8 @@ typedef bool (*vc_asr_result_cb)(vc_result_event_e event, const char* result, vo */ int vc_set_command_list_from_file(const char* file_path, int type); +int vc_prepare_sync(void); + #ifdef __cplusplus } -- 2.7.4 From 401cf4c6ac309c0921e40effa7f86b55fda540a8 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Fri, 22 Sep 2017 15:53:05 +0900 Subject: [PATCH 04/16] change dbus signal to dbus method for service state to vcm Change-Id: Ia2ff62442716458f925acb12b3808dbb2988a096 Signed-off-by: Wonnam Jang (cherry picked from commit 699a77e930ab8b68af90ce690fa37ee071390b5d) --- client/vc_mgr_dbus.c | 2 +- server/vcd_dbus.c | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/client/vc_mgr_dbus.c b/client/vc_mgr_dbus.c index 7a005e0..e3a2f73 100644 --- a/client/vc_mgr_dbus.c +++ b/client/vc_mgr_dbus.c @@ -146,7 +146,7 @@ static Eina_Bool vc_mgr_listener_event_callback(void* data, Ecore_Fd_Handler *fd } /* VCD_MANAGER_METHOD_SET_VOLUME */ - else if (dbus_message_is_signal(msg, if_name, VCD_MANAGER_METHOD_SET_SERVICE_STATE)) { + else if (dbus_message_is_method_call(msg, if_name, VCD_MANAGER_METHOD_SET_SERVICE_STATE)) { int state = 0; dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &state, DBUS_TYPE_INVALID); diff --git a/server/vcd_dbus.c b/server/vcd_dbus.c index 3493459..22562b5 100755 --- a/server/vcd_dbus.c +++ b/server/vcd_dbus.c @@ -485,10 +485,7 @@ int vcdc_send_service_state(vcd_state_e state) DBusMessage* msg = NULL; - msg = dbus_message_new_signal( - VC_MANAGER_SERVICE_OBJECT_PATH, - VC_MANAGER_SERVICE_INTERFACE, - VCD_MANAGER_METHOD_SET_SERVICE_STATE); + msg = __get_message(vcd_client_manager_get_pid(), VCD_MANAGER_METHOD_SET_SERVICE_STATE, VCD_CLIENT_TYPE_MANAGER); if (NULL == msg) { SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Message is NULL"); @@ -497,6 +494,8 @@ int vcdc_send_service_state(vcd_state_e state) dbus_message_append_args(msg, DBUS_TYPE_INT32, &state, DBUS_TYPE_INVALID); + dbus_message_set_no_reply(msg, TRUE); + if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) { SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to Send"); return VCD_ERROR_OPERATION_FAILED; -- 2.7.4 From 459863743d3e14f72bbf2c97534ffa7572bf6e34 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Mon, 25 Sep 2017 11:58:47 +0900 Subject: [PATCH 05/16] Update base lang when default base lang doesn't exist Change-Id: I73e2a32b45aea3fde910239f917330c6e82a02de Signed-off-by: Wonnam Jang (cherry picked from commit d28bca88cf08821cb6e98e791074cbb083246114) --- common/vc_config_mgr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/vc_config_mgr.c b/common/vc_config_mgr.c index 246d842..a85b57f 100755 --- a/common/vc_config_mgr.c +++ b/common/vc_config_mgr.c @@ -263,6 +263,10 @@ int __vc_config_mgr_select_lang(const char* engine_id, char** language) } /* Not support base language */ + iter_lang = g_slist_nth(engine_info->languages, 0); + if (NULL != iter_lang) + engine_lang = iter_lang->data; + if (NULL != engine_lang) { *language = strdup(engine_lang); SLOG(LOG_DEBUG, vc_config_tag(), "Selected language : %s", *language); -- 2.7.4 From 789c792f9a4abb07b7d07e01c560e4e23f5493bf Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Tue, 26 Sep 2017 10:16:34 +0900 Subject: [PATCH 06/16] Add description and retry limitation for vc_prepare_sync Change-Id: I5dd1448ff1f861d1ac23d4aad2988b789f9376b1 Signed-off-by: Suyeon Hwang --- client/vc.c | 10 +++++++++- common/vc_defs.h | 1 + include/voice_control_internal.h | 20 ++++++++++++++++++-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/client/vc.c b/client/vc.c index 7fe220e..78e5193 100644 --- a/client/vc.c +++ b/client/vc.c @@ -597,10 +597,18 @@ int vc_prepare_sync(void) return VC_ERROR_INVALID_STATE; } - while (EINA_TRUE == __vc_connect_daemon(NULL)); + int cnt = 0; + while (EINA_TRUE == __vc_connect_daemon(NULL) && VC_CONNECTION_RETRY_COUNT > cnt) { + cnt++; + } SLOG(LOG_DEBUG, TAG_VCC, "@@@"); + if (VC_CONNECTION_RETRY_COUNT == cnt) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to connect daemon"); + return VC_ERROR_OPERATION_FAILED; + } + return VC_ERROR_NONE; } diff --git a/common/vc_defs.h b/common/vc_defs.h index 31d4725..7947a92 100755 --- a/common/vc_defs.h +++ b/common/vc_defs.h @@ -202,6 +202,7 @@ extern "C" { #define VC_BASE_LANGUAGE "en_US" #define VC_RETRY_COUNT 5 #define VC_RUNTIME_INFO_NO_FOREGROUND -1 +#define VC_CONNECTION_RETRY_COUNT 10 #define VC_FEATURE_PATH "tizen.org/feature/speech.control" #define VC_MIC_FEATURE_PATH "tizen.org/feature/microphone" diff --git a/include/voice_control_internal.h b/include/voice_control_internal.h index d73dcfb..cc5b4ad 100644 --- a/include/voice_control_internal.h +++ b/include/voice_control_internal.h @@ -49,8 +49,8 @@ typedef bool (*vc_asr_result_cb)(vc_result_event_e event, const char* result, vo * @privilege %http://tizen.org/privilege/recorder * * @remarks The command type is valid for #VC_COMMAND_TYPE_FOREGROUND and #VC_COMMAND_TYPE_BACKGROUND. - * Therefore, @a type is either #VC_COMMAND_TYPE_FOREGROUND or #VC_COMMAND_TYPE_BACKGROUND. \n - * In the file corresponding to @a file_path, there must be commands and command types. + * Therefore, @a type is either #VC_COMMAND_TYPE_FOREGROUND or #VC_COMMAND_TYPE_BACKGROUND. + * In the file corresponding to @a file_path, there must be commands and command types. * * @param[in] file_path The command file path (absolute or relative) * @param[in] type Command type @@ -68,6 +68,22 @@ typedef bool (*vc_asr_result_cb)(vc_result_event_e event, const char* result, vo */ int vc_set_command_list_from_file(const char* file_path, int type); +/** + * @brief Connects the voice control service synchronously. + * @since_tizen 4.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/recorder + * @return @c 0 on success, + * otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_OPERATION_FAILED Operation failure + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED Not supported + * @pre The state should be #VC_STATE_INITIALIZED. + * @post If this function is called, the state will be #VC_STATE_READY. + * @see vc_unprepare() + */ int vc_prepare_sync(void); -- 2.7.4 From 2f963c0f1183e02812a8e900e30295068e2438f2 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Wed, 11 Oct 2017 16:40:51 +0900 Subject: [PATCH 07/16] Fix memory leaks Change-Id: I0ffca49978f84cab61fa4e190588e26f00cacffc Signed-off-by: Suyeon Hwang --- client/vc_dbus.c | 2 -- client/vc_mgr_dbus.c | 2 -- client/vc_setting_dbus.c | 2 -- client/vc_widget_dbus.c | 2 -- common/vc_cmd_db.c | 6 +++++- common/vc_json_parser.c | 4 ++++ server/vcd_dbus.c | 8 +++----- server/vcd_server.c | 18 ++++++++++-------- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/client/vc_dbus.c b/client/vc_dbus.c index 245ea13..7e69069 100644 --- a/client/vc_dbus.c +++ b/client/vc_dbus.c @@ -191,12 +191,10 @@ static void __vc_dbus_connection_free() { if (NULL != g_conn_listener) { dbus_connection_close(g_conn_listener); - dbus_connection_unref(g_conn_listener); g_conn_listener = NULL; } if (NULL != g_conn_sender) { dbus_connection_close(g_conn_sender); - dbus_connection_unref(g_conn_sender); g_conn_sender = NULL; } } diff --git a/client/vc_mgr_dbus.c b/client/vc_mgr_dbus.c index e3a2f73..a552504 100644 --- a/client/vc_mgr_dbus.c +++ b/client/vc_mgr_dbus.c @@ -594,12 +594,10 @@ static void __vc_mgr_dbus_connection_free() { if (NULL != g_m_conn_listener) { dbus_connection_close(g_m_conn_listener); - dbus_connection_unref(g_m_conn_listener); g_m_conn_listener = NULL; } if (NULL != g_m_conn_sender) { dbus_connection_close(g_m_conn_sender); - dbus_connection_unref(g_m_conn_sender); g_m_conn_sender = NULL; } } diff --git a/client/vc_setting_dbus.c b/client/vc_setting_dbus.c index 7f6b7d8..3da5868 100755 --- a/client/vc_setting_dbus.c +++ b/client/vc_setting_dbus.c @@ -103,12 +103,10 @@ static void __vc_setting_dbus_connection_free() { if (NULL != g_s_conn_listener) { dbus_connection_close(g_s_conn_listener); - dbus_connection_unref(g_s_conn_listener); g_s_conn_listener = NULL; } if (NULL != g_s_conn_sender) { dbus_connection_close(g_s_conn_sender); - dbus_connection_unref(g_s_conn_sender); g_s_conn_sender = NULL; } } diff --git a/client/vc_widget_dbus.c b/client/vc_widget_dbus.c index 0ef7019..adebea1 100644 --- a/client/vc_widget_dbus.c +++ b/client/vc_widget_dbus.c @@ -266,12 +266,10 @@ static void __vc_mgr_dbus_connection_free() { if (NULL != g_w_conn_listener) { dbus_connection_close(g_w_conn_listener); - dbus_connection_unref(g_w_conn_listener); g_w_conn_listener = NULL; } if (NULL != g_w_conn_sender) { dbus_connection_close(g_w_conn_sender); - dbus_connection_unref(g_w_conn_sender); g_w_conn_sender = NULL; } } diff --git a/common/vc_cmd_db.c b/common/vc_cmd_db.c index 43642da..b60d778 100644 --- a/common/vc_cmd_db.c +++ b/common/vc_cmd_db.c @@ -392,6 +392,9 @@ static int __vc_db_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list) free(temp_text); temp_text = NULL; + vc_cmd_destroy(temp_cmd); + temp_cmd = NULL; + ret = sqlite3_step(stmt); if (SQLITE_DONE == ret) break; @@ -442,7 +445,8 @@ static int __vc_db_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list) } else { SLOG(LOG_WARN, vc_db_tag(), "[WARNING] Command type(%d) is NOT valid : request type(%d)", temp, type); - vc_cmd_destroy((vc_cmd_h)temp_cmd); + vc_cmd_destroy(temp_cmd); + temp_cmd = NULL; } ret = sqlite3_step(stmt); if (SQLITE_DONE == ret) diff --git a/common/vc_json_parser.c b/common/vc_json_parser.c index 6e715ab..79e6b31 100755 --- a/common/vc_json_parser.c +++ b/common/vc_json_parser.c @@ -131,6 +131,10 @@ static int __vc_json_set_commands(JsonObject *root_obj, int type, char* invocati ret = vc_db_begin_transaction(); if (0 != ret) { SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to begin transaction for db"); + free(temp_type); + free(prev_appid); + temp_type = NULL; + prev_appid = NULL; return ret; } diff --git a/server/vcd_dbus.c b/server/vcd_dbus.c index 22562b5..0f05eed 100755 --- a/server/vcd_dbus.c +++ b/server/vcd_dbus.c @@ -614,6 +614,7 @@ int vcdc_send_dialog(int manger_pid, int pid, const char* disp_text, const char* char* disp_null = NULL; char* utt_null = NULL; + int ret = VCD_ERROR_NONE; if (NULL == disp_text) { disp_null = strdup("#NULL"); disp_text = disp_null; @@ -635,7 +636,7 @@ int vcdc_send_dialog(int manger_pid, int pid, const char* disp_text, const char* if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) { SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to Send"); - return VCD_ERROR_OPERATION_FAILED; + ret = VCD_ERROR_OPERATION_FAILED; } else { SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] SUCCESS Send"); dbus_connection_flush(g_conn_sender); @@ -653,7 +654,7 @@ int vcdc_send_dialog(int manger_pid, int pid, const char* disp_text, const char* utt_null = NULL; } - return 0; + return ret; } int vcdc_send_error_signal_to_manager(int manager_pid, int reason, char *err_msg) @@ -1163,9 +1164,6 @@ int vcd_dbus_close_connection() dbus_connection_close(g_conn_listener); dbus_connection_close(g_conn_sender); - dbus_connection_unref(g_conn_listener); - dbus_connection_unref(g_conn_sender); - g_conn_listener = NULL; g_conn_sender = NULL; diff --git a/server/vcd_server.c b/server/vcd_server.c index 0129914..ceaf322 100755 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -570,13 +570,14 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int if (top_priority == temp_cmd->priority) { filtered_id[filtered_count] = result_id[i]; filtered_count++; - } else if (top_priority < temp_cmd->priority) { - continue; - } else { + } else if (top_priority > temp_cmd->priority) { filtered_id[0] = result_id[i]; filtered_count = 1; top_priority = temp_cmd->priority; } + + vc_cmd_destroy((vc_cmd_h)temp_cmd); + temp_cmd = NULL; } } @@ -610,6 +611,7 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int if (0 != vc_cmd_list_add(vc_cmd_list, (vc_cmd_h)temp_cmd)) { SLOG(LOG_DEBUG, TAG_VCD, "Fail to add command to list"); vc_cmd_destroy((vc_cmd_h)temp_cmd); + temp_cmd = NULL; } } else { SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] NOT found matached result(%d)", filtered_id[i]); @@ -1139,8 +1141,8 @@ static void __vcd_cleanup_client(vcd_client_type_e type) for (j = 0; j < g_list_length(g_proc_list); j++) { iter = g_list_nth(g_proc_list, j); if (NULL != iter) { - if (client_list[i] == GPOINTER_TO_INT(iter->data)) { - SLOG(LOG_DEBUG, TAG_VCD, "%s pid(%d) is running", type ? (type == 1) ? "Widget" : "Manager" : "Normal", client_list[i]); + if (*(client_list + i) == GPOINTER_TO_INT(iter->data)) { + SLOG(LOG_DEBUG, TAG_VCD, "%s pid(%d) is running", type ? (type == 1) ? "Widget" : "Manager" : "Normal", *(client_list + i)); exist = true; break; } @@ -1148,11 +1150,11 @@ static void __vcd_cleanup_client(vcd_client_type_e type) } if (false == exist) { - SLOG(LOG_ERROR, TAG_VCD, "%s pid(%d) should be removed", type ? (type == 1) ? "Widget" : "Manager" : "Normal", client_list[i]); + SLOG(LOG_ERROR, TAG_VCD, "%s pid(%d) should be removed", type ? (type == 1) ? "Widget" : "Manager" : "Normal", *(client_list + i)); if (VCD_CLIENT_TYPE_NORMAL == type) - vcd_server_finalize(client_list[i]); + vcd_server_finalize(*(client_list + i)); else if (VCD_CLIENT_TYPE_WIDGET == type) - vcd_server_widget_finalize(client_list[i]); + vcd_server_widget_finalize(*(client_list + i)); else vcd_server_mgr_finalize(mgr_pid); } -- 2.7.4 From 89b7affb93d61a35145715753607787e4f7ccf8e Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Fri, 13 Oct 2017 15:08:38 +0900 Subject: [PATCH 08/16] Change api for transfering characters & Fix error check for fread Change-Id: I1b51f5703745bde141b01048dc1f736fc098a29d Signed-off-by: Suyeon Hwang --- client/vc.c | 12 ++++++------ common/vc_cmd_db.c | 2 +- common/vc_command.c | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/client/vc.c b/client/vc.c index 78e5193..cc99912 100644 --- a/client/vc.c +++ b/client/vc.c @@ -104,15 +104,15 @@ static int __check_privilege(const char* uid, const char * privilege) char smack_label[1024] = {'\0',}; if (!p_cynara) { - return false; + return false; } fp = fopen(label_path, "r"); if (fp != NULL) { - if (fread(smack_label, 1, sizeof(smack_label), fp) <= 0) - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] fail to fread"); + if (sizeof(smack_label) != fread(smack_label, 1, sizeof(smack_label), fp)) + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] fail to fread"); - fclose(fp); + fclose(fp); } pid_t pid = getpid(); @@ -120,10 +120,10 @@ static int __check_privilege(const char* uid, const char * privilege) int ret = cynara_check(p_cynara, smack_label, session, uid, privilege); SLOG(LOG_DEBUG, TAG_VCC, "[Client]cynara_check returned %d(%s)", ret, (CYNARA_API_ACCESS_ALLOWED == ret) ? "Allowed" : "Denied"); if (session) - free(session); + free(session); if (ret != CYNARA_API_ACCESS_ALLOWED) - return false; + return false; return true; } diff --git a/common/vc_cmd_db.c b/common/vc_cmd_db.c index b60d778..1105002 100644 --- a/common/vc_cmd_db.c +++ b/common/vc_cmd_db.c @@ -1434,7 +1434,7 @@ static void __vc_db_remove_space(char** string) //remove previous space if (' ' == temp[0]) - strncpy(temp, temp + 1, strlen(temp)); + memmove(temp, temp + 1, strlen(temp)); // remove next space if (' ' == temp[strlen(temp) - 1]) diff --git a/common/vc_command.c b/common/vc_command.c index 2d588e5..b1f0e68 100644 --- a/common/vc_command.c +++ b/common/vc_command.c @@ -97,15 +97,15 @@ static int __check_privilege(const char* uid, const char * privilege) char smack_label[1024] = {'\0',}; if (!p_cynara) { - return false; + return false; } fp = fopen(label_path, "r"); if (fp != NULL) { - if (fread(smack_label, 1, sizeof(smack_label), fp) <= 0) - SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] fail to fread"); + if (sizeof(smack_label) != fread(smack_label, 1, sizeof(smack_label), fp)) + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] fail to fread"); - fclose(fp); + fclose(fp); } pid_t pid = getpid(); @@ -113,10 +113,10 @@ static int __check_privilege(const char* uid, const char * privilege) int ret = cynara_check(p_cynara, smack_label, session, uid, privilege); SLOG(LOG_DEBUG, TAG_VCCMD, "[Client]cynara_check returned %d(%s)", ret, (CYNARA_API_ACCESS_ALLOWED == ret) ? "Allowed" : "Denied"); if (session) - free(session); + free(session); if (ret != CYNARA_API_ACCESS_ALLOWED) - return false; + return false; return true; } -- 2.7.4 From d9132be37d293949d402384952e5793f9997d80b Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Fri, 20 Oct 2017 10:51:23 +0900 Subject: [PATCH 09/16] Add to set false as exit when dbus disconnects Change-Id: I7966ef43d27f65111798a8f86797d32765678695 Signed-off-by: Wonnam Jang --- client/vc_dbus.c | 6 +++++- client/vc_mgr_dbus.c | 4 ++++ client/vc_widget_dbus.c | 4 ++++ server/vcd_dbus.c | 4 ++++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/client/vc_dbus.c b/client/vc_dbus.c index 7e69069..49d4510 100644 --- a/client/vc_dbus.c +++ b/client/vc_dbus.c @@ -225,6 +225,8 @@ int vc_dbus_open_connection() return VC_ERROR_OPERATION_FAILED; } + dbus_connection_set_exit_on_disconnect(g_conn_sender, false); + g_conn_listener = dbus_bus_get_private(DBUS_BUS_SESSION, &err); if (dbus_error_is_set(&err)) { @@ -238,6 +240,8 @@ int vc_dbus_open_connection() return VC_ERROR_OPERATION_FAILED; } + dbus_connection_set_exit_on_disconnect(g_conn_listener, false); + int pid = getpid(); char service_name[64]; @@ -1568,4 +1572,4 @@ int vc_dbus_request_auth_cancel(int pid, int mgr_pid) } return result; -} \ No newline at end of file +} diff --git a/client/vc_mgr_dbus.c b/client/vc_mgr_dbus.c index a552504..2cfd533 100644 --- a/client/vc_mgr_dbus.c +++ b/client/vc_mgr_dbus.c @@ -628,6 +628,8 @@ int vc_mgr_dbus_open_connection() return VC_ERROR_OPERATION_FAILED; } + dbus_connection_set_exit_on_disconnect(g_m_conn_sender, false); + /* connect to the DBUS system bus, and check for errors */ g_m_conn_listener = dbus_bus_get_private(DBUS_BUS_SESSION, &err); @@ -642,6 +644,8 @@ int vc_mgr_dbus_open_connection() return VC_ERROR_OPERATION_FAILED; } + dbus_connection_set_exit_on_disconnect(g_m_conn_listener, false); + SLOG(LOG_DEBUG, TAG_VCM, "service name is %s", VC_MANAGER_SERVICE_NAME); /* register our name on the bus, and check for errors */ diff --git a/client/vc_widget_dbus.c b/client/vc_widget_dbus.c index adebea1..a40fd93 100644 --- a/client/vc_widget_dbus.c +++ b/client/vc_widget_dbus.c @@ -300,6 +300,8 @@ int vc_widget_dbus_open_connection() return VC_ERROR_OPERATION_FAILED; } + dbus_connection_set_exit_on_disconnect(g_w_conn_sender, false); + g_w_conn_listener = dbus_bus_get_private(DBUS_BUS_SESSION, &err); if (dbus_error_is_set(&err)) { @@ -313,6 +315,8 @@ int vc_widget_dbus_open_connection() return VC_ERROR_OPERATION_FAILED; } + dbus_connection_set_exit_on_disconnect(g_w_conn_listener, false); + int pid = getpid(); char service_name[64]; diff --git a/server/vcd_dbus.c b/server/vcd_dbus.c index 0f05eed..f2486e4 100755 --- a/server/vcd_dbus.c +++ b/server/vcd_dbus.c @@ -1089,6 +1089,8 @@ int vcd_dbus_open_connection() return VCD_ERROR_OPERATION_FAILED; } + dbus_connection_set_exit_on_disconnect(g_conn_sender, false); + /* connect to the bus and check for errors */ g_conn_listener = dbus_bus_get_private(DBUS_BUS_SESSION, &err); @@ -1102,6 +1104,8 @@ int vcd_dbus_open_connection() return VCD_ERROR_OPERATION_FAILED; } + dbus_connection_set_exit_on_disconnect(g_conn_listener, false); + /* request our name on the bus and check for errors */ ret = dbus_bus_request_name(g_conn_listener, VC_SERVER_SERVICE_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING, &err); -- 2.7.4 From b0f1e20c19fa34c2643f0d0ab506f2dab29f499a Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Mon, 23 Oct 2017 18:45:21 +0900 Subject: [PATCH 10/16] Add logic to set default language of the engine Change-Id: I086ff98a7ce7c1d04f4f03e7a63297bad573a9e3 Signed-off-by: Suyeon Hwang (cherry picked from commit 661dc62bec74e1294096cf94f16feef8d4f38987) --- common/vc_config_mgr.c | 46 +++++++++++++--------------------------------- common/vc_config_parser.c | 23 +++++++++++++++++++++++ common/vc_config_parser.h | 1 + 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/common/vc_config_mgr.c b/common/vc_config_mgr.c index a85b57f..c8dc9de 100755 --- a/common/vc_config_mgr.c +++ b/common/vc_config_mgr.c @@ -215,7 +215,7 @@ int __vc_config_mgr_select_lang(const char* engine_id, char** language) { if (NULL == engine_id || NULL == language) { SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL"); - return false; + return VC_ERROR_OPERATION_FAILED; } GSList *iter = NULL; @@ -223,7 +223,7 @@ int __vc_config_mgr_select_lang(const char* engine_id, char** language) if (0 >= g_slist_length(g_engine_list)) { SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine!!"); - return false; + return VC_ERROR_OPERATION_FAILED; } /* Get a first item */ @@ -234,7 +234,8 @@ int __vc_config_mgr_select_lang(const char* engine_id, char** language) if (NULL == engine_info) { SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] engine info is NULL"); - return false; + iter = g_slist_next(iter); + continue; } if (0 != strcmp(engine_id, engine_info->uuid)) { @@ -242,41 +243,20 @@ int __vc_config_mgr_select_lang(const char* engine_id, char** language) continue; } - GSList *iter_lang = NULL; - char* engine_lang = NULL; - if (g_slist_length(engine_info->languages) > 0) { - /* Get a first item */ - iter_lang = g_slist_nth(engine_info->languages, 0); - - while (NULL != iter_lang) { - engine_lang = iter_lang->data; - if (NULL != engine_lang) { - /* Check base language */ - if (0 == strcmp(VC_BASE_LANGUAGE, engine_lang)) { - *language = strdup(engine_lang); - SLOG(LOG_DEBUG, vc_config_tag(), "Selected language : %s", *language); - return 0; - } - } + if (NULL == engine_info->default_lang) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] default language of engine info is NULL"); + return VC_ERROR_INVALID_LANGUAGE; + } - iter_lang = g_slist_next(iter_lang); - } + *language = strdup(engine_info->default_lang); - /* Not support base language */ - iter_lang = g_slist_nth(engine_info->languages, 0); - if (NULL != iter_lang) - engine_lang = iter_lang->data; - - if (NULL != engine_lang) { - *language = strdup(engine_lang); - SLOG(LOG_DEBUG, vc_config_tag(), "Selected language : %s", *language); - return 0; - } + if (NULL != *language) { + SLOG(LOG_DEBUG, vc_config_tag(), "Selected language : %s", *language); + return VC_ERROR_NONE; } - break; } - return -1; + return VC_ERROR_OPERATION_FAILED; } Eina_Bool vc_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handler) diff --git a/common/vc_config_parser.c b/common/vc_config_parser.c index 3950472..0048a05 100644 --- a/common/vc_config_parser.c +++ b/common/vc_config_parser.c @@ -29,6 +29,7 @@ #define VC_TAG_ENGINE_BASE_TAG "voice-control-engine" #define VC_TAG_ENGINE_NAME "name" #define VC_TAG_ENGINE_ID "id" +#define VC_TAG_ENGINE_DEFAULT "default" #define VC_TAG_ENGINE_LANGUAGE_SET "languages" #define VC_TAG_ENGINE_LANGUAGE "lang" #define VC_TAG_ENGINE_NON_FIXED_SUPPORT "non-fixed-support" @@ -116,9 +117,12 @@ int vc_parser_get_engine_info(const char* path, vc_engine_info_s** engine_info) temp->name = NULL; temp->uuid = NULL; + temp->default_lang = NULL; temp->languages = NULL; temp->non_fixed_support = false; + bool is_default_lang_set = false; + while (cur != NULL) { if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_ENGINE_NAME)) { key = xmlNodeGetContent(cur); @@ -140,6 +144,18 @@ int vc_parser_get_engine_info(const char* path, vc_engine_info_s** engine_info) } else { SLOG(LOG_WARN, vc_config_tag(), "[WARNING] <%s> has no content", VC_TAG_ENGINE_ID); } + } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_ENGINE_DEFAULT)) { + key = xmlNodeGetContent(cur); + if (NULL != key) { + /* SLOG(LOG_DEBUG, vc_config_tag(), "Engine uuid : %s", (char *)key); */ + if (NULL != temp->default_lang) free(temp->default_lang); + temp->default_lang = strdup((char*)key); + + is_default_lang_set = true; + xmlFree(key); + } else { + SLOG(LOG_WARN, vc_config_tag(), "[WARNING] <%s> has no content", VC_TAG_ENGINE_DEFAULT); + } } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_ENGINE_LANGUAGE_SET)) { xmlNodePtr lang_node = NULL; char* temp_lang = NULL; @@ -153,6 +169,13 @@ int vc_parser_get_engine_info(const char* path, vc_engine_info_s** engine_info) /* SLOG(LOG_DEBUG, vc_config_tag(), "language : %s", (char *)key); */ temp_lang = strdup((char*)key); temp->languages = g_slist_append(temp->languages, temp_lang); + + if (false == is_default_lang_set) { + if (NULL != temp->default_lang) free(temp->default_lang); + temp->default_lang = strdup((char*)key); + + is_default_lang_set = true; + } xmlFree(key); } else { SLOG(LOG_WARN, vc_config_tag(), "[WARNING] <%s> has no content", VC_TAG_ENGINE_LANGUAGE); diff --git a/common/vc_config_parser.h b/common/vc_config_parser.h index e862865..253aa11 100644 --- a/common/vc_config_parser.h +++ b/common/vc_config_parser.h @@ -28,6 +28,7 @@ extern "C" { typedef struct { char* name; char* uuid; + char* default_lang; GSList* languages; bool non_fixed_support; } vc_engine_info_s; -- 2.7.4 From 10b9f960de6b162309c90f24a163a5a6680525ac Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Fri, 27 Oct 2017 10:19:37 +0900 Subject: [PATCH 11/16] Add to check db integrity and restore logic Change-Id: Ibf2f91c1eca9a00c43ed80e5c8cb3f5dbb55c12a Signed-off-by: Wonnam Jang --- client/vc.c | 16 +- common/vc_cmd_db.c | 468 ++++++++++++++++++++++++++++++++++-------------- common/vc_cmd_db.h | 10 +- common/vc_defs.h | 30 ++-- common/vc_info_parser.c | 4 +- common/vc_json_parser.c | 2 +- 6 files changed, 373 insertions(+), 157 deletions(-) mode change 100755 => 100644 common/vc_json_parser.c diff --git a/client/vc.c b/client/vc.c index cc99912..2afb878 100644 --- a/client/vc.c +++ b/client/vc.c @@ -51,6 +51,7 @@ static vc_h g_vc = NULL; static int g_daemon_pid = 0; static int g_feature_enabled = -1; +static bool g_backup = false; static int g_privilege_allowed = -1; static cynara *p_cynara = NULL; @@ -397,6 +398,8 @@ static void __vc_internal_unprepare(void) int vc_deinitialize(void) { + int ret = VC_ERROR_NONE; + if (0 != __vc_get_feature_enabled()) { return VC_ERROR_NOT_SUPPORTED; } @@ -439,7 +442,15 @@ int vc_deinitialize(void) } SLOG(LOG_DEBUG, TAG_VCC, "Success: destroy"); - int ret = vc_db_finalize(); + + if (true == g_backup) { + ret = vc_db_backup_command(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to backup command, ret(%d)", ret); + } + } + + ret = vc_db_finalize(); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to finalize DB, ret(%d)", ret); } @@ -1111,6 +1122,9 @@ int vc_set_command_list(vc_cmd_list_h vc_cmd_list, int type) invocation_name = NULL; } + if (VC_COMMAND_TYPE_BACKGROUND == type) + g_backup = true; + SLOG(LOG_DEBUG, TAG_VCC, "@@@"); return ret; diff --git a/common/vc_cmd_db.c b/common/vc_cmd_db.c index 1105002..5b1face 100644 --- a/common/vc_cmd_db.c +++ b/common/vc_cmd_db.c @@ -56,12 +56,14 @@ const char* vc_db_tag() //#define DB_PATH tzplatform_mkpath(TZ_USER_DB, ".vc_info.db") -static sqlite3* db_handle = NULL; -char* path = NULL; +static sqlite3* g_db_handle = NULL; +static sqlite3* g_db_backup_handle = NULL; +char* g_path = NULL; +char* g_backup_path = NULL; int g_fpid = -1; int g_ref_cnt = 0; -static int __vc_db_transaction(const char* transaction) +static int __vc_db_transaction(sqlite3* db_handle, const char* transaction) { sqlite3_stmt* pStmt = NULL; @@ -81,25 +83,25 @@ static int __vc_db_transaction(const char* transaction) return VC_DB_ERROR_NONE; } -static int __vc_db_begin_transaction(void) +static int __vc_db_begin_transaction(sqlite3* db_handle) { - int ret = __vc_db_transaction("BEGIN TRANSACTION"); + int ret = __vc_db_transaction(db_handle, "BEGIN TRANSACTION"); return ret; } -static int __vc_db_rollback_transaction(void) +static int __vc_db_rollback_transaction(sqlite3* db_handle) { - int ret = __vc_db_transaction("ROLLBACK TRANSACTION"); + int ret = __vc_db_transaction(db_handle, "ROLLBACK TRANSACTION"); return ret; } -static int __vc_db_commit_transaction(void) +static int __vc_db_commit_transaction(sqlite3* db_handle) { - int ret = __vc_db_transaction("COMMIT TRANSACTION"); + int ret = __vc_db_transaction(db_handle, "COMMIT TRANSACTION"); return ret; } -static int __vc_db_exec_query(const char* sql) +static int __vc_db_exec_query(sqlite3* db_handle, const char* sql) { char* err_msg = NULL; @@ -112,7 +114,7 @@ static int __vc_db_exec_query(const char* sql) return VC_DB_ERROR_NONE; } -static int __vc_db_delete_commands(int pid, vc_cmd_type_e type, const char* appid) +static int __vc_db_delete_commands(sqlite3* db_handle, int pid, vc_cmd_type_e type, const char* appid) { sqlite3_stmt* stmt = NULL; char* sql = NULL; @@ -191,7 +193,7 @@ static int __vc_db_delete_commands(int pid, vc_cmd_type_e type, const char* appi return VC_DB_ERROR_NONE; } -static int __vc_db_insert_commands(int pid, vc_cmd_type_e type, vc_cmd_s* cmd) +static int __vc_db_insert_commands(sqlite3* db_handle, int pid, vc_cmd_type_e type, vc_cmd_s* cmd) { SLOG(LOG_DEBUG, vc_db_tag(), "pid(%d), type(%d)", pid, type); @@ -290,7 +292,7 @@ static int __vc_db_insert_commands(int pid, vc_cmd_type_e type, vc_cmd_s* cmd) return VC_DB_ERROR_NONE; } -static int __vc_db_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list) +static int __vc_db_get_commands(sqlite3* db_handle, int pid, vc_cmd_type_e type, GSList** cmd_list) { SLOG(LOG_DEBUG, vc_db_tag(), "pid(%d), type(%d)", pid, type); @@ -500,7 +502,7 @@ static int __vc_db_get_pid(const char* appid, int* pid) return VC_DB_ERROR_NONE; } -static int __vc_db_insert_result(const char* result_text, int event, const char* msg, bool exclusive, vc_cmd_s* cmd) +static int __vc_db_insert_result(sqlite3* db_handle, const char* result_text, int event, const char* msg, bool exclusive, vc_cmd_s* cmd) { SLOG(LOG_DEBUG, vc_db_tag(), "result_text(%s), event(%d), msg(%s), exclusive(%d), cmd(%p)", result_text, event, msg, exclusive, cmd); @@ -707,7 +709,7 @@ static int __vc_db_extract_unfixed_command(char* command, char* fixed, char** te return VC_DB_ERROR_NONE; } -static int __vc_db_get_result(char** result_text, int* event, char** msg, int pid, char* appid, vc_cmd_list_h vc_cmd_list, bool exclusive) +static int __vc_db_get_result(sqlite3* db_handle, char** result_text, int* event, char** msg, int pid, char* appid, vc_cmd_list_h vc_cmd_list, bool exclusive) { int ret = 0; sqlite3_stmt* stmt = NULL; @@ -929,7 +931,7 @@ void __vc_db_demandable_client_free(void* data) } } -static int __vc_db_get_appid(const char* result, GSList** app_list) +static int __vc_db_get_appid(sqlite3* db_handle, const char* result, GSList** app_list) { GSList* temp_app_list = NULL; @@ -1001,7 +1003,7 @@ static int __vc_db_get_appid(const char* result, GSList** app_list) return VC_DB_ERROR_NONE; } -int __vc_db_get_result_pid_list(const char* result, GSList** pid_list) +int __vc_db_get_result_pid_list(sqlite3* db_handle, const char* result, GSList** pid_list) { GSList* temp_pid_list = NULL; @@ -1070,7 +1072,7 @@ int __vc_db_get_result_pid_list(const char* result, GSList** pid_list) return VC_DB_ERROR_NONE; } -static int __vc_db_append_commands(int pid, int type, vc_cmd_list_h vc_cmd_list) +static int __vc_db_append_commands(sqlite3* db_handle, int pid, int type, vc_cmd_list_h vc_cmd_list) { SLOG(LOG_ERROR, vc_db_tag(), "pid(%d), type(%d)", pid, type); @@ -1229,73 +1231,182 @@ static vc_cmd_s* __vc_db_command_copy(vc_cmd_s* src_cmd) return temp_cmd; } -int vc_db_initialize(void) +int __vc_db_create_table(sqlite3* db_handle) { - SLOG(LOG_INFO, vc_db_tag(), "DB initialization"); + const char* vc_info_sql = "CREATE TABLE IF NOT EXISTS vc_info (id INTEGER PRIMARY KEY AUTOINCREMENT, pid INTEGER, type INTEGER, format INTEGER, domain INTEGER, \ + command TEXT, parameter TEXT, appid TEXT, invocation_name TEXT, fixed TEXT);"; + const char* vc_result_sql = "CREATE TABLE IF NOT EXISTS vc_result (id INTEGER PRIMARY KEY AUTOINCREMENT, result TEXT, event INTEGER, msg TEXT, exclusive INTEGER,\ + pid INTEGER, type INTEGER, format INTEGER, domain INTEGER, command TEXT, parameter TEXT, appid TEXT, invocation_name TEXT, fixed TEXT);"; - if (0 < g_ref_cnt) { - g_ref_cnt++; - return VC_DB_ERROR_NONE; + int ret = __vc_db_exec_query(db_handle, vc_info_sql); + if (ret != VC_DB_ERROR_NONE) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to create table, %d", ret); + return VC_DB_ERROR_OPERATION_FAILED; } + SLOG(LOG_WARN, vc_db_tag(), "[SQL] %s", vc_info_sql); - path = (char*)calloc(256, sizeof(char)); - if (NULL == path) { - SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to allocate memory"); - return VC_DB_ERROR_OUT_OF_MEMORY; + ret = __vc_db_exec_query(db_handle, vc_result_sql); + if (ret != VC_DB_ERROR_NONE) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to create table, %d", ret); + return ret; } + SLOG(LOG_WARN, vc_db_tag(), "[SQL] %s", vc_result_sql); - /* This should be changed to general DB space - TZ_USER_DB */ - snprintf(path, 256, "%s/.vc_info.db", VC_RUNTIME_INFO_ROOT); + return VC_DB_ERROR_NONE; +} +int __vc_db_open_db(char** path, sqlite3** db_handle) +{ struct stat stat; - int ret = db_util_open(path, &db_handle, DB_UTIL_REGISTER_HOOK_METHOD); + int ret = db_util_open(*path, db_handle, DB_UTIL_REGISTER_HOOK_METHOD); if (ret != SQLITE_OK) { - SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open db, path = %s, ret %d: %s", path, ret, sqlite3_errmsg(db_handle)); - if (db_handle) { - db_util_close(db_handle); - db_handle = NULL; + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open db, path = %s, ret %d: %s", *path, ret, sqlite3_errmsg(*db_handle)); + if (*db_handle) { + db_util_close(*db_handle); + *db_handle = NULL; } - free(path); - path = NULL; + free(*path); + *path = NULL; return VC_DB_ERROR_OPERATION_FAILED; } - if (lstat(path, &stat) < 0) { + if (lstat(*path, &stat) < 0) { char buf_err[256]; SLOG(LOG_ERROR, vc_db_tag(), "%d", strerror_r(errno, buf_err, sizeof(buf_err))); - if (db_handle) - db_util_close(db_handle); - db_handle = NULL; + if (*db_handle) + db_util_close(*db_handle); + *db_handle = NULL; - free(path); - path = NULL; + free(*path); + *path = NULL; return VC_DB_ERROR_OPERATION_FAILED; } if (!S_ISREG(stat.st_mode)) { SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] S_ISREG failed"); - if (db_handle) - db_util_close(db_handle); - db_handle = NULL; + if (*db_handle) + db_util_close(*db_handle); + *db_handle = NULL; - free(path); - path = NULL; + free(*path); + *path = NULL; return VC_DB_ERROR_OPERATION_FAILED; } if (!stat.st_size) { - vc_db_create_table(); + __vc_db_begin_transaction(*db_handle); + + int ret = __vc_db_create_table(*db_handle); + if (ret != VC_DB_ERROR_NONE) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to create table, %d", ret); + __vc_db_rollback_transaction(*db_handle); + return VC_DB_ERROR_OPERATION_FAILED; + } + + __vc_db_commit_transaction(*db_handle); } - if (db_handle) { + if (*db_handle) { char* err_msg = NULL; static const const char* sql = "PRAGMA journal_mode = WAL"; - int ret = sqlite3_exec(db_handle, sql, NULL, NULL, &err_msg); + int ret = sqlite3_exec(*db_handle, sql, NULL, NULL, &err_msg); if (ret != SQLITE_OK) { SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_exec returned %d: %s", ret, err_msg); } } + return VC_DB_ERROR_NONE; +} + +static int __vc_db_integrity_check_cb(void *NotUsed, int argc, char **argv, char **azColName) +{ + SLOG(LOG_INFO, vc_db_tag(), "integrity check cb is called"); + return 0; +} + +int vc_db_initialize(void) +{ + SLOG(LOG_INFO, vc_db_tag(), "DB initialization"); + + if (0 < g_ref_cnt) { + g_ref_cnt++; + return VC_DB_ERROR_NONE; + } + + /* For voice control DB */ + g_path = (char*)calloc(256, sizeof(char)); + if (NULL == g_path) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to allocate memory"); + return VC_DB_ERROR_OUT_OF_MEMORY; + } + /* This should be changed to general DB space - TZ_USER_DB */ + snprintf(g_path, 256, "%s/.vc_info.db", VC_RUNTIME_INFO_ROOT); + + /* For Backup DB */ + g_backup_path = (char*)calloc(256, sizeof(char)); + if (NULL == g_backup_path) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to allocate memory"); + return VC_DB_ERROR_OUT_OF_MEMORY; + } + snprintf(g_backup_path, 256, "%s/.vc_backup.db", VC_RUNTIME_INFO_ROOT); + + if (0 != __vc_db_open_db(&g_path, &g_db_handle)) { + int cnt = 0; + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open DB"); + if (0 != remove(g_path)) { + SLOG(LOG_ERROR, vc_db_tag(), "[Error] remove file(%s) is failed", g_path); + } + if (0 != __vc_db_open_db(&g_path, &g_db_handle)) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open DB"); + } + while (cnt <= 5) { + if (0 != __vc_db_open_db(&g_backup_path, &g_db_backup_handle)) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open backup DB"); + } else { + break; + } + cnt++; + } + if (0 != vc_db_restore_command()) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to restore command"); + } + } + + if (SQLITE_CORRUPT == sqlite3_exec(g_db_handle, "pragma integrity_check", __vc_db_integrity_check_cb, NULL, NULL)) { + int cnt = 0; + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open DB"); + if (0 != remove(g_path)) { + SLOG(LOG_ERROR, vc_db_tag(), "[Error] remove file(%s) is failed", g_path); + } + if (0 != __vc_db_open_db(&g_path, &g_db_handle)) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open DB"); + } + while (cnt <= 5) { + if (0 != __vc_db_open_db(&g_backup_path, &g_db_backup_handle)) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open backup DB"); + } else { + break; + } + cnt++; + } + if (0 != vc_db_restore_command()) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to restore command"); + } + } + + if (0 != __vc_db_open_db(&g_backup_path, &g_db_backup_handle)) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open backup DB"); + if (0 != remove(g_backup_path)) { + SLOG(LOG_ERROR, vc_db_tag(), "[Error] remove file(%s) is failed", g_backup_path); + } + if (0 != __vc_db_open_db(&g_backup_path, &g_db_backup_handle)) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open backup DB"); + } + if (0 != vc_db_backup_command()) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to backup command"); + } + } + g_ref_cnt++; return VC_DB_ERROR_NONE; } @@ -1306,56 +1417,51 @@ int vc_db_finalize(void) if (0 != --g_ref_cnt) return VC_DB_ERROR_NONE; - if (NULL != path) { - free(path); - path = NULL; + if (NULL != g_path) { + free(g_path); + g_path = NULL; + } + + if (NULL != g_backup_path) { + free(g_backup_path); + g_backup_path = NULL; } - if (!db_handle) + if (!g_db_handle) return 0; + db_util_close(g_db_handle); + g_db_handle = NULL; - db_util_close(db_handle); + if (!g_db_backup_handle) + return 0; + db_util_close(g_db_backup_handle); + g_db_backup_handle = NULL; - db_handle = NULL; return VC_DB_ERROR_NONE; } -int vc_db_create_table(void) +int vc_db_create_table() { - __vc_db_begin_transaction(); + __vc_db_begin_transaction(g_db_handle); - const char* vc_info_sql = "CREATE TABLE IF NOT EXISTS vc_info (id INTEGER PRIMARY KEY AUTOINCREMENT, pid INTEGER, type INTEGER, format INTEGER, domain INTEGER, \ - command TEXT, parameter TEXT, appid TEXT, invocation_name TEXT, fixed TEXT);"; - const char* vc_result_sql = "CREATE TABLE IF NOT EXISTS vc_result (id INTEGER PRIMARY KEY AUTOINCREMENT, result TEXT, event INTEGER, msg TEXT, exclusive INTEGER,\ - pid INTEGER, type INTEGER, format INTEGER, domain INTEGER, command TEXT, parameter TEXT, appid TEXT, invocation_name TEXT, fixed TEXT);"; - - int ret = __vc_db_exec_query(vc_info_sql); + int ret = __vc_db_create_table(g_db_handle); if (ret != VC_DB_ERROR_NONE) { SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to create table, %d", ret); - __vc_db_rollback_transaction(); + __vc_db_rollback_transaction(g_db_handle); return VC_DB_ERROR_OPERATION_FAILED; } - SLOG(LOG_WARN, vc_db_tag(), "[SQL] %s", vc_info_sql); - ret = __vc_db_exec_query(vc_result_sql); - if (ret != VC_DB_ERROR_NONE) { - SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to create table, %d", ret); - __vc_db_rollback_transaction(); - return ret; - } - SLOG(LOG_WARN, vc_db_tag(), "[SQL] %s", vc_result_sql); - - __vc_db_commit_transaction(); + __vc_db_commit_transaction(g_db_handle); return VC_DB_ERROR_NONE; } -int vc_db_delete_table(const char* table) +int __vc_db_delete_table(sqlite3* db_handle, const char* table) { char* sql = NULL; - if (0 == strncmp(table, "result", strlen(table))) { + if (0 == strncmp(table, VC_RESULT_TABLE, strlen(table))) { sql = strdup("DELETE FROM vc_result;"); - } else if (0 == strncmp(table, "command", strlen(table))) { - sql = strdup("DELETE_FROM vc_info;"); + } else if (0 == strncmp(table, VC_INFO_TABLE, strlen(table))) { + sql = strdup("DELETE FROM vc_info;"); } else { return VC_DB_ERROR_INVALID_PARAMETER; } @@ -1365,12 +1471,9 @@ int vc_db_delete_table(const char* table) return VC_DB_ERROR_OUT_OF_MEMORY; } - __vc_db_begin_transaction(); - - int ret = __vc_db_exec_query(sql); + int ret = __vc_db_exec_query(db_handle, sql); if (ret != VC_DB_ERROR_NONE) { SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to delete table, %d", ret); - __vc_db_rollback_transaction(); free(sql); sql = NULL; return ret; @@ -1379,9 +1482,9 @@ int vc_db_delete_table(const char* table) free(sql); sql = NULL; - if (0 == strncmp(table, "result", strlen(table))) { + if (0 == strncmp(table, VC_RESULT_TABLE, strlen(table))) { sql = strdup("UPDATE SQLITE_SEQUENCE SET SEQ=0 WHERE NAME='vc_result';"); - } else if (0 == strncmp(table, "command", strlen(table))) { + } else if (0 == strncmp(table, VC_INFO_TABLE, strlen(table))) { sql = strdup("UPDATE SQLITE_SEQUENCE SET SEQ=0 WHERE NAME='vc_info';"); } @@ -1390,38 +1493,52 @@ int vc_db_delete_table(const char* table) return VC_DB_ERROR_OUT_OF_MEMORY; } - ret = __vc_db_exec_query(sql); + ret = __vc_db_exec_query(db_handle, sql); if (ret != VC_DB_ERROR_NONE) { SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to delete table, %d", ret); - __vc_db_rollback_transaction(); free(sql); sql = NULL; return ret; } SLOG(LOG_WARN, vc_db_tag(), "[SQL] %s", sql); - __vc_db_commit_transaction(); free(sql); sql = NULL; return VC_DB_ERROR_NONE; } +int vc_db_delete_table(const char* table) +{ + __vc_db_begin_transaction(g_db_handle); + + int ret = __vc_db_delete_table(g_db_handle, table); + if (0 != ret) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to delete table"); + __vc_db_rollback_transaction(g_db_handle); + return ret; + } + + __vc_db_commit_transaction(g_db_handle); + + return VC_DB_ERROR_NONE; +} + int vc_db_begin_transaction(void) { - int ret = __vc_db_begin_transaction(); + int ret = __vc_db_begin_transaction(g_db_handle); return ret; } int vc_db_rollback_transaction(void) { - int ret = __vc_db_rollback_transaction(); + int ret = __vc_db_rollback_transaction(g_db_handle); return ret; } int vc_db_commit_transaction(void) { - int ret = __vc_db_commit_transaction(); + int ret = __vc_db_commit_transaction(g_db_handle); return ret; } @@ -1562,7 +1679,7 @@ static int __vc_db_generate_command(vc_cmd_s* cmd, char** fixed_cmd, GSList** cm return VC_DB_ERROR_NONE; } -int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd) +static int __vc_db_insert_command(sqlite3* db_handle, int pid, vc_cmd_type_e type, vc_cmd_s* cmd, bool skip_invocation) { GSList* cmd_list = NULL; char* fixed_cmd = NULL; @@ -1597,7 +1714,7 @@ int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd) else tmp_cmd->fixed = NULL; - ret = __vc_db_insert_commands(pid, type, tmp_cmd); + ret = __vc_db_insert_commands(db_handle, pid, type, tmp_cmd); if (ret != VC_DB_ERROR_NONE) { if (NULL != fixed_cmd) { free(fixed_cmd); @@ -1607,7 +1724,7 @@ int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd) break; } - if (VC_COMMAND_TYPE_BACKGROUND == type && NULL != tmp_cmd->invocation_name) { + if (VC_COMMAND_TYPE_BACKGROUND == type && NULL != tmp_cmd->invocation_name && false == skip_invocation) { char temp[256] = {0, }; snprintf(temp, 256, "%s %s", tmp_cmd->invocation_name, tmp_cmd->command); if (NULL != tmp_cmd->command) @@ -1615,7 +1732,7 @@ int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd) tmp_cmd->command = strdup(temp); - ret = __vc_db_insert_commands(pid, type, tmp_cmd); + ret = __vc_db_insert_commands(db_handle, pid, type, tmp_cmd); if (ret != VC_DB_ERROR_NONE) { if (NULL != fixed_cmd) { free(fixed_cmd); @@ -1661,7 +1778,17 @@ int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd) return VC_DB_ERROR_NONE; } -int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, char* invocation_name) +int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd, bool skip_invocation) +{ + int ret = __vc_db_insert_command(g_db_handle, pid, type, cmd, skip_invocation); + if (0 != ret) { + SLOG(LOG_DEBUG, vc_db_tag(), "[ERROR] Fail to insert command, %d", ret); + } + return ret; +} + + +static int __vc_db_insert_commands_list(sqlite3* db_handle, int pid, vc_cmd_type_e type, GSList* cmd_list, char* invocation_name, bool skip_invocation) { GSList *iter = NULL; vc_cmd_s *temp_cmd; @@ -1672,8 +1799,6 @@ int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, ch SLOG(LOG_DEBUG, vc_db_tag(), "list count : %d", count); - __vc_db_begin_transaction(); - for (i = 0; i < count; i++) { if (NULL == iter) break; @@ -1689,10 +1814,9 @@ int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, ch if (NULL != invocation_name) temp_cmd->invocation_name = strdup(invocation_name); - int ret = vc_db_insert_command(pid, type, temp_cmd); + int ret = __vc_db_insert_command(db_handle, pid, type, temp_cmd, skip_invocation); if (ret != VC_DB_ERROR_NONE) { SLOG(LOG_ERROR, vc_db_tag(), "Fail to insert command, ret(%d)", ret); - __vc_db_rollback_transaction(); return ret; } } else { @@ -1701,22 +1825,35 @@ int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, ch iter = g_slist_next(iter); } - __vc_db_commit_transaction(); + return VC_DB_ERROR_NONE; +} + +int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, char* invocation_name, bool skip_invocation) +{ + __vc_db_begin_transaction(g_db_handle); + + int ret = __vc_db_insert_commands_list(g_db_handle, pid, type, cmd_list, invocation_name, false); + if (ret != VC_DB_ERROR_NONE) { + __vc_db_rollback_transaction(g_db_handle); + return ret; + } + + __vc_db_commit_transaction(g_db_handle); return VC_DB_ERROR_NONE; } int vc_db_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list) { - __vc_db_begin_transaction(); + __vc_db_begin_transaction(g_db_handle); - int ret = __vc_db_get_commands(pid, type, cmd_list); + int ret = __vc_db_get_commands(g_db_handle, pid, type, cmd_list); if (ret != VC_DB_ERROR_NONE) { - __vc_db_rollback_transaction(); + __vc_db_rollback_transaction(g_db_handle); return ret; } - __vc_db_commit_transaction(); + __vc_db_commit_transaction(g_db_handle); return VC_DB_ERROR_NONE; } @@ -1727,18 +1864,18 @@ int vc_db_insert_result(const char* result_text, int event, const char* msg, vc_ return VC_DB_ERROR_INVALID_PARAMETER; } - int ret = vc_db_delete_table("result"); + int ret = vc_db_delete_table(VC_RESULT_TABLE); if (0 != ret) LOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to delete table"); if (NULL == vc_cmd_list) { - __vc_db_begin_transaction(); - int ret = __vc_db_insert_result(result_text, event, msg, exclusive, NULL); + __vc_db_begin_transaction(g_db_handle); + int ret = __vc_db_insert_result(g_db_handle, result_text, event, msg, exclusive, NULL); if (ret != VC_DB_ERROR_NONE) { - __vc_db_rollback_transaction(); + __vc_db_rollback_transaction(g_db_handle); return ret; } - __vc_db_commit_transaction(); + __vc_db_commit_transaction(g_db_handle); return VC_DB_ERROR_NONE; } @@ -1760,13 +1897,13 @@ int vc_db_insert_result(const char* result_text, int event, const char* msg, vc_ vc_cmd_s* temp_cmd = NULL; temp_cmd = (vc_cmd_s*)vc_command; - __vc_db_begin_transaction(); - ret = __vc_db_insert_result(result_text, event, msg, exclusive, temp_cmd); + __vc_db_begin_transaction(g_db_handle); + ret = __vc_db_insert_result(g_db_handle, result_text, event, msg, exclusive, temp_cmd); if (ret != VC_DB_ERROR_NONE) { - __vc_db_rollback_transaction(); + __vc_db_rollback_transaction(g_db_handle); return ret; } - __vc_db_commit_transaction(); + __vc_db_commit_transaction(g_db_handle); ret = vc_cmd_list_next(vc_cmd_list); } @@ -1776,11 +1913,11 @@ int vc_db_insert_result(const char* result_text, int event, const char* msg, vc_ int vc_db_get_result(char** result_text, int* event, char** msg, int pid, vc_cmd_list_h vc_cmd_list, bool exclusive) { - __vc_db_begin_transaction(); + __vc_db_begin_transaction(g_db_handle); - int ret = __vc_db_get_result(result_text, event, msg, pid, NULL, vc_cmd_list, exclusive); + int ret = __vc_db_get_result(g_db_handle, result_text, event, msg, pid, NULL, vc_cmd_list, exclusive); if (ret != VC_DB_ERROR_NONE) { - __vc_db_rollback_transaction(); + __vc_db_rollback_transaction(g_db_handle); return VC_DB_ERROR_OPERATION_FAILED; } @@ -1797,9 +1934,9 @@ int vc_db_get_result(char** result_text, int* event, char** msg, int pid, vc_cmd if (APP_MANAGER_ERROR_NONE != ret) { SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] fail to get app id, ret(%d), pid(%d)", ret, pid); } - ret = __vc_db_get_result(result_text, event, msg, pid, appid, vc_cmd_list, exclusive); + ret = __vc_db_get_result(g_db_handle, result_text, event, msg, pid, appid, vc_cmd_list, exclusive); if (ret != VC_DB_ERROR_NONE) { - __vc_db_rollback_transaction(); + __vc_db_rollback_transaction(g_db_handle); return ret; } if (NULL != appid) { @@ -1808,63 +1945,122 @@ int vc_db_get_result(char** result_text, int* event, char** msg, int pid, vc_cmd } } } - __vc_db_commit_transaction(); + __vc_db_commit_transaction(g_db_handle); return VC_DB_ERROR_NONE; } int vc_db_get_appid_list(const char* result, GSList** app_list) { - __vc_db_begin_transaction(); + __vc_db_begin_transaction(g_db_handle); - int ret = __vc_db_get_appid(result, app_list); + int ret = __vc_db_get_appid(g_db_handle, result, app_list); if (ret != VC_DB_ERROR_NONE) { - __vc_db_rollback_transaction(); + __vc_db_rollback_transaction(g_db_handle); return ret; } - __vc_db_commit_transaction(); + __vc_db_commit_transaction(g_db_handle); return VC_DB_ERROR_NONE; } int vc_db_get_result_pid_list(const char* result, GSList** pid_list) { - __vc_db_begin_transaction(); + __vc_db_begin_transaction(g_db_handle); - int ret = __vc_db_get_result_pid_list(result, pid_list); + int ret = __vc_db_get_result_pid_list(g_db_handle, result, pid_list); if (ret != VC_DB_ERROR_NONE) { - __vc_db_rollback_transaction(); + __vc_db_rollback_transaction(g_db_handle); return ret; } - __vc_db_commit_transaction(); + __vc_db_commit_transaction(g_db_handle); return VC_DB_ERROR_NONE; } int vc_db_append_commands(int pid, int type, vc_cmd_list_h vc_cmd_list) { - __vc_db_begin_transaction(); + __vc_db_begin_transaction(g_db_handle); - int ret = __vc_db_append_commands(pid, type, vc_cmd_list); + int ret = __vc_db_append_commands(g_db_handle, pid, type, vc_cmd_list); if (ret != VC_DB_ERROR_NONE) { - __vc_db_rollback_transaction(); + __vc_db_rollback_transaction(g_db_handle); return ret; } - __vc_db_commit_transaction(); + __vc_db_commit_transaction(g_db_handle); return VC_DB_ERROR_NONE; } int vc_db_delete_commands(int pid, vc_cmd_type_e type, char* appid) { - __vc_db_begin_transaction(); + __vc_db_begin_transaction(g_db_handle); int ret = 0; - ret = __vc_db_delete_commands(pid, type, appid); + ret = __vc_db_delete_commands(g_db_handle, pid, type, appid); + if (ret != VC_DB_ERROR_NONE) { + __vc_db_rollback_transaction(g_db_handle); + return ret; + } + + __vc_db_commit_transaction(g_db_handle); + return VC_DB_ERROR_NONE; +} + +int vc_db_backup_command() +{ + GSList* list = NULL; + + __vc_db_begin_transaction(g_db_backup_handle); + + int ret = __vc_db_delete_table(g_db_backup_handle, VC_INFO_TABLE); + if (0 != ret) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to delete table"); + __vc_db_rollback_transaction(g_db_backup_handle); + return ret; + } + __vc_db_commit_transaction(g_db_backup_handle); + + ret = vc_db_get_commands(-1, VC_COMMAND_TYPE_BACKGROUND, &list); + if (ret != VC_DB_ERROR_NONE) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to get commands"); + return ret; + } + + __vc_db_begin_transaction(g_db_backup_handle); + + ret = __vc_db_insert_commands_list(g_db_backup_handle, -1, VC_COMMAND_TYPE_BACKGROUND, list, NULL, true); + if (ret != VC_DB_ERROR_NONE) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to insert command list to backup db"); + __vc_db_rollback_transaction(g_db_backup_handle); + return ret; + } + + __vc_db_commit_transaction(g_db_backup_handle); + + SLOG(LOG_ERROR, vc_db_tag(), "[SUCCESS] Backup commands"); + return VC_DB_ERROR_NONE; +} + +int vc_db_restore_command() +{ + GSList* list = NULL; + + __vc_db_begin_transaction(g_db_backup_handle); + + int ret = __vc_db_get_commands(g_db_backup_handle, -1, VC_COMMAND_TYPE_BACKGROUND, &list); + if (ret != VC_DB_ERROR_NONE) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to get commands from backup db"); + __vc_db_rollback_transaction(g_db_backup_handle); + return ret; + } + __vc_db_commit_transaction(g_db_backup_handle); + + ret = vc_db_insert_commands_list(-1, VC_COMMAND_TYPE_BACKGROUND, list, NULL, true); if (ret != VC_DB_ERROR_NONE) { - __vc_db_rollback_transaction(); + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to insert command list"); return ret; } - __vc_db_commit_transaction(); + SLOG(LOG_ERROR, vc_db_tag(), "[SUCCESS] Restore commands"); return VC_DB_ERROR_NONE; } diff --git a/common/vc_cmd_db.h b/common/vc_cmd_db.h index b7a97df..0a4f76a 100644 --- a/common/vc_cmd_db.h +++ b/common/vc_cmd_db.h @@ -43,6 +43,9 @@ typedef enum { VC_DB_ERROR_SERVICE_RESET = TIZEN_ERROR_VOICE_CONTROL | 0x018 /**< Service daemon reset (Since 3.0) */ } vc_db_error_e; +#define VC_INFO_TABLE "vc_info" +#define VC_RESULT_TABLE "vc_result" + typedef struct _deactivated_app_s { char* appid; } vc_deactivated_app_s; @@ -61,9 +64,9 @@ int vc_db_rollback_transaction(void); int vc_db_commit_transaction(void); -int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd); +int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd, bool skip_invocation); -int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, char* invocation_name); +int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, char* invocation_name, bool skip_invocation); int vc_db_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list); @@ -81,6 +84,9 @@ int vc_db_select_by_pid(int pid); int vc_db_delete_commands(int pid, vc_cmd_type_e type, char* appid); +int vc_db_backup_command(); + +int vc_db_restore_command(); #ifdef __cplusplus } diff --git a/common/vc_defs.h b/common/vc_defs.h index 7947a92..ed3a88a 100755 --- a/common/vc_defs.h +++ b/common/vc_defs.h @@ -168,35 +168,35 @@ extern "C" { * Definitions for configuration *******************************************************************************************/ -#define VC_DAEMON_PATH tzplatform_mkpath(TZ_SYS_BIN, "vc-daemon") +#define VC_DAEMON_PATH tzplatform_mkpath(tzplatform_getid("TZ_SYS_BIN"), "vc-daemon") -#define VC_CONFIG_DEFAULT tzplatform_mkpath(TZ_SYS_RO_SHARE, "voice/vc/1.0/vc-config.xml") +#define VC_CONFIG_DEFAULT tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "voice/vc/1.0/vc-config.xml") -#define VC_DEFAULT_BASE tzplatform_mkpath(TZ_SYS_RO_SHARE, "voice/vc/1.0") +#define VC_DEFAULT_BASE tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "voice/vc/1.0") -#define VC_DEFAULT_ENGINE tzplatform_mkpath(TZ_SYS_RO_SHARE, "voice/vc/1.0/engine") +#define VC_DEFAULT_ENGINE tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "voice/vc/1.0/engine") -#define VC_DEFAULT_ENGINE_SETTING tzplatform_mkpath(TZ_SYS_RO_SHARE, "voice/vc/1.0/engine-setting") +#define VC_DEFAULT_ENGINE_SETTING tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "voice/vc/1.0/engine-setting") -#define VC_DEFAULT_ENGINE_INFO tzplatform_mkpath(TZ_SYS_RO_SHARE, "voice/vc/1.0/engine-info") +#define VC_DEFAULT_ENGINE_INFO tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "voice/vc/1.0/engine-info") -#define VC_CONFIG_BASE tzplatform_mkpath(TZ_USER_HOME, "share/.voice") +#define VC_CONFIG_BASE tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice") -#define VC_CONFIG tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc-config.xml") +#define VC_CONFIG tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/vc-config.xml") -#define VC_RUNTIME_INFO_ROOT tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc") +#define VC_RUNTIME_INFO_ROOT tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/vc") -#define VC_RUNTIME_INFO_FOREGROUND tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc/vc-info-foreground.xml") +#define VC_RUNTIME_INFO_FOREGROUND tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/vc/vc-info-foreground.xml") -#define VC_RUNTIME_INFO_DEMANDABLE_LIST tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc/vc-demandable-client.xml") +#define VC_RUNTIME_INFO_DEMANDABLE_LIST tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/vc/vc-demandable-client.xml") -#define VC_RUNTIME_INFO_RESULT tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc/vc-result.xml") +#define VC_RUNTIME_INFO_RESULT tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/vc/vc-result.xml") -#define VC_RUNTIME_INFO_EX_RESULT tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc/vc-ex-result.xml") +#define VC_RUNTIME_INFO_EX_RESULT tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/vc/vc-ex-result.xml") -#define VC_RUNTIME_INFO_NLU_RESULT tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc/vc-nlu-result.xml") +#define VC_RUNTIME_INFO_NLU_RESULT tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/vc/vc-nlu-result.xml") -#define VC_RUNTIME_INFO_CLIENT tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc/vc-client-info.xml") +#define VC_RUNTIME_INFO_CLIENT tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/vc/vc-client-info.xml") #define VC_NO_FOREGROUND_PID -1 #define VC_BASE_LANGUAGE "en_US" diff --git a/common/vc_info_parser.c b/common/vc_info_parser.c index 8fda8ae..864f470 100644 --- a/common/vc_info_parser.c +++ b/common/vc_info_parser.c @@ -91,7 +91,7 @@ int vc_cmd_parser_save_file(int pid, vc_cmd_type_e type, GSList* cmd_list, char* return -1; } - int ret = vc_db_insert_commands_list(pid, type, cmd_list, invocation_name); + int ret = vc_db_insert_commands_list(pid, type, cmd_list, invocation_name, false); if (0 != ret) { SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Insert db is failed, ret = %d", ret); } @@ -357,7 +357,7 @@ int vc_info_parser_get_result(char** result_text, int* event, char** result_mess int vc_info_parser_unset_result(bool exclusive) { int ret = 0; - ret = vc_db_delete_table("result"); + ret = vc_db_delete_table(VC_RESULT_TABLE); if (0 != ret) { SLOG(LOG_DEBUG, vc_info_tag(), "[ERROR] Fail to delete result table"); } diff --git a/common/vc_json_parser.c b/common/vc_json_parser.c old mode 100755 new mode 100644 index 79e6b31..06386f4 --- a/common/vc_json_parser.c +++ b/common/vc_json_parser.c @@ -328,7 +328,7 @@ static int __vc_json_set_commands(JsonObject *root_obj, int type, char* invocati } } - ret = vc_db_insert_command(cmd->pid, type, cmd); + ret = vc_db_insert_command(cmd->pid, type, cmd, false); if (VC_ERROR_NONE != ret) { SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to insert command into db, type(%s), command(%s)", temp_type, temp_text); if (NULL != cmd->command) free(cmd->command); -- 2.7.4 From b4209658300ef13c69cffba9207c0aa1e45c61f7 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Tue, 17 Oct 2017 17:49:05 +0900 Subject: [PATCH 12/16] Change to support VC downloadable engine (hybrid) Change-Id: I92f82785c7c6576a7d4b816f7b5325aa4b833fe9 Signed-off-by: sooyeon.kim --- include/CMakeLists.txt | 2 +- include/vce.h | 743 ++++++++++++++++++++++++++ include/voice-control-engine.pc.in | 1 + include/voice_control_common.h | 3 +- include/voice_control_manager.h | 6 +- include/voice_control_plugin_engine.h | 799 ---------------------------- org.tizen.voice.vcserver.service | 3 +- packaging/voice-control.spec | 5 +- server/CMakeLists.txt | 17 +- server/vcd_engine_agent.c | 951 ++++++++++------------------------ server/vcd_engine_agent.h | 58 +-- server/vcd_main.c | 75 --- server/vcd_main.h | 39 ++ server/vcd_recorder.c | 127 ++--- server/vcd_recorder.h | 3 +- server/vcd_server.c | 282 ++++++---- server/vcd_server.h | 36 +- server/vce.c | 262 ++++++++++ 18 files changed, 1653 insertions(+), 1759 deletions(-) create mode 100755 include/vce.h delete mode 100644 include/voice_control_plugin_engine.h delete mode 100644 server/vcd_main.c create mode 100755 server/vce.c diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 7d0db51..84fd0df 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -21,6 +21,6 @@ INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_command_expand.h DESTINA INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_common.h DESTINATION ${INCLUDEDIR}) INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_key_defines.h DESTINATION ${INCLUDEDIR}) INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_manager.h DESTINATION ${INCLUDEDIR}) -INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_plugin_engine.h DESTINATION ${INCLUDEDIR}) INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_setting.h DESTINATION ${INCLUDEDIR}) INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_widget.h DESTINATION ${INCLUDEDIR}) +INSTALL(FILES ${CMAKE_BINARY_DIR}/include/vce.h DESTINATION ${INCLUDEDIR}) diff --git a/include/vce.h b/include/vce.h new file mode 100755 index 0000000..68f411a --- /dev/null +++ b/include/vce.h @@ -0,0 +1,743 @@ +/* +* Copyright (c) 2011-2017 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the License); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an AS IS BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __VCE_H__ +#define __VCE_H__ + +#include + +/** +* @addtogroup CAPI_UIX_VCE_MODULE +* @{ +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* @brief Enumerations of error codes. +* @since_tizen 5.0 +*/ +typedef enum { + VCE_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + VCE_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of Memory */ + VCE_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< I/O error */ + VCE_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER,/**< Invalid parameter */ + VCE_ERROR_OUT_OF_NETWORK = TIZEN_ERROR_NETWORK_DOWN, /**< Out of network */ + VCE_ERROR_INVALID_STATE = TIZEN_ERROR_VOICE_CONTROL | 0x011, /**< Invalid state */ + VCE_ERROR_INVALID_LANGUAGE = TIZEN_ERROR_VOICE_CONTROL | 0x012, /**< Invalid language */ + VCE_ERROR_OPERATION_FAILED = TIZEN_ERROR_VOICE_CONTROL | 0x014, /**< Operation failed */ + VCE_ERROR_NOT_SUPPORTED_FEATURE = TIZEN_ERROR_VOICE_CONTROL | 0x022 /**< Not supported feature of current engine */ +} vce_error_e; + +/** +* @brief Enumerations of audio type. +* @since_tizen 5.0 +*/ +typedef enum { + VCE_AUDIO_TYPE_PCM_S16_LE = 0, /**< Signed 16bit audio type, Little endian */ + VCE_AUDIO_TYPE_PCM_U8 /**< Unsigned 8bit audio type */ +} vce_audio_type_e; + +/** +* @brief Enumerations of callback event. +* @since_tizen 5.0 +*/ +typedef enum { + VCE_RESULT_EVENT_SUCCESS = 0, /**< Event when the recognition full result is ready */ + VCE_RESULT_EVENT_REJECTED, /**< Event when the recognition result is rejected */ + VCE_RESULT_EVENT_ERROR /**< Event when the recognition has failed */ +} vce_result_event_e; + +/** +* @brief Enumerations of command type. +* @since_tizen 5.0 +*/ +typedef enum { + VCE_COMMAND_FORMAT_FIXED = 0, /**< Fixed command */ + VCE_COMMAND_FORMAT_FIXED_AND_VFIXED, /**< Fixed command + variable-fixed command */ + VCE_COMMAND_FORMAT_VFIXED_AND_FIXED, /**< variable-fixed command + Fixed command */ + VCE_COMMAND_FORMAT_FIXED_AND_NONFIXED, /**< Fixed command + Non-fixed command */ + VCE_COMMAND_FORMAT_NONFIXED_AND_FIXED, /**< Non-fixed command + Fixed command */ + VCE_COMMAND_FORMAT_ACTION, + VCE_COMMAND_FORMAT_PARTIAL +} vce_command_format_e; + +/** +* @brief Definition for foreground command type. +* @since_tizen 5.0 +*/ +#define VCE_COMMAND_TYPE_FOREGROUND 1 + +/** +* @brief Definition for background command type. +* @since_tizen 5.0 +*/ +#define VCE_COMMAND_TYPE_BACKGROUND 2 + +/** +* @brief Definition for widget command type. +* @since_tizen 5.0 +*/ +#define VCE_COMMAND_TYPE_WIDGET 3 + +/** +* @brief Definition for system command type. +* @since_tizen 5.0 +*/ +#define VCE_COMMAND_TYPE_SYSTEM 4 + +/** +* @brief Definition for system background command type. +* @since_tizen 5.0 +*/ +#define VCE_COMMAND_TYPE_SYSTEM_BACKGROUND 5 + +/** +* @brief Definitions for exclusive command type. +* @since_tizen 5.0 +*/ +#define VCE_COMMAND_TYPE_EXCLUSIVE 6 + + +/** +* @brief Enumerations of speech detect. +* @since_tizen 5.0 +*/ +typedef enum { + VCE_SPEECH_DETECT_NONE = 0, /**< No event */ + VCE_SPEECH_DETECT_BEGIN, /**< Begin of speech detected */ + VCE_SPEECH_DETECT_END, /**< End of speech detected */ +} vce_speech_detect_e; + +/** +* @brief Enumerations of ASR result events +* @since_tizen 5.0 +*/ +typedef enum { + VCE_ASR_RESULT_EVENT_FINAL_RESULT = 0, + VCE_ASR_RESULT_EVENT_PARTIAL_RESULT, + VCE_ASR_RESULT_EVENT_ERROR +} vce_asr_result_event_e; + +/** +* @brief A structure of handle for VC command +* @since_tizen 5.0 +*/ +typedef int vce_cmd_h; + +/** +* @brief Definition of bluetooth audio id. +* @since_tizen 5.0 +*/ +#define VCE_AUDIO_ID_BLUETOOTH "VC_AUDIO_ID_BLUETOOTH" /**< Bluetooth audio id */ + +/** +* @brief Definition of Wi-Fi audio id. +* @since_tizen 5.0 +*/ +#define VCE_AUDIO_ID_WIFI "VC_AUDIO_ID_WIFI" /**< Wi-Fi audio id */ + +/** +* @brief Definition for none message. +*/ +#define VC_RESULT_MESSAGE_NONE "vc.result.message.none" + +/** +* @brief Definition for failed recognition because the speech is too loud to listen. +*/ +#define VC_RESULT_MESSAGE_ERROR_TOO_LOUD "vc.result.message.error.too.loud" + + + +/** +* @brief Called when VC engine informs the engine service user about whole supported languages. +* @details This callback function is implemented by the engine service user. Therefore, the engine developer does NOT have to implement this callback function. +* @since_tizen 5.0 +* @remarks This callback function is called by vce_foreach_supported_languages_cb() to retrieve the whole supported language list. +* @a user_data must be transferred from vce_foreach_supported_languages_cb(). +* +* @param[in] language A language is specified as an ISO 3166 alpha-2 two letter country-code +* followed by ISO 639-1 for the two-letter language code \n +* For example, "ko_KR" for Korean, "en_US" for American English +* @param[in] user_data The user data passed from the foreach function +* +* @return @c true to continue with the next iteration of the loop \n @c false to break out of the loop +* +* @pre vce_foreach_supported_languages() will invoke this callback. +* +* @see vce_foreach_supported_languages() +*/ +typedef bool (*vce_supported_language_cb)(const char* language, void* user_data); + +/** +* @brief Called when the engine service user initializes VC engine. +* @since_tizen 5.0 +* @remarks This callback function is mandatory and must be registered using vce_main(). +* +* @return 0 on success, otherwise a negative error value +* @retval #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VCE_ERROR_INVALID_STATE Already initialized +* @retval #VCE_ERROR_OPERATION_FAILED Operation failed +* +* @see vce_deinitialize_cb() +*/ +typedef int (*vce_initialize_cb)(void); + +/** +* @brief Called when the engine service user deinitializes VC engine +* @since_tizen 5.0 +* @remarks This callback function is mandatory and must be registered using vce_main(). +* +* @return 0 on success, otherwise a negative error value +* @retval #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_INVALID_STATE Not initialized +* +* @see vce_initialize_cb() +*/ +typedef int (*vce_deinitialize_cb)(void); + +/** +* @brief Called when the engine service user requests the recording format of VC engine. +* +* @param[in] audio_id The audio device id. +* @param[out] types The format used by the recorder. +* @param[out] rate The sample rate used by the recorder. +* @param[out] channels The number of channels used by the recorder. +* +* @return 0 on success, otherwise a negative error value +* @retval #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_INVALID_PARAMETER Not initialized +*/ +typedef int (*vce_get_recording_format_cb)(const char* audio_id, vce_audio_type_e* types, int* rate, int* channels); + +/** +* @brief Called when the engine service user retrieves all supported languages of VC engine. +* +* @param[in] callback a callback function +* @param[in] user_data The user data to be passed to the callback function +* +* @return 0 on success, otherwise a negative error value +* @retval #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VCE_ERROR_INVALID_STATE Not initialized +* +* @post This function invokes vce_supported_language_cb() repeatedly for getting supported languages. +* +* @see vce_supported_language_cb() +*/ +typedef int (*vce_foreach_supported_languages_cb)(vce_supported_language_cb callback, void* user_data); + +/** +* @brief Called when the engine service user checks whether a language is supported or not. +* +* @param[in] language A language +* +* @return @c true = supported, \n @c false = not supported. +*/ +typedef bool (*vce_is_language_supported_cb)(const char* language); + +/** +* @brief Called when the engine service user sets language. +* +* @param[in] language A language. +* +* @return 0 on success, otherwise a negative error value +* @retval #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_INVALID_LANGUAGE Invalid language +* @retval #VCE_ERROR_INVALID_STATE Not initialized +*/ +typedef int (*vce_set_language_cb)(const char* language); + +/** +* @brief Called when the engine service user sets command list before recognition. +* +* @remark This function should set commands via vcd_foreach_command(). +* +* @param[in] vc_command command handle. +* +* @return 0 on success, otherwise a negative error value +* @retval #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VCE_ERROR_INVALID_STATE Invalid state +* @retval #VCE_ERROR_OPERATION_FAILED Operation failed +* @retval #VCE_ERROR_NOT_SUPPORTED_FEATURE Not supported command type +* +* @post vce_start() is called after this function is successful. +* +* @see vce_start() +* @see vcd_foreach_command() +* @see vce_unset_commands() +*/ +typedef int (*vce_set_commands_cb)(vce_cmd_h vc_command); + +/** +* @brief Called when the engine service user unsets command list for reset. +* +* @return 0 on success, otherwise a negative error value +* @retval #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VCE_ERROR_INVALID_STATE Invalid state +* @retval #VCE_ERROR_OPERATION_FAILED Operation failed +* +* @see vce_set_commands() +*/ +typedef int (*vce_unset_commands_cb)(); + +/** +* @brief Called when the engine service user starts recognition. +* +* @return 0 on success, otherwise a negative error value +* @retval #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VCE_ERROR_INVALID_STATE Invalid state +* @retval #VCE_ERROR_INVALID_LANGUAGE Invalid language +* @retval #VCE_ERROR_OUT_OF_NETWORK Out of network +* @retval #VCE_ERROR_OPERATION_FAILED Operation failed +* +* @pre vcd_foreach_command() is successful. +* +* @see vce_set_recording_data() +* @see vce_stop() +* @see vce_cancel() +*/ +typedef int (*vce_start_cb)(bool stop_by_silence); + +/** +* @brief Called when the engine service user sets recording data for speech recognition from recorder. +* +* @remark This function should be returned immediately after recording data copy. +* +* @param[in] data A recording data +* @param[in] length A length of recording data +* @param[out] silence_detected @c true Silence detected \n @c false No silence detected +* +* @return 0 on success, otherwise a negative error value +* @retval #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VCE_ERROR_INVALID_STATE Invalid state +* @retval #VCE_ERROR_OPERATION_FAILED Operation failed +* +* @pre vce_start() is successful. +* +* @see vce_start() +* @see vce_cancel() +* @see vce_stop() +*/ +typedef int(*vce_set_recording_data_cb)(const void* data, unsigned int length, vce_speech_detect_e* speech_detected); + +/** +* @brief Called when the engine service user stops to get the result of recognition. +* +* @return 0 on success, otherwise a negative error value +* @retval #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_INVALID_STATE Invalid state +* @retval #VCE_ERROR_OPERATION_FAILED Operation failed +* @retval #VCE_ERROR_OUT_OF_NETWORK Out of network +* +* @pre vce_set_recording_data() is successful. +* +* @see vce_start() +* @see vce_set_recording_data() +* @see vce_result_cb() +* @see vce_cancel() +*/ +typedef int (*vce_stop_cb)(void); + +/** +* @brief Called when the engine service user cancels the recognition process. +* +* @return 0 on success, otherwise a negative error value. +* @retval #VCE_ERROR_NONE Successful. +* @retval #VCE_ERROR_INVALID_STATE Invalid state. +* +* @pre vce_start() is successful. +* +* @see vce_start() +* @see vce_stop() +*/ +typedef int (*vce_cancel_cb)(void); + +/** +* @brief Set audio recording type. +* +* @return 0 on success, otherwise a negative error value. +* @retval #VCE_ERROR_NONE Successful. +* +*/ +typedef int (*vce_set_audio_type)(const char* audio); + + +/** +* @brief Called when the engine service user sets domain (Agent or device type) +* +* @param[in] domain Available agent or device type +* +* @return 0 on success, otherwise a negative error value. +* +*/ +typedef int (*vce_set_domain_cb)(const char* domain); + +/** +* @brief Called when the engine service user requests essential value from nlu result. +* @since_tizen 5.0 +* @remarks This function is available inside vce_nlu_result_cb() +* +* @param[in] key NLU base info key +* @parma[out] value NLU base info value +* +* @return 0 on success, otherwise a negative error value. +* +*/ +typedef int (*vce_nlu_base_info_requested_cb)(const char* key, char** value); + +/** +* @brief Called when the engine service user sets private data between app and engine. +* +* @param[in] key Private key +* @param[in] data Private data +* +* @return 0 on success, otherwise a negative error value. +* +*/ +typedef int (*vce_private_data_set_cb)(const char* key, const char* data); + +/** +* @brief Called when the engine service user requests private data between app and engine. +* +* @param[in] key Private key +* @param[out] data Private data +* +* @return 0 on success, otherwise a negative error value. +* +*/ +typedef int (*vce_private_data_requested_cb)(const char* key, char** data); + +/** +* @brief Called when the engine service user requests process text. +* +* @param[in] text Requested text +* +* @return 0 on success, otherwise a negative error value. +* +*/ +typedef int (*vce_process_text_cb)(const char* text); + +/** +* @brief Called when the engine service user requests list event. +* +* @param[in] event Requested list event +* +* @return 0 on success, otherwise a negative error value. +* +*/ +typedef int (*vce_process_list_event_cb)(const char* event); + +/** +* @brief Called when the engine service user requests haptic event. +* +* @param[in] event Requested haptic event +* +* @return 0 on success, otherwise a negative error value. +* +*/ +typedef int (*vce_process_haptic_event_cb)(const char* event); + +/** +* @brief Called when the engine service user requests the base information of VC engine. +* @since_tizen 5.0 +* +* @param[in] engine_uuid The engine id +* @param[in] engine_name The engine name +*/ +typedef int (*vce_get_info_cb)(char** engine_uuid, char** engine_name); + + +/** +* Daemon API. +*/ + +/** +* @brief Called to retrieve the commands. +* +* @param[in] id command id +* @param[in] type command type +* @param[in] format command format +* @param[in] command command text +* @param[in] param parameter text +* @param[in] domain command domain +* @param[in] user_data The user data passed from the foreach function +* +* @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop. +* @pre vce_get_foreach_command() will invoke this callback. +* +* @see vce_get_foreach_command() +*/ +typedef bool (*vce_command_cb)(int id, int type, int format, const char* command, const char* param, int domain, void* user_data); + +/** +* @brief Retrieves all commands using callback function. +* +* @param[in] vce_command The handle to be passed to the vce_set_commands() function +* @param[in] callback The callback function to invoke +* @param[in] user_data The user data to be passed to the callback function +* +* @return 0 on success, otherwise a negative error value +* @retval #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VCE_ERROR_OPERATION_FAILED Operation failure +* @retval #VCE_ERROR_INVALID_STATE Invalid state +* +* @post This function invokes vce_command_cb() repeatedly for getting commands. +* +* @see vce_foreach_command_cb() +* @see vce_set_commands() +*/ +int vce_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void* user_data); + +/** +* @brief Gets command length. +* +* @param[in] vce_command The handle to be passed to the vce_set_commands() function +* +* @return the value greater than 0 on success, otherwise a negative error value +* +* @see vce_set_commands() +*/ +int vce_get_command_count(vce_cmd_h vce_command); + +/** +* @brief Gets current audio type. +* +* @remarks audio_type must be released using free() when it is no longer required. +* +* @param[in] audio_type Current audio type (e.g. #VCE_AUDIO_ID_BLUETOOTH or usb device id) +* +* @return the value greater than 0 on success, otherwise a negative error value +* +*/ +int vce_get_audio_type(char** audio_type); + +/** +* @brief Sets private data to Manager client. +* +* @param[in] key Private key +* @param[in] data Private data +* +* @return 0 on success, otherwise a negative error value. +* +*/ +int vce_set_private_data(const char* key, const char* data); + +/** +* @brief Gets private data from Manager client. +* +* @param[in] key Private key +* @param[out] data Private data +* +* @return 0 on success, otherwise a negative error value. +* +*/ +int vce_get_private_data(const char* key, char** data); + +/** +* @brief Request start recording. +* +* @return 0 on success, otherwise a negative error value. +* +*/ +int vce_start_recording(); + +/** +* @brief Request stop recording. +* +* @return 0 on success, otherwise a negative error value. +* +*/ +int vce_stop_recording(); + + +/** +* @brief A structure for the VC engine functions. +* @details This structure contains essential callback functions for operating VC engine. +* @since_tizen 5.0 +* @remarks These functions ar mandatory for operating VC engine. Therefore, all functions MUST be implemented. +*/ +typedef struct { + int version; /**< Version */ + + /* Get engine information */ + vce_get_info_cb get_info; /**< Called when the engine service user requests the basic information of VC engine */ + vce_get_recording_format_cb get_recording_format; /**< Get recording format */ + vce_foreach_supported_languages_cb foreach_langs; /**< Foreach language list */ + vce_is_language_supported_cb is_lang_supported; /**< Check language */ + + vce_initialize_cb initialize; /**< Initialize engine */ + vce_deinitialize_cb deinitialize; /**< Shutdown engine */ + + /* Set info */ + vce_set_language_cb set_language; /**< Set language */ + vce_set_commands_cb set_commands; /**< Request to set current commands */ + vce_unset_commands_cb unset_commands; /**< Request to unset current commands */ + + /* Control recognition */ + vce_start_cb start; /**< Start recognition */ + vce_set_recording_data_cb set_recording; /**< Set recording data */ + vce_stop_cb stop; /**< Stop recording for getting result */ + vce_cancel_cb cancel; /**< Cancel recording and processing */ + + vce_set_audio_type set_audio_type; /**< Set audio type */ + + vce_set_domain_cb set_domain; /**< Set domain */ + vce_process_text_cb process_text; /**< Request to process text */ + vce_process_list_event_cb process_list_event; /**< Request to process list event */ + vce_process_haptic_event_cb process_haptic_event; /**< Request to process haptic event */ +} vce_request_callback_s; + +/** +* @brief Loads the engine. +* +* @param[in] argc The argument count(original) +* @param[in] argv The argument(original) +* @param[in] callback The structure of engine request callback function +* +* @return This function returns zero on success, or negative with error code on failure +* @retval #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VCE_ERROR_OPERATION_FAILED Operation failed +* +* @pre The vce_get_engine_info() should be successful. +* @post The daemon calls engine functions of vce_funcs_s. +* +* @see vce_get_engine_info() +* @see vce_unload_engine() +*/ +int vce_main(int argc, char** argv, vce_request_callback_s *callback); + + +/** +* @brief Sends the results to the engine service user. +* @since_tizen 5.0 +* +* @param[in] event A result event +* @param[in] result_id Result ids +* @param[in] count Result count +* @param[in] all_result All result text +* @param[in] non_fixed_result Non-fixed command result text +* @param[in] nlu_result NLU result text +* @param[in] msg Engine message (e.g. #VC_RESULT_MESSAGE_NONE, #VC_RESULT_MESSAGE_ERROR_TOO_LOUD) +* @param[in] user_data The user data passed from set callback function +* +* @pre The vce_main() function should be invoked before this function is called. +* vce_stop_cb() will invoke this callback. +* +* @see vce_stop_cb() +*/ +int vce_send_result(vce_result_event_e event, int* result_id, int count, const char* all_result, const char* non_fixed_result, const char* nlu_result, const char* msg, void *user_data); + +/** +* @brief Sends the ASR result to the engine service user. +* @since_tizen 5.0 +* +* @param[in] event A asr result event +* @param[in] asr_result A asr result text +* @param[in] user_data The user data passed from the start +* +* @pre The vce_main() function should be invoked before this function is called. +*/ +int vce_send_asr_result(vce_asr_result_event_e event, const char* asr_result, void *user_data); + +/** +* @brief Called when the daemon gets nlg(natural language generation) result. +* +* @param[in] nlg_result A nlg result +* @param[in] user_data The user data passed from the start +*/ +int vce_send_nlg_result(const char* nlg_result, void *user_data); + +/** +* @brief Sends the error to the engine service user. +* @details The following error codes can be delivered. +* #VCE_ERROR_NONE, +* #VCE_ERROR_OUT_OF_MEMORY, +* #VCE_ERROR_IO_ERROR, +* #VCE_ERROR_INVALID_PARAMETER, +* #VCE_ERROR_OUT_OF_NETWORK, +* #VCE_ERROR_INVALID_STATE, +* #VCE_ERROR_INVALID_LANGUAGE, +* #VCE_ERROR_OPERATION_FAILED, +* #VCE_ERROR_NOT_SUPPORTED_FEATURE. +* @since_tizen 5.0 +* +* @param[in] error Error type +* @param[in] msg Error message +* @param[in] user_data The user data passed from set callback function +* +* @pre The vce_main() function should be invoked before this function is called. +*/ +int vce_send_error(vce_error_e error, const char* msg, void *user_data); + +/** +* @brief Sets a callback function for setting the private data to the engine service. +* @since_tizen 5.0 +* @remarks The vce_private_data_set_cb() function is called when the engine service user sets the private data to the engine service. +* +* @param[in] callback_func vce_private_data_set event callback function +* @return +* +* @see vce_private_data_set_cb() +*/ +int vce_set_private_data_set_cb(vce_private_data_set_cb callback_func); + +/** +* @brief Sets a callback function for requesting the private data to the engine service. +* @since_tizen 5.0 +* @remarks The vce_private_data_requested_cb() function is called when the engine service user requests the private data to the engine service. +* +* @param[in] callback_func vce_private_data_requested event callback function +* @return +* +* @see vce_private_data_requested_cb() +*/ +int vce_set_private_data_requested_cb(vce_private_data_requested_cb callback_func); + +/** +* @brief Sets a callback function for requesting the NLU base information to the engine service. +* @since_tizen 5.0 +* @remarks The vce_nlu_base_info_requested_cb() function is called when the engine service user requests the NLU base information to the engine service. +* +* @param[in] callback_func vce_nlu_base_info_requested event callback function +* @return +* +* @see vce_nlu_base_info_requested_cb() +*/ +int vce_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_func); + + +#ifdef __cplusplus +} +#endif + +/** +* @}@} +*/ + +#endif /* __VCE_H__ */ + + diff --git a/include/voice-control-engine.pc.in b/include/voice-control-engine.pc.in index 7808dfb..d089851 100644 --- a/include/voice-control-engine.pc.in +++ b/include/voice-control-engine.pc.in @@ -7,4 +7,5 @@ Name: lib@PROJECT_NAME@_engine Description: Voice control engine header Requires: glib-2.0 dbus-1 capi-base-common Version: @VERSION@ +Libs: -L${libdir} -l@PROJECT_NAME@_engine Cflags: -I${includedir} diff --git a/include/voice_control_common.h b/include/voice_control_common.h index a23ccbe..42e0ef0 100644 --- a/include/voice_control_common.h +++ b/include/voice_control_common.h @@ -56,7 +56,8 @@ typedef enum { VC_ERROR_SERVICE_RESET = TIZEN_ERROR_VOICE_CONTROL | 0x018, /**< Service daemon reset (Since 3.0) */ VC_ERROR_IN_PROGRESS_TO_READY = TIZEN_ERROR_VOICE_CONTROL | 0x019, /**< In progress to ready (Since 3.0) */ VC_ERROR_IN_PROGRESS_TO_RECORDING = TIZEN_ERROR_VOICE_CONTROL | 0x020, /**< In progress to recording (Since 3.0) */ - VC_ERROR_IN_PROGRESS_TO_PROCESSING = TIZEN_ERROR_VOICE_CONTROL | 0x021 /**< In progress to processing (Since 3.0) */ + VC_ERROR_IN_PROGRESS_TO_PROCESSING = TIZEN_ERROR_VOICE_CONTROL | 0x021, /**< In progress to processing (Since 3.0) */ + VC_ERROR_NOT_SUPPORTED_FEATURE = TIZEN_ERROR_VOICE_CONTROL | 0x022 /**< Not supported feature of current engine (Since 4.0) */ } vc_error_e; diff --git a/include/voice_control_manager.h b/include/voice_control_manager.h index 3f31922..1039771 100644 --- a/include/voice_control_manager.h +++ b/include/voice_control_manager.h @@ -34,14 +34,14 @@ extern "C" /** - * @brief Definition of audio-in type. + * @brief Definition of bluetooth audio-in type. */ #define VC_AUDIO_TYPE_BLUETOOTH "VC_AUDIO_ID_BLUETOOTH" /**< Bluetooth audio type */ /** - * @brief Definition of audio-in type. + * @brief Definition of Wi-Fi audio-in type. */ -#define VC_AUDIO_TYPE_MSF "VC_AUDIO_ID_MSF" /**< MSF (wifi) audio type */ +#define VC_AUDIO_TYPE_WIFI "VC_AUDIO_ID_WIFI" /**< Wi-Fi audio type */ /** * @brief Definition for foreground command type. diff --git a/include/voice_control_plugin_engine.h b/include/voice_control_plugin_engine.h deleted file mode 100644 index b6926da..0000000 --- a/include/voice_control_plugin_engine.h +++ /dev/null @@ -1,799 +0,0 @@ -/* -* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved -* -* Licensed under the Apache License, Version 2.0 (the License); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an AS IS BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#ifndef __VOICE_CONTROL_PLUGIN_ENGINE_H__ -#define __VOICE_CONTROL_PLUGIN_ENGINE_H__ - -#include - -/** -* @addtogroup VOICE_CONTROL_PLUGIN_ENGINE -* @{ -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -/** -* @brief Enumerations of error codes. -*/ -typedef enum { - VCP_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ - VCP_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of Memory */ - VCP_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< I/O error */ - VCP_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER,/**< Invalid parameter */ - VCP_ERROR_OUT_OF_NETWORK = TIZEN_ERROR_NETWORK_DOWN, /**< Out of network */ - VCP_ERROR_INVALID_STATE = -0x0100031, /**< Invalid state */ - VCP_ERROR_INVALID_LANGUAGE = -0x0100032, /**< Invalid language */ - VCP_ERROR_OPERATION_FAILED = -0x0100034, /**< Operation failed */ - VCP_ERROR_NOT_SUPPORTED_FEATURE = -0x0100035 /**< Not supported feature */ -} vcp_error_e; - -/** -* @brief Enumerations of audio type. -*/ -typedef enum { - VCP_AUDIO_TYPE_PCM_S16_LE = 0, /**< Signed 16bit audio type, Little endian */ - VCP_AUDIO_TYPE_PCM_U8 /**< Unsigned 8bit audio type */ -} vcp_audio_type_e; - -/** -* @brief Enumerations of callback event. -*/ -typedef enum { - VCP_RESULT_EVENT_SUCCESS = 0, /**< Event when the recognition full result is ready */ - VCP_RESULT_EVENT_REJECTED, /**< Event when the recognition result is rejected */ - VCP_RESULT_EVENT_ERROR /**< Event when the recognition has failed */ -} vcp_result_event_e; - -/** -* @brief Enumerations of command type. -*/ -typedef enum { - VCP_COMMAND_FORMAT_FIXED = 0, /**< Fixed command */ - VCP_COMMAND_FORMAT_FIXED_AND_VFIXED, /**< Fixed command + variable-fixed command */ - VCP_COMMAND_FORMAT_VFIXED_AND_FIXED, /**< variable-fixed command + Fixed command */ - VCP_COMMAND_FORMAT_FIXED_AND_NONFIXED, /**< Fixed command + Non-fixed command */ - VCP_COMMAND_FORMAT_NONFIXED_AND_FIXED, /**< Non-fixed command + Fixed command */ - VCP_COMMAND_FORMAT_ACTION, - VCP_COMMAND_FORMAT_PARTIAL -} vcp_command_format_e; - -/** -* @brief Definition for foreground command type. -* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif -*/ -#define VCP_COMMAND_TYPE_FOREGROUND 1 - -/** -* @brief Definition for background command type. -* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif -*/ -#define VCP_COMMAND_TYPE_BACKGROUND 2 - -/** -* @brief Definition for widget command type. -* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif -*/ -#define VCP_COMMAND_TYPE_WIDGET 3 - -/** -* @brief Definition for system command type. -* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif -*/ -#define VCP_COMMAND_TYPE_SYSTEM 4 - -/** -* @brief Definition for exclusive command type. -* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif -*/ -#define VCP_COMMAND_TYPE_SYSTEM_BACKGROUND 5 - -/** -* @brief Definitions for exclusive command type. -* @since_tizen 2.4 -*/ -#define VCP_COMMAND_TYPE_EXCLUSIVE 6 - - -/** -* @brief Enumerations of speech detect. -*/ -typedef enum { - VCP_SPEECH_DETECT_NONE = 0, /**< No event */ - VCP_SPEECH_DETECT_BEGIN, /**< Begin of speech detected */ - VCP_SPEECH_DETECT_END, /**< End of speech detected */ -} vcp_speech_detect_e; - -typedef enum { - VCP_ASR_RESULT_EVENT_FINAL_RESULT = 0, - VCP_ASR_RESULT_EVENT_PARTIAL_RESULT, - VCP_ASR_RESULT_EVENT_ERROR -} vcp_asr_result_event_e; - -/** -* @brief A structure of handle for VC command -*/ -typedef int vcp_cmd_h; - -/** - * @brief Definition of bluetooth audio id. -*/ -#define VCP_AUDIO_ID_BLUETOOTH "VC_AUDIO_ID_BLUETOOTH" /**< Bluetooth audio id */ - -/** - * @brief Definition of MSF(wifi) audio id. -*/ -#define VCP_AUDIO_ID_MSF "VC_AUDIO_ID_MSF" /**< MSF (wifi) audio id */ - -/** -* @brief Definition for none message. -*/ -#define VC_RESULT_MESSAGE_NONE "vc.result.message.none" - -/** -* @brief Definition for failed recognition because the speech is too loud to listen. -*/ -#define VC_RESULT_MESSAGE_ERROR_TOO_LOUD "vc.result.message.error.too.loud" - - -/** -* @brief Called when the daemon gets synthesized result. -* -* @param[in] event A result event -* @param[in] result_id Result ids -* @param[in] count Result count -* @param[in] all_result All result text -* @param[in] non_fixed_result Non-fixed command result text -* @param[in] nlu_result NLU result text -* @param[in] msg Engine message (e.g. #VC_RESULT_MESSAGE_NONE, #VC_RESULT_MESSAGE_ERROR_TOO_LOUD) -* @param[in] user_data The user data passed from set callback function -* -* @pre vcpe_stop() will invoke this callback. -* -* @see vcpe_stop() -*/ -typedef void (*vcpe_result_cb)(vcp_result_event_e event, int* result_id, int count, - const char* all_result, const char* non_fixed_result, const char* nlu_result, const char* msg, void *user_data); - - -/** -* @brief Called when the daemon gets ASR result. -* -* @param[in] event A asr result event -* @param[in] pre_result result text -* @param[in] user_data The user data passed from the start -*/ -typedef void (*vcpe_asr_result_cb)(vcp_asr_result_event_e event, const char* asr_result, void *user_data); - -/** -* @brief Called when the daemon gets nlg result. -* -* @param[in] nlg_result Nlg result -* @param[in] user_data The user data passed from the start -*/ -typedef void (*vcpe_nlg_result_cb)(const char* nlg_result, void *user_data); - -/** -* @brief Called when the daemon gets error. -* -* @param[in] error Error type -* @param[in] msg Error message -* @param[in] user_data The user data passed from set callback function -* -*/ -typedef void (*vcpe_error_cb)(vcp_error_e error, const char* msg, void *user_data); - -/** -* @brief Called to retrieve the supported languages. -* -* @param[in] language A language is specified as an ISO 3166 alpha-2 two letter country-code -* followed by ISO 639-1 for the two-letter language code \n -* For example, "ko_KR" for Korean, "en_US" for American English -* @param[in] user_data The user data passed from the foreach function -* -* @return @c true to continue with the next iteration of the loop \n @c false to break out of the loop -* -* @pre vcpe_foreach_supported_languages() will invoke this callback. -* -* @see vcpe_foreach_supported_languages() -*/ -typedef bool (*vcpe_supported_language_cb)(const char* language, void* user_data); - -/** -* @brief Initializes the engine. -* -* @param[in] result_cb A callback function for recognition result -* @param[in] silence_cb A callback function for silence detection -* -* @return 0 on success, otherwise a negative error value -* @retval #VCP_ERROR_NONE Successful -* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter -* @retval #VCP_ERROR_INVALID_STATE Already initialized -* @retval #VCP_ERROR_OPERATION_FAILED Operation failed -* -* @see vcpe_deinitialize() -*/ -typedef int (*vcpe_initialize)(void); - -/** -* @brief Deinitializes the engine -* -* @return 0 on success, otherwise a negative error value -* @retval #VCP_ERROR_NONE Successful -* @retval #VCP_ERROR_INVALID_STATE Not initialized -* -* @see vcpe_initialize() -*/ -typedef void (*vcpe_deinitialize)(void); - -/** -* @brief Registers a callback function for getting recognition result. -* -* @param[in] callback Callback function to register -* @param[in] user_data The user data to be passed to the callback function -* -* @return 0 on success, otherwise a negative error value -* @retval #VCP_ERROR_NONE Successful -* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter -* -* @see vcpe_result_cb() -*/ -typedef int (*vcpe_set_result_cb)(vcpe_result_cb callback, void* user_data); - -/** -* @brief Registers a callback function for getting ASR recognition result. -* -* @param[in] callback Callback function to register -* @param[in] user_data The user data to be passed to the callback function -* -* @return 0 on success, otherwise a negative error value -* -* @see vcpe_asr_result_cb() -*/ -typedef int (*vcpe_set_asr_result_cb)(vcpe_asr_result_cb callback, void* user_data); - -/** -* @brief Registers a callback function for getting nlg result. -* -* @param[in] callback Callback function to register -* @param[in] user_data The user data to be passed to the callback function -* -* @return 0 on success, otherwise a negative error value -* -*/ -typedef int (*vcpe_set_nlg_result_cb)(vcpe_nlg_result_cb, void* user_data); - -#if 0 -/** -* @brief Registers a callback function for getting partial recognition result. -* -* @param[in] callback Callback function to register -* @param[in] user_data The user data to be passed to the callback function -* -* @return 0 on success, otherwise a negative error value -* -* @see vcpe_pre_result_cb() -*/ -typedef int (*vcpe_set_pre_result_cb)(vcpe_pre_result_cb callback, void* user_data); -#endif - -/** -* @brief Registers a callback function for error. -* -* @param[in] callback Callback function to register -* @param[in] user_data The user data to be passed to the callback function -* -* @return 0 on success, otherwise a negative error value -* -*/ -typedef int (*vcpe_set_error_cb)(vcpe_error_cb callback, void* user_data); - -#if 0 -/** -* @brief Registers a callback function for getting NLU result. -* -* @param[in] callback Callback function to register -* @param[in] user_data The user data to be passed to the callback function -* -* @return 0 on success, otherwise a negative error value -* -*/ -typedef int (*vcpe_set_nlu_result_cb)(vcpe_nlu_result_cb, void* user_data); -#endif - -/** -* @brief Gets recording format of the engine. -* -* @param[in] audio_id The audio device id. -* @param[out] types The format used by the recorder. -* @param[out] rate The sample rate used by the recorder. -* @param[out] channels The number of channels used by the recorder. -* -* @return 0 on success, otherwise a negative error value -* @retval #VCP_ERROR_NONE Successful -* @retval #VCP_ERROR_INVALID_PARAMETER Not initialized -*/ -typedef int (*vcpe_get_recording_format)(const char* audio_id, vcp_audio_type_e* types, int* rate, int* channels); - -/** -* @brief Retrieves all supported languages of the engine. -* -* @param[in] callback a callback function -* @param[in] user_data The user data to be passed to the callback function -* -* @return 0 on success, otherwise a negative error value -* @retval #VCP_ERROR_NONE Successful -* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter -* @retval #VCP_ERROR_INVALID_STATE Not initialized -* -* @post This function invokes vcpe_supported_language_cb() repeatedly for getting supported languages. -* -* @see vcpe_supported_language_cb() -*/ -typedef int (*vcpe_foreach_supported_languages)(vcpe_supported_language_cb callback, void* user_data); - -/** -* @brief Checks whether a language is supported or not. -* -* @param[in] language A language -* -* @return @c true = supported, \n @c false = not supported. -*/ -typedef bool (*vcpe_is_language_supported)(const char* language); - -/** -* @brief Sets language. -* -* @param[in] language language. -* -* @return 0 on success, otherwise a negative error value -* @retval #VCP_ERROR_NONE Successful -* @retval #VCP_ERROR_INVALID_LANGUAGE Invalid language -* @retval #VCP_ERROR_INVALID_STATE Not initialized -*/ -typedef int (*vcpe_set_language)(const char* language); - -/** -* @brief Sets command list before recognition. -* -* @remark This function should set commands via vcpd_foreach_command(). -* -* @param[in] vcp_command command handle. -* -* @return 0 on success, otherwise a negative error value -* @retval #VCP_ERROR_NONE Successful -* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter -* @retval #VCP_ERROR_INVALID_STATE Invalid state -* @retval #VCP_ERROR_OPERATION_FAILED Operation failed -* @retval #VCP_ERROR_NOT_SUPPORTED_FEATURE Not supported command type -* -* @post vcpe_start() is called after this function is successful. -* -* @see vcpe_start() -* @see vcpd_foreach_command() -* @see vcpe_unset_commands() -*/ -typedef int (*vcpe_set_commands)(vcp_cmd_h vcp_command); - -/** -* @brief Unset command list for reset. -* -* @return 0 on success, otherwise a negative error value -* @retval #VCP_ERROR_NONE Successful -* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter -* @retval #VCP_ERROR_INVALID_STATE Invalid state -* @retval #VCP_ERROR_OPERATION_FAILED Operation failed -* -* @see vcpe_set_commands() -*/ -typedef int (*vcpe_unset_commands)(); - -/** -* @brief Start recognition. -* -* @return 0 on success, otherwise a negative error value -* @retval #VCP_ERROR_NONE Successful -* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter -* @retval #VCP_ERROR_INVALID_STATE Invalid state -* @retval #VCP_ERROR_INVALID_LANGUAGE Invalid language -* @retval #VCP_ERROR_OUT_OF_NETWORK Out of network -* @retval #VCP_ERROR_OPERATION_FAILED Operation failed -* -* @pre vcpd_foreach_command() is successful. -* -* @see vcpe_set_recording_data() -* @see vcpe_stop() -* @see vcpe_cancel() -*/ -typedef int (*vcpe_start)(bool stop_by_silence); - -/** -* @brief Sets recording data for speech recognition from recorder. -* -* @remark This function should be returned immediately after recording data copy. -* -* @param[in] data A recording data -* @param[in] length A length of recording data -* @param[out] silence_detected @c true Silence detected \n @c false No silence detected -* -* @return 0 on success, otherwise a negative error value -* @retval #VCP_ERROR_NONE Successful -* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter -* @retval #VCP_ERROR_INVALID_STATE Invalid state -* @retval #VCP_ERROR_OPERATION_FAILED Operation failed -* -* @pre vcpe_start() is successful. -* -* @see vcpe_start() -* @see vcpe_cancel() -* @see vcpe_stop() -*/ -typedef int(*vcpe_set_recording_data)(const void* data, unsigned int length, vcp_speech_detect_e* speech_detected); - -/** -* @brief Stops to get the result of recognition. -* -* @return 0 on success, otherwise a negative error value -* @retval #VCP_ERROR_NONE Successful -* @retval #VCP_ERROR_INVALID_STATE Invalid state -* @retval #VCP_ERROR_OPERATION_FAILED Operation failed -* @retval #VCP_ERROR_OUT_OF_NETWORK Out of network -* -* @pre vcpe_set_recording_data() is successful. -* -* @see vcpe_start() -* @see vcpe_set_recording_data() -* @see vcpe_result_cb() -* @see vcpe_cancel() -*/ -typedef int (*vcpe_stop)(void); - -/** -* @brief Cancels the recognition process. -* -* @return 0 on success, otherwise a negative error value. -* @retval #VCP_ERROR_NONE Successful. -* @retval #VCP_ERROR_INVALID_STATE Invalid state. -* -* @pre vcpe_start() is successful. -* -* @see vcpe_start() -* @see vcpe_stop() -*/ -typedef int (*vcpe_cancel)(void); - -/** -* @brief Set audio recording type. -* -* @return 0 on success, otherwise a negative error value. -* @retval #VCP_ERROR_NONE Successful. -* -*/ -typedef int (*vcpe_set_audio_type)(const char* audio); - -/** -* @brief Sets domain (Agent or device type) -* -* @param[in] domain available Agent or device type -* -* @return 0 on success, otherwise a negative error value. -* -*/ -typedef int (*vcpe_set_domain)(const char* domain); - -/** -* @brief Gets essential value from nlu result. This function is available inside vcpe_nlu_result_cb() -* -* @param[in] key NLU base info key -* @parma[out] value NLU base info value -* -* @return 0 on success, otherwise a negative error value. -* -*/ -typedef int (*vcpe_get_nlu_base_info)(const char* key, char** value); - -/** -* @brief Sets private data between app and engine. -* -* @param[in] key Private key -* @param[in] data Private data -* -* @return 0 on success, otherwise a negative error value. -* -*/ -typedef int (*vcpe_set_private_data)(const char* key, const char* data); - -/** -* @brief Gets private data between app and engine. -* -* @param[in] key Private key -* @param[out] data Private data -* -* @return 0 on success, otherwise a negative error value. -* -*/ -typedef int (*vcpe_get_private_data)(const char* key, char** data); - -/** -* @brief Request process text. -* -* @param[in] text Requested text -* -* @return 0 on success, otherwise a negative error value. -* -*/ -typedef int (*vcpe_process_text)(const char* text); - -/** -* @brief Request list event. -* -* @param[in] event Requested list event -* -* @return 0 on success, otherwise a negative error value. -* -*/ -typedef int (*vcpe_process_list_event)(const char* event); - -/** -* @brief Request haptic event. -* -* @param[in] event Requested haptic event -* -* @return 0 on success, otherwise a negative error value. -* -*/ -typedef int (*vcpe_process_haptic_event)(const char* event); - -/** -* Daemon API. -*/ - -/** -* @brief Called to retrieve the commands. -* -* @param[in] id command id -* @param[in] type command type -* @param[in] format command format -* @param[in] command command text -* @param[in] param parameter text -* @param[in] domain command domain -* @param[in] user_data The user data passed from the foreach function -* -* @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop. -* @pre vcpd_foreach_command() will invoke this callback. -* -* @see vcpd_foreach_command() -*/ -typedef bool (*vcpd_foreach_command_cb)(int id, int type, int format, const char* command, const char* param, int domain, void* user_data); - -/** -* @brief Retrieves all commands using callback function. -* -* @param[in] vcp_command The handle to be passed to the vcpe_set_commands() function -* @param[in] callback The callback function to invoke -* @param[in] user_data The user data to be passed to the callback function -* -* @return 0 on success, otherwise a negative error value -* @retval #VCP_ERROR_NONE Successful -* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter -* @retval #VCP_ERROR_OPERATION_FAILED Operation failure -* @retval #VCP_ERROR_INVALID_STATE Invalid state -* -* @post This function invokes vcpd_foreach_command_cb() repeatedly for getting commands. -* -* @see vcpd_foreach_command_cb() -* @see vcpe_set_commands() -*/ -typedef int (*vcpd_foreach_command)(vcp_cmd_h vcp_command, vcpd_foreach_command_cb callback, void* user_data); - -/** -* @brief Gets command length. -* -* @param[in] vcp_command The handle to be passed to the vcpe_set_commands() function -* -* @return the value greater than 0 on success, otherwise a negative error value -* -* @see vcpe_set_commands() -*/ -typedef int (*vcpd_get_command_count)(vcp_cmd_h vcp_command); - -/** -* @brief Gets current audio type. -* -* @remarks audio_type must be released using free() when it is no longer required. -* -* @param[in] audio_type Current audio type (e.g. #VCP_AUDIO_ID_BLUETOOTH or usb device id) -* -* @return the value greater than 0 on success, otherwise a negative error value -* -*/ -typedef int (*vcpd_get_audio_type)(char** audio_type); - -/** -* @brief Sets private data to Manager client. -* -* @param[in] key Private key -* @param[in] data Private data -* -* @return 0 on success, otherwise a negative error value. -* -*/ -typedef int (*vcpd_set_private_data)(const char* key, const char* data); - -/** -* @brief Gets private data from Manager client. -* -* @param[in] key Private key -* @param[out] data Private data -* -* @return 0 on success, otherwise a negative error value. -* -*/ -typedef int (*vcpd_get_private_data)(const char* key, char** data); - -/** -* @brief Request start recording. -* -* @return 0 on success, otherwise a negative error value. -* -*/ -typedef int (*vcpd_start_recording)(); - -/** -* @brief Request stop recording. -* -* @return 0 on success, otherwise a negative error value. -* -*/ -typedef int (*vcpd_stop_recording)(); - -/** -* @brief A structure of the engine functions. -*/ -typedef struct { - int size; /**< Size of structure */ - int version; /**< Version */ - - vcpe_initialize initialize; /**< Initialize engine */ - vcpe_deinitialize deinitialize; /**< Shutdown engine */ - - /* Get engine information */ - vcpe_get_recording_format get_recording_format; /**< Get recording format */ - vcpe_foreach_supported_languages foreach_langs; /**< Foreach language list */ - vcpe_is_language_supported is_lang_supported; /**< Check language */ - - /* Set info */ - vcpe_set_result_cb set_result_cb; /**< Set result callback */ - vcpe_set_language set_language; /**< Set language */ - vcpe_set_commands set_commands; /**< Request to set current commands */ - vcpe_unset_commands unset_commands; /**< Request to unset current commands */ - - /* Control recognition */ - vcpe_start start; /**< Start recognition */ - vcpe_set_recording_data set_recording; /**< Set recording data */ - vcpe_stop stop; /**< Stop recording for getting result */ - vcpe_cancel cancel; /**< Cancel recording and processing */ - - vcpe_set_audio_type set_audio_type; /**< Set audio type */ - - //vcpe_set_pre_result_cb set_pre_result_cb; /**< Set pre result callback */ - vcpe_set_asr_result_cb set_asr_result_cb; /**< Set asr result callback */ - vcpe_set_nlg_result_cb set_nlg_result_cb; /**< Set nlg result callback */ - vcpe_set_error_cb set_error_cb; /**< Set error callback */ - vcpe_set_domain set_domain; /**< Set domain */ - vcpe_get_nlu_base_info get_nlu_base_info; /**< Get essential info */ - //vcpe_set_nlu_result_cb set_nlu_result_cb; /**< Set nlu result callback */ - vcpe_set_private_data set_private_data; /**< Set private data */ - vcpe_get_private_data get_private_data; /**< Get private data */ - vcpe_process_text process_text; /**< Request to process text */ - vcpe_process_list_event process_list_event; /**< Request to process list event */ - vcpe_process_haptic_event process_haptic_event; /**< Request to process haptic event */ -} vcpe_funcs_s; - -/** -* @brief A structure of the daemon functions. -*/ -typedef struct { - int size; /**< Size of structure */ - int version; /**< Version */ - - vcpd_foreach_command foreach_command; /**< Foreach command */ - vcpd_get_command_count get_command_count; /**< Get command count */ - - vcpd_get_audio_type get_audio_type; /**< Get audio type */ - - vcpd_set_private_data set_private_data; /**< Set private data to Manager */ - vcpd_get_private_data get_private_data; /**< Get private data from Manager */ - - vcpd_start_recording start_recording; /**< Request start recording */ - vcpd_stop_recording stop_recording; /**< Request stop recording */ -} vcpd_funcs_s; - -/** -* @brief Loads the engine. -* -* @param[in] pdfuncs The daemon functions -* @param[out] pefuncs The engine functions -* -* @return This function returns zero on success, or negative with error code on failure -* @retval #VCP_ERROR_NONE Successful -* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter -* @retval #VCP_ERROR_OPERATION_FAILED Operation failed -* -* @pre The vcp_get_engine_info() should be successful. -* @post The daemon calls engine functions of vcpe_funcs_s. -* -* @see vcp_get_engine_info() -* @see vcp_unload_engine() -*/ -int vcp_load_engine(vcpd_funcs_s* pdfuncs, vcpe_funcs_s* pefuncs); - -/** -* @brief Unloads this engine by the daemon. -* -* @pre The vcp_load_engine() should be successful. -* -* @see vcp_load_engine() -*/ -void vcp_unload_engine(void); - -/** -* @brief Called to get the engine base information. -* -* @param[in] engine_uuid The engine id -* @param[in] engine_name The engine name -* @param[in] engine_setting The setting ug name -* @param[in] use_network @c true to need network @c false not to need network. -* @param[in] user_data The User data passed from vcp_get_engine_info() -* -* @pre vcp_get_engine_info() will invoke this callback. -* -* @see vcp_get_engine_info() -*/ -typedef void (*vcpe_engine_info_cb)(const char* engine_uuid, const char* engine_name, const char* engine_setting, - bool use_network, void* user_data); - -/** -* @brief Gets the engine base information before the engine is loaded by the daemon. -* -* @param[in] callback Callback function -* @param[in] user_data User data to be passed to the callback function -* -* @return This function returns zero on success, or negative with error code on failure -* @retval #VCP_ERROR_NONE Successful -* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter -* @retval #VCP_ERROR_OPERATION_FAILED Operation failed -* -* @post This function invokes vcpe_engine_info_cb() for getting engine information. -* -* @see vcpe_engine_info_cb() -* @see vcp_load_engine() -*/ -int vcp_get_engine_info(vcpe_engine_info_cb callback, void* user_data); - - -#ifdef __cplusplus -} -#endif - -/** -* @}@} -*/ - -#endif /* __VOICE_CONTROL_PLUGIN_ENGINE_H__ */ diff --git a/org.tizen.voice.vcserver.service b/org.tizen.voice.vcserver.service index a6f1e01..c5006a2 100644 --- a/org.tizen.voice.vcserver.service +++ b/org.tizen.voice.vcserver.service @@ -1,3 +1,4 @@ [D-BUS Service] Name=org.tizen.voice.vcserver -Exec=/usr/bin/vc-daemon +#Exec=/usr/bin/vc-daemon +Exec=/bin/sh -c "launch_app org.tizen.vc-engine-default" diff --git a/packaging/voice-control.spec b/packaging/voice-control.spec index bb50859..3b585bc 100644 --- a/packaging/voice-control.spec +++ b/packaging/voice-control.spec @@ -121,7 +121,7 @@ mkdir -p %{_libdir}/voice/vc %{_libdir}/libvc_setting.so %{_libdir}/libvc_widget.so %{_libdir}/libvc_manager.so -%{_bindir}/vc-daemon +%{_libdir}/libvc_engine.so %{TZ_SYS_RO_SHARE}/voice/vc/1.0/vc-config.xml %{TZ_SYS_RO_SHARE}/dbus-1/services/org.tizen.voice* /etc/dbus-1/session.d/vc-server.conf @@ -165,4 +165,5 @@ mkdir -p %{_libdir}/voice/vc %files engine-devel %defattr(-,root,root,-) %{_libdir}/pkgconfig/voice-control-engine.pc -%{_includedir}/voice_control_plugin_engine.h +%{_includedir}/vce.h + diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index d2cf638..f9e8d48 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -10,11 +10,13 @@ SET(SRCS vcd_dbus_server.c vcd_dbus.c vcd_engine_agent.c - vcd_main.c +# vcd_main.c vcd_recorder.c vcd_server.c + vce.c ) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/common) INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/include) @@ -28,8 +30,15 @@ SET(CMAKE_C_FLAGS_RELEASE "-O2 -fPIE") SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie") ## Executable ## -ADD_EXECUTABLE("${PROJECT_NAME}-daemon" ${SRCS}) -TARGET_LINK_LIBRARIES("${PROJECT_NAME}-daemon" -ldl -lm ${pkgs_LDFLAGS}) +#ADD_EXECUTABLE("${PROJECT_NAME}-daemon" ${SRCS}) +#TARGET_LINK_LIBRARIES("${PROJECT_NAME}-daemon" -ldl -lm ${pkgs_LDFLAGS}) ## Install -INSTALL(TARGETS "${PROJECT_NAME}-daemon" DESTINATION bin) +#INSTALL(TARGETS "${PROJECT_NAME}-daemon" DESTINATION bin) + +## Executable ## +ADD_LIBRARY("${PROJECT_NAME}_engine" SHARED ${SRCS}) +TARGET_LINK_LIBRARIES("${PROJECT_NAME}_engine" -ldl ${pkgs_LDFLAGS}) + +## Install +INSTALL(TARGETS "${PROJECT_NAME}_engine" DESTINATION ${LIBDIR} COMPONENT RuntimeLibraries) diff --git a/server/vcd_engine_agent.c b/server/vcd_engine_agent.c index 2811020..c502151 100644 --- a/server/vcd_engine_agent.c +++ b/server/vcd_engine_agent.c @@ -1,18 +1,18 @@ /* -* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved -* -* Licensed under the Apache License, Version 2.0 (the License); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an AS IS BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include @@ -26,8 +26,8 @@ #include "vcd_dbus.h" /* -* Internal data structure -*/ + * Internal data structure + */ typedef struct { /* engine info */ char* engine_uuid; @@ -40,11 +40,7 @@ typedef struct { bool is_command_ready; void *handle; - vcpe_funcs_s* pefuncs; - vcpd_funcs_s* pdfuncs; - - int (*vcp_load_engine)(vcpd_funcs_s* pdfuncs, vcpe_funcs_s* pefuncs); - int (*vcp_unload_engine)(); + vc_engine_callback_s* callbacks; } vcengine_s; typedef struct _vcengine_info { @@ -55,68 +51,34 @@ typedef struct _vcengine_info { /* -* static data -*/ + * static data + */ /** vc engine agent init */ static bool g_agent_init; -/** vc engine list */ -static GList *g_engine_list; - /** current engine information */ static vcengine_s g_dynamic_engine; static char* g_default_lang; -/** callback functions */ -static result_callback g_result_cb = NULL; - -static asr_result_callback g_asr_result_cb = NULL; -static nlg_result_callback g_nlg_result_cb = NULL; - -#if 0 -static pre_result_callback g_pre_result_cb = NULL; - -static nlu_result_callback g_nlu_result_cb = NULL; -#endif - -static error_callback g_error_cb = NULL; - bool __supported_language_cb(const char* language, void* user_data); -void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* engine_setting, bool use_network, void* user_data); - -bool __engine_setting_cb(const char* key, const char* value, void* user_data); - -/** Free voice list */ -void __free_language_list(GList* lang_list); - - /* -* Internal Interfaces -*/ - -/** check engine id */ -int __internal_check_engine_id(const char* engine_uuid); - -/** update engine list */ -int __internal_update_engine_list(); + * Internal Interfaces + */ /** get engine info */ -int __internal_get_engine_info(const char* filepath, vcengine_info_s** info); - -int __log_enginelist(); +int __internal_get_engine_info(vce_request_callback_s* callback); /* -* VCS Engine Agent Interfaces -*/ -//int vcd_engine_agent_init(pre_result_callback pre_result_cb, result_callback result_cb, nlu_result_callback nlu_result_cb, error_callback error_cb) -int vcd_engine_agent_init(asr_result_callback asr_result_cb, result_callback result_cb, nlg_result_callback nlg_result_cb, error_callback error_cb) + * VCS Engine Agent Interfaces + */ +int vcd_engine_agent_init() { - if (/*NULL == pre_result_cb*/ NULL == asr_result_cb || NULL == result_cb /*|| NULL == nlu_result_cb*/ || NULL == error_cb) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Input parameter is NULL"); - return VCD_ERROR_OPERATION_FAILED; + if (true == g_agent_init) { + SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Already initialized"); + return VCD_ERROR_NONE; } /* init dynamic engine */ @@ -128,17 +90,14 @@ int vcd_engine_agent_init(asr_result_callback asr_result_cb, result_callback res g_dynamic_engine.is_loaded = false; g_dynamic_engine.handle = NULL; g_dynamic_engine.is_command_ready = false; - g_dynamic_engine.pefuncs = (vcpe_funcs_s*)calloc(1, sizeof(vcpe_funcs_s)); - g_dynamic_engine.pdfuncs = (vcpd_funcs_s*)calloc(1, sizeof(vcpd_funcs_s)); - g_agent_init = true; + g_dynamic_engine.callbacks = (vc_engine_callback_s*)calloc(1, sizeof(vc_engine_callback_s)); + if (NULL == g_dynamic_engine.callbacks) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] Fail to allocate memory"); + return VCD_ERROR_OUT_OF_MEMORY; + } - //g_pre_result_cb = pre_result_cb; - g_asr_result_cb = asr_result_cb; - g_nlg_result_cb = nlg_result_cb; - g_result_cb = result_cb; - //g_nlu_result_cb = nlu_result_cb; - g_error_cb = error_cb; + g_agent_init = true; if (0 != vcd_config_get_default_language(&g_default_lang)) { SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] There is No default voice in config"); @@ -161,61 +120,14 @@ int vcd_engine_agent_release() /* unload current engine */ vcd_engine_agent_unload_current_engine(); - /* release engine list */ - GList *iter = NULL; - vcengine_s *data = NULL; - - if (g_list_length(g_engine_list) > 0) { - /* Get a first item */ - iter = g_list_first(g_engine_list); - - while (NULL != iter) { - /* Get handle data from list */ - data = iter->data; - iter = g_list_remove(iter, data); - - if (NULL != data) { - if (NULL != data->engine_uuid) { - g_free(data->engine_uuid); - data->engine_uuid = NULL; - } - if (NULL != data->engine_name) { - g_free(data->engine_name); - data->engine_name = NULL; - } - if (NULL != data->engine_path) { - g_free(data->engine_path); - data->engine_path = NULL; - } - - free(data); - data = NULL; - } - } - } - - g_list_free(iter); - g_engine_list = NULL; - /* release current engine data */ - if (NULL != g_dynamic_engine.pefuncs) { - free(g_dynamic_engine.pefuncs); - g_dynamic_engine.pefuncs = NULL; - } - if (NULL != g_dynamic_engine.pdfuncs) { - free(g_dynamic_engine.pdfuncs); - g_dynamic_engine.pdfuncs = NULL; + if (NULL != g_dynamic_engine.callbacks) { + free(g_dynamic_engine.callbacks); + g_dynamic_engine.callbacks = NULL; } g_agent_init = false; - //g_pre_result_cb = NULL; - g_asr_result_cb = NULL; - g_nlg_result_cb = NULL; - g_result_cb = NULL; - //g_nlu_result_cb = NULL; - g_error_cb = NULL; - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Engine Agent release"); return 0; @@ -229,561 +141,173 @@ bool vcd_engine_is_available_engine() return false; } -int vcd_engine_agent_initialize_current_engine() +int __internal_get_engine_info(vce_request_callback_s* callback) { - /* check agent init */ - if (false == g_agent_init) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized"); - return VCD_ERROR_OPERATION_FAILED; - } + SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] inside __internal_get_engine_info"); - /* update engine list */ - if (0 != __internal_update_engine_list()) { - SLOG(LOG_ERROR, TAG_VCD, "[engine agent] vcd_engine_agent_init : __internal_update_engine_list : no engine error"); + if (NULL == callback) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid engine"); return VCD_ERROR_ENGINE_NOT_FOUND; } - /* check whether engine id is valid or not.*/ - GList *iter = NULL; - vcengine_info_s *dynamic_engine = NULL; - - if (g_list_length(g_engine_list) > 0) { - /*Get a first item*/ - iter = g_list_first(g_engine_list); - - while (NULL != iter) { - /*Get handle data from list*/ - dynamic_engine = iter->data; - if (NULL != dynamic_engine) { - break; - } - - /*Get next item*/ - iter = g_list_next(iter); - } - } else { + if (NULL == callback->get_info) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid engine"); return VCD_ERROR_ENGINE_NOT_FOUND; } - if (NULL == dynamic_engine) { + if (0 != callback->get_info(&(g_dynamic_engine.engine_uuid), &(g_dynamic_engine.engine_name))) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get engine info"); return VCD_ERROR_ENGINE_NOT_FOUND; - } else { - if (NULL != g_dynamic_engine.engine_uuid) { - /* set data from g_engine_list */ - if (g_dynamic_engine.engine_uuid != NULL) g_free(g_dynamic_engine.engine_uuid); - if (g_dynamic_engine.engine_name != NULL) g_free(g_dynamic_engine.engine_name); - if (g_dynamic_engine.engine_path != NULL) g_free(g_dynamic_engine.engine_path); - } - - g_dynamic_engine.engine_uuid = g_strdup(dynamic_engine->engine_uuid); - g_dynamic_engine.engine_name = g_strdup(dynamic_engine->engine_name); - g_dynamic_engine.engine_path = g_strdup(dynamic_engine->engine_path); - - g_dynamic_engine.handle = NULL; - g_dynamic_engine.is_loaded = false; - g_dynamic_engine.is_set = true; - - SLOG(LOG_DEBUG, TAG_VCD, "@@@"); - SLOG(LOG_DEBUG, TAG_VCD, " Dynamic engine uuid : %s", g_dynamic_engine.engine_uuid); - SLOG(LOG_DEBUG, TAG_VCD, " Dynamic engine name : %s", g_dynamic_engine.engine_name); - SLOG(LOG_DEBUG, TAG_VCD, " Dynamic engine path : %s", g_dynamic_engine.engine_path); - SLOG(LOG_DEBUG, TAG_VCD, "@@@"); - - } - - return 0; -} - -int __internal_check_engine_id(const char* engine_uuid) -{ - if (NULL == engine_uuid) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter"); - return VCD_ERROR_INVALID_PARAMETER; - } - - GList *iter = NULL; - vcengine_s *data = NULL; - - if (0 < g_list_length(g_engine_list)) { - /*Get a first item*/ - iter = g_list_first(g_engine_list); - - while (NULL != iter) { - data = iter->data; - - if (0 == strncmp(engine_uuid, data->engine_uuid, strlen(data->engine_uuid))) { - return 0; - } - - iter = g_list_next(iter); - } - } - - return -1; -} - -void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* engine_setting, bool use_network, void* user_data) -{ - vcengine_info_s* temp = (vcengine_info_s*)user_data; - - temp->engine_uuid = g_strdup(engine_uuid); - temp->engine_name = g_strdup(engine_name); -} - - -int __internal_get_engine_info(const char* filepath, vcengine_info_s** info) -{ - if (NULL == filepath || NULL == info) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter"); - return VCD_ERROR_INVALID_PARAMETER; } - /* load engine */ - char *error; - void* handle; - - handle = dlopen(filepath, RTLD_LAZY); - if (!handle) { - SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Invalid engine : %s", filepath); - if ((error = dlerror()) != NULL) { - SLOG(LOG_ERROR, TAG_VCD, "[ERROR] %s", error); - } - return -1; + if (NULL != g_dynamic_engine.callbacks) { + free(g_dynamic_engine.callbacks); + g_dynamic_engine.callbacks = NULL; } - - /* link engine to daemon */ - dlsym(handle, "vcp_load_engine"); - if ((error = dlerror()) != NULL) { - SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Invalid engine. Fail to open vcp_load_engine : %s", filepath); - dlclose(handle); - return -1; - } - - dlsym(handle, "vcp_unload_engine"); - if ((error = dlerror()) != NULL) { - SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Invalid engine. Fail to open vcp_unload_engine : %s", filepath); - dlclose(handle); - return -1; - } - - int (*get_engine_info)(vcpe_engine_info_cb callback, void* user_data); - - get_engine_info = (int (*)(vcpe_engine_info_cb, void*))dlsym(handle, "vcp_get_engine_info"); - if (NULL != (error = dlerror()) || NULL == get_engine_info) { - SLOG(LOG_WARN, TAG_VCD, "[Engine Agent WARNING] Invalid engine. Fail to open vcp_get_engine_info : %s", filepath); - dlclose(handle); - return -1; - } - - vcengine_info_s* temp; - temp = (vcengine_info_s*)calloc(1, sizeof(vcengine_info_s)); - if (NULL == temp) { - SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to allocate memory"); - dlclose(handle); + g_dynamic_engine.callbacks = (vc_engine_callback_s*)calloc(1, sizeof(vc_engine_callback_s)); + if (NULL == g_dynamic_engine.callbacks) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to allocate memory"); return VCD_ERROR_OUT_OF_MEMORY; } - /* get engine info */ - if (0 != get_engine_info(__engine_info_cb, (void*)temp)) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get engine info from engine"); - dlclose(handle); - free(temp); - return -1; - } - - /* close engine */ - dlclose(handle); - - temp->engine_path = g_strdup(filepath); + g_dynamic_engine.callbacks->get_info = callback->get_info; + g_dynamic_engine.callbacks->get_recording_format = callback->get_recording_format; + g_dynamic_engine.callbacks->foreach_langs = callback->foreach_langs; + g_dynamic_engine.callbacks->is_lang_supported = callback->is_lang_supported; + g_dynamic_engine.callbacks->initialize = callback->initialize; + g_dynamic_engine.callbacks->deinitialize = callback->deinitialize; + g_dynamic_engine.callbacks->set_language = callback->set_language; + g_dynamic_engine.callbacks->set_commands = callback->set_commands; + g_dynamic_engine.callbacks->unset_commands = callback->unset_commands; + + g_dynamic_engine.callbacks->start = callback->start; + g_dynamic_engine.callbacks->set_recording = callback->set_recording; + g_dynamic_engine.callbacks->stop = callback->stop; + g_dynamic_engine.callbacks->cancel = callback->cancel; + g_dynamic_engine.callbacks->set_domain = callback->set_domain; + g_dynamic_engine.callbacks->set_audio_type = callback->set_audio_type; + g_dynamic_engine.callbacks->process_text = callback->process_text; + g_dynamic_engine.callbacks->process_list_event = callback->process_list_event; + g_dynamic_engine.callbacks->process_haptic_event = callback->process_haptic_event; + + g_dynamic_engine.callbacks->private_data_set = NULL; + g_dynamic_engine.callbacks->private_data_request = NULL; + g_dynamic_engine.callbacks->nlu_base_info_request = NULL; SLOG(LOG_DEBUG, TAG_VCD, "@@@ Valid Engine"); - SLOG(LOG_DEBUG, TAG_VCD, "Engine uuid : %s", temp->engine_uuid); - SLOG(LOG_DEBUG, TAG_VCD, "Engine name : %s", temp->engine_name); - SLOG(LOG_DEBUG, TAG_VCD, "Engine path : %s", temp->engine_path); + SLOG(LOG_DEBUG, TAG_VCD, "Engine uuid : %s", g_dynamic_engine.engine_uuid); + SLOG(LOG_DEBUG, TAG_VCD, "Engine name : %s", g_dynamic_engine.engine_name); SLOG(LOG_DEBUG, TAG_VCD, "@@@"); - *info = temp; - return 0; } -int __internal_update_engine_list() +int vcd_engine_agent_load_current_engine(vce_request_callback_s* callback) { - /* relsease engine list */ - GList *iter = NULL; - vcengine_info_s *data = NULL; - - if (0 < g_list_length(g_engine_list)) { - /* Get a first item */ - iter = g_list_first(g_engine_list); - - while (NULL != iter) { - /* Get handle data from list */ - data = iter->data; + SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] load current engine START"); - if (NULL != data) { - if (NULL != data->engine_uuid) g_free(data->engine_uuid); - if (NULL != data->engine_path) g_free(data->engine_path); - if (NULL != data->engine_name) g_free(data->engine_name); - - data->engine_uuid = NULL; - data->engine_path = NULL; - data->engine_name = NULL; - - free(data); - } - - g_engine_list = g_list_remove_link(g_engine_list, iter); - iter = g_list_first(g_engine_list); - } + if (false == g_agent_init) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized"); + return VCD_ERROR_OPERATION_FAILED; } - /* Get file name from default engine directory */ - DIR *dp = NULL; - struct dirent *dirp = NULL; - - dp = opendir(VC_DEFAULT_ENGINE); - if (NULL != dp) { - do { - dirp = readdir(dp); - - if (NULL != dirp) { - if (!strcmp(".", dirp->d_name) || !strcmp("..", dirp->d_name)) - continue; - - vcengine_info_s* info = NULL; - char* filepath = NULL; - int filesize = 0; - - filesize = strlen(VC_DEFAULT_ENGINE) + strlen(dirp->d_name) + 5; - filepath = (char*)calloc(filesize, sizeof(char)); - - if (NULL != filepath) { - snprintf(filepath, filesize, "%s/%s", VC_DEFAULT_ENGINE, dirp->d_name); - } else { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Memory not enough!!"); - continue; - } - - /* get its info and update engine list */ - if (0 == __internal_get_engine_info(filepath, &info)) { - /* add engine info to g_engine_list */ - g_engine_list = g_list_append(g_engine_list, info); - } - - if (NULL != filepath) { - free(filepath); - filepath = NULL; - } - } - } while (NULL != dirp); - - closedir(dp); - } else { - SLOG(LOG_WARN, TAG_VCD, "[Engine Agent WARNING] Fail to open default directory"); + if (true == g_dynamic_engine.is_loaded) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] Engine has already been loaded"); + return 0; } - if (0 >= g_list_length(g_engine_list)) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] No Engine"); + if (NULL == callback) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid engine"); return VCD_ERROR_ENGINE_NOT_FOUND; } - __log_enginelist(); - - return 0; -} - - -int __foreach_command(vcp_cmd_h vc_command, vcpd_foreach_command_cb callback, void* user_data) -{ - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request foreach command from engine"); - return vcd_client_foreach_command((client_foreach_command_cb)callback, user_data); -} - -int __command_get_length(vcp_cmd_h vc_command) -{ - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request command length from engine"); - return vcd_client_get_length(); -} - -int __get_audio_type(char** audio_type) -{ - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request audio type"); - - return vcd_recorder_get(audio_type); -} - -int __set_private_data(const char* key, const char* data) -{ - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request set private data"); - vcdc_send_request_set_private_data(vcd_client_manager_get_pid(), key, data); - - return 0; -} - -int __get_private_data(const char* key, char** data) -{ - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request get private data"); - vcdc_send_request_get_private_data(vcd_client_manager_get_pid(), key, data); - - return 0; -} - -int __start_recording() -{ - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request start recording"); - - int ret = vcd_recorder_start(); + /* Get current engine info */ + int ret = __internal_get_engine_info(callback); if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recorder : result(%d)", ret); - vcd_engine_recognize_cancel(); - /* Send error cb to manager */ - vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_engine.error.proc_fail"); + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get engine info"); return ret; } - return 0; -} - -int __stop_recording() -{ - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request stop recording"); - - return vcd_recorder_stop(); -} - -void __result_cb(vcp_result_event_e event, int* result_id, int count, const char* all_result, const char* non_fixed, const char* nlu_result, const char* msg, void *user_data) -{ - SLOG(LOG_DEBUG, TAG_VCD, "[Engine agent] Event(%d), Count(%d) Text(%s) Nonfixed(%s) NLU result(%s) Msg(%s)", event, count, all_result, non_fixed, nlu_result, msg); - - if (NULL != g_result_cb) { - g_result_cb(event, result_id, count, all_result, non_fixed, nlu_result, msg, user_data); - } else { - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent ERROR] Result callback function is NOT valid"); - } - - return; -} - -void __asr_result_cb(vcp_asr_result_event_e event, const char* asr_result, void *user_data) -{ - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] ASR result - Event(%d), Result(%s)", event, asr_result); - - if (NULL != g_asr_result_cb) { - g_asr_result_cb(event, asr_result, user_data); - } else { - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent ERROR] ASR result callback function is NOT valid"); - } - - return; -} - -void __nlg_result_cb(const char* nlg_result, void *user_data) -{ - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] NLG result - Result(%s)", nlg_result); - - if (NULL != g_nlg_result_cb) { - g_nlg_result_cb(nlg_result, user_data); - } else { - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent ERROR] NLG result callback function is NOT valid"); - } - - return; -} - -void __error_cb(vcp_error_e error, const char* msg, void *user_data) -{ - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] ERROR(%d)", error); - - if (NULL != g_error_cb) { - g_error_cb(error, msg, user_data); - } else { - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent ERROR] Error callback function is NOT vaild"); - } - - return; -} - -int __load_engine(vcengine_s* engine) -{ - /* check whether current engine is loaded or not */ - if (true == engine->is_loaded) { - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Engine has already been loaded "); - return 0; - } - - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Current engine path : %s", engine->engine_path); - - /* open engine */ - char *error; - engine->handle = dlopen(engine->engine_path, RTLD_LAZY); - - if ((error = dlerror()) != NULL || !engine->handle) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get engine handle"); - return VCD_ERROR_OPERATION_FAILED; - } - - engine->vcp_unload_engine = (int (*)())dlsym(engine->handle, "vcp_unload_engine"); - if ((error = dlerror()) != NULL) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to link daemon to vcp_unload_engine()"); - dlclose(engine->handle); - return VCD_ERROR_OPERATION_FAILED; - } - - engine->vcp_load_engine = (int (*)(vcpd_funcs_s*, vcpe_funcs_s*))dlsym(engine->handle, "vcp_load_engine"); - if (NULL != (error = dlerror()) || NULL == engine->vcp_load_engine) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to link daemon to vcp_load_engine()"); - dlclose(engine->handle); - return VCD_ERROR_OPERATION_FAILED; - } - - /* load engine */ - engine->pdfuncs->version = 1; - engine->pdfuncs->size = sizeof(vcpd_funcs_s); - - engine->pdfuncs->foreach_command = __foreach_command; - engine->pdfuncs->get_command_count = __command_get_length; - engine->pdfuncs->get_audio_type = __get_audio_type; - - engine->pdfuncs->set_private_data = __set_private_data; - engine->pdfuncs->get_private_data = __get_private_data; - - engine->pdfuncs->start_recording = __start_recording; - engine->pdfuncs->stop_recording = __stop_recording; - - if (0 != engine->vcp_load_engine(engine->pdfuncs, engine->pefuncs)) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail vcp_load_engine()"); - dlclose(engine->handle); - return VCD_ERROR_OPERATION_FAILED; - } - - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] engine info : version(%d), size(%d)(%d)", engine->pefuncs->version, engine->pefuncs->size, sizeof(vcpe_funcs_s)); - - /* engine error check */ - if (engine->pefuncs->size != sizeof(vcpe_funcs_s)) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not valid"); - return VCD_ERROR_OPERATION_FAILED; - } - /* Check all engine functions */ - if (NULL == engine->pefuncs->initialize || - NULL == engine->pefuncs->deinitialize || - NULL == engine->pefuncs->get_recording_format || - NULL == engine->pefuncs->foreach_langs || - NULL == engine->pefuncs->is_lang_supported || - NULL == engine->pefuncs->set_result_cb || - NULL == engine->pefuncs->set_language || - NULL == engine->pefuncs->set_commands || - NULL == engine->pefuncs->unset_commands || - NULL == engine->pefuncs->start || - NULL == engine->pefuncs->set_recording || - NULL == engine->pefuncs->stop || - NULL == engine->pefuncs->cancel || - NULL == engine->pefuncs->set_audio_type || - NULL == engine->pefuncs->set_asr_result_cb || - NULL == engine->pefuncs->set_nlg_result_cb || - //NULL == engine->pefuncs->set_pre_result_cb || - NULL == engine->pefuncs->set_error_cb || - NULL == engine->pefuncs->set_domain || - NULL == engine->pefuncs->get_nlu_base_info || - //NULL == engine->pefuncs->set_nlu_result_cb || - NULL == engine->pefuncs->set_private_data || - NULL == engine->pefuncs->get_private_data || - NULL == engine->pefuncs->process_text || - NULL == engine->pefuncs->process_list_event || - NULL == engine->pefuncs->process_haptic_event) { + if (NULL == g_dynamic_engine.callbacks->get_info || + NULL == g_dynamic_engine.callbacks->get_recording_format || + NULL == g_dynamic_engine.callbacks->foreach_langs || + NULL == g_dynamic_engine.callbacks->is_lang_supported || + NULL == g_dynamic_engine.callbacks->initialize || + NULL == g_dynamic_engine.callbacks->deinitialize || + NULL == g_dynamic_engine.callbacks->set_language || + NULL == g_dynamic_engine.callbacks->set_commands || + NULL == g_dynamic_engine.callbacks->unset_commands || + NULL == g_dynamic_engine.callbacks->start || + NULL == g_dynamic_engine.callbacks->set_recording || + NULL == g_dynamic_engine.callbacks->stop || + NULL == g_dynamic_engine.callbacks->cancel || + NULL == g_dynamic_engine.callbacks->set_audio_type || + NULL == g_dynamic_engine.callbacks->set_domain || + NULL == g_dynamic_engine.callbacks->process_text || + NULL == g_dynamic_engine.callbacks->process_list_event || + NULL == g_dynamic_engine.callbacks->process_haptic_event) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] The current engine is NOT valid"); - return VCD_ERROR_OPERATION_FAILED; + return VCD_ERROR_ENGINE_NOT_FOUND; } /* initalize engine */ - if (0 != engine->pefuncs->initialize()) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to initialize vc-engine"); - return VCD_ERROR_OPERATION_FAILED; - } - - if (0 != engine->pefuncs->set_result_cb(__result_cb, NULL)) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set result callback of vc-engine"); - return VCD_ERROR_OPERATION_FAILED; - } - - if (0 != engine->pefuncs->set_asr_result_cb(__asr_result_cb, NULL)) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set asr result callback of vc-engine"); - return VCD_ERROR_OPERATION_FAILED; + ret = g_dynamic_engine.callbacks->initialize(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to initialize vc engine service"); + return ret; } - if (0 != engine->pefuncs->set_nlg_result_cb(__nlg_result_cb, NULL)) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set nlg result callback of vc-engine"); - return VCD_ERROR_OPERATION_FAILED; - } + /* set the supported language */ + if (true == g_dynamic_engine.callbacks->is_lang_supported(g_default_lang)) { + ret = g_dynamic_engine.callbacks->set_language(g_default_lang); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set the supported language"); + return ret; + } - if (0 != engine->pefuncs->set_error_cb(__error_cb, NULL)) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set error callback of vc-engine"); + SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] The %s has been loaded!!!", g_dynamic_engine.engine_name); + g_dynamic_engine.is_loaded = true; + } else { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent WARNING] This engine do not support default language : lang(%s)", g_default_lang); + g_dynamic_engine.is_loaded = false; return VCD_ERROR_OPERATION_FAILED; } - /* load engine */ - if (true == engine->pefuncs->is_lang_supported(g_default_lang)) { - if (0 != engine->pefuncs->set_language(g_default_lang)) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to load current engine"); - return VCD_ERROR_OPERATION_FAILED; - } - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] The %s has been loaded !!!", engine->engine_name); - engine->is_loaded = true; - } else { - SLOG(LOG_WARN, TAG_VCD, "[Engine Agent WARNING] This engine do not support default language : lang(%s)", g_default_lang); - engine->is_loaded = false; - } + SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] load current engine FINISH"); return 0; } -int vcd_engine_agent_load_current_engine() +int vcd_engine_agent_unload_current_engine() { if (false == g_agent_init) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized"); return VCD_ERROR_OPERATION_FAILED; } - if (true == g_dynamic_engine.is_set) { - if (0 != __load_engine(&g_dynamic_engine)) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to load dynamic engine"); - - /* need to initialize dynamic engine data */ - g_dynamic_engine.is_loaded = false; - } else { - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Load dynamic engine"); - } + if (false == g_dynamic_engine.is_loaded) { + SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Engine has already been unloaded"); + return VCD_ERROR_NONE; } - return 0; -} - -int vcd_engine_agent_unload_current_engine() -{ - if (false == g_agent_init) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized "); - return VCD_ERROR_OPERATION_FAILED; + /* shut down engine */ + int ret = 0; + ret = g_dynamic_engine.callbacks->deinitialize(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to deinitialize"); } - if (true == g_dynamic_engine.is_set) { - /* unload dynamic engine */ - if (true == g_dynamic_engine.is_loaded) { - /* shutdown engine */ - g_dynamic_engine.pefuncs->deinitialize(); - g_dynamic_engine.vcp_unload_engine(); - dlclose(g_dynamic_engine.handle); - g_dynamic_engine.handle = NULL; - g_dynamic_engine.is_loaded = false; - } - } + /* reset current engine data */ + g_dynamic_engine.is_loaded = false; + return 0; } /* -* VCS Engine Interfaces for client -*/ + * VCS Engine Interfaces for client + */ int vcd_engine_set_commands() { @@ -796,7 +320,7 @@ int vcd_engine_set_commands() if (true == g_dynamic_engine.is_loaded) { /* Set dynamic command */ - ret = g_dynamic_engine.pefuncs->set_commands((vcp_cmd_h)0); + ret = g_dynamic_engine.callbacks->set_commands((vce_cmd_h)0); if (0 != ret) { SLOG(LOG_WARN, TAG_VCD, "[Engine Agent ERROR] Fail to set command of dynamic engine : error(%d)", ret); g_dynamic_engine.is_command_ready = false; @@ -823,7 +347,7 @@ int vcd_engine_recognize_start(bool silence) SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] silence is %s", silence ? "true" : "false"); if (true == g_dynamic_engine.is_loaded && true == g_dynamic_engine.is_command_ready) { - ret = g_dynamic_engine.pefuncs->start(silence); + ret = g_dynamic_engine.callbacks->start(silence); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] Fail to start engine error(%d)", ret); return VCD_ERROR_OPERATION_FAILED; @@ -837,7 +361,7 @@ int vcd_engine_recognize_start(bool silence) return 0; } -int vcd_engine_recognize_audio(const void* data, unsigned int length, vcp_speech_detect_e* speech_detected) +int vcd_engine_recognize_audio(const void* data, unsigned int length, vce_speech_detect_e* speech_detected) { if (false == g_agent_init) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized"); @@ -852,10 +376,10 @@ int vcd_engine_recognize_audio(const void* data, unsigned int length, vcp_speech int ret = -1; if (true == g_dynamic_engine.is_loaded) { - ret = g_dynamic_engine.pefuncs->set_recording(data, length, speech_detected); + ret = g_dynamic_engine.callbacks->set_recording(data, length, speech_detected); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set recording dynamic engine error(%d)", ret); - if (VCP_ERROR_OUT_OF_NETWORK == ret) { + if (VCE_ERROR_OUT_OF_NETWORK == ret) { return VCD_ERROR_TIMED_OUT; } return VCD_ERROR_OPERATION_FAILED; @@ -874,7 +398,7 @@ int vcd_engine_recognize_stop() if (true == g_dynamic_engine.is_loaded) { int ret = -1; - ret = g_dynamic_engine.pefuncs->stop(); + ret = g_dynamic_engine.callbacks->stop(); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to stop dynamic engine error(%d)", ret); return VCD_ERROR_OPERATION_FAILED; @@ -896,7 +420,7 @@ int vcd_engine_recognize_cancel() int ret = -1; if (true == g_dynamic_engine.is_loaded) { - ret = g_dynamic_engine.pefuncs->cancel(); + ret = g_dynamic_engine.callbacks->cancel(); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to cancel dynamic engine error(%d)", ret); return VCD_ERROR_OPERATION_FAILED; @@ -915,7 +439,7 @@ int vcd_engine_set_audio_type(const char* audio) int ret = -1; if (true == g_dynamic_engine.is_loaded) { - ret = g_dynamic_engine.pefuncs->set_audio_type(audio); + ret = g_dynamic_engine.callbacks->set_audio_type(audio); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set audio type(%d)", ret); return VCD_ERROR_OPERATION_FAILED; @@ -934,7 +458,7 @@ int vcd_engine_set_domain(int pid, const char* domain) int ret = -1; if (true == g_dynamic_engine.is_loaded) { - ret = g_dynamic_engine.pefuncs->set_domain(domain); + ret = g_dynamic_engine.callbacks->set_domain(domain); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set domain (%d)", ret); return VCD_ERROR_OPERATION_FAILED; @@ -957,12 +481,15 @@ int vcd_engine_get_nlu_base_info(int pid, const char* key, char** value) } int ret = -1; - if (true == g_dynamic_engine.is_loaded) { - ret = g_dynamic_engine.pefuncs->get_nlu_base_info(key, value); + if (true == g_dynamic_engine.is_loaded && NULL != g_dynamic_engine.callbacks->nlu_base_info_request) { + ret = g_dynamic_engine.callbacks->nlu_base_info_request(key, value); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get nlu base info (%d)", ret); return VCD_ERROR_OPERATION_FAILED; } + } else { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded or There is no nlu_base_info_request callback"); + return VCD_ERROR_OPERATION_FAILED; } return 0; @@ -976,12 +503,15 @@ int vcd_engine_set_private_data(int pid, const char* key, const char* data) } int ret = -1; - if (true == g_dynamic_engine.is_loaded) { - ret = g_dynamic_engine.pefuncs->set_private_data(key, data); + if (true == g_dynamic_engine.is_loaded && NULL != g_dynamic_engine.callbacks->private_data_set) { + ret = g_dynamic_engine.callbacks->private_data_set(key, data); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set private data (%d)", ret); return VCD_ERROR_OPERATION_FAILED; } + } else { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded or There is no private_data_set callback"); + return VCD_ERROR_OPERATION_FAILED; } return 0; @@ -1000,12 +530,15 @@ int vcd_engine_get_private_data(int pid, const char* key, char** data) } int ret = -1; - if (true == g_dynamic_engine.is_loaded) { - ret = g_dynamic_engine.pefuncs->get_private_data(key, data); + if (true == g_dynamic_engine.is_loaded && NULL != g_dynamic_engine.callbacks->private_data_request) { + ret = g_dynamic_engine.callbacks->private_data_request(key, data); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get private data (%d)", ret); return VCD_ERROR_OPERATION_FAILED; } + } else { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded or There is no private_data_request callback"); + return VCD_ERROR_OPERATION_FAILED; } return 0; @@ -1020,7 +553,7 @@ int vcd_engine_process_text(int pid, const char* text) int ret = -1; if (true == g_dynamic_engine.is_loaded) { - ret = g_dynamic_engine.pefuncs->process_text(text); + ret = g_dynamic_engine.callbacks->process_text(text); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to process text (%d)", ret); return VCD_ERROR_OPERATION_FAILED; @@ -1039,7 +572,7 @@ int vcd_engine_process_list_event(int pid, const char* event) int ret = -1; if (true == g_dynamic_engine.is_loaded) { - ret = g_dynamic_engine.pefuncs->process_list_event(event); + ret = g_dynamic_engine.callbacks->process_list_event(event); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to process list event (%d)", ret); return VCD_ERROR_OPERATION_FAILED; @@ -1058,7 +591,7 @@ int vcd_engine_process_haptic_event(int pid, const char* event) int ret = -1; if (true == g_dynamic_engine.is_loaded) { - ret = g_dynamic_engine.pefuncs->process_haptic_event(event); + ret = g_dynamic_engine.callbacks->process_haptic_event(event); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to process haptic event (%d)", ret); return VCD_ERROR_OPERATION_FAILED; @@ -1069,10 +602,10 @@ int vcd_engine_process_haptic_event(int pid, const char* event) } /* -* VCS Engine Interfaces for client and setting -*/ + * VCS Engine Interfaces for client and setting + */ -int vcd_engine_get_audio_format(const char* audio_id, vcp_audio_type_e* types, int* rate, int* channels) +int vcd_engine_get_audio_format(const char* audio_id, vce_audio_type_e* types, int* rate, int* channels) { if (false == g_agent_init) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized"); @@ -1083,12 +616,7 @@ int vcd_engine_get_audio_format(const char* audio_id, vcp_audio_type_e* types, i SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded"); } - if (NULL == g_dynamic_engine.pefuncs->get_recording_format) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] The function of engine is NULL!!"); - return VCD_ERROR_OPERATION_FAILED; - } - - int ret = g_dynamic_engine.pefuncs->get_recording_format(audio_id, types, rate, channels); + int ret = g_dynamic_engine.callbacks->get_recording_format(audio_id, types, rate, channels); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] get recording format(%d)", ret); return VCD_ERROR_OPERATION_FAILED; @@ -1126,12 +654,7 @@ int vcd_engine_supported_langs(GList** lang_list) SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded"); } - if (NULL == g_dynamic_engine.pefuncs->foreach_langs) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] The function of engine is NULL!!"); - return VCD_ERROR_OPERATION_FAILED; - } - - int ret = g_dynamic_engine.pefuncs->foreach_langs(__supported_language_cb, (void*)lang_list); + int ret = g_dynamic_engine.callbacks->foreach_langs(__supported_language_cb, (void*)lang_list); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] get language list error(%d)", ret); return VCD_ERROR_OPERATION_FAILED; @@ -1176,7 +699,7 @@ int vcd_engine_set_current_language(const char* language) if (true == g_dynamic_engine.is_loaded) { g_dynamic_engine.is_command_ready = false; - ret = g_dynamic_engine.pefuncs->set_language(language); + ret = g_dynamic_engine.callbacks->set_language(language); if (0 != ret) { SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Fail to set language of dynamic engine error(%d, %s)", ret, language); } @@ -1187,59 +710,113 @@ int vcd_engine_set_current_language(const char* language) return 0; } -void __free_language_list(GList* lang_list) +int vcd_engine_agent_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void* user_data) +{ + SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request foreach command from engine"); + return vcd_client_foreach_command((client_foreach_command_cb)callback, user_data); +} + +int vcd_engine_agent_get_command_count(vce_cmd_h vce_command) +{ + SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request command length from engine"); + + return vcd_client_get_length(); +} + +int vcd_engine_agent_get_audio_type(char** audio_type) { - GList *iter = NULL; - char* data = NULL; + SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request audio type"); - /* if list have item */ - if (g_list_length(lang_list) > 0) { - /* Get a first item */ - iter = g_list_first(lang_list); + return vcd_recorder_get(audio_type); +} - while (NULL != iter) { - data = iter->data; +int vcd_engine_agent_set_private_data(const char* key, const char* data) +{ + SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request set private data"); + vcdc_send_request_set_private_data(vcd_client_manager_get_pid(), key, data); - if (NULL != data) - free(data); + return VCD_ERROR_NONE; +} - lang_list = g_list_remove_link(lang_list, iter); +int vcd_engine_agent_get_private_data(const char* key, char** data) +{ + SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request get private data"); + vcdc_send_request_get_private_data(vcd_client_manager_get_pid(), key, data); - iter = g_list_first(lang_list); - } + return VCD_ERROR_NONE; +} + +int vcd_engine_agent_start_recording() +{ + SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request start recording"); + + int ret = vcd_recorder_start(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recorder : result(%d)", ret); + vcd_engine_recognize_cancel(); + /* Send error cb to manager */ + vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_engine.error.proc_fail"); + return ret; } + + return VCD_ERROR_NONE; } -int __log_enginelist() +int vcd_engine_agent_stop_recording() { - GList *iter = NULL; - vcengine_info_s *data = NULL; + SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request stop recording"); - if (0 < g_list_length(g_engine_list)) { + return vcd_recorder_stop(); +} - /* Get a first item */ - iter = g_list_first(g_engine_list); +int vcd_engine_agent_set_private_data_set_cb(vce_private_data_set_cb callback_func) +{ + if (false == g_agent_init) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized"); + return VCD_ERROR_OPERATION_FAILED; + } + + if (false == g_dynamic_engine.is_loaded) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not loaded engine"); + return VCD_ERROR_OPERATION_FAILED; + } - SLOG(LOG_DEBUG, TAG_VCD, "@ engine list @"); + g_dynamic_engine.callbacks->private_data_set = callback_func; - int i = 1; - while (NULL != iter) { - /* Get handle data from list */ - data = iter->data; + return VCD_ERROR_NONE; +} - SLOG(LOG_DEBUG, TAG_VCD, "[%dth]", i); - SLOG(LOG_DEBUG, TAG_VCD, " engine uuid : %s", data->engine_uuid); - SLOG(LOG_DEBUG, TAG_VCD, " engine name : %s", data->engine_name); - SLOG(LOG_DEBUG, TAG_VCD, " engine path : %s", data->engine_path); - iter = g_list_next(iter); - i++; - } - SLOG(LOG_DEBUG, TAG_VCD, "@@@@"); - } else { - SLOG(LOG_DEBUG, TAG_VCD, "@ engine list @"); - SLOG(LOG_DEBUG, TAG_VCD, " No Engine in engine directory"); - SLOG(LOG_DEBUG, TAG_VCD, "@@@@"); +int vcd_engine_agent_set_private_data_requested_cb(vce_private_data_requested_cb callback_func) +{ + if (false == g_agent_init) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized"); + return VCD_ERROR_OPERATION_FAILED; } - return 0; + if (false == g_dynamic_engine.is_loaded) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not loaded engine"); + return VCD_ERROR_OPERATION_FAILED; + } + + g_dynamic_engine.callbacks->private_data_request = callback_func; + + return VCD_ERROR_NONE; } + +int vcd_engine_agent_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_func) +{ + if (false == g_agent_init) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized"); + return VCD_ERROR_OPERATION_FAILED; + } + + if (false == g_dynamic_engine.is_loaded) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not loaded engine"); + return VCD_ERROR_OPERATION_FAILED; + } + + g_dynamic_engine.callbacks->nlu_base_info_request = callback_func; + + return VCD_ERROR_NONE; +} + diff --git a/server/vcd_engine_agent.h b/server/vcd_engine_agent.h index 7166cc8..4fa59d8 100644 --- a/server/vcd_engine_agent.h +++ b/server/vcd_engine_agent.h @@ -19,7 +19,6 @@ #define __VCD_ENGINE_AGENT_H_ #include "vcd_main.h" -#include "voice_control_plugin_engine.h" #ifdef __cplusplus extern "C" { @@ -31,48 +30,22 @@ extern "C" { #define ENGINE_PATH_SIZE 256 -typedef void (*result_callback)(vcp_result_event_e event, int* result_id, int count, const char* all_result, - const char* non_fixed_result, const char* nlu_result, const char* msg, void *user_data); - -typedef void (*asr_result_callback)(vcp_asr_result_event_e event, const char* asr_result, void *user_data); - -typedef void (*nlg_result_callback)(const char* nlg_result, void *user_data); - -#if 0 -typedef void (*pre_result_callback)(vcp_pre_result_event_e event, const char* pre_result, void *user_data); - -typedef void (*nlu_result_callback)(vcp_result_event_e event, const char* nlu_result, void *user_data); -#endif - -typedef void (*error_callback)(vcp_error_e error, const char* msg, void *user_data); - -typedef void (*silence_dectection_callback)(void *user_data); - - - /** Init engine agent */ -//int vcd_engine_agent_init(pre_result_callback pre_result_cb, result_callback result_cb, nlu_result_callback nlu_result_cb, error_callback error_cb); -int vcd_engine_agent_init(asr_result_callback asr_result_cb, result_callback result_cb, nlg_result_callback nlg_result_cb, error_callback error_cb); +int vcd_engine_agent_init(); /** Release engine agent */ int vcd_engine_agent_release(); bool vcd_engine_is_available_engine(); -/** Set current engine */ -int vcd_engine_agent_initialize_current_engine(); - /** load current engine */ -int vcd_engine_agent_load_current_engine(); +int vcd_engine_agent_load_current_engine(vce_request_callback_s* callback); /** Unload current engine */ int vcd_engine_agent_unload_current_engine(); -/** test for language list */ -int vcd_print_enginelist(); - -int vcd_engine_get_audio_format(const char* audio_id, vcp_audio_type_e* types, int* rate, int* channels); +int vcd_engine_get_audio_format(const char* audio_id, vce_audio_type_e* types, int* rate, int* channels); int vcd_engine_supported_langs(GList** lang_list); @@ -85,7 +58,7 @@ int vcd_engine_set_commands(); /* normal recognition */ int vcd_engine_recognize_start(bool silence); -int vcd_engine_recognize_audio(const void* data, unsigned int length, vcp_speech_detect_e* speech_detected); +int vcd_engine_recognize_audio(const void* data, unsigned int length, vce_speech_detect_e* speech_detected); int vcd_engine_recognize_stop(); @@ -97,10 +70,8 @@ int vcd_engine_set_domain(int pid, const char* domain); int vcd_engine_get_nlu_base_info(int pid, const char* key, char** value); -// int vcd_engine_set_private_data(const char* data); int vcd_engine_set_private_data(int pid, const char* key, const char* data); -// int vcd_engine_get_private_data(char** data); int vcd_engine_get_private_data(int pid, const char* key, char** data); int vcd_engine_process_text(int pid, const char* text); @@ -109,6 +80,27 @@ int vcd_engine_process_list_event(int pid, const char* event); int vcd_engine_process_haptic_event(int pid, const char* event); +/* for engine service */ +int vcd_engine_agent_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void* user_data); + +int vcd_engine_agent_get_command_count(vce_cmd_h vce_command); + +int vcd_engine_agent_get_audio_type(char** audio_type); + +int vcd_engine_agent_set_private_data(const char* key, const char* data); + +int vcd_engine_agent_get_private_data(const char* key, char** data); + +int vcd_engine_agent_start_recording(); + +int vcd_engine_agent_stop_recording(); + +int vcd_engine_agent_set_private_data_set_cb(vce_private_data_set_cb callback_func); + +int vcd_engine_agent_set_private_data_requested_cb(vce_private_data_requested_cb callback_func); + +int vcd_engine_agent_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_func); + #ifdef __cplusplus } diff --git a/server/vcd_main.c b/server/vcd_main.c deleted file mode 100644 index f91fbd1..0000000 --- a/server/vcd_main.c +++ /dev/null @@ -1,75 +0,0 @@ -/* -* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved -* -* Licensed under the Apache License, Version 2.0 (the License); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an AS IS BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#include "vcd_dbus.h" -#include "vcd_main.h" -#include "vcd_server.h" - -#define CLIENT_CLEAN_UP_TIME 500 - -static Ecore_Timer* g_check_client_timer = NULL; - -int main(int argc, char** argv) -{ - SLOG(LOG_DEBUG, TAG_VCD, "@@@ VC Daemon Initialize"); - - if (!ecore_init()) { - SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail ecore_init()"); - return -1; - } - - if (0 != vcd_dbus_open_connection()) { - SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to open connection"); - ecore_shutdown(); - return EXIT_FAILURE; - } - - if (0 != vcd_initialize()) { - SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to initialize vc-daemon"); - ecore_shutdown(); - return EXIT_FAILURE; - } - - g_check_client_timer = ecore_timer_add(CLIENT_CLEAN_UP_TIME, vcd_cleanup_client_all, NULL); - if (NULL == g_check_client_timer) { - SLOG(LOG_WARN, TAG_VCD, "[Main Warning] Fail to create timer of client check"); - } - - SLOG(LOG_DEBUG, TAG_VCD, "[Main] vc-daemon start"); - - SLOG(LOG_DEBUG, TAG_VCD, "@@@"); - - ecore_main_loop_begin(); - - SLOG(LOG_DEBUG, TAG_VCD, "@@@ VC Daemon Finalize"); - - if (NULL != g_check_client_timer) { - ecore_timer_del(g_check_client_timer); - } - - vcd_finalize(); - - vcd_dbus_close_connection(); - - ecore_shutdown(); - - SLOG(LOG_DEBUG, TAG_VCD, "@@@"); - - return 0; -} - - diff --git a/server/vcd_main.h b/server/vcd_main.h index 1f83fb9..a4e5705 100644 --- a/server/vcd_main.h +++ b/server/vcd_main.h @@ -31,6 +31,8 @@ #include "vc_defs.h" +#include "vce.h" + #ifdef __cplusplus extern "C" { #endif @@ -70,6 +72,43 @@ typedef enum { VCD_STATE_PROCESSING = 3 } vcd_state_e; +typedef struct { + int version; /**< Version */ + + /* Mandatory callbacks */ + /* Get engine information */ + vce_get_info_cb get_info; /**< Called when the engine service user requests the basic information of VC engine */ + vce_get_recording_format_cb get_recording_format; /**< Get recording format */ + vce_foreach_supported_languages_cb foreach_langs; /**< Foreach language list */ + vce_is_language_supported_cb is_lang_supported; /**< Check language */ + + vce_initialize_cb initialize; /**< Initialize engine */ + vce_deinitialize_cb deinitialize; /**< Shutdown engine */ + + /* Set info */ + vce_set_language_cb set_language; /**< Set language */ + vce_set_commands_cb set_commands; /**< Request to set current commands */ + vce_unset_commands_cb unset_commands; /**< Request to unset current commands */ + + /* Control recognition */ + vce_start_cb start; /**< Start recognition */ + vce_set_recording_data_cb set_recording; /**< Set recording data */ + vce_stop_cb stop; /**< Stop recording for getting result */ + vce_cancel_cb cancel; /**< Cancel recording and processing */ + + vce_set_audio_type set_audio_type; /**< Set audio type */ + + vce_set_domain_cb set_domain; /**< Set domain */ + vce_process_text_cb process_text; /**< Request to process text */ + vce_process_list_event_cb process_list_event; /**< Request to process list event */ + vce_process_haptic_event_cb process_haptic_event; /**< Request to process haptic event */ + + /* Optional callbacks */ + vce_private_data_set_cb private_data_set; + vce_private_data_requested_cb private_data_request; + vce_nlu_base_info_requested_cb nlu_base_info_request; +} vc_engine_callback_s; + #ifdef __cplusplus } diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index 1d69fff..aab017a 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -1,18 +1,18 @@ /* -* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved -* -* Licensed under the Apache License, Version 2.0 (the License); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an AS IS BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2011-2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #ifdef TV_PRODUCT #define TV_BT_MODE @@ -38,14 +38,13 @@ #include "vcd_engine_agent.h" #include "vcd_recorder.h" #include "vcd_main.h" -#include "voice_control_plugin_engine.h" #define FRAME_LENGTH 160 #define BUFFER_LENGTH FRAME_LENGTH * 2 #define FOCUS_SERVER_READY "/tmp/.focus_server_ready" -#define VCP_AUDIO_ID_NONE "VC_AUDIO_ID_NONE" /**< None audio id */ +#define VCE_AUDIO_ID_NONE "VC_AUDIO_ID_NONE" /**< None audio id */ static vcd_recorder_state_e g_recorder_state = VCD_RECORDER_STATE_READY; @@ -57,7 +56,7 @@ static audio_in_h g_audio_h; static sound_stream_info_h g_stream_info_h; -static vcp_audio_type_e g_audio_type; +static vce_audio_type_e g_audio_type; static int g_audio_rate; @@ -78,7 +77,7 @@ static int g_device_id = -1; /* Sound buf save */ /* #define BUF_SAVE_MODE -*/ + */ #ifdef BUF_SAVE_MODE static FILE* g_normal_file; @@ -91,10 +90,10 @@ static float get_volume_decibel(char* data, int size); #ifdef TV_MSF_WIFI_MODE static void __msf_wifi_audio_data_receive_cb(msf_wifi_voice_data_s *voice_data, void* user_data) { - if (0 != strncmp(g_current_audio_type, VCP_AUDIO_ID_MSF, sizeof(VCP_AUDIO_ID_MSF))) { + if (0 != strncmp(g_current_audio_type, VCE_AUDIO_ID_WIFI, sizeof(VCE_AUDIO_ID_WIFI))) { vcd_state_e state = vcd_config_get_service_state(); if (VCD_STATE_READY == state) { - vcd_recorder_set(VCP_AUDIO_ID_MSF, VCP_AUDIO_TYPE_PCM_S16_LE, 16000, 1); + vcd_recorder_set(VCE_AUDIO_ID_WIFI, VCE_AUDIO_TYPE_PCM_S16_LE, 16000, 1); } else { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] current audio type is (%s)", g_current_audio_type); return; @@ -102,7 +101,7 @@ static void __msf_wifi_audio_data_receive_cb(msf_wifi_voice_data_s *voice_data, } if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) { - SLOG(LOG_WARN, TAG_VCD, "[Recorder] Not start yet, but send audio data vi MSF"); + SLOG(LOG_WARN, TAG_VCD, "[Recorder] Not start yet, but send audio data vi Wi-Fi"); vcd_recorder_start(); } @@ -154,10 +153,10 @@ static void _bt_cb_hid_state_changed(int result, bool connected, const char *rem static void _bt_hid_audio_data_receive_cb(bt_hid_voice_data_s *voice_data, void *user_data) { - if (0 != strncmp(g_current_audio_type, VCP_AUDIO_ID_BLUETOOTH, sizeof(VCP_AUDIO_ID_BLUETOOTH))) { + if (0 != strncmp(g_current_audio_type, VCE_AUDIO_ID_BLUETOOTH, sizeof(VCE_AUDIO_ID_BLUETOOTH))) { vcd_state_e state = vcd_config_get_service_state(); if (VCD_STATE_READY == state) { - vcd_recorder_set(VCP_AUDIO_ID_BLUETOOTH, VCP_AUDIO_TYPE_PCM_S16_LE, 16000, 1); + vcd_recorder_set(VCE_AUDIO_ID_BLUETOOTH, VCE_AUDIO_TYPE_PCM_S16_LE, 16000, 1); } else { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] current audio type is (%s)", g_current_audio_type); return; @@ -166,7 +165,7 @@ static void _bt_hid_audio_data_receive_cb(bt_hid_voice_data_s *voice_data, void if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) { SLOG(LOG_WARN, TAG_VCD, "[Recorder] Not start yet, but send audio data vi Bluetooth"); -// vcd_recorder_start(); + // vcd_recorder_start(); } if (NULL != g_audio_cb) { @@ -233,7 +232,7 @@ static const char* __get_focus_changed_reason_code(sound_stream_focus_change_rea } static void __recorder_focus_state_cb(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_e focus_state, - sound_stream_focus_change_reason_e reason, int sound_behavior, const char *extra_info, void *user_data) + sound_stream_focus_change_reason_e reason, int sound_behavior, const char *extra_info, void *user_data) { SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Focus state changed cb"); @@ -356,7 +355,7 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb g_is_valid_bt_in = false; g_current_audio_type = NULL; - g_audio_type = VCP_AUDIO_TYPE_PCM_S16_LE; + g_audio_type = VCE_AUDIO_TYPE_PCM_S16_LE; g_audio_rate = 16000; g_audio_channel = 1; @@ -375,8 +374,8 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb } switch (g_audio_type) { - case VCP_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE; break; - case VCP_AUDIO_TYPE_PCM_U8: audio_type = AUDIO_SAMPLE_TYPE_U8; break; + case VCE_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE; break; + case VCE_AUDIO_TYPE_PCM_U8: audio_type = AUDIO_SAMPLE_TYPE_U8; break; default: SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type"); return VCD_ERROR_OPERATION_FAILED; @@ -437,10 +436,10 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb #endif /* Select default audio type */ if (true == g_is_valid_audio_in) { - g_current_audio_type = strdup(VCP_AUDIO_ID_NONE); + g_current_audio_type = strdup(VCE_AUDIO_ID_NONE); } else { if (true == g_is_valid_bt_in) { - g_current_audio_type = strdup(VCP_AUDIO_ID_BLUETOOTH); + g_current_audio_type = strdup(VCE_AUDIO_ID_BLUETOOTH); } else { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] No valid audio"); return -1; @@ -455,11 +454,11 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb int vcd_recorder_destroy() { if (VCD_RECORDER_STATE_RECORDING == g_recorder_state) { - if (0 == strncmp(VCP_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCP_AUDIO_ID_BLUETOOTH))) { + if (0 == strncmp(VCE_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCE_AUDIO_ID_BLUETOOTH))) { #ifdef TV_BT_MODE bt_hid_unset_audio_data_receive_cb(); #endif - } else if (0 == strncmp(VCP_AUDIO_ID_MSF, g_current_audio_type, strlen(VCP_AUDIO_ID_MSF))) { + } else if (0 == strncmp(VCE_AUDIO_ID_WIFI, g_current_audio_type, strlen(VCE_AUDIO_ID_WIFI))) { #ifdef TV_MSF_WIFI_MODE UnRegisterMSFAudioCallback(); #endif @@ -497,7 +496,7 @@ int vcd_recorder_destroy() return 0; } -int vcd_recorder_set(const char* audio_type, vcp_audio_type_e type, int rate, int channel) +int vcd_recorder_set(const char* audio_type, vce_audio_type_e type, int rate, int channel) { if (NULL == audio_type) { return VCD_ERROR_INVALID_PARAMETER; @@ -517,24 +516,26 @@ int vcd_recorder_set(const char* audio_type, vcp_audio_type_e type, int rate, in vcd_engine_set_audio_type(audio_type); if (VCD_RECORDER_STATE_READY != g_recorder_state) { - if ((!strncmp(g_current_audio_type, VCP_AUDIO_ID_NONE, strlen(g_current_audio_type)) && - strncmp(audio_type, VCP_AUDIO_ID_BLUETOOTH, strlen(audio_type)) && - strncmp(audio_type, VCP_AUDIO_ID_MSF, strlen(audio_type))) || - (strncmp(g_current_audio_type, VCP_AUDIO_ID_BLUETOOTH, strlen(g_current_audio_type)) && - strncmp(g_current_audio_type, VCP_AUDIO_ID_MSF, strlen(g_current_audio_type)) && - strncmp(g_current_audio_type, VCP_AUDIO_ID_NONE, strlen(g_current_audio_type)) && - !strncmp(audio_type, VCP_AUDIO_ID_NONE, strlen(audio_type)))) { + if (NULL != g_current_audio_type) { + if ((!strncmp(g_current_audio_type, VCE_AUDIO_ID_NONE, strlen(g_current_audio_type)) && + strncmp(audio_type, VCE_AUDIO_ID_BLUETOOTH, strlen(audio_type)) && + strncmp(audio_type, VCE_AUDIO_ID_WIFI, strlen(audio_type))) || + (strncmp(g_current_audio_type, VCE_AUDIO_ID_BLUETOOTH, strlen(g_current_audio_type)) && + strncmp(g_current_audio_type, VCE_AUDIO_ID_WIFI, strlen(g_current_audio_type)) && + strncmp(g_current_audio_type, VCE_AUDIO_ID_NONE, strlen(g_current_audio_type)) && + !strncmp(audio_type, VCE_AUDIO_ID_NONE, strlen(audio_type)))) { SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Skip stop recording while Recorder is NOT ready"); - } else { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Recorder is NOT ready"); - vcd_recorder_stop(); - //return VCD_ERROR_INVALID_STATE; + } else { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Recorder is NOT ready"); + vcd_recorder_stop(); + //return VCD_ERROR_INVALID_STATE; + } } } int ret = -1; /* Check BT audio */ - if (0 == strncmp(VCP_AUDIO_ID_BLUETOOTH, audio_type, strlen(VCP_AUDIO_ID_BLUETOOTH))) { + if (0 == strncmp(VCE_AUDIO_ID_BLUETOOTH, audio_type, strlen(VCE_AUDIO_ID_BLUETOOTH))) { if (false == g_is_valid_bt_in) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder] BT audio is NOT valid"); return VCD_ERROR_OPERATION_REJECTED; @@ -546,7 +547,7 @@ int vcd_recorder_set(const char* audio_type, vcp_audio_type_e type, int rate, in } g_current_audio_type = strdup(audio_type); - } else if (0 == strncmp(VCP_AUDIO_ID_MSF, audio_type, strlen(VCP_AUDIO_ID_MSF))) { + } else if (0 == strncmp(VCE_AUDIO_ID_WIFI, audio_type, strlen(VCE_AUDIO_ID_WIFI))) { if (NULL != g_current_audio_type) { free(g_current_audio_type); g_current_audio_type = NULL; @@ -576,8 +577,8 @@ int vcd_recorder_set(const char* audio_type, vcp_audio_type_e type, int rate, in } switch (type) { - case VCP_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE; break; - case VCP_AUDIO_TYPE_PCM_U8: audio_type = AUDIO_SAMPLE_TYPE_U8; break; + case VCE_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE; break; + case VCE_AUDIO_TYPE_PCM_U8: audio_type = AUDIO_SAMPLE_TYPE_U8; break; default: SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type"); return VCD_ERROR_OPERATION_FAILED; @@ -724,11 +725,11 @@ static void __timer_read_normal_func(void *data) static void __check_audio_format() { - vcp_audio_type_e type; + vce_audio_type_e type; int rate; int channel; - int ret = vcd_engine_get_audio_format(VCP_AUDIO_ID_NONE, &type, &rate, &channel); + int ret = vcd_engine_get_audio_format(VCE_AUDIO_ID_NONE, &type, &rate, &channel); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio format : %d", ret); return; @@ -756,8 +757,8 @@ static void __check_audio_format() } switch (type) { - case VCP_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE; break; - case VCP_AUDIO_TYPE_PCM_U8: audio_type = AUDIO_SAMPLE_TYPE_U8; break; + case VCE_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE; break; + case VCE_AUDIO_TYPE_PCM_U8: audio_type = AUDIO_SAMPLE_TYPE_U8; break; default: SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type"); return; @@ -798,7 +799,7 @@ int vcd_recorder_start() SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] audio type : %s", g_current_audio_type); if (NULL != g_current_audio_type) { - if (0 == strncmp(VCP_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCP_AUDIO_ID_BLUETOOTH))) { + if (0 == strncmp(VCE_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCE_AUDIO_ID_BLUETOOTH))) { #ifdef TV_BT_MODE const unsigned char input_data[2] = {SMART_CONTROL_START_CMD, 0x00}; int bt_retry = 0; @@ -823,7 +824,7 @@ int vcd_recorder_start() g_bt_extend_count = 0; #endif - } else if (0 == strncmp(VCP_AUDIO_ID_MSF, g_current_audio_type, strlen(VCP_AUDIO_ID_MSF))) { + } else if (0 == strncmp(VCE_AUDIO_ID_WIFI, g_current_audio_type, strlen(VCE_AUDIO_ID_WIFI))) { SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] call RegisterMSFAudioCallback() function"); #ifdef TV_MSF_WIFI_MODE @@ -832,7 +833,7 @@ int vcd_recorder_start() if (MSFResult_OK == ret) { started = true; } else { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start MSF(wifi) audio"); + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start Wi-Fi audio"); return VCD_ERROR_OPERATION_FAILED; } #endif @@ -921,7 +922,7 @@ int vcd_recorder_stop() bool stoped = false; if (NULL != g_current_audio_type) { - if (0 == strncmp(VCP_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCP_AUDIO_ID_BLUETOOTH))) { + if (0 == strncmp(VCE_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCE_AUDIO_ID_BLUETOOTH))) { #ifdef TV_BT_MODE int bt_retry = 0; while (5 > bt_retry) { @@ -939,10 +940,10 @@ int vcd_recorder_stop() } } if (NULL != g_current_audio_type && - (!strncmp(g_current_audio_type, VCP_AUDIO_ID_BLUETOOTH, sizeof(VCP_AUDIO_ID_BLUETOOTH)) || - !strncmp(g_current_audio_type, VCP_AUDIO_ID_MSF, sizeof(VCP_AUDIO_ID_MSF)))) { + (!strncmp(g_current_audio_type, VCE_AUDIO_ID_BLUETOOTH, sizeof(VCE_AUDIO_ID_BLUETOOTH)) || + !strncmp(g_current_audio_type, VCE_AUDIO_ID_WIFI, sizeof(VCE_AUDIO_ID_WIFI)))) { SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] Recorder reset to NONE"); - vcd_recorder_set(VCP_AUDIO_ID_NONE, g_audio_type, g_audio_rate, g_audio_channel); + vcd_recorder_set(VCE_AUDIO_ID_NONE, g_audio_type, g_audio_rate, g_audio_channel); } if (false == stoped) { @@ -950,14 +951,14 @@ int vcd_recorder_stop() return VCD_ERROR_OPERATION_FAILED; } #endif - } else if (0 == strncmp(VCP_AUDIO_ID_MSF, g_current_audio_type, strlen(VCP_AUDIO_ID_MSF))) { + } else if (0 == strncmp(VCE_AUDIO_ID_WIFI, g_current_audio_type, strlen(VCE_AUDIO_ID_WIFI))) { #ifdef TV_MSF_WIFI_MODE UnRegisterMSFAudioCallback(); if (NULL != g_current_audio_type && - (!strncmp(g_current_audio_type, VCP_AUDIO_ID_BLUETOOTH, sizeof(VCP_AUDIO_ID_BLUETOOTH)) || - !strncmp(g_current_audio_type, VCP_AUDIO_ID_MSF, sizeof(VCP_AUDIO_ID_MSF)))) { + (!strncmp(g_current_audio_type, VCE_AUDIO_ID_BLUETOOTH, sizeof(VCE_AUDIO_ID_BLUETOOTH)) || + !strncmp(g_current_audio_type, VCE_AUDIO_ID_WIFI, sizeof(VCE_AUDIO_ID_WIFI)))) { SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] Recorder reset to NONE"); - vcd_recorder_set(VCP_AUDIO_ID_NONE, g_audio_type, g_audio_rate, g_audio_channel); + vcd_recorder_set(VCE_AUDIO_ID_NONE, g_audio_type, g_audio_rate, g_audio_channel); } stoped = true; #endif diff --git a/server/vcd_recorder.h b/server/vcd_recorder.h index dafef24..a061d2a 100644 --- a/server/vcd_recorder.h +++ b/server/vcd_recorder.h @@ -23,7 +23,6 @@ extern "C" { #endif -#include "voice_control_plugin_engine.h" typedef enum { VCD_RECORDER_STATE_READY, /**< Recorder is ready to start */ @@ -40,7 +39,7 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb int vcd_recorder_destroy(); -int vcd_recorder_set(const char* audio_type, vcp_audio_type_e type, int rate, int channel); +int vcd_recorder_set(const char* audio_type, vce_audio_type_e type, int rate, int channel); int vcd_recorder_get(char** audio_type); diff --git a/server/vcd_server.c b/server/vcd_server.c index ceaf322..10cb388 100755 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -36,8 +36,6 @@ /* * VC Server static variable */ -static bool g_is_engine; - static GList *g_proc_list = NULL; static Ecore_Timer *g_restart_timer = NULL; @@ -121,7 +119,7 @@ static int __server_recorder_callback(const void* data, const unsigned int lengt return 0; } - vcp_speech_detect_e speech_detected = VCP_SPEECH_DETECT_NONE; + vce_speech_detect_e speech_detected = VCE_SPEECH_DETECT_NONE; int ret; ret = vcd_engine_recognize_audio(data, length, &speech_detected); @@ -131,7 +129,7 @@ static int __server_recorder_callback(const void* data, const unsigned int lengt SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set recording data to engine(%d)", ret); ecore_timer_add(0, __cancel_by_interrupt, NULL); /* Send error cb to manager */ - if (VCP_ERROR_OUT_OF_NETWORK == ret) { + if (VCE_ERROR_OUT_OF_NETWORK == ret) { vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_TIMED_OUT, "Engine connection failed"); } else { vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "Engine recognition failed"); @@ -139,14 +137,14 @@ static int __server_recorder_callback(const void* data, const unsigned int lengt return 0; } - if (VCP_SPEECH_DETECT_BEGIN == speech_detected) { + if (VCE_SPEECH_DETECT_BEGIN == speech_detected) { if (-1 != vcd_client_manager_get_pid()) { /* Manager client is available */ if (0 != vcdc_send_speech_detected(vcd_client_manager_get_pid())) { SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send speech detected"); } } - } else if (VCP_SPEECH_DETECT_END == speech_detected) { + } else if (VCE_SPEECH_DETECT_END == speech_detected) { if (VCD_RECOGNITION_MODE_STOP_BY_SILENCE == vcd_client_get_recognition_mode()) { /* silence detected */ ecore_timer_add(0, __stop_by_silence, NULL); @@ -424,29 +422,28 @@ static Eina_Bool __vcd_send_selected_result(void *data) return EINA_FALSE; } -//static void __vcd_server_pre_result_cb(vcp_pre_result_event_e event, const char* pre_result, void *user_data) -static void __vcd_server_asr_result_cb(vcp_asr_result_event_e event, const char* asr_result, void *user_data) +int vcd_send_asr_result(vce_asr_result_event_e event, const char* asr_result, void *user_data) { if (NULL != asr_result) { SLOG(LOG_DEBUG, TAG_VCD, "[Server] ASR result - Event(%d), Text(%s)", event, asr_result); vcdc_send_pre_result_to_manager(vcd_client_manager_get_pid(), event, asr_result); } - return; + return VCD_ERROR_NONE; } -static void __vcd_server_nlg_result_cb(const char* nlg_result, void *user_data) +int vcd_send_nlg_result(const char* nlg_result, void *user_data) { int ret = __vcd_server_launch_manager_app(); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send dialog : mgr_pid(%d), nlg_result(%s)", vcd_client_manager_get_pid(), nlg_result); - return; + return ret; } ret = vcdc_send_dialog(vcd_client_manager_get_pid(), -1, nlg_result, NULL, 0); //0: VC_DIALOG_END if (0 != ret) SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send dialog : mgr_pid(%d), nlg_result(%s)", vcd_client_manager_get_pid(), nlg_result); - return; + return ret; } static void* __recorder_stop(void *data) @@ -455,9 +452,17 @@ static void* __recorder_stop(void *data) return NULL; } -static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int count, const char* all_result, - const char* non_fixed_result, const char* nlu_result, const char* msg, void *user_data) +int vcd_send_result(vce_result_event_e event, int* result_id, int count, const char* all_result, const char* non_fixed_result, const char* nlu_result, const char* msg, void *user_data) { + int ret = 0; + + if (VCD_STATE_PROCESSING != vcd_config_get_service_state()) { + if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY != vcd_client_get_recognition_mode()) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not 'Processing' and mode is not 'Restart continuously'"); + return VCD_ERROR_INVALID_STATE; + } + } + vc_info_parser_unset_result(vcd_client_manager_get_exclusive()); vcd_client_manager_set_result_text(all_result); @@ -465,18 +470,19 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int event, all_result, non_fixed_result, msg, count); if (VCD_RECOGNITION_MODE_RESTART_AFTER_REJECT == vcd_client_get_recognition_mode()) { - if (VCP_RESULT_EVENT_REJECTED == event) { + if (VCE_RESULT_EVENT_REJECTED == event) { SLOG(LOG_DEBUG, TAG_VCD, "[Server] Restart by no or rejected result"); /* If no result and restart option is ON */ /* Send reject message */ bool temp = vcd_client_manager_get_exclusive(); vc_info_parser_set_result(all_result, event, msg, NULL, temp); - if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NOTIFICATION)) { + ret = vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NOTIFICATION); + if (0 != ret) { SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result"); } g_restart_timer = ecore_timer_add(0, __restart_engine, NULL); - return; + return ret; } SLOG(LOG_DEBUG, TAG_VCD, "[Server] Stop recorder due to success"); //vcd_recorder_stop(); @@ -485,13 +491,14 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int SLOG(LOG_DEBUG, TAG_VCD, "[Server] Restart continuously"); /* Restart option is ON */ g_restart_timer = ecore_timer_add(0, __restart_engine, NULL); - if (VCP_RESULT_EVENT_REJECTED == event) { + if (VCE_RESULT_EVENT_REJECTED == event) { bool temp = vcd_client_manager_get_exclusive(); vc_info_parser_set_result(all_result, event, msg, NULL, temp); - if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NOTIFICATION)) { + ret = vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NOTIFICATION); + if (0 != ret) { SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result"); } - return; + return ret; } } #if 1 @@ -524,7 +531,7 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int vcd_config_set_service_state(VCD_STATE_READY); vcdc_send_service_state(VCD_STATE_READY); - return; + return VCD_ERROR_NONE; } } } @@ -535,7 +542,6 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int /* Normal result */ SLOG(LOG_DEBUG, TAG_VCD, "[Server] @ Get engine result @"); - int ret = -1; vc_cmd_s* temp_cmd = NULL; vc_cmd_list_h vc_cmd_list = NULL; @@ -544,7 +550,7 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int vcd_client_manager_set_exclusive(false); vcd_config_set_service_state(VCD_STATE_READY); vcdc_send_service_state(VCD_STATE_READY); - return; + return VCD_ERROR_NONE; } /* priority filter */ @@ -553,7 +559,7 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int int* filtered_id = (int*)calloc(count, sizeof(int)); if (!filtered_id) { SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to allocate memory"); - return; + return VCD_ERROR_OUT_OF_MEMORY; } int filtered_count = 0; int top_priority = VC_COMMAND_PRIORITY_BACKGROUND; @@ -681,7 +687,7 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int vcd_client_manager_set_exclusive(false); - return; + return VCD_ERROR_NONE; } else { if (false == vcd_client_manager_get_exclusive()) { int pid = vcd_client_widget_get_foreground_pid(); @@ -721,7 +727,7 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int vc_cmd_list_destroy(vc_cmd_list, true); - return; + return VCD_ERROR_NONE; #else /* No result */ @@ -872,7 +878,7 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int } #if 0 -static void __vcd_server_nlu_result_cb(vcp_result_event_e event, const char* nlu_result, void *user_data) +static void __vcd_server_nlu_result_cb(vce_result_event_e event, const char* nlu_result, void *user_data) { SLOG(LOG_DEBUG, TAG_VCD, "[Server] NLU result cb - event(%d)", event); SLOG(LOG_DEBUG, TAG_VCD, "[Server] result (%s)", nlu_result); @@ -886,7 +892,7 @@ static void __vcd_server_nlu_result_cb(vcp_result_event_e event, const char* nlu } #endif -static void __vcd_server_error_cb(vcp_error_e error, const char* msg, void *user_data) +int vcd_send_error(vce_error_e error, const char* msg, void *user_data) { SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Engine Error cb - reason(%d), msg(%s)", error, msg); ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL); @@ -905,7 +911,7 @@ static void __vcd_server_error_cb(vcp_error_e error, const char* msg, void *user error_msg = NULL; } - return; + return VCD_ERROR_NONE; } /* @@ -960,7 +966,7 @@ static int __vcd_db_clean_up() return ret; } -int vcd_initialize() +int vcd_initialize(vce_request_callback_s *callback) { int ret = 0; @@ -981,8 +987,7 @@ int vcd_initialize() vcd_config_set_service_state(VCD_STATE_NONE); - //ret = vcd_engine_agent_init(__vcd_server_pre_result_cb, __vcd_server_result_cb, __vcd_server_nlu_result_cb, __vcd_server_error_cb); - ret = vcd_engine_agent_init(__vcd_server_asr_result_cb, __vcd_server_result_cb, __vcd_server_nlg_result_cb, __vcd_server_error_cb); + ret = vcd_engine_agent_init(); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret); return ret; @@ -993,21 +998,8 @@ int vcd_initialize() return VCD_ERROR_OPERATION_FAILED; } - /* Find engine */ - ret = vcd_engine_agent_initialize_current_engine(); - if (0 != ret) { - if (VCD_ERROR_ENGINE_NOT_FOUND == ret) - SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] There is No Voice control engine"); - else - SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to init engine"); - - g_is_engine = false; - } else { - g_is_engine = true; - } - /* Load engine */ - if (0 != vcd_engine_agent_load_current_engine()) { + if (0 != vcd_engine_agent_load_current_engine(callback)) { SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to load current engine"); return VCD_ERROR_OPERATION_FAILED; } @@ -1172,7 +1164,7 @@ static void __vcd_cleanup_client(vcd_client_type_e type) Eina_Bool vcd_cleanup_client_all(void *data) { __read_proc(); - + __vcd_cleanup_client(VCD_CLIENT_TYPE_NORMAL); __vcd_cleanup_client(VCD_CLIENT_TYPE_WIDGET); __vcd_cleanup_client(VCD_CLIENT_TYPE_MANAGER); @@ -1303,16 +1295,6 @@ int vcd_server_get_foreground() */ int vcd_server_mgr_initialize(int pid) { - if (false == g_is_engine) { - if (0 != vcd_engine_agent_initialize_current_engine()) { - SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine"); - g_is_engine = false; - return VCD_ERROR_ENGINE_NOT_FOUND; - } else { - g_is_engine = true; - } - } - /* check if pid is valid */ if (false == vcd_client_manager_is_valid(pid)) { SLOG(LOG_ERROR, TAG_VCD, "[Server] old manager pid(%d) be removed", vcd_client_manager_get_pid()); @@ -1413,7 +1395,7 @@ int vcd_server_mgr_set_audio_type(int pid, const char* audio_type) } int ret = 0; - vcp_audio_type_e type = VCP_AUDIO_TYPE_PCM_S16_LE; + vce_audio_type_e type = VCE_AUDIO_TYPE_PCM_S16_LE; int rate = 16000; int channel = 1; @@ -1859,21 +1841,9 @@ int vcd_server_mgr_disable_command_type(int pid, int cmd_type) */ int vcd_server_initialize(int pid) { - if (false == g_is_engine) { - if (0 != vcd_engine_agent_initialize_current_engine()) { - SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine"); - g_is_engine = false; - return VCD_ERROR_ENGINE_NOT_FOUND; - } else { - g_is_engine = true; - } - } - if (false == vcd_engine_is_available_engine()) { - if (0 != vcd_engine_agent_initialize_current_engine()) { - SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine"); - return VCD_ERROR_ENGINE_NOT_FOUND; - } + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine"); + return VCD_ERROR_ENGINE_NOT_FOUND; } /* check if pid is valid */ @@ -2176,21 +2146,9 @@ int vcd_server_request_cancel(int pid) */ int vcd_server_widget_initialize(int pid) { - if (false == g_is_engine) { - if (0 != vcd_engine_agent_initialize_current_engine()) { - SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine"); - g_is_engine = false; - return VCD_ERROR_ENGINE_NOT_FOUND; - } else { - g_is_engine = true; - } - } - if (false == vcd_engine_is_available_engine()) { - if (0 != vcd_engine_agent_initialize_current_engine()) { - SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine"); - return VCD_ERROR_ENGINE_NOT_FOUND; - } + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine"); + return VCD_ERROR_ENGINE_NOT_FOUND; } /* check if pid is valid */ @@ -2366,4 +2324,154 @@ int vcd_server_set_language(const char* language) } return ret; -} \ No newline at end of file +} +/* +* For engine service +*/ +int vcd_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void* user_data) +{ + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Get foreach command"); + + if (NULL == callback) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] input parameter is NULL"); + return VCD_ERROR_INVALID_PARAMETER; + } + + int ret = 0; + ret = vcd_engine_agent_get_foreach_command(vce_command, callback, user_data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get foreach command : ret(%d)", ret); + } + + return ret; +} + +int vcd_get_command_count(vce_cmd_h vce_command) +{ + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Get command count"); + + int ret = 0; + ret = vcd_engine_agent_get_command_count(vce_command); + if (0 > ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get command count : ret(%d)", ret); + } + + return ret; +} + +int vcd_get_audio_type(char** audio_type) +{ + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Get audio type"); + + int ret = 0; + ret = vcd_engine_agent_get_audio_type(audio_type); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio type : ret(%d)", ret); + } + + return ret; +} + +int vcd_set_private_data(const char* key, const char* data) +{ + vcd_state_e state = vcd_config_get_service_state(); + + if (VCD_STATE_READY != state) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state(%d) is NOT 'READY'", state); + return VCD_ERROR_INVALID_STATE; + } + + int ret = vcd_engine_agent_set_private_data(key, data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set private data to the manager client : ret(%d)", ret); + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set private data to the manager client, key(%s), data(%s)", key, data); + } + + return ret; +} + +int vcd_get_private_data(const char* key, char** data) +{ + vcd_state_e state = vcd_config_get_service_state(); + + if (VCD_STATE_READY != state) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state(%d) is NOT 'READY'", state); + return VCD_ERROR_INVALID_STATE; + } + + int ret = vcd_engine_agent_get_private_data(key, data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get private data from the manager client : ret(%d)", ret); + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Get private data from the manager client, key(%s), data(%s)", key, data); + } + + return ret; +} + +int vcd_start_recording() +{ + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Start recording"); + + int ret = 0; + ret = vcd_engine_agent_start_recording(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recording : ret(%d)", ret); + } + + return ret; +} + +int vcd_stop_recording() +{ + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Stop recording"); + + int ret = 0; + ret = vcd_engine_agent_stop_recording(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recording : ret(%d)", ret); + } + + return ret; +} + +int vcd_set_private_data_set_cb(vce_private_data_set_cb callback_func) +{ + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set private data set cb"); + + int ret = 0; + ret = vcd_engine_agent_set_private_data_set_cb(callback_func); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set private data set cb : ret(%d)", ret); + } + + return ret; +} + +int vcd_set_private_data_requested_cb(vce_private_data_requested_cb callback_func) +{ + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set private data requested cb"); + + int ret = 0; + ret = vcd_engine_agent_set_private_data_requested_cb(callback_func); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set private data requested cb : ret(%d)", ret); + } + + return ret; +} + +int vcd_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_func) +{ + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set nlu base info requested cb"); + + int ret = 0; + ret = vcd_engine_agent_set_nlu_base_info_requested_cb(callback_func); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set nlu base info requested cb : ret(%d)", ret); + } + + return ret; +} + diff --git a/server/vcd_server.h b/server/vcd_server.h index 14fcbd2..d317a3e 100644 --- a/server/vcd_server.h +++ b/server/vcd_server.h @@ -21,6 +21,8 @@ #include "vcd_main.h" #include "vcd_client_data.h" +#include "vce.h" + #ifdef __cplusplus extern "C" { #endif @@ -28,7 +30,7 @@ extern "C" { /* * Daemon functions */ -int vcd_initialize(); +int vcd_initialize(vce_request_callback_s *callback); void vcd_finalize(); @@ -124,6 +126,38 @@ int vcd_server_widget_enable_asr_result(int pid, bool enable); int vcd_server_set_language(const char* language); +/* +* For engine service +*/ +int vcd_send_result(vce_result_event_e event, int* result_id, int count, const char* all_result, const char* non_fixed_result, const char* nlu_result, const char* msg, void *user_data); + +int vcd_send_asr_result(vce_asr_result_event_e event, const char* asr_result, void *user_data); + +int vcd_send_nlg_result(const char* nlg_result, void *user_data); + +int vcd_send_error(vce_error_e error, const char* msg, void *user_data); + +int vcd_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void* user_data); + +int vcd_get_command_count(vce_cmd_h vce_command); + +int vcd_get_audio_type(char** audio_type); + +int vcd_set_private_data(const char* key, const char* data); + +int vcd_get_private_data(const char* key, char** data); + +int vcd_start_recording(); + +int vcd_stop_recording(); + +int vcd_set_private_data_set_cb(vce_private_data_set_cb callback_func); + +int vcd_set_private_data_requested_cb(vce_private_data_requested_cb callback_func); + +int vcd_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_func); + + #ifdef __cplusplus } #endif diff --git a/server/vce.c b/server/vce.c new file mode 100755 index 0000000..25f1f46 --- /dev/null +++ b/server/vce.c @@ -0,0 +1,262 @@ +/* +* Copyright (c) 2011-2017 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the License); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an AS IS BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#include "vcd_dbus.h" +#include "vcd_main.h" +#include "vcd_server.h" + +#include "vce.h" + + +int vce_main(int argc, char** argv, vce_request_callback_s *callback) +{ + SLOG(LOG_DEBUG, TAG_VCD, " "); + SLOG(LOG_DEBUG, TAG_VCD, " "); + SLOG(LOG_DEBUG, TAG_VCD, "===== VC Engine Service Initialize"); + + int ret = VCE_ERROR_NONE; + + if (!ecore_init()) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail ecore_init()"); + return VCE_ERROR_OPERATION_FAILED; + } + + if (0 != vcd_dbus_open_connection()) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to open connection"); + ecore_shutdown(); + return VCE_ERROR_OPERATION_FAILED; + } + + ret = vcd_initialize(callback); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to initialize"); + vcd_dbus_close_connection(); + ecore_shutdown(); + return ret; + } + + SLOG(LOG_DEBUG, TAG_VCD, "[Main] VC Engine Service start..."); + + SLOG(LOG_DEBUG, TAG_VCD, "====="); + SLOG(LOG_DEBUG, TAG_VCD, " "); + SLOG(LOG_DEBUG, TAG_VCD, " "); + + return 0; +} + +int vce_send_result(vce_result_event_e event, int* result_id, int count, const char* all_result, const char* non_fixed_result, const char* nlu_result, const char* msg, void *user_data) +{ + int ret = VCE_ERROR_NONE; + + if (NULL == all_result || NULL == non_fixed_result || NULL == nlu_result) { + SLOG(LOG_ERROR, TAG_VCD, "[INFO] Input parameter is NULL. (no result)"); + } + + ret = vcd_send_result(event, result_id, count, all_result, non_fixed_result, nlu_result, msg, user_data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send result"); + } else { + SLOG(LOG_INFO, TAG_VCD, "[INFO] Success to send result"); + } + + return ret; +} + + +int vce_send_asr_result(vce_asr_result_event_e event, const char* asr_result, void *user_data) +{ + int ret = VCE_ERROR_NONE; + + if (NULL == asr_result) { + SLOG(LOG_ERROR, TAG_VCD, "[INFO] Input parameter is NULL. (no result)"); + } + + ret = vcd_send_asr_result(event, asr_result, user_data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send ASR result"); + } else { + SLOG(LOG_INFO, TAG_VCD, "[INFO] Success to send ASR result"); + } + + return ret; +} + +int vce_send_nlg_result(const char* nlg_result, void *user_data) +{ + int ret = VCE_ERROR_NONE; + + if (NULL == nlg_result) { + SLOG(LOG_ERROR, TAG_VCD, "[INFO] Input parameter is NULL. (no result)"); + } + + ret = vcd_send_nlg_result(nlg_result, user_data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send NLG result"); + } else { + SLOG(LOG_INFO, TAG_VCD, "[INFO] Success to send NLG result"); + } + + return ret; +} + +int vce_send_error(vce_error_e error, const char* msg, void *user_data) +{ + int ret = VCE_ERROR_NONE; + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Input parameter is NULL. (no error message)"); + } + + ret = vcd_send_error(error, msg, user_data); + + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send error"); + } + + return ret; +} + + +/* Daemon API */ +int vce_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void* user_data) +{ + int ret = VCE_ERROR_NONE; + + ret = vcd_get_foreach_command(vce_command, callback, user_data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get foreach command"); + } + + return ret; +} + +int vce_get_command_count(vce_cmd_h vce_command) +{ + int ret = VCE_ERROR_NONE; + + ret = vcd_get_command_count(vce_command); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get command count"); + } + + return ret; +} + +int vce_get_audio_type(char** audio_type) +{ + int ret = VCE_ERROR_NONE; + + ret = vcd_get_audio_type(audio_type); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get audio type"); + } + + return ret; +} + +int vce_set_private_data(const char* key, const char* data) +{ + int ret = VCE_ERROR_NONE; + + ret = vcd_set_private_data(key, data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set private data to vc manager"); + } + + return ret; +} + +int vce_get_private_data(const char* key, char** data) +{ + int ret = VCE_ERROR_NONE; + + ret = vcd_get_private_data(key, data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get private data from vc manager"); + } + + return ret; +} + +int vce_start_recording() +{ + int ret = VCE_ERROR_NONE; + + ret = vcd_start_recording(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to start recording"); + } + + return ret; +} + +int vce_stop_recording() +{ + int ret = VCE_ERROR_NONE; + + ret = vcd_stop_recording(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to stop recording"); + } + + return ret; +} + +int vce_set_private_data_set_cb(vce_private_data_set_cb callback_func) +{ + if (NULL == callback_func) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter"); + return VCE_ERROR_INVALID_PARAMETER; + } + + int ret = vcd_set_private_data_set_cb(callback_func); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set private data set cb"); + } + + return ret; +} + +int vce_set_private_data_requested_cb(vce_private_data_requested_cb callback_func) +{ + if (NULL == callback_func) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter"); + return VCE_ERROR_INVALID_PARAMETER; + } + + int ret = vcd_set_private_data_requested_cb(callback_func); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set private data requested cb"); + } + + return ret; +} + +int vce_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_func) +{ + if (NULL == callback_func) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter"); + return VCE_ERROR_INVALID_PARAMETER; + } + + int ret = vcd_set_nlu_base_info_requested_cb(callback_func); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set nlu-base info requested cb"); + } + + return ret; +} -- 2.7.4 From 4926d22dddee86592b321f3436de4248059fec74 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Tue, 7 Nov 2017 16:30:10 +0900 Subject: [PATCH 13/16] Change ecore timer to thread for connecting daemon Change-Id: I92e6f9cd5a6e4f1db86041747efc9cb3fad4120c Signed-off-by: Wonnam Jang (cherry picked from commit 7e35c08d1960335a77963ba6a299e2ef5742a22e) --- client/vc.c | 74 ++++++++++++++++++++++++++++++++++++++++------------ client/vc_dbus.c | 1 + client/vc_mgr.c | 12 ++++----- client/vc_mgr_dbus.c | 1 + 4 files changed, 64 insertions(+), 24 deletions(-) diff --git a/client/vc.c b/client/vc.c index 2afb878..c89e7f9 100644 --- a/client/vc.c +++ b/client/vc.c @@ -56,8 +56,8 @@ static bool g_backup = false; static int g_privilege_allowed = -1; static cynara *p_cynara = NULL; -Eina_Bool __vc_notify_state_changed(void *data); -Eina_Bool __vc_notify_error(void *data); +static void __vc_notify_state_changed(void *data); +static void __vc_notify_error(void *data); static int __vc_get_feature_enabled() { @@ -110,7 +110,7 @@ static int __check_privilege(const char* uid, const char * privilege) fp = fopen(label_path, "r"); if (fp != NULL) { - if (sizeof(smack_label) != fread(smack_label, 1, sizeof(smack_label), fp)) + if (strlen(smack_label) != fread(smack_label, 1, sizeof(smack_label), fp)) SLOG(LOG_ERROR, TAG_VCC, "[ERROR] fail to fread"); fclose(fp); @@ -489,7 +489,7 @@ static Eina_Bool __vc_connect_daemon(void *data) SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to initialize : %s", __vc_get_error_code(ret)); vc_client_set_error(g_vc, VC_ERROR_ENGINE_NOT_FOUND); - ecore_timer_add(0, __vc_notify_error, g_vc); + ecore_main_loop_thread_safe_call_async(__vc_notify_error, (void*)g_vc); SLOG(LOG_DEBUG, TAG_VCC, "@@@"); return EINA_FALSE; @@ -498,7 +498,7 @@ static Eina_Bool __vc_connect_daemon(void *data) SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to initialize :%s", __vc_get_error_code(ret)); vc_client_set_error(g_vc, VC_ERROR_TIMED_OUT); - ecore_timer_add(0, __vc_notify_error, g_vc); + ecore_main_loop_thread_safe_call_async(__vc_notify_error, (void*)g_vc); SLOG(LOG_DEBUG, TAG_VCC, "@@@"); return EINA_FALSE; @@ -542,7 +542,7 @@ static Eina_Bool __vc_connect_daemon(void *data) } vc_client_set_client_state(g_vc, VC_STATE_READY); - ecore_timer_add(0, __vc_notify_state_changed, g_vc); + ecore_main_loop_thread_safe_call_async(__vc_notify_state_changed, (void*)g_vc); vc_client_set_mgr_pid(g_vc, mgr_pid); @@ -551,6 +551,50 @@ static Eina_Bool __vc_connect_daemon(void *data) return EINA_FALSE; } +static void __start_prepare_thread(void *data, Ecore_Thread *thread) +{ + SLOG(LOG_ERROR, TAG_VCC, "@@@ Start prepare thread"); + int ret = -1, retry_count = 0; + + /* Send hello */ + while (0 != ret) { + + if (retry_count == 10) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request hello !!"); + return; + } + + ret = vc_dbus_request_hello(); + if (ret == 0) { + SLOG(LOG_DEBUG, TAG_VCC, "Success to request hello. retry count(%d)", retry_count); + break; + } else { + retry_count++; + } + } + + ret = -1; + retry_count = 0; + while (0 != ret) { + if (retry_count == 10) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to connect daemon !!"); + return; + } + ret = __vc_connect_daemon(NULL); + if (ret == 0) + break; + else + retry_count++; + } + + return; +} + +static void __end_prepare_thread(void *data, Ecore_Thread *thread) +{ + SLOG(LOG_DEBUG, TAG_VCC, "@@@ End prepare thread"); +} + int vc_prepare(void) { if (0 != __vc_get_feature_enabled()) { @@ -576,7 +620,7 @@ int vc_prepare(void) return VC_ERROR_INVALID_STATE; } - g_connect_timer = ecore_timer_add(0, __vc_connect_daemon, NULL); + ecore_thread_run(__start_prepare_thread, __end_prepare_thread, NULL, NULL); SLOG(LOG_DEBUG, TAG_VCC, "@@@"); @@ -651,7 +695,7 @@ int vc_unprepare(void) __vc_internal_unprepare(); vc_client_set_client_state(g_vc, VC_STATE_INITIALIZED); - ecore_timer_add(0, __vc_notify_state_changed, g_vc); + ecore_main_loop_thread_safe_call_async(__vc_notify_state_changed, (void*)g_vc); SLOG(LOG_DEBUG, TAG_VCC, "@@@"); @@ -1522,7 +1566,7 @@ int vc_request_cancel(void) } #endif -Eina_Bool __vc_notify_error(void *data) +static void __vc_notify_error(void *data) { vc_h vc = (vc_h)data; @@ -1541,8 +1585,6 @@ Eina_Bool __vc_notify_error(void *data) } else { SLOG(LOG_WARN, TAG_VCC, "[WARNING] Error callback is null"); } - - return EINA_FALSE; } int __vc_cb_error(int reason, int daemon_pid, char* msg) @@ -1563,22 +1605,22 @@ int __vc_cb_error(int reason, int daemon_pid, char* msg) SLOG(LOG_ERROR, TAG_VCC, "[ERROR] VC daemon reset"); vc_client_set_client_state(g_vc, VC_STATE_INITIALIZED); - __vc_notify_state_changed(g_vc); + ecore_main_loop_thread_safe_call_async(__vc_notify_state_changed, (void*)g_vc); if (0 != vc_prepare()) { SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to prepare"); } } - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Error reason(%d), msg(%s)", reason, msg); + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Error reason(%d), msg(%s)", reason, msg); vc_client_set_error(g_vc, reason); - ecore_timer_add(0, __vc_notify_error, g_vc); + ecore_main_loop_thread_safe_call_async(__vc_notify_error, (void*)g_vc); return 0; } -Eina_Bool __vc_notify_state_changed(void *data) +static void __vc_notify_state_changed(void *data) { vc_h vc = (vc_h)data; @@ -1600,8 +1642,6 @@ Eina_Bool __vc_notify_state_changed(void *data) } else { SLOG(LOG_WARN, TAG_VCC, "[WARNING] State changed callback is null"); } - - return EINA_FALSE; } static Eina_Bool __vc_notify_result(void *data) diff --git a/client/vc_dbus.c b/client/vc_dbus.c index 49d4510..7ab57c5 100644 --- a/client/vc_dbus.c +++ b/client/vc_dbus.c @@ -401,6 +401,7 @@ int vc_dbus_request_hello() result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, 500, &err); if (dbus_error_is_set(&err)) { + SLOG(LOG_DEBUG, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message); dbus_error_free(&err); } diff --git a/client/vc_mgr.c b/client/vc_mgr.c index b8c5458..f29f08c 100644 --- a/client/vc_mgr.c +++ b/client/vc_mgr.c @@ -55,7 +55,7 @@ static int g_feature_enabled = -1; static bool g_err_callback_status = false; static Eina_Bool __vc_mgr_notify_state_changed(void *data); -static Eina_Bool __vc_mgr_notify_error(void *data); +static void __vc_mgr_notify_error(void *data); static Eina_Bool __vc_mgr_notify_result(void *data); static const char* __vc_mgr_get_error_code(vc_error_e err) @@ -262,7 +262,7 @@ static Eina_Bool __vc_mgr_connect_daemon(void *data) SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to initialize : %s", __vc_mgr_get_error_code(ret)); vc_mgr_client_set_error(g_vc_m, VC_ERROR_ENGINE_NOT_FOUND); - ecore_timer_add(0, __vc_mgr_notify_error, g_vc_m); + ecore_main_loop_thread_safe_call_async(__vc_mgr_notify_error, (void*)g_vc_m); SLOG(LOG_DEBUG, TAG_VCM, "@@@"); return EINA_FALSE; @@ -314,7 +314,7 @@ static void __start_prepare_thread(void *data, Ecore_Thread *thread) int ret = 1, retry_count = 0; /* Send hello */ - while (ret) { + while (0 != ret) { if (retry_count == 10) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request hello !!"); @@ -332,7 +332,7 @@ static void __start_prepare_thread(void *data, Ecore_Thread *thread) ret = 1; retry_count = 0; - while (ret) { + while (0 != ret) { if (retry_count == 10) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to connect daemon !!"); return; @@ -2321,7 +2321,7 @@ int vc_mgr_get_error_message(char** err_msg) return ret; } -static Eina_Bool __vc_mgr_notify_error(void *data) +static void __vc_mgr_notify_error(void *data) { vc_h vc_m = (vc_h)data; @@ -2342,8 +2342,6 @@ static Eina_Bool __vc_mgr_notify_error(void *data) } else { SLOG(LOG_WARN, TAG_VCM, "[WARNING] Error callback is null"); } - - return EINA_FALSE; } int __vc_mgr_cb_error(int reason, int daemon_pid, char* msg) diff --git a/client/vc_mgr_dbus.c b/client/vc_mgr_dbus.c index 2cfd533..4c43f45 100644 --- a/client/vc_mgr_dbus.c +++ b/client/vc_mgr_dbus.c @@ -788,6 +788,7 @@ int vc_mgr_dbus_request_hello() result_msg = dbus_connection_send_with_reply_and_block(g_m_conn_sender, msg, 500, &err); if (dbus_error_is_set(&err)) { + SLOG(LOG_DEBUG, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message); dbus_error_free(&err); } -- 2.7.4 From 908696a4e3c87da49edb98d17f7253a09d5000a4 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Thu, 23 Nov 2017 09:26:52 +0900 Subject: [PATCH 14/16] Remove unnecessary DB access Change-Id: Ie5080b25a9a7c5d2c9e950b958f95e322d3bdd16 Signed-off-by: Wonnam Jang --- client/vc_widget.c | 20 +++----------------- client/vc_widget_dbus.c | 14 +++++++++++--- server/vcd_dbus.c | 4 +++- server/vcd_dbus.h | 2 +- server/vcd_server.c | 3 +-- 5 files changed, 19 insertions(+), 24 deletions(-) diff --git a/client/vc_widget.c b/client/vc_widget.c index 178f360..257478f 100644 --- a/client/vc_widget.c +++ b/client/vc_widget.c @@ -1128,18 +1128,9 @@ void __vc_widget_cb_result() return; } -bool __vc_widget_cb_asr_result() +bool __vc_widget_cb_asr_result(int event, const char* asr_result) { - char* temp_text; - int event; - vc_cmd_list_h vc_cmd_list = NULL; - if (0 != vc_cmd_list_create(&vc_cmd_list)) { - SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to create command list"); - return false; - } - - vc_info_parser_get_result(&temp_text, &event, NULL, -1, vc_cmd_list, false); - SLOG(LOG_DEBUG, TAG_VCW, "Result info : result text(%s) event(%d)", temp_text, event); + SLOG(LOG_DEBUG, TAG_VCW, "Result info : result text(%s) event(%d)", asr_result, event); vc_asr_result_cb callback = NULL; void* user_data = NULL; @@ -1168,7 +1159,7 @@ bool __vc_widget_cb_asr_result() } vc_widget_client_use_callback(vc_w); - consumed = callback(event, temp_text, user_data); + consumed = callback(event, asr_result, user_data); vc_widget_client_not_use_callback(vc_w); if (true == consumed) break; @@ -1177,11 +1168,6 @@ bool __vc_widget_cb_asr_result() } } - /* Release result */ - if (NULL != temp_text) free(temp_text); - - vc_cmd_list_destroy(vc_cmd_list, true); - return consumed; } diff --git a/client/vc_widget_dbus.c b/client/vc_widget_dbus.c index a40fd93..9d5dbc0 100644 --- a/client/vc_widget_dbus.c +++ b/client/vc_widget_dbus.c @@ -33,7 +33,7 @@ extern void __vc_widget_cb_show_tooltip(int pid, bool show); extern void __vc_widget_cb_result(); -extern bool __vc_widget_cb_asr_result(); +extern bool __vc_widget_cb_asr_result(int event, const char* asr_result); extern int __vc_widget_cb_service_state(int state); @@ -168,7 +168,15 @@ static Eina_Bool widget_listener_event_callback(void* data, Ecore_Fd_Handler *fd else if (dbus_message_is_method_call(msg, if_name, VCD_WIDGET_METHOD_ASR_RESULT)) { SLOG(LOG_DEBUG, TAG_VCW, "@@@ Get widget asr result"); int ret = 0; - if (false == __vc_widget_cb_asr_result()) + int event = -1; + char* asr_result = NULL; + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &event, + DBUS_TYPE_STRING, &asr_result, + DBUS_TYPE_INVALID); + + if (false == __vc_widget_cb_asr_result(event, asr_result)) ret = 0; else ret = 1; @@ -179,7 +187,7 @@ static Eina_Bool widget_listener_event_callback(void* data, Ecore_Fd_Handler *fd if (!dbus_connection_send(g_w_conn_listener, reply, NULL)) SLOG(LOG_ERROR, TAG_VCW, "@@ vc widget get asr result : fail to send reply"); else - SLOG(LOG_DEBUG, TAG_VCW, "@@ vc widget get asr result"); + SLOG(LOG_DEBUG, TAG_VCW, "@@ vc widget get asr result, event(%d), asr_result(%s), consumed(%d)", event, asr_result, ret); dbus_connection_flush(g_w_conn_listener); dbus_message_unref(reply); diff --git a/server/vcd_dbus.c b/server/vcd_dbus.c index f2486e4..72cad70 100755 --- a/server/vcd_dbus.c +++ b/server/vcd_dbus.c @@ -311,7 +311,7 @@ int vcdc_send_result(int pid, int manager_pid, int cmd_type) return 0; } -int vcdc_send_asr_result(int pid, int cmd_type, bool* is_consumed) +int vcdc_send_asr_result(int pid, int event, const char* asr_result, int cmd_type, bool* is_consumed) { if (0 != __dbus_check()) { return VCD_ERROR_OPERATION_FAILED; @@ -335,6 +335,8 @@ int vcdc_send_asr_result(int pid, int cmd_type, bool* is_consumed) return VCD_ERROR_OUT_OF_MEMORY; } + dbus_message_append_args(msg, DBUS_TYPE_INT32, &event, DBUS_TYPE_STRING, &asr_result, DBUS_TYPE_INVALID); + DBusError err; dbus_error_init(&err); diff --git a/server/vcd_dbus.h b/server/vcd_dbus.h index ad6ebb8..d4674ec 100644 --- a/server/vcd_dbus.h +++ b/server/vcd_dbus.h @@ -44,7 +44,7 @@ int vcdc_send_set_volume(int manger_pid, float volume); int vcdc_send_result(int pid, int manager_pid, int cmd_type); -int vcdc_send_asr_result(int pid, int cmd_type, bool* is_consumed); +int vcdc_send_asr_result(int pid, int event, const char* asr_result, int cmd_type, bool* is_consumed); int vcdc_send_pre_result_to_manager(int manager_pid, int event, const char* pre_result); diff --git a/server/vcd_server.c b/server/vcd_server.c index 10cb388..58b2f37 100755 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -506,13 +506,12 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c int pid = vcd_client_widget_get_foreground_pid(); if (-1 != pid) { if (NULL != all_result) { - vc_info_parser_set_result(all_result, event, msg, NULL, false); bool enable = false; vcd_client_widget_get_asr_result_enabled(pid, &enable); if (true == enable) { SLOG(LOG_DEBUG, TAG_VCD, "[Server] Send ASR result to Widget client"); bool is_consumed = false; - if (0 != vcdc_send_asr_result(pid, VC_COMMAND_TYPE_WIDGET, &is_consumed)) { + if (0 != vcdc_send_asr_result(pid, event, all_result, VC_COMMAND_TYPE_WIDGET, &is_consumed)) { SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send asr result"); } else { SLOG(LOG_DEBUG, TAG_VCD, "[Server] ASR result is consumed(%d)", is_consumed); -- 2.7.4 From e112589ee1778b325974881fc0a614cd4cd437a4 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Wed, 29 Nov 2017 16:35:34 +0900 Subject: [PATCH 15/16] delete timer when vc widget is deinitialized Change-Id: I5bce055aedb601d08decfac3136d67e2f063dd4b Signed-off-by: Wonnam Jang (cherry picked from commit 0cbf9e60b8594da0711e89b7c21c435381da06bc) --- client/vc_widget.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/client/vc_widget.c b/client/vc_widget.c index 257478f..d6bcc47 100644 --- a/client/vc_widget.c +++ b/client/vc_widget.c @@ -35,6 +35,9 @@ static Ecore_Event_Handler* g_focus_in_handler = NULL; static Ecore_Event_Handler* g_focus_out_handler = NULL; static Ecore_Timer* g_w_start_timer = NULL; +static Ecore_Timer* g_w_notify_error_timer = NULL; +static Ecore_Timer* g_w_notify_state_timer = NULL; +static Ecore_Timer* g_w_notify_result_timer = NULL; static int g_daemon_pid = 0; @@ -189,6 +192,28 @@ static void __vc_widget_internal_unprepare(vc_h vc_w) return; } +static void __vc_widget_delete_timer() +{ + SLOG(LOG_DEBUG, TAG_VCW, "@@@ [Widget] timers are deleted"); + if (NULL != g_w_start_timer) { + ecore_timer_del(g_w_start_timer); + g_w_start_timer = NULL; + } + if (NULL != g_w_notify_error_timer) { + ecore_timer_del(g_w_notify_error_timer); + g_w_notify_error_timer = NULL; + } + if (NULL != g_w_notify_state_timer) { + ecore_timer_del(g_w_notify_state_timer); + g_w_notify_state_timer = NULL; + } + if (NULL != g_w_notify_result_timer) { + ecore_timer_del(g_w_notify_result_timer); + g_w_notify_result_timer = NULL; + } + return; +} + int vc_widget_deinitialize(vc_h vc_w) { SLOG(LOG_DEBUG, TAG_VCW, "@@@ [Widget] Deinitialize"); @@ -228,6 +253,8 @@ int vc_widget_deinitialize(vc_h vc_w) break; } + __vc_widget_delete_timer(); + SLOG(LOG_DEBUG, TAG_VCW, "Success: destroy"); if (0 == vc_widget_client_get_count()) { @@ -298,7 +325,7 @@ static Eina_Bool __vc_widget_connect_daemon(void *data) SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to initialize : %s", __vc_widget_get_error_code(ret)); vc_widget_client_set_error(vc_w, VC_ERROR_ENGINE_NOT_FOUND); - ecore_timer_add(0, __vc_widget_notify_error, vc_w); + g_w_notify_error_timer = ecore_timer_add(0, __vc_widget_notify_error, vc_w); SLOG(LOG_DEBUG, TAG_VCW, "@@@"); return EINA_FALSE; @@ -309,7 +336,7 @@ static Eina_Bool __vc_widget_connect_daemon(void *data) SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to initialize : %s", __vc_widget_get_error_code(ret)); vc_widget_client_set_error(vc_w, VC_ERROR_TIMED_OUT); - ecore_timer_add(0, __vc_widget_notify_error, vc_w); + g_w_notify_error_timer = ecore_timer_add(0, __vc_widget_notify_error, vc_w); SLOG(LOG_DEBUG, TAG_VCW, "@@@"); return EINA_FALSE; @@ -335,7 +362,7 @@ static Eina_Bool __vc_widget_connect_daemon(void *data) } vc_widget_client_set_state(vc_w, VC_STATE_READY); - ecore_timer_add(0, __vc_widget_notify_state_changed, vc_w); + g_w_notify_state_timer = ecore_timer_add(0, __vc_widget_notify_state_changed, vc_w); SLOG(LOG_DEBUG, TAG_VCW, "@@@"); @@ -395,7 +422,7 @@ int vc_widget_unprepare(vc_h vc_w) __vc_widget_internal_unprepare(vc_w); vc_widget_client_set_state(vc_w, VC_STATE_INITIALIZED); - ecore_timer_add(0, __vc_widget_notify_state_changed, vc_w); + g_w_notify_state_timer = ecore_timer_add(0, __vc_widget_notify_state_changed, vc_w); SLOG(LOG_DEBUG, TAG_VCW, "@@@"); @@ -932,7 +959,7 @@ int __vc_widget_cb_error(int reason, int daemon_pid, char* msg) SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Error reason(%d), msg(%s)", reason, msg); vc_widget_client_set_error(vc_w, reason); - ecore_timer_add(0, __vc_widget_notify_error, vc_w); + g_w_notify_error_timer = ecore_timer_add(0, __vc_widget_notify_error, vc_w); } } @@ -1123,7 +1150,7 @@ static Eina_Bool __vc_widget_notify_result(void *data) void __vc_widget_cb_result() { - ecore_timer_add(0, __vc_widget_notify_result, NULL); + g_w_notify_result_timer = ecore_timer_add(0, __vc_widget_notify_result, NULL); return; } -- 2.7.4 From 7833b656b6dd2c226b87c207b4e5bcd5238005a2 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Wed, 29 Nov 2017 21:20:01 +0900 Subject: [PATCH 16/16] check null before use when dbus close connection Change-Id: I00e45405980dfcd1572afa428f5937688a0aee94 Signed-off-by: Wonnam Jang --- client/vc_dbus.c | 18 ++++++++++-------- client/vc_mgr_dbus.c | 18 ++++++++++-------- client/vc_widget_dbus.c | 18 ++++++++++-------- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/client/vc_dbus.c b/client/vc_dbus.c index 7ab57c5..2bfeb78 100644 --- a/client/vc_dbus.c +++ b/client/vc_dbus.c @@ -313,17 +313,19 @@ int vc_dbus_close_connection() g_fd_handler = NULL; } - int pid = getpid(); + if (NULL != g_conn_listener) { + int pid = getpid(); - char service_name[64]; - memset(service_name, '\0', 64); - snprintf(service_name, 64, "%s%d", VC_CLIENT_SERVICE_NAME, pid); + char service_name[64]; + memset(service_name, '\0', 64); + snprintf(service_name, 64, "%s%d", VC_CLIENT_SERVICE_NAME, pid); - dbus_bus_release_name(g_conn_listener, service_name, &err); + dbus_bus_release_name(g_conn_listener, service_name, &err); - if (dbus_error_is_set(&err)) { - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message); - dbus_error_free(&err); + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message); + dbus_error_free(&err); + } } __vc_dbus_connection_free(); diff --git a/client/vc_mgr_dbus.c b/client/vc_mgr_dbus.c index 4c43f45..d08e9e9 100644 --- a/client/vc_mgr_dbus.c +++ b/client/vc_mgr_dbus.c @@ -712,17 +712,19 @@ int vc_mgr_dbus_close_connection() g_m_fd_handler = NULL; } - int pid = getpid(); + if (NULL != g_m_conn_listener) { + int pid = getpid(); - char service_name[64]; - memset(service_name, '\0', 64); - snprintf(service_name, 64, "%s%d", VC_MANAGER_SERVICE_NAME, pid); + char service_name[64]; + memset(service_name, '\0', 64); + snprintf(service_name, 64, "%s%d", VC_MANAGER_SERVICE_NAME, pid); - dbus_bus_release_name(g_m_conn_listener, service_name, &err); + dbus_bus_release_name(g_m_conn_listener, service_name, &err); - if (dbus_error_is_set(&err)) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message); - dbus_error_free(&err); + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message); + dbus_error_free(&err); + } } __vc_mgr_dbus_connection_free(); diff --git a/client/vc_widget_dbus.c b/client/vc_widget_dbus.c index 9d5dbc0..59d7a60 100644 --- a/client/vc_widget_dbus.c +++ b/client/vc_widget_dbus.c @@ -397,17 +397,19 @@ int vc_widget_dbus_close_connection() g_w_fd_handler = NULL; } - int pid = getpid(); + if (NULL != g_w_conn_listener) { + int pid = getpid(); - char service_name[64]; - memset(service_name, '\0', 64); - snprintf(service_name, 64, "%s%d", VC_WIDGET_SERVICE_NAME, pid); + char service_name[64]; + memset(service_name, '\0', 64); + snprintf(service_name, 64, "%s%d", VC_WIDGET_SERVICE_NAME, pid); - dbus_bus_release_name(g_w_conn_listener, service_name, &err); + dbus_bus_release_name(g_w_conn_listener, service_name, &err); - if (dbus_error_is_set(&err)) { - SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Dbus Error (%s)", err.message); - dbus_error_free(&err); + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Dbus Error (%s)", err.message); + dbus_error_free(&err); + } } __vc_mgr_dbus_connection_free(); -- 2.7.4