2 * Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 * http://www.apache.org/licenses/LICENSE-2.0
7 * Unless required by applicable law or agreed to in writing, software
8 * distributed under the License is distributed on an "AS IS" BASIS,
9 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 * See the License for the specific language governing permissions and
11 * limitations under the License.
14 #include <dbus/dbus.h>
19 #include "multi_assistant_main.h"
20 #include "multi_assistant_dbus_server.h"
21 #include "multi_assistant_dbus.h"
23 static DBusConnection* g_conn_sender = NULL;
24 static DBusConnection* g_conn_listener = NULL;
26 static Ecore_Fd_Handler* g_dbus_fd_handler = NULL;
28 static int g_waiting_time = 3000;
30 int mas_dbus_reconnect()
32 if (!g_conn_sender || !g_conn_listener) {
33 mas_dbus_close_connection();
35 if (0 != mas_dbus_open_connection()) {
36 MAS_LOGE("[ERROR] Fail to reconnect");
40 MAS_LOGD("[DBUS] Reconnect");
44 bool sender_connected = dbus_connection_get_is_connected(g_conn_sender);
45 bool listener_connected = dbus_connection_get_is_connected(g_conn_listener);
46 MAS_LOGW("[DBUS] Sender(%s) Listener(%s)",
47 sender_connected ? "Connected" : "Not connected", listener_connected ? "Connected" : "Not connected");
49 if (false == sender_connected || false == listener_connected) {
50 mas_dbus_close_connection();
52 if (0 != mas_dbus_open_connection()) {
53 MAS_LOGE("[ERROR] Fail to reconnect");
57 MAS_LOGD("[DBUS] Reconnect");
63 static int __dbus_check()
65 if (NULL == g_conn_sender || NULL == g_conn_listener) {
66 MAS_LOGE("[ERROR] NULL connection");
67 return mas_dbus_reconnect();
72 int mas_check_dbus_connection()
74 if (NULL == g_conn_sender || NULL == g_conn_listener) {
75 MAS_LOGE("[ERROR] NULL connection sender(%p), listener(%p)", g_conn_sender, g_conn_listener);
81 int masc_dbus_send_hello(int pid)
83 if (0 != __dbus_check()) {
84 return -1; //MAS_ERROR_OPERATION_FAILED;
89 dbus_error_init(&err);
91 msg = dbus_message_new_method_call(
92 MA_CLIENT_SERVICE_NAME,
93 MA_CLIENT_SERVICE_OBJECT_PATH,
94 MA_CLIENT_SERVICE_INTERFACE,
98 MAS_LOGE("[DBus ERROR] Request masc hello : Fail to make message");
103 DBusMessage* result_msg = NULL;
104 result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, 500, &err);
106 if (dbus_error_is_set(&err)) {
107 MAS_LOGE("[Dbus ERROR] Dbus Error (%s)", err.message);
108 dbus_error_free(&err);
111 dbus_message_unref(msg);
113 if (NULL != result_msg) {
114 dbus_message_unref(result_msg);
117 result = -1; //MAS_ERROR_TIMED_OUT;
123 int masc_dbus_send_error_message(int reason, const char* err_msg)
125 if (0 != __dbus_check()) {
126 return -1; //MAS_ERROR_OPERATION_FAILED;
129 if (NULL == g_conn_sender) {
130 MAS_LOGE("[Dbus ERROR] Dbus connection is not available");
134 DBusMessage* msg = NULL;
136 /* create a message */
137 msg = dbus_message_new_signal(
138 MA_CLIENT_SERVICE_OBJECT_PATH, /* object name of the signal */
139 MA_CLIENT_SERVICE_INTERFACE, /* interface name of the signal */
140 MAS_METHOD_ERROR); /* name of the signal */
143 MAS_LOGE("[Dbus ERROR] Fail to create error message");
148 err_msg = strdup("#NULL");
150 dbus_message_append_args(msg,
151 DBUS_TYPE_INT32, &reason,
152 DBUS_TYPE_STRING, &err_msg,
155 dbus_message_set_no_reply(msg, TRUE);
157 if (!dbus_connection_send(g_conn_sender, msg, NULL)) {
158 MAS_LOGE("[Dbus ERROR] <<<< error message : Out Of Memory !");
160 MAS_LOGD("<<<< Send error message : reason(%d), err_msg(%s)", reason, err_msg);
161 dbus_connection_flush(g_conn_sender);
164 dbus_message_unref(msg);
171 int masc_dbus_send_speech_data(int event, unsigned char* data, unsigned int data_size)
173 if (0 != __dbus_check()) {
174 return -1; //MAS_ERROR_OPERATION_FAILED;
179 dbus_error_init(&err);
181 msg = dbus_message_new_method_call(
182 MA_CLIENT_SERVICE_NAME,
183 MA_CLIENT_SERVICE_OBJECT_PATH,
184 MA_CLIENT_SERVICE_INTERFACE,
185 MAS_METHOD_SEND_SPEECH_DATA);
188 MAS_LOGE(">>>> Request mas send speech data : Fail to make message");
189 return -1; // MAS_ERROR_OPERATION_FAILED;
191 MAS_LOGD(">>>> Request mas send speech data");
194 if (true != dbus_message_append_args(msg,
195 DBUS_TYPE_INT32, &event,
196 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
198 DBUS_TYPE_INVALID)) {
199 dbus_message_unref(msg);
200 MAS_LOGE("[ERROR] Fail to append args");
205 dbus_message_set_no_reply(msg, TRUE);
207 if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
208 MAS_LOGE("[Dbus ERROR] Fail to Send");
209 return -1; // MAS_ERROR_OPERATION_FAILED;
211 MAS_LOGD("[Dbus DEBUG] Success to Send speech data");
212 dbus_connection_flush(g_conn_sender);
215 dbus_message_unref(msg);
218 DBusMessage* result_msg;
221 result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, g_waiting_time, &err);
222 dbus_message_unref(msg);
223 if (dbus_error_is_set(&err)) {
224 MAS_LOGE("[ERROR] Send error (%s)", err.message);
225 dbus_error_free(&err);
228 if (NULL != result_msg) {
229 dbus_message_get_args(result_msg, &err,
230 DBUS_TYPE_INT32, &result,
233 if (dbus_error_is_set(&err)) {
234 MAS_LOGE("<<<< mas send speech data : Get arguments error (%s)", err.message);
235 dbus_error_free(&err);
238 dbus_message_unref(result_msg);
241 MAS_LOGD("<<<< mas send speech data : result(%d)", result);
243 MAS_LOGE("<<<< mas send speech data : result(%d)", result);
246 MAS_LOGE("<<<< Result message is NULL ");
247 mas_dbus_reconnect();
254 int masc_ui_dbus_send_hello(void)
256 if (0 != __dbus_check()) {
257 return -1; //MAS_ERROR_OPERATION_FAILED;
262 dbus_error_init(&err);
264 msg = dbus_message_new_method_call(
265 MA_UI_CLIENT_SERVICE_NAME,
266 MA_UI_CLIENT_SERVICE_OBJECT_PATH,
267 MA_UI_CLIENT_SERVICE_INTERFACE,
271 MAS_LOGE("[DBus ERROR] Request masc hello : Fail to make message");
275 DBusMessage* result_msg = NULL;
278 result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, 500, &err);
280 if (dbus_error_is_set(&err)) {
281 MAS_LOGE("[Dbus ERROR] Dbus Error (%s)", err.message);
282 dbus_error_free(&err);
285 dbus_message_unref(msg);
287 if (NULL != result_msg) {
288 dbus_message_unref(result_msg);
291 result = -1; //ERROR_TIMED_OUT;
297 int masc_ui_dbus_send_asr_result(int pid, int event, char* asr_result)
299 if (0 != __dbus_check()) {
300 return -1; //MAS_ERROR_OPERATION_FAILED;
305 msg = dbus_message_new_method_call(
306 MA_UI_CLIENT_SERVICE_NAME,
307 MA_UI_CLIENT_SERVICE_OBJECT_PATH,
308 MA_UI_CLIENT_SERVICE_INTERFACE,
309 MAS_UI_METHOD_SEND_ASR_RESULT);
312 MAS_LOGE("@@ Request multi-assistant send ASR result : Fail to make message");
313 return -1; //MA_ERROR_OPERATION_FAILED;
315 MAS_LOGD("[DEBUG] multi-assistant send ASR result, asr_result(%d)", asr_result);
318 char* temp_asr_result = NULL;
320 temp_asr_result = strdup("#NULL");
322 temp_asr_result = strdup(asr_result);
324 dbus_message_append_args(msg,
325 DBUS_TYPE_INT32, &pid,
326 DBUS_TYPE_INT32, &event,
327 DBUS_TYPE_STRING, &temp_asr_result,
330 dbus_message_set_no_reply(msg, TRUE);
332 if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
333 MAS_LOGE("[Dbus ERROR] Fail to Send");
334 if (NULL != temp_asr_result) {
335 free(temp_asr_result);
336 temp_asr_result = NULL;
338 return -1; // MAS_ERROR_OPERATION_FAILED;
340 MAS_LOGD("[Dbus DEBUG] Success to Send ASR result");
341 dbus_connection_flush(g_conn_sender);
344 dbus_message_unref(msg);
347 free(temp_asr_result);
351 int masc_ui_dbus_send_result(int pid, const char* display_text, const char* utterance_text, const char* result_json)
353 if (0 != __dbus_check()) {
354 return -1; //MA_ERROR_OPERATION_FAILED;
359 msg = dbus_message_new_method_call(
360 MA_UI_CLIENT_SERVICE_NAME,
361 MA_UI_CLIENT_SERVICE_OBJECT_PATH,
362 MA_UI_CLIENT_SERVICE_INTERFACE,
363 MAS_UI_METHOD_SEND_RESULT);
366 MAS_LOGE("@@ Request multi-assistant send result : Fail to make message");
367 return -1; //MA_ERROR_OPERATION_FAILED;
369 MAS_LOGD("[DEBUG] multi-assistant send result");
371 char* temp_display_text = NULL;
372 char* temp_utterance_text = NULL;
373 char* temp_result_json = NULL;
376 dbus_message_append_args(msg,
377 DBUS_TYPE_INT32, &pid,
378 DBUS_TYPE_STRING, &display_text,
379 DBUS_TYPE_STRING, &utterance_text,
380 DBUS_TYPE_STRING, &result_json,
383 dbus_message_set_no_reply(msg, TRUE);
385 if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
386 MAS_LOGE("[Dbus ERROR] Fail to Send");
387 return -1; //MA_ERROR_OPERATION_FAILED;
389 MAS_LOGD("[Dbus DEBUG] Success to Send result");
390 dbus_connection_flush(g_conn_sender);
393 dbus_message_unref(msg);
396 temp_display_text = strdup("#NULL");
398 temp_display_text = strdup(display_text);
400 temp_utterance_text = strdup("#NULL");
402 temp_utterance_text = strdup(utterance_text);
404 temp_result_json = strdup("#NULL");
406 temp_result_json = strdup(result_json);
408 dbus_message_append_args(msg,
409 DBUS_TYPE_INT32, &pid,
410 DBUS_TYPE_STRING, &temp_display_text,
411 DBUS_TYPE_STRING, &temp_utterance_text,
412 DBUS_TYPE_STRING, &temp_result_json,
415 dbus_message_set_no_reply(msg, TRUE);
417 if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
418 MAS_LOGE("[Dbus ERROR] Fail to Send");
419 if (temp_display_text)
420 free(temp_display_text);
421 if (temp_utterance_text)
422 free(temp_utterance_text);
423 if (temp_result_json)
424 free(temp_result_json);
425 return -1; //MA_ERROR_OPERATION_FAILED;
427 MAS_LOGD("[Dbus DEBUG] Success to Send result");
428 dbus_connection_flush(g_conn_sender);
431 dbus_message_unref(msg);
433 if (temp_display_text)
434 free(temp_display_text);
435 if (temp_utterance_text)
436 free(temp_utterance_text);
437 if (temp_result_json)
438 free(temp_result_json);
443 int masc_ui_dbus_send_error_message(int reason, const char* err_msg)
445 if (NULL == g_conn_sender) {
446 MAS_LOGE("[Dbus ERROR] Dbus connection is not available");
450 DBusMessage* msg = NULL;
452 /* create a message */
453 msg = dbus_message_new_signal(
454 MA_UI_CLIENT_SERVICE_OBJECT_PATH, /* object name of the signal */
455 MA_UI_CLIENT_SERVICE_INTERFACE, /* interface name of the signal */
456 MAS_UI_METHOD_ERROR); /* name of the signal */
459 MAS_LOGE("[Dbus ERROR] Fail to create error message");
464 err_msg = strdup("#NULL");
466 dbus_message_append_args(msg,
467 DBUS_TYPE_INT32, &reason,
468 DBUS_TYPE_STRING, &err_msg,
471 dbus_message_set_no_reply(msg, TRUE);
473 if (!dbus_connection_send(g_conn_sender, msg, NULL)) {
474 MAS_LOGE("[Dbus ERROR] <<<< error message : Out Of Memory !");
476 MAS_LOGD("<<<< Send error message : reason(%d), err_msg(%s)", reason, err_msg);
477 dbus_connection_flush(g_conn_sender);
480 dbus_message_unref(msg);
487 static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handler)
489 if (NULL == g_conn_listener) return ECORE_CALLBACK_RENEW;
491 dbus_connection_read_write_dispatch(g_conn_listener, 50);
494 DBusMessage* msg = NULL;
495 msg = dbus_connection_pop_message(g_conn_listener);
497 if (true != dbus_connection_get_is_connected(g_conn_listener)) {
498 MAS_LOGE("[ERROR] Connection is disconnected");
499 return ECORE_CALLBACK_RENEW;
502 /* loop again if we haven't read a message */
504 return ECORE_CALLBACK_RENEW;
508 if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_HELLO)) {
509 ma_service_dbus_hello(g_conn_listener, msg);
511 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_INITIALIZE)) {
512 ma_service_dbus_initialize(g_conn_listener, msg);
514 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_DEINITIALIZE)) {
515 ma_service_dbus_deinitialize(g_conn_listener, msg);
517 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_GET_RECORDING_AUDIO_FORMAT)) {
518 ma_service_dbus_get_audio_format(g_conn_listener, msg);
520 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_ASR_RESULT)) {
521 ma_service_dbus_send_asr_result(g_conn_listener, msg);
523 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_RESULT)) {
524 ma_service_dbus_send_result(g_conn_listener, msg);
526 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_UI_METHOD_INITIALIZE)) {
527 ma_service_ui_dbus_initialize(g_conn_listener, msg);
529 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_UI_METHOD_DEINITIALIZE)) {
530 ma_service_ui_dbus_deinitialize(g_conn_listener, msg);
532 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_UI_METHOD_CHANGE_ASSISTANT)) {
533 ma_service_ui_dbus_change_assistant(g_conn_listener, msg);
536 MAS_LOGD("Message is NOT valid");
539 /* free the message */
540 dbus_message_unref(msg);
543 return ECORE_CALLBACK_RENEW;
546 static void __mas_dbus_connection_free()
548 if (NULL != g_conn_listener) {
549 dbus_connection_close(g_conn_listener);
550 dbus_connection_unref(g_conn_listener);
551 g_conn_listener = NULL;
553 if (NULL != g_conn_sender) {
554 dbus_connection_close(g_conn_sender);
555 dbus_connection_unref(g_conn_sender);
556 g_conn_sender = NULL;
560 int mas_dbus_open_connection()
563 dbus_error_init(&err);
567 /* Create connection for sender */
568 g_conn_sender = dbus_bus_get_private(DBUS_BUS_SESSION, &err);
570 if (dbus_error_is_set(&err)) {
571 MAS_LOGE("[Dbus ERROR] Fail dbus_bus_get : %s", err.message);
572 dbus_error_free(&err);
575 if (NULL == g_conn_sender) {
576 MAS_LOGE("[Dbus ERROR] Fail to get dbus connection");
580 dbus_connection_set_exit_on_disconnect(g_conn_sender, false);
582 /* connect to the bus and check for errors */
583 g_conn_listener = dbus_bus_get_private(DBUS_BUS_SESSION, &err);
585 if (dbus_error_is_set(&err)) {
586 MAS_LOGE("[Dbus ERROR] Fail dbus_bus_get : %s", err.message);
587 dbus_error_free(&err);
590 if (NULL == g_conn_listener) {
591 MAS_LOGE("[Dbus ERROR] Fail to get dbus connection");
592 __mas_dbus_connection_free();
596 dbus_connection_set_exit_on_disconnect(g_conn_listener, false);
598 /* request our name on the bus and check for errors */
599 ret = dbus_bus_request_name(g_conn_listener, MA_SERVER_SERVICE_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
601 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
602 printf("Fail to be primary owner in dbus request.");
603 MAS_LOGE("[Dbus ERROR] Fail to be primary owner");
604 __mas_dbus_connection_free();
608 if (dbus_error_is_set(&err)) {
609 MAS_LOGE("[Dbus ERROR] dbus_bus_request_name() : %s", err.message);
610 dbus_error_free(&err);
611 __mas_dbus_connection_free();
615 /* Flush messages which are received before fd event handler registration */
616 while (DBUS_DISPATCH_DATA_REMAINS == dbus_connection_get_dispatch_status(g_conn_listener)) {
617 listener_event_callback(NULL, NULL);
620 /* add a rule for getting signal */
622 snprintf(rule, 128, "type='signal',interface='%s'", MA_SERVER_SERVICE_INTERFACE);
624 /* add a rule for which messages we want to see */
625 dbus_bus_add_match(g_conn_listener, rule, &err);/* see signals from the given interface */
627 if (dbus_error_is_set(&err)) {
628 MAS_LOGE("[Dbus ERROR] dbus_bus_add_match() : %s", err.message);
629 dbus_error_free(&err);
630 __mas_dbus_connection_free();
635 if (1 != dbus_connection_get_unix_fd(g_conn_listener, &fd)) {
636 MAS_LOGE("fail to get fd from dbus ");
637 __mas_dbus_connection_free();
640 MAS_LOGD("Get fd from dbus : %d", fd);
644 g_dbus_fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)listener_event_callback, g_conn_listener, NULL, NULL);
646 if (NULL == g_dbus_fd_handler) {
647 MAS_LOGE("[Dbus ERROR] Fail to get fd handler");
648 __mas_dbus_connection_free();
655 int mas_dbus_close_connection()
658 dbus_error_init(&err);
660 if (NULL != g_dbus_fd_handler) {
661 ecore_main_fd_handler_del(g_dbus_fd_handler);
662 g_dbus_fd_handler = NULL;
665 dbus_bus_release_name(g_conn_listener, MA_SERVER_SERVICE_NAME, &err);
667 if (dbus_error_is_set(&err)) {
668 MAS_LOGE("[Dbus ERROR] dbus_bus_release_name() : %s", err.message);
669 dbus_error_free(&err);
672 __mas_dbus_connection_free();