--- /dev/null
- } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SET_ASSISTANT_LANGUAGE)) {
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 <dirent.h>
+#include <dlfcn.h>
+#include <message_port.h>
+
+#include "service_common.h"
+#include "service_main.h"
+#include "service_ipc_dbus.h"
+
+int CServiceIpcDbus::reconnect()
+{
+ if (!mConnectionSender || !mConnectionListener) {
+ close_connection();
+
+ if (0 != open_connection()) {
+ MAS_LOGE("[ERROR] Fail to reconnect");
+ return -1;
+ }
+
+ MAS_LOGD("[DBUS] Reconnect");
+ return 0;
+ }
+
+ bool sender_connected = dbus_connection_get_is_connected(mConnectionSender);
+ bool listener_connected = dbus_connection_get_is_connected(mConnectionListener);
+ MAS_LOGW("[DBUS] Sender(%s) Listener(%s)",
+ sender_connected ? "Connected" : "Not connected", listener_connected ? "Connected" : "Not connected");
+
+ if (false == sender_connected || false == listener_connected) {
+ close_connection();
+
+ if (0 != open_connection()) {
+ MAS_LOGE("[ERROR] Fail to reconnect");
+ return -1;
+ }
+
+ MAS_LOGD("[DBUS] Reconnect");
+ }
+
+ return 0;
+}
+
+int CServiceIpcDbus::__dbus_check()
+{
+ if (NULL == mConnectionSender || NULL == mConnectionListener) {
+ MAS_LOGE("[ERROR] NULL connection");
+ return reconnect();
+ }
+ return 0;
+}
+
+int CServiceIpcDbus::mas_check_dbus_connection()
+{
+ if (NULL == mConnectionSender || NULL == mConnectionListener) {
+ MAS_LOGE("[ERROR] NULL connection sender(%p), listener(%p)", mConnectionSender, mConnectionListener);
+ return -1;
+ }
+ return 0;
+}
+
+int CServiceIpcDbus::send_hello(int pid)
+{
+ if (0 != __dbus_check()) {
+ return -1; //MAS_ERROR_OPERATION_FAILED;
+ }
+
+ DBusMessage* msg;
+ DBusError err;
+ dbus_error_init(&err);
+
+ msg = dbus_message_new_method_call(
+ MA_CLIENT_SERVICE_NAME,
+ MA_CLIENT_SERVICE_OBJECT_PATH,
+ MA_CLIENT_SERVICE_INTERFACE,
+ MAS_METHOD_HELLO);
+
+ if (NULL == msg) {
+ MAS_LOGE("[DBus ERROR] Request masc hello : Fail to make message");
+ return -1;
+ }
+
+ int result = -1;
+ DBusMessage* result_msg = NULL;
+ result_msg = dbus_connection_send_with_reply_and_block(mConnectionSender, msg, 500, &err);
+
+ if (dbus_error_is_set(&err)) {
+ MAS_LOGE("[Dbus ERROR] Dbus Error (%s)", err.message);
+ dbus_error_free(&err);
+ }
+
+ dbus_message_unref(msg);
+
+ if (NULL != result_msg) {
+ dbus_message_unref(result_msg);
+ result = 0;
+ } else {
+ result = -1; //MAS_ERROR_TIMED_OUT;
+ }
+
+ return result;
+}
+
+int CServiceIpcDbus::send_error_message(int reason, const char* err_msg)
+{
+ if (0 != __dbus_check()) {
+ return -1; //MAS_ERROR_OPERATION_FAILED;
+ }
+
+ if (NULL == mConnectionSender) {
+ MAS_LOGE("[Dbus ERROR] Dbus connection is not available");
+ return -1;
+ }
+
+ DBusMessage* msg = NULL;
+
+ /* create a message */
+ msg = dbus_message_new_signal(
+ MA_CLIENT_SERVICE_OBJECT_PATH, /* object name of the signal */
+ MA_CLIENT_SERVICE_INTERFACE, /* interface name of the signal */
+ MAS_METHOD_ERROR); /* name of the signal */
+
+ if (NULL == msg) {
+ MAS_LOGE("[Dbus ERROR] Fail to create error message");
+ return -1;
+ }
+
+ char* temp_err_msg = NULL;
+
+ if (err_msg)
+ temp_err_msg = strdup(err_msg);
+ else
+ temp_err_msg = strdup("#NULL");
+
+ dbus_message_append_args(msg,
+ DBUS_TYPE_INT32, &reason,
+ DBUS_TYPE_STRING, &temp_err_msg,
+ DBUS_TYPE_INVALID);
+
+ dbus_message_set_no_reply(msg, TRUE);
+
+ if (!dbus_connection_send(mConnectionSender, msg, NULL)) {
+ MAS_LOGE("[Dbus ERROR] <<<< error message : Out Of Memory !");
+ } else {
+ MAS_LOGI("<<<< Send error message : reason(%d), err_msg(%s)", reason, temp_err_msg);
+ dbus_connection_flush(mConnectionSender);
+ }
+
+ dbus_message_unref(msg);
+
+ if (temp_err_msg)
+ free(temp_err_msg);
+ return 0;
+}
+
+const char *message_port = "ma_streaming_port";
+
+#define STREAMING_BUFFER_SIZE 4096
+
+typedef enum {
+ streaming_data_type_audio_data,
+ streaming_data_type_streaming_section
+} streaming_data_type_e;
+
+typedef struct {
+ unsigned int streaming_data_size;
+ int streaming_data_type;
+ int streaming_data_serial;
+} streaming_data_header;
+
+typedef struct {
+ int event;
+ unsigned int data_size;
+} streaming_data_audio_data_header;
+
+typedef struct {
+ int section;
+} streaming_data_streaming_section_header;
+
+static void masc_message_port_error(int error)
+{
+ MAS_LOGE("message_port error found : %s",
+ (MESSAGE_PORT_ERROR_NONE == error) ? "MESSAGE_PORT_ERROR_NONE" :
+ (MESSAGE_PORT_ERROR_IO_ERROR == error) ? "MESSAGE_PORT_ERROR_IO_ERROR" :
+ (MESSAGE_PORT_ERROR_OUT_OF_MEMORY == error) ? "MESSAGE_PORT_ERROR_OUT_OF_MEMORY" :
+ (MESSAGE_PORT_ERROR_INVALID_PARAMETER == error) ? "MESSAGE_PORT_ERROR_INVALID_PARAMETER" :
+ (MESSAGE_PORT_ERROR_PORT_NOT_FOUND == error) ? "MESSAGE_PORT_ERROR_PORT_NOT_FOUND" :
+ (MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH == error) ? "MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH" :
+ (MESSAGE_PORT_ERROR_MAX_EXCEEDED == error) ? "MESSAGE_PORT_ERROR_MAX_EXCEEDED" :
+ (MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE == error) ? "MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE" :
+ "MESSAGE_PORT_ERROR_UNKNOWN");
+}
+
+int CServiceIpcDbus::send_streaming_audio_data(int pid, int event, void* data, unsigned int data_size)
+{
+ if (nullptr == mClientManager) {
+ MAS_LOGE("mClientManager variable is NULL");
+ return -1;
+ }
+
+ static unsigned char pending_buffer[STREAMING_BUFFER_SIZE];
+ static unsigned int pending_buffer_size = 0;
+
+ streaming_data_header header;
+ header.streaming_data_type = 0;
+ header.streaming_data_size = sizeof(streaming_data_header) + sizeof(streaming_data_audio_data_header) + data_size;
+ header.streaming_data_serial = mStreamingDataSerial++;
+
+ streaming_data_audio_data_header audio_data_header;
+ audio_data_header.event = event;
+ audio_data_header.data_size = data_size;
+
+ unsigned char buffer[STREAMING_BUFFER_SIZE];
+ size_t total_size = 0;
+ memcpy(buffer, &header, sizeof(header));
+ total_size += sizeof(header);
+ memcpy(buffer + total_size, &audio_data_header, sizeof(audio_data_header));
+ total_size += sizeof(audio_data_header);
+ memcpy(buffer + total_size, data, data_size);
+ total_size += data_size;
+
+ static int last_serial_waiting_for_flush = -1;
+ if (0 == header.streaming_data_serial % 50) {
+ last_serial_waiting_for_flush = header.streaming_data_serial;
+ MAS_LOGI("queueing streaming data, serial : %d", last_serial_waiting_for_flush);
+ }
+ if (pending_buffer_size + total_size > STREAMING_BUFFER_SIZE ||
+ MAS_SPEECH_STREAMING_EVENT_FINISH == event) {
+ bundle *b = bundle_create();
+ if (b) {
+ bundle_add_byte(b, "content", pending_buffer, pending_buffer_size);
+ int ret = message_port_send_message(
+ mClientManager->find_client_appid_by_pid(pid).c_str(), message_port, b);
+ if (MESSAGE_PORT_ERROR_NONE != ret)
+ masc_message_port_error(ret);
+
+ pending_buffer_size = 0;
+ bundle_free(b);
+ } else {
+ MAS_LOGE("Bundle creation failed!!!");
+ }
+
+ if (-1 != last_serial_waiting_for_flush) {
+ MAS_LOGI("flushing streaming data, serial : %d", last_serial_waiting_for_flush);
+ last_serial_waiting_for_flush = -1;
+ }
+ }
+
+ if (MAS_SPEECH_STREAMING_EVENT_FINISH == event) {
+ bundle *b = bundle_create();
+ if (b) {
+ bundle_add_byte(b, "content", buffer, total_size);
+ int ret = message_port_send_message(
+ mClientManager->find_client_appid_by_pid(pid).c_str(), message_port, b);
+ if (MESSAGE_PORT_ERROR_NONE != ret)
+ masc_message_port_error(ret);
+
+ bundle_free(b);
+ } else {
+ MAS_LOGE("Bundle creation failed!!!");
+ }
+ } else {
+ memcpy(pending_buffer + pending_buffer_size, buffer, total_size);
+ pending_buffer_size += total_size;
+ }
+ return 0;
+}
+
+int CServiceIpcDbus::change_active_state(int pid, int state)
+{
+ if (0 != __dbus_check()) {
+ return -1; //MAS_ERROR_OPERATION_FAILED;
+ }
+
+ DBusMessage* msg;
+
+ DBusError err;
+ dbus_error_init(&err);
+
+ char service_name[64];
+ memset(service_name, '\0', 64);
+ snprintf(service_name, 64, "%s_%d", MA_CLIENT_SERVICE_NAME, pid);
+
+ msg = dbus_message_new_method_call(
+ service_name,
+ MA_CLIENT_SERVICE_OBJECT_PATH,
+ MA_CLIENT_SERVICE_INTERFACE,
+ MAS_METHOD_ACTIVE_STATE_CHANGE);
+
+ if (NULL == msg) {
+ MAS_LOGE(">>>> Request mas send activate message : Fail to make message");
+ return -1; // MAS_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGD(">>>> Request mas send activate message : %s", service_name);
+ }
+
+ if (true != dbus_message_append_args(msg,
+ DBUS_TYPE_INT32, &state,
+ DBUS_TYPE_INVALID)) {
+ dbus_message_unref(msg);
+ MAS_LOGE("[ERROR] Fail to append args");
+ return -1;
+ }
+
+ dbus_message_set_no_reply(msg, TRUE);
+
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
+ MAS_LOGE("[Dbus ERROR] Fail to Send");
+ return -1; // MAS_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGI("[Dbus DEBUG] Success to Send activate message : %d %d", pid, state);
+ dbus_connection_flush(mConnectionSender);
+ }
+
+ dbus_message_unref(msg);
+ return 0;
+}
+
+int CServiceIpcDbus::send_preprocessing_information(int pid, const char* app_id)
+{
+ if (0 != __dbus_check()) {
+ return -1; //MAS_ERROR_OPERATION_FAILED;
+ }
+
+ DBusMessage* msg;
+
+ DBusError err;
+ dbus_error_init(&err);
+
+ char service_name[64];
+ memset(service_name, '\0', 64);
+ snprintf(service_name, 64, "%s_%d", MA_CLIENT_SERVICE_NAME, pid);
+
+ msg = dbus_message_new_method_call(
+ service_name,
+ MA_CLIENT_SERVICE_OBJECT_PATH,
+ MA_CLIENT_SERVICE_INTERFACE,
+ MAS_METHOD_SEND_PREPROCESSING_INFORMATION);
+
+ if (NULL == msg) {
+ MAS_LOGE(">>>> Request mas send preprocessing assistant information : Fail to make message");
+ return -1; // MAS_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGD(">>>> Request mas send preprocessing assistant information : %s", service_name);
+ }
+
+ char* temp_app_id = NULL;
+ if (!app_id)
+ temp_app_id = strdup("#NULL");
+ else
+ temp_app_id = strdup(app_id);
+
+ if (true != dbus_message_append_args(msg,
+ DBUS_TYPE_STRING, &temp_app_id,
+ DBUS_TYPE_INVALID)) {
+ dbus_message_unref(msg);
+ MAS_LOGE("[ERROR] Fail to append args");
+ if (temp_app_id)
+ free(temp_app_id);
+ return -1;
+ }
+
+ dbus_message_set_no_reply(msg, TRUE);
+
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
+ MAS_LOGE("[Dbus ERROR] Fail to Send");
+ if (temp_app_id)
+ free(temp_app_id);
+ return -1; // MAS_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGI("[Dbus DEBUG] Success to Send preprocessing assistant information : %d %s", pid, app_id);
+ dbus_connection_flush(mConnectionSender);
+ }
+
+ dbus_message_unref(msg);
+
+ if (temp_app_id)
+ free(temp_app_id);
+
+ return 0;
+}
+
+int CServiceIpcDbus::send_streaming_section_changed(int pid, int section)
+{
+ if (nullptr == mClientManager) {
+ MAS_LOGE("mClientManager variable is NULL");
+ return -1;
+ }
+
+ bundle *b = bundle_create();
+
+ streaming_data_header header;
+ header.streaming_data_type = 1;
+ header.streaming_data_size = sizeof(streaming_data_header) + sizeof(streaming_data_streaming_section_header);
+ header.streaming_data_serial = mStreamingDataSerial++;
+
+ streaming_data_streaming_section_header streaming_section_header;
+ streaming_section_header.section = section;
+
+ unsigned char buffer[STREAMING_BUFFER_SIZE];
+ size_t total_size = 0;
+ memcpy(buffer, &header, sizeof(header));
+ total_size += sizeof(header);
+ memcpy(buffer + total_size, &streaming_section_header, sizeof(streaming_section_header));
+ total_size += sizeof(streaming_section_header);
+
+ bundle_add_byte(b, "content", buffer, total_size);
+ int ret = message_port_send_message(
+ mClientManager->find_client_appid_by_pid(pid).c_str(), message_port, b);
+ if (MESSAGE_PORT_ERROR_NONE != ret)
+ masc_message_port_error(ret);
+
+ bundle_free(b);
+
+ return 0;
+}
+
+int CServiceIpcDbus::send_preprocessing_result(int pid, bool result)
+{
+ if (0 != __dbus_check()) {
+ return -1; //MAS_ERROR_OPERATION_FAILED;
+ }
+
+ DBusMessage* msg;
+
+ DBusError err;
+ dbus_error_init(&err);
+
+ char service_name[64];
+ memset(service_name, '\0', 64);
+ snprintf(service_name, 64, "%s_%d", MA_CLIENT_SERVICE_NAME, pid);
+
+ msg = dbus_message_new_method_call(
+ service_name,
+ MA_CLIENT_SERVICE_OBJECT_PATH,
+ MA_CLIENT_SERVICE_INTERFACE,
+ MAS_METHOD_SEND_PREPROCESSING_RESULT);
+
+ if (NULL == msg) {
+ MAS_LOGE(">>>> Request mas send preprocessing result : Fail to make message");
+ return -1; // MAS_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGD(">>>> Request mas send preprocessing result : %s", service_name);
+ }
+
+ int temp_result = result;
+
+ if (true != dbus_message_append_args(msg,
+ DBUS_TYPE_INT32, &temp_result,
+ DBUS_TYPE_INVALID)) {
+ dbus_message_unref(msg);
+ MAS_LOGE("[ERROR] Fail to append args");
+ return -1;
+ }
+
+ dbus_message_set_no_reply(msg, TRUE);
+
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
+ MAS_LOGE("[Dbus ERROR] Fail to Send");
+ return -1; // MAS_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGI("[Dbus DEBUG] Success to Send preprocessing result : %d %d", pid, temp_result);
+ dbus_connection_flush(mConnectionSender);
+ }
+
+ dbus_message_unref(msg);
+
+ return 0;
+}
+
+int CServiceIpcDbus::send_wakeup_engine_command(int pid, const char* command)
+{
+ if (0 != __dbus_check()) {
+ return -1; //MAS_ERROR_OPERATION_FAILED;
+ }
+
+ DBusMessage* msg;
+
+ DBusError err;
+ dbus_error_init(&err);
+
+ char service_name[64];
+ memset(service_name, '\0', 64);
+ snprintf(service_name, 64, "%s_%d", MA_CLIENT_SERVICE_NAME, pid);
+
+ msg = dbus_message_new_method_call(
+ service_name,
+ MA_CLIENT_SERVICE_OBJECT_PATH,
+ MA_CLIENT_SERVICE_INTERFACE,
+ MAS_METHOD_SEND_WAKEUP_ENGINE_COMMAND);
+
+ if (NULL == msg) {
+ MAS_LOGE(">>>> Request mas send wakeup engine command : Fail to make message");
+ return -1; // MAS_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGD(">>>> Request mas send wakeup engine command : %s", service_name);
+ }
+
+ char* temp_command = NULL;
+ if (!command)
+ temp_command = strdup("#NULL");
+ else
+ temp_command = strdup(command);
+
+ if (true != dbus_message_append_args(msg,
+ DBUS_TYPE_STRING, &temp_command,
+ DBUS_TYPE_INVALID)) {
+ dbus_message_unref(msg);
+ MAS_LOGE("[ERROR] Fail to append args");
+ if (temp_command)
+ free(temp_command);
+ return -1;
+ }
+
+ dbus_message_set_no_reply(msg, TRUE);
+
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
+ MAS_LOGE("[Dbus ERROR] Fail to Send");
+ if (temp_command)
+ free(temp_command);
+ return -1; // MAS_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGI("[Dbus DEBUG] Success to Send wakeup_engine_command : %d %s", pid, command);
+ dbus_connection_flush(mConnectionSender);
+ }
+
+ dbus_message_unref(msg);
+
+ if (temp_command)
+ free(temp_command);
+
+ return 0;
+}
+
+int CServiceIpcDbus::change_service_state(int pid, int state)
+{
+ if (0 != __dbus_check()) {
+ return -1; //MAS_ERROR_OPERATION_FAILED;
+ }
+
+ DBusMessage* msg;
+
+ DBusError err;
+ dbus_error_init(&err);
+
+ char service_name[64];
+ memset(service_name, '\0', 64);
+ snprintf(service_name, 64, "%s_%d", MA_CLIENT_SERVICE_NAME, pid);
+
+ msg = dbus_message_new_method_call(
+ service_name,
+ MA_CLIENT_SERVICE_OBJECT_PATH,
+ MA_CLIENT_SERVICE_INTERFACE,
+ MAS_METHOD_SERVICE_STATE_CHANGE);
+
+ if (NULL == msg) {
+ MAS_LOGE(">>>> Request mas send service state message : Fail to make message");
+ return -1; // MAS_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGD(">>>> Request mas send service state message : %s", service_name);
+ }
+
+ if (true != dbus_message_append_args(msg,
+ DBUS_TYPE_INT32, &state,
+ DBUS_TYPE_INVALID)) {
+ dbus_message_unref(msg);
+ MAS_LOGE("[ERROR] Fail to append args");
+ return -1;
+ }
+
+ dbus_message_set_no_reply(msg, TRUE);
+
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
+ MAS_LOGE("[Dbus ERROR] Fail to Send");
+ return -1; // MAS_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGI("[Dbus DEBUG] Success to Send service state message : %d %d", pid, state);
+ dbus_connection_flush(mConnectionSender);
+ }
+
+ dbus_message_unref(msg);
+ return 0;
+}
+
+int CServiceIpcDbus::change_voice_key_status(int pid, int status)
+{
+ if (0 != __dbus_check()) {
+ return -1; //MAS_ERROR_OPERATION_FAILED;
+ }
+
+ DBusMessage* msg;
+
+ DBusError err;
+ dbus_error_init(&err);
+
+ char service_name[64];
+ memset(service_name, '\0', 64);
+ snprintf(service_name, 64, "%s_%d", MA_CLIENT_SERVICE_NAME, pid);
+
+ msg = dbus_message_new_method_call(
+ service_name,
+ MA_CLIENT_SERVICE_OBJECT_PATH,
+ MA_CLIENT_SERVICE_INTERFACE,
+ MAS_METHOD_VOICE_KEY_STATUS_CHANGE);
+
+ if (NULL == msg) {
+ MAS_LOGE(">>>> Request mas send voice key status change message : Fail to make message");
+ return -1; // MAS_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGD(">>>> Request mas send voice key status change message : %s", service_name);
+ }
+
+ if (true != dbus_message_append_args(msg,
+ DBUS_TYPE_INT32, &status,
+ DBUS_TYPE_INVALID)) {
+ dbus_message_unref(msg);
+ MAS_LOGE("[ERROR] Fail to append args");
+ return -1;
+ }
+
+ dbus_message_set_no_reply(msg, TRUE);
+
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
+ MAS_LOGE("[Dbus ERROR] Fail to Send");
+ return -1; // MAS_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGI("[Dbus DEBUG] Success to Send voice key status change : %d %d", pid, status);
+ dbus_connection_flush(mConnectionSender);
+ }
+
+ dbus_message_unref(msg);
+ return 0;
+}
+
+int CServiceIpcDbus::masc_ui_dbus_send_hello(void)
+{
+ if (0 != __dbus_check()) {
+ return -1; //MAS_ERROR_OPERATION_FAILED;
+ }
+
+ DBusMessage* msg;
+
+ DBusError err;
+ dbus_error_init(&err);
+
+ msg = dbus_message_new_method_call(
+ MA_UI_CLIENT_SERVICE_NAME,
+ MA_UI_CLIENT_SERVICE_OBJECT_PATH,
+ MA_UI_CLIENT_SERVICE_INTERFACE,
+ MAS_METHOD_HELLO);
+
+ if (NULL == msg) {
+ MAS_LOGE("[DBus ERROR] Request masc hello : Fail to make message");
+ return -1;
+ }
+
+ DBusMessage* result_msg = NULL;
+ int result = 0;
+
+ result_msg = dbus_connection_send_with_reply_and_block(mConnectionSender, msg, 500, &err);
+
+ if (dbus_error_is_set(&err)) {
+ MAS_LOGE("[Dbus ERROR] Dbus Error (%s)", err.message);
+ dbus_error_free(&err);
+ }
+
+ dbus_message_unref(msg);
+
+ if (NULL != result_msg) {
+ dbus_message_unref(result_msg);
+ result = 0;
+ } else {
+ result = -1; //ERROR_TIMED_OUT;
+ }
+
+ return result;
+}
+
+int CServiceIpcDbus::masc_ui_dbus_send_asr_result(int pid, int event, const char* asr_result)
+{
+ if (0 != __dbus_check()) {
+ return -1; //MAS_ERROR_OPERATION_FAILED;
+ }
+
+ DBusMessage* msg;
+
+ msg = dbus_message_new_method_call(
+ MA_UI_CLIENT_SERVICE_NAME,
+ MA_UI_CLIENT_SERVICE_OBJECT_PATH,
+ MA_UI_CLIENT_SERVICE_INTERFACE,
+ MAS_UI_METHOD_SEND_ASR_RESULT);
+
+ if (NULL == msg) {
+ MAS_LOGE("@@ Request multi-assistant send ASR result : Fail to make message");
+ return -1; //MA_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGD("[DEBUG] multi-assistant send ASR result, asr_result(%p)", asr_result);
+ }
+
+ char* temp_asr_result = NULL;
+ if (!asr_result)
+ temp_asr_result = strdup("#NULL");
+ else
+ temp_asr_result = strdup(asr_result);
+
+ dbus_message_append_args(msg,
+ DBUS_TYPE_INT32, &pid,
+ DBUS_TYPE_INT32, &event,
+ DBUS_TYPE_STRING, &temp_asr_result,
+ DBUS_TYPE_INVALID);
+
+ dbus_message_set_no_reply(msg, TRUE);
+
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
+ MAS_LOGE("[Dbus ERROR] Fail to Send");
+ if (NULL != temp_asr_result) {
+ free(temp_asr_result);
+ temp_asr_result = NULL;
+ }
+ return -1; // MAS_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGD("[Dbus DEBUG] Success to Send ASR result");
+ dbus_connection_flush(mConnectionSender);
+ }
+
+ dbus_message_unref(msg);
+
+ if (temp_asr_result)
+ free(temp_asr_result);
+ return 0;
+}
+
+int CServiceIpcDbus::masc_ui_dbus_send_result(int pid, const char* display_text, const char* utterance_text, const char* result_json)
+{
+ if (0 != __dbus_check()) {
+ return -1; //MA_ERROR_OPERATION_FAILED;
+ }
+
+ DBusMessage* msg;
+
+ msg = dbus_message_new_method_call(
+ MA_UI_CLIENT_SERVICE_NAME,
+ MA_UI_CLIENT_SERVICE_OBJECT_PATH,
+ MA_UI_CLIENT_SERVICE_INTERFACE,
+ MAS_UI_METHOD_SEND_RESULT);
+
+ if (NULL == msg) {
+ MAS_LOGE("@@ Request multi-assistant send result : Fail to make message");
+ return -1; //MA_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGD("[DEBUG] multi-assistant send result");
+ }
+ char* temp_display_text = NULL;
+ char* temp_utterance_text = NULL;
+ char* temp_result_json = NULL;
+
+#if 0
+ dbus_message_append_args(msg,
+ DBUS_TYPE_INT32, &pid,
+ DBUS_TYPE_STRING, &display_text,
+ DBUS_TYPE_STRING, &utterance_text,
+ DBUS_TYPE_STRING, &result_json,
+ DBUS_TYPE_INVALID);
+
+ dbus_message_set_no_reply(msg, TRUE);
+
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
+ MAS_LOGE("[Dbus ERROR] Fail to Send");
+ return -1; //MA_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGD("[Dbus DEBUG] Success to Send result");
+ dbus_connection_flush(mConnectionSender);
+ }
+
+ dbus_message_unref(msg);
+#else
+ if (!display_text)
+ temp_display_text = strdup("#NULL");
+ else
+ temp_display_text = strdup(display_text);
+ if (!utterance_text)
+ temp_utterance_text = strdup("#NULL");
+ else
+ temp_utterance_text = strdup(utterance_text);
+ if (!result_json)
+ temp_result_json = strdup("#NULL");
+ else
+ temp_result_json = strdup(result_json);
+
+ dbus_message_append_args(msg,
+ DBUS_TYPE_INT32, &pid,
+ DBUS_TYPE_STRING, &temp_display_text,
+ DBUS_TYPE_STRING, &temp_utterance_text,
+ DBUS_TYPE_STRING, &temp_result_json,
+ DBUS_TYPE_INVALID);
+
+ dbus_message_set_no_reply(msg, TRUE);
+
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
+ MAS_LOGE("[Dbus ERROR] Fail to Send");
+ if (temp_display_text)
+ free(temp_display_text);
+ if (temp_utterance_text)
+ free(temp_utterance_text);
+ if (temp_result_json)
+ free(temp_result_json);
+ return -1; //MA_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGD("[Dbus DEBUG] Success to Send result");
+ dbus_connection_flush(mConnectionSender);
+ }
+
+ dbus_message_unref(msg);
+
+ if (temp_display_text)
+ free(temp_display_text);
+ if (temp_utterance_text)
+ free(temp_utterance_text);
+ if (temp_result_json)
+ free(temp_result_json);
+#endif
+ return 0;
+}
+
+int CServiceIpcDbus::masc_ui_dbus_change_assistant(const char* app_id)
+{
+ if (0 != __dbus_check()) {
+ return -1; //MAS_ERROR_OPERATION_FAILED;
+ }
+
+ if (NULL == app_id) {
+ MAS_LOGE("@@ Request multi-assistant send change assistant request : Fail to make message");
+ return -1; //MA_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGD("[DEBUG] multi-assistant send change assistant request app_id(%s)", app_id);
+ }
+
+ DBusMessage* msg;
+
+ msg = dbus_message_new_method_call(
+ MA_UI_CLIENT_SERVICE_NAME,
+ MA_UI_CLIENT_SERVICE_OBJECT_PATH,
+ MA_UI_CLIENT_SERVICE_INTERFACE,
+ MAS_UI_METHOD_CHANGE_ASSISTANT);
+
+ dbus_message_append_args(msg,
+ DBUS_TYPE_STRING, &app_id,
+ DBUS_TYPE_INVALID);
+
+ dbus_message_set_no_reply(msg, TRUE);
+
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
+ MAS_LOGE("[Dbus ERROR] Fail to Send");
+ return -1; // MAS_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGD("[Dbus DEBUG] Success to Send change assistant request");
+ dbus_connection_flush(mConnectionSender);
+ }
+
+ dbus_message_unref(msg);
+
+ return 0;
+}
+
+int CServiceIpcDbus::masc_ui_dbus_send_error_message(int reason, const char* err_msg)
+{
+ if (NULL == mConnectionSender) {
+ MAS_LOGE("[Dbus ERROR] Dbus connection is not available");
+ return -1;
+ }
+
+ DBusMessage* msg = NULL;
+
+ /* create a message */
+ msg = dbus_message_new_signal(
+ MA_UI_CLIENT_SERVICE_OBJECT_PATH, /* object name of the signal */
+ MA_UI_CLIENT_SERVICE_INTERFACE, /* interface name of the signal */
+ MAS_UI_METHOD_ERROR); /* name of the signal */
+
+ if (NULL == msg) {
+ MAS_LOGE("[Dbus ERROR] Fail to create error message");
+ return -1;
+ }
+
+ char* temp_err_msg = NULL;
+
+ if (err_msg)
+ temp_err_msg = strdup(err_msg);
+ else
+ temp_err_msg = strdup("#NULL");
+
+ dbus_message_append_args(msg,
+ DBUS_TYPE_INT32, &reason,
+ DBUS_TYPE_STRING, &temp_err_msg,
+ DBUS_TYPE_INVALID);
+
+ dbus_message_set_no_reply(msg, TRUE);
+
+ if (!dbus_connection_send(mConnectionSender, msg, NULL)) {
+ MAS_LOGE("[Dbus ERROR] <<<< error message : Out Of Memory !");
+ } else {
+ MAS_LOGD("<<<< Send error message : reason(%d), err_msg(%s)", reason, temp_err_msg);
+ dbus_connection_flush(mConnectionSender);
+ }
+
+ dbus_message_unref(msg);
+
+ if (temp_err_msg)
+ free(temp_err_msg);
+ return 0;
+}
+
+int CServiceIpcDbus::masc_ui_dbus_send_recognition_result(int pid, int result)
+{
+ if (0 != __dbus_check()) {
+ return -1; //MAS_ERROR_OPERATION_FAILED;
+ }
+
+ DBusMessage* msg;
+
+ msg = dbus_message_new_method_call(
+ MA_UI_CLIENT_SERVICE_NAME,
+ MA_UI_CLIENT_SERVICE_OBJECT_PATH,
+ MA_UI_CLIENT_SERVICE_INTERFACE,
+ MAS_UI_METHOD_SEND_RECOGNITION_RESULT);
+
+ if (NULL == msg) {
+ MAS_LOGE("@@ Request multi-assistant send recognition result : Fail to make message");
+ return -1; //MA_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGD("[DEBUG] multi-assistant send recognition result(%d)", result);
+ }
+
+ dbus_message_append_args(msg,
+ DBUS_TYPE_INT32, &pid,
+ DBUS_TYPE_INT32, &result,
+ DBUS_TYPE_INVALID);
+
+ dbus_message_set_no_reply(msg, TRUE);
+
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
+ MAS_LOGE("[Dbus ERROR] Fail to Send");
+ return -1; // MAS_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGD("[Dbus DEBUG] Success to Send ASR result");
+ dbus_connection_flush(mConnectionSender);
+ }
+
+ dbus_message_unref(msg);
+
+ return 0;
+}
+
+int CServiceIpcDbus::masc_ui_dbus_enable_common_ui(int enable)
+{
+ if (0 != __dbus_check()) {
+ return -1; //MAS_ERROR_OPERATION_FAILED;
+ }
+
+ DBusMessage* msg;
+
+ msg = dbus_message_new_method_call(
+ MA_UI_CLIENT_SERVICE_NAME,
+ MA_UI_CLIENT_SERVICE_OBJECT_PATH,
+ MA_UI_CLIENT_SERVICE_INTERFACE,
+ MAS_UI_METHOD_ENABLE_COMMON_UI);
+
+ if (NULL == msg) {
+ MAS_LOGE("@@ Request multi-assistant enable common ui : Fail to make message");
+ return -1; //MA_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGD("[DEBUG] multi-assistant enable common ui (%d)", enable);
+ }
+
+ dbus_message_append_args(msg,
+ DBUS_TYPE_INT32, &enable,
+ DBUS_TYPE_INVALID);
+
+ dbus_message_set_no_reply(msg, TRUE);
+
+ if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
+ MAS_LOGE("[Dbus ERROR] Fail to Send");
+ return -1; // MAS_ERROR_OPERATION_FAILED;
+ } else {
+ MAS_LOGD("[Dbus DEBUG] Success to Send ASR result");
+ dbus_connection_flush(mConnectionSender);
+ }
+
+ dbus_message_unref(msg);
+
+ return 0;
+}
+
+static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handler)
+{
+ CServiceIpcDbus* service_ipc = static_cast<CServiceIpcDbus*>(data);
+ if (NULL == service_ipc) {
+ MAS_LOGE("Error : service_ipc NULL");
+ return ECORE_CALLBACK_RENEW;
+ }
+
+ DBusConnection* mConnectionListener = service_ipc->get_connection_listener();
+ if (NULL == mConnectionListener) {
+ MAS_LOGE("Error : mConnectionListener NULL");
+ return ECORE_CALLBACK_RENEW;
+ }
+
+ CServiceIpcDbusDispatcher* dispatcher = service_ipc->get_dispatcher();
+ if (NULL == dispatcher) {
+ MAS_LOGE("Error : dispatcher NULL");
+ return ECORE_CALLBACK_RENEW;
+ }
+
+ dbus_connection_read_write_dispatch(mConnectionListener, 50);
+
+ while (1) {
+ DBusMessage* msg = NULL;
+ msg = dbus_connection_pop_message(mConnectionListener);
+
+ if (true != dbus_connection_get_is_connected(mConnectionListener)) {
+ MAS_LOGE("[ERROR] Connection is disconnected");
+ return ECORE_CALLBACK_RENEW;
+ }
+
+ /* loop again if we haven't read a message */
+ if (NULL == msg) {
+ return ECORE_CALLBACK_RENEW;
+ }
+
+ /* client event */
+ if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_HELLO)) {
+ dispatcher->on_hello(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_INITIALIZE)) {
+ dispatcher->on_initialize(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_DEINITIALIZE)) {
+ dispatcher->on_deinitialize(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_GET_RECORDING_AUDIO_FORMAT)) {
+ dispatcher->on_get_audio_format(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_GET_RECORDING_AUDIO_SOURCE_TYPE)) {
+ dispatcher->on_get_audio_source_type(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_ASR_RESULT)) {
+ dispatcher->on_send_asr_result(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_RESULT)) {
+ dispatcher->on_send_result(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_RECOGNITION_RESULT)) {
+ dispatcher->on_send_recognition_result(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_START_STREAMING_AUDIO_DATA)) {
+ dispatcher->on_start_streaming_audio_data(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_STOP_STREAMING_AUDIO_DATA)) {
+ dispatcher->on_stop_streaming_audio_data(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_UPDATE_VOICE_FEEDBACK_STATE)) {
+ dispatcher->on_update_voice_feedback_state(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_ASSISTANT_SPECIFIC_COMMAND)) {
+ dispatcher->on_send_assistant_specific_command(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SET_BACKGROUND_VOLUME)) {
+ dispatcher->on_set_background_volume(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SET_PREPROCESSING_ALLOW_MODE)) {
+ dispatcher->on_set_preprocessing_allow_mode(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_PREPROCESSING_RESULT)) {
+ dispatcher->on_send_preprocessing_result(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SET_WAKE_WORD_AUDIO_REQUIRE_FLAG)) {
+ dispatcher->on_set_wake_word_audio_require_flag(mConnectionListener, msg);
+
++ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SET_ASSISTANT_WAKEUP_LANGUAGE)) {
+ dispatcher->on_set_assistant_language(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_ADD_WAKE_WORD)) {
+ dispatcher->on_add_wake_word(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_REMOVE_WAKE_WORD)) {
+ dispatcher->on_remove_wake_word(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_UI_METHOD_INITIALIZE)) {
+ dispatcher->on_ui_initialize(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_UI_METHOD_DEINITIALIZE)) {
+ dispatcher->on_ui_deinitialize(mConnectionListener, msg);
+
+ } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_UI_METHOD_CHANGE_ASSISTANT)) {
+ dispatcher->on_ui_change_assistant(mConnectionListener, msg);
+
+ } else {
+ MAS_LOGD("Message is NOT valid");
+ /* Invalid method */
+ }
+ /* free the message */
+ dbus_message_unref(msg);
+ }
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+void CServiceIpcDbus::connection_free()
+{
+ if (NULL != mConnectionListener) {
+ dbus_connection_close(mConnectionListener);
+ dbus_connection_unref(mConnectionListener);
+ mConnectionListener = NULL;
+ }
+ if (NULL != mConnectionSender) {
+ dbus_connection_close(mConnectionSender);
+ dbus_connection_unref(mConnectionSender);
+ mConnectionSender = NULL;
+ }
+}
+
+int CServiceIpcDbus::open_connection()
+{
+ DBusError err;
+ dbus_error_init(&err);
+
+ int ret;
+
+ /* Create connection for sender */
+ mConnectionSender = dbus_bus_get_private(DBUS_BUS_SESSION, &err);
+
+ if (dbus_error_is_set(&err)) {
+ MAS_LOGE("[Dbus ERROR] Fail dbus_bus_get : %s", err.message);
+ dbus_error_free(&err);
+ }
+
+ if (NULL == mConnectionSender) {
+ MAS_LOGE("[Dbus ERROR] Fail to get dbus connection");
+ return -1;
+ }
+
+ dbus_connection_set_exit_on_disconnect(mConnectionSender, false);
+
+ /* connect to the bus and check for errors */
+ mConnectionListener = dbus_bus_get_private(DBUS_BUS_SESSION, &err);
+
+ if (dbus_error_is_set(&err)) {
+ MAS_LOGE("[Dbus ERROR] Fail dbus_bus_get : %s", err.message);
+ dbus_error_free(&err);
+ }
+
+ if (NULL == mConnectionListener) {
+ MAS_LOGE("[Dbus ERROR] Fail to get dbus connection");
+ connection_free();
+ return -1;
+ }
+
+ dbus_connection_set_exit_on_disconnect(mConnectionListener, false);
+
+ /* request our name on the bus and check for errors */
+ ret = dbus_bus_request_name(mConnectionListener, MA_SERVER_SERVICE_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
+
+ if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
+ printf("Fail to be primary owner in dbus request.");
+ MAS_LOGE("[Dbus ERROR] Fail to be primary owner");
+ connection_free();
+ return -1;
+ }
+
+ if (dbus_error_is_set(&err)) {
+ MAS_LOGE("[Dbus ERROR] dbus_bus_request_name() : %s", err.message);
+ dbus_error_free(&err);
+ connection_free();
+ return -1;
+ }
+
+ /* Flush messages which are received before fd event handler registration */
+ while (DBUS_DISPATCH_DATA_REMAINS == dbus_connection_get_dispatch_status(mConnectionListener)) {
+ listener_event_callback(this, NULL);
+ }
+
+ /* add a rule for getting signal */
+ char rule[128];
+ snprintf(rule, 128, "type='signal',interface='%s'", MA_SERVER_SERVICE_INTERFACE);
+
+ /* add a rule for which messages we want to see */
+ dbus_bus_add_match(mConnectionListener, rule, &err);/* see signals from the given interface */
+
+ if (dbus_error_is_set(&err)) {
+ MAS_LOGE("[Dbus ERROR] dbus_bus_add_match() : %s", err.message);
+ dbus_error_free(&err);
+ connection_free();
+ return -1;
+ }
+
+ int fd = 0;
+ if (1 != dbus_connection_get_unix_fd(mConnectionListener, &fd)) {
+ MAS_LOGE("fail to get fd from dbus ");
+ connection_free();
+ return -1;
+ } else {
+ MAS_LOGD("Get fd from dbus : %d", fd);
+ }
+
+ mFdHandler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)listener_event_callback, this, NULL, NULL);
+
+ if (NULL == mFdHandler) {
+ MAS_LOGE("[Dbus ERROR] Fail to get fd handler");
+ connection_free();
+ return -1;
+ }
+
+ return 0;
+}
+
+int CServiceIpcDbus::close_connection()
+{
+ DBusError err;
+ dbus_error_init(&err);
+
+ if (NULL != mFdHandler) {
+ ecore_main_fd_handler_del(mFdHandler);
+ mFdHandler = NULL;
+ }
+
+ dbus_bus_release_name(mConnectionListener, MA_SERVER_SERVICE_NAME, &err);
+
+ if (dbus_error_is_set(&err)) {
+ MAS_LOGE("[Dbus ERROR] dbus_bus_release_name() : %s", err.message);
+ dbus_error_free(&err);
+ }
+
+ connection_free();
+
+ return 0;
+}