Use trusted message port for secure audio transmission
[platform/core/uifw/multi-assistant-service.git] / src / service_ipc_dbus.cpp
1 /*
2  * Copyright 2020 Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #include <dirent.h>
19 #include <dlfcn.h>
20 #include <message_port.h>
21
22 #include "service_common.h"
23 #include "service_main.h"
24 #include "service_ipc_dbus.h"
25
26 int CServiceIpcDbus::reconnect()
27 {
28         if (!mConnectionSender || !mConnectionListener) {
29                 close_connection();
30
31                 if (0 != open_connection()) {
32                         MAS_LOGE("[ERROR] Fail to reconnect");
33                         return -1;
34                 }
35
36                 MAS_LOGD("[DBUS] Reconnect");
37                 return 0;
38         }
39
40         bool sender_connected = dbus_connection_get_is_connected(mConnectionSender);
41         bool listener_connected = dbus_connection_get_is_connected(mConnectionListener);
42         MAS_LOGW("[DBUS] Sender(%s) Listener(%s)",
43                 sender_connected ? "Connected" : "Not connected", listener_connected ? "Connected" : "Not connected");
44
45         if (false == sender_connected || false == listener_connected) {
46                 close_connection();
47
48                 if (0 != open_connection()) {
49                         MAS_LOGE("[ERROR] Fail to reconnect");
50                         return -1;
51                 }
52
53                 MAS_LOGD("[DBUS] Reconnect");
54         }
55
56         return 0;
57 }
58
59 int CServiceIpcDbus::__dbus_check()
60 {
61         if (NULL == mConnectionSender || NULL == mConnectionListener) {
62                 MAS_LOGE("[ERROR] NULL connection");
63                 return reconnect();
64         }
65         return 0;
66 }
67
68 int CServiceIpcDbus::mas_check_dbus_connection()
69 {
70         if (NULL == mConnectionSender || NULL == mConnectionListener) {
71                 MAS_LOGE("[ERROR] NULL connection sender(%p), listener(%p)", mConnectionSender, mConnectionListener);
72                 return -1;
73         }
74         return 0;
75 }
76
77 int CServiceIpcDbus::send_hello(pid_t pid)
78 {
79         if (0 != __dbus_check()) {
80                 return -1; //MAS_ERROR_OPERATION_FAILED;
81         }
82
83         DBusMessage* msg;
84         DBusError err;
85         dbus_error_init(&err);
86
87         msg = dbus_message_new_method_call(
88                         MA_CLIENT_SERVICE_NAME,
89                         MA_CLIENT_SERVICE_OBJECT_PATH,
90                         MA_CLIENT_SERVICE_INTERFACE,
91                         MAS_METHOD_HELLO);
92
93         if (NULL == msg) {
94                 MAS_LOGE("[DBus ERROR] Request masc hello : Fail to make message");
95                 return -1;
96         }
97
98         int result = -1;
99         DBusMessage* result_msg = NULL;
100         result_msg = dbus_connection_send_with_reply_and_block(mConnectionSender, msg, 500, &err);
101
102         if (dbus_error_is_set(&err)) {
103                 MAS_LOGE("[Dbus ERROR] Dbus Error (%s)", err.message);
104                 dbus_error_free(&err);
105         }
106
107         dbus_message_unref(msg);
108
109         if (NULL != result_msg) {
110                 dbus_message_unref(result_msg);
111                 result = 0;
112         } else {
113                 result = -1; //MAS_ERROR_TIMED_OUT;
114         }
115
116         return result;
117 }
118
119 int CServiceIpcDbus::send_error_message(int reason, const char* err_msg)
120 {
121         if (0 != __dbus_check()) {
122                 return -1; //MAS_ERROR_OPERATION_FAILED;
123         }
124
125         if (NULL == mConnectionSender) {
126                 MAS_LOGE("[Dbus ERROR] Dbus connection is not available");
127                 return -1;
128         }
129
130         DBusMessage* msg = NULL;
131
132         /* create a message */
133         msg = dbus_message_new_signal(
134                 MA_CLIENT_SERVICE_OBJECT_PATH,  /* object name of the signal */
135                 MA_CLIENT_SERVICE_INTERFACE,    /* interface name of the signal */
136                 MAS_METHOD_ERROR);              /* name of the signal */
137
138         if (NULL == msg) {
139                 MAS_LOGE("[Dbus ERROR] Fail to create error message");
140                 return -1;
141         }
142
143         char* temp_err_msg = NULL;
144
145         if (err_msg)
146                 temp_err_msg = strdup(err_msg);
147         else
148                 temp_err_msg = strdup("#NULL");
149
150         dbus_message_append_args(msg,
151                 DBUS_TYPE_INT32, &reason,
152                 DBUS_TYPE_STRING, &temp_err_msg,
153                 DBUS_TYPE_INVALID);
154
155         dbus_message_set_no_reply(msg, TRUE);
156
157         if (!dbus_connection_send(mConnectionSender, msg, NULL)) {
158                 MAS_LOGE("[Dbus ERROR] <<<< error message : Out Of Memory !");
159         } else {
160                 MAS_LOGI("<<<< Send error message : reason(%d), err_msg(%s)", reason, temp_err_msg);
161                 dbus_connection_flush(mConnectionSender);
162         }
163
164         dbus_message_unref(msg);
165
166         if (temp_err_msg)
167                 free(temp_err_msg);
168         return 0;
169 }
170
171 const char *message_port = "ma_streaming_port";
172
173 #define STREAMING_BUFFER_SIZE 4096
174
175 typedef enum {
176         streaming_data_type_audio_data,
177         streaming_data_type_streaming_section
178 } streaming_data_type_e;
179
180 typedef struct {
181         unsigned int streaming_data_size;
182         int streaming_data_type;
183         int streaming_data_serial;
184 } streaming_data_header;
185
186 typedef struct {
187         int event;
188         unsigned int data_size;
189 } streaming_data_audio_data_header;
190
191 typedef struct {
192         int section;
193 } streaming_data_streaming_section_header;
194
195 static void masc_message_port_error(int error)
196 {
197         MAS_LOGE("message_port error found : %s",
198                 (MESSAGE_PORT_ERROR_NONE == error) ? "MESSAGE_PORT_ERROR_NONE" :
199                 (MESSAGE_PORT_ERROR_IO_ERROR == error) ? "MESSAGE_PORT_ERROR_IO_ERROR" :
200                 (MESSAGE_PORT_ERROR_OUT_OF_MEMORY == error) ? "MESSAGE_PORT_ERROR_OUT_OF_MEMORY" :
201                 (MESSAGE_PORT_ERROR_INVALID_PARAMETER == error) ? "MESSAGE_PORT_ERROR_INVALID_PARAMETER" :
202                 (MESSAGE_PORT_ERROR_PORT_NOT_FOUND == error) ? "MESSAGE_PORT_ERROR_PORT_NOT_FOUND" :
203                 (MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH == error) ? "MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH" :
204                 (MESSAGE_PORT_ERROR_MAX_EXCEEDED == error) ? "MESSAGE_PORT_ERROR_MAX_EXCEEDED" :
205                 (MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE == error) ? "MESSAGE_PORT_ERROR_RESOURCE_UNAVAILABLE" :
206                 "MESSAGE_PORT_ERROR_UNKNOWN");
207 }
208
209 int CServiceIpcDbus::send_streaming_audio_data(pid_t pid, int event, void* data, unsigned int data_size)
210 {
211         if (nullptr == mClientManager) {
212                 MAS_LOGE("mClientManager variable is NULL");
213                 return -1;
214         }
215
216         static unsigned char pending_buffer[STREAMING_BUFFER_SIZE];
217         static unsigned int pending_buffer_size = 0;
218
219         streaming_data_header header;
220         header.streaming_data_type = 0;
221         header.streaming_data_size = sizeof(streaming_data_header) + sizeof(streaming_data_audio_data_header) + data_size;
222         header.streaming_data_serial = mStreamingDataSerial++;
223
224         streaming_data_audio_data_header audio_data_header;
225         audio_data_header.event = event;
226         audio_data_header.data_size = data_size;
227
228         unsigned char buffer[STREAMING_BUFFER_SIZE];
229         size_t total_size = 0;
230         memcpy(buffer, &header, sizeof(header));
231         total_size += sizeof(header);
232         memcpy(buffer + total_size, &audio_data_header, sizeof(audio_data_header));
233         total_size += sizeof(audio_data_header);
234         memcpy(buffer + total_size, data, data_size);
235         total_size += data_size;
236
237         static int last_serial_waiting_for_flush = -1;
238         if (0 == header.streaming_data_serial % 50) {
239                 last_serial_waiting_for_flush = header.streaming_data_serial;
240                 MAS_LOGI("queueing streaming data, serial : %d", last_serial_waiting_for_flush);
241         }
242         if (pending_buffer_size + total_size > STREAMING_BUFFER_SIZE ||
243                 MAS_SPEECH_STREAMING_EVENT_FINISH == event) {
244                 bundle *b = bundle_create();
245                 if (b) {
246                         bundle_add_byte(b, "content", pending_buffer, pending_buffer_size);
247                         boost::optional<std::string> appid = mApplicationManager->get_appid_by_pid(pid);
248                         if (appid) {
249 #if USE_TRUSTED_MESSAGE_PORT
250                                 int ret = message_port_send_trusted_message((*appid).c_str(), message_port, b);
251 #else
252                                 int ret = message_port_send_message((*appid).c_str(), message_port, b);
253 #endif
254                                 if (MESSAGE_PORT_ERROR_NONE != ret)
255                                         masc_message_port_error(ret);
256                         } else {
257                                 MAS_LOGE("AppID for PID %d not found!!!", pid);
258                         }
259
260                         pending_buffer_size = 0;
261                         bundle_free(b);
262                 } else {
263                         MAS_LOGE("Bundle creation failed!!!");
264                 }
265
266                 if (-1 != last_serial_waiting_for_flush) {
267                         MAS_LOGI("flushing streaming data, serial : %d", last_serial_waiting_for_flush);
268                         last_serial_waiting_for_flush =  -1;
269                 }
270         }
271
272         if (MAS_SPEECH_STREAMING_EVENT_FINISH == event) {
273                 bundle *b = bundle_create();
274                 if (b) {
275                         bundle_add_byte(b, "content", buffer, total_size);
276                         boost::optional<std::string> appid = mApplicationManager->get_appid_by_pid(pid);
277                         if (appid) {
278 #if USE_TRUSTED_MESSAGE_PORT
279                                 int ret = message_port_send_trusted_message((*appid).c_str(), message_port, b);
280 #else
281                                 int ret = message_port_send_message((*appid).c_str(), message_port, b);
282 #endif
283                                 if (MESSAGE_PORT_ERROR_NONE != ret)
284                                         masc_message_port_error(ret);
285                         } else {
286                                 MAS_LOGE("AppID for PID %d not found!!!", pid);
287                         }
288
289                         bundle_free(b);
290                 } else {
291                         MAS_LOGE("Bundle creation failed!!!");
292                 }
293         } else {
294                 memcpy(pending_buffer + pending_buffer_size, buffer, total_size);
295                 pending_buffer_size += total_size;
296         }
297         return 0;
298 }
299
300 int CServiceIpcDbus::change_active_state(pid_t pid, int state)
301 {
302         if (0 != __dbus_check()) {
303                 return -1; //MAS_ERROR_OPERATION_FAILED;
304         }
305
306         DBusMessage* msg;
307
308         DBusError err;
309         dbus_error_init(&err);
310
311         char service_name[64];
312         memset(service_name, '\0', 64);
313         snprintf(service_name, 64, "%s_%d", MA_CLIENT_SERVICE_NAME, pid);
314
315         msg = dbus_message_new_method_call(
316                         service_name,
317                         MA_CLIENT_SERVICE_OBJECT_PATH,
318                         MA_CLIENT_SERVICE_INTERFACE,
319                         MAS_METHOD_ACTIVE_STATE_CHANGE);
320
321         if (NULL == msg) {
322                 MAS_LOGE(">>>> Request mas send activate message : Fail to make message");
323                 return -1; // MAS_ERROR_OPERATION_FAILED;
324         } else {
325                 MAS_LOGD(">>>> Request mas send activate message : %s", service_name);
326         }
327
328         if (true != dbus_message_append_args(msg,
329                 DBUS_TYPE_INT32, &state,
330                 DBUS_TYPE_INVALID)) {
331                 dbus_message_unref(msg);
332                 MAS_LOGE("[ERROR] Fail to append args");
333                 return -1;
334         }
335
336         dbus_message_set_no_reply(msg, TRUE);
337
338         if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
339                 MAS_LOGE("[Dbus ERROR] Fail to Send");
340                 return -1; // MAS_ERROR_OPERATION_FAILED;
341         } else {
342                 MAS_LOGI("[Dbus DEBUG] Success to Send activate message : %d %d", pid, state);
343                 dbus_connection_flush(mConnectionSender);
344         }
345
346         dbus_message_unref(msg);
347         return 0;
348 }
349
350 int CServiceIpcDbus::send_preprocessing_information(pid_t pid, const char* app_id)
351 {
352         if (0 != __dbus_check()) {
353                 return -1; //MAS_ERROR_OPERATION_FAILED;
354         }
355
356         DBusMessage* msg;
357
358         DBusError err;
359         dbus_error_init(&err);
360
361         char service_name[64];
362         memset(service_name, '\0', 64);
363         snprintf(service_name, 64, "%s_%d", MA_CLIENT_SERVICE_NAME, pid);
364
365         msg = dbus_message_new_method_call(
366                         service_name,
367                         MA_CLIENT_SERVICE_OBJECT_PATH,
368                         MA_CLIENT_SERVICE_INTERFACE,
369                         MAS_METHOD_SEND_PREPROCESSING_INFORMATION);
370
371         if (NULL == msg) {
372                 MAS_LOGE(">>>> Request mas send preprocessing assistant information : Fail to make message");
373                 return -1; // MAS_ERROR_OPERATION_FAILED;
374         } else {
375                 MAS_LOGD(">>>> Request mas send preprocessing assistant information : %s", service_name);
376         }
377
378         char* temp_app_id = NULL;
379         if (!app_id)
380                 temp_app_id = strdup("#NULL");
381         else
382                 temp_app_id = strdup(app_id);
383
384         if (true != dbus_message_append_args(msg,
385                 DBUS_TYPE_STRING, &temp_app_id,
386                 DBUS_TYPE_INVALID)) {
387                 dbus_message_unref(msg);
388                 MAS_LOGE("[ERROR] Fail to append args");
389                 if (temp_app_id)
390                         free(temp_app_id);
391                 return -1;
392         }
393
394         dbus_message_set_no_reply(msg, TRUE);
395
396         if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
397                 MAS_LOGE("[Dbus ERROR] Fail to Send");
398                 if (temp_app_id)
399                         free(temp_app_id);
400                 return -1; // MAS_ERROR_OPERATION_FAILED;
401         } else {
402                 MAS_LOGI("[Dbus DEBUG] Success to Send preprocessing assistant information : %d %s", pid, app_id);
403                 dbus_connection_flush(mConnectionSender);
404         }
405
406         dbus_message_unref(msg);
407
408         if (temp_app_id)
409                 free(temp_app_id);
410
411         return 0;
412 }
413
414 int CServiceIpcDbus::send_streaming_section_changed(pid_t pid, int section)
415 {
416         if (nullptr == mClientManager) {
417                 MAS_LOGE("mClientManager variable is NULL");
418                 return -1;
419         }
420
421         bundle *b = bundle_create();
422
423         streaming_data_header header;
424         header.streaming_data_type = 1;
425         header.streaming_data_size = sizeof(streaming_data_header) + sizeof(streaming_data_streaming_section_header);
426         header.streaming_data_serial = mStreamingDataSerial++;
427
428         streaming_data_streaming_section_header streaming_section_header;
429         streaming_section_header.section = section;
430
431         unsigned char buffer[STREAMING_BUFFER_SIZE];
432         size_t total_size = 0;
433         memcpy(buffer, &header, sizeof(header));
434         total_size += sizeof(header);
435         memcpy(buffer + total_size, &streaming_section_header, sizeof(streaming_section_header));
436         total_size += sizeof(streaming_section_header);
437
438         bundle_add_byte(b, "content", buffer, total_size);
439 #if USE_TRUSTED_MESSAGE_PORT
440         int ret = message_port_send_trusted_message(
441                 mClientManager->find_client_appid_by_pid(pid).c_str(), message_port, b);
442 #else
443         int ret = message_port_send_message(
444                 mClientManager->find_client_appid_by_pid(pid).c_str(), message_port, b);
445 #endif
446         if (MESSAGE_PORT_ERROR_NONE != ret)
447                 masc_message_port_error(ret);
448
449         bundle_free(b);
450
451         return 0;
452 }
453
454 int CServiceIpcDbus::send_preprocessing_result(pid_t pid, bool result)
455 {
456         if (0 != __dbus_check()) {
457                 return -1; //MAS_ERROR_OPERATION_FAILED;
458         }
459
460         DBusMessage* msg;
461
462         DBusError err;
463         dbus_error_init(&err);
464
465         char service_name[64];
466         memset(service_name, '\0', 64);
467         snprintf(service_name, 64, "%s_%d", MA_CLIENT_SERVICE_NAME, pid);
468
469         msg = dbus_message_new_method_call(
470                         service_name,
471                         MA_CLIENT_SERVICE_OBJECT_PATH,
472                         MA_CLIENT_SERVICE_INTERFACE,
473                         MAS_METHOD_SEND_PREPROCESSING_RESULT);
474
475         if (NULL == msg) {
476                 MAS_LOGE(">>>> Request mas send preprocessing result : Fail to make message");
477                 return -1; // MAS_ERROR_OPERATION_FAILED;
478         } else {
479                 MAS_LOGD(">>>> Request mas send preprocessing result : %s", service_name);
480         }
481
482         int temp_result = result;
483
484         if (true != dbus_message_append_args(msg,
485                 DBUS_TYPE_INT32, &temp_result,
486                 DBUS_TYPE_INVALID)) {
487                 dbus_message_unref(msg);
488                 MAS_LOGE("[ERROR] Fail to append args");
489                 return -1;
490         }
491
492         dbus_message_set_no_reply(msg, TRUE);
493
494         if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
495                 MAS_LOGE("[Dbus ERROR] Fail to Send");
496                 return -1; // MAS_ERROR_OPERATION_FAILED;
497         } else {
498                 MAS_LOGI("[Dbus DEBUG] Success to Send preprocessing result : %d %d", pid, temp_result);
499                 dbus_connection_flush(mConnectionSender);
500         }
501
502         dbus_message_unref(msg);
503
504         return 0;
505 }
506
507 int CServiceIpcDbus::send_wakeup_engine_command(pid_t pid, const char* command)
508 {
509         if (0 != __dbus_check()) {
510                 return -1; //MAS_ERROR_OPERATION_FAILED;
511         }
512
513         DBusMessage* msg;
514
515         DBusError err;
516         dbus_error_init(&err);
517
518         char service_name[64];
519         memset(service_name, '\0', 64);
520         snprintf(service_name, 64, "%s_%d", MA_CLIENT_SERVICE_NAME, pid);
521
522         msg = dbus_message_new_method_call(
523                         service_name,
524                         MA_CLIENT_SERVICE_OBJECT_PATH,
525                         MA_CLIENT_SERVICE_INTERFACE,
526                         MAS_METHOD_SEND_WAKEUP_ENGINE_COMMAND);
527
528         if (NULL == msg) {
529                 MAS_LOGE(">>>> Request mas send wakeup engine command : Fail to make message");
530                 return -1; // MAS_ERROR_OPERATION_FAILED;
531         } else {
532                 MAS_LOGD(">>>> Request mas send wakeup engine command : %s", service_name);
533         }
534
535         char* temp_command = NULL;
536         if (!command)
537                 temp_command = strdup("#NULL");
538         else
539                 temp_command = strdup(command);
540
541         if (true != dbus_message_append_args(msg,
542                 DBUS_TYPE_STRING, &temp_command,
543                 DBUS_TYPE_INVALID)) {
544                 dbus_message_unref(msg);
545                 MAS_LOGE("[ERROR] Fail to append args");
546                 if (temp_command)
547                         free(temp_command);
548                 return -1;
549         }
550
551         dbus_message_set_no_reply(msg, TRUE);
552
553         if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
554                 MAS_LOGE("[Dbus ERROR] Fail to Send");
555                 if (temp_command)
556                         free(temp_command);
557                 return -1; // MAS_ERROR_OPERATION_FAILED;
558         } else {
559                 MAS_LOGI("[Dbus DEBUG] Success to Send wakeup_engine_command : %d %s", pid, command);
560                 dbus_connection_flush(mConnectionSender);
561         }
562
563         dbus_message_unref(msg);
564
565         if (temp_command)
566                 free(temp_command);
567
568         return 0;
569 }
570
571 int CServiceIpcDbus::change_service_state(pid_t pid, int state)
572 {
573         if (0 != __dbus_check()) {
574                 return -1; //MAS_ERROR_OPERATION_FAILED;
575         }
576
577         DBusMessage* msg;
578
579         DBusError err;
580         dbus_error_init(&err);
581
582         char service_name[64];
583         memset(service_name, '\0', 64);
584         snprintf(service_name, 64, "%s_%d", MA_CLIENT_SERVICE_NAME, pid);
585
586         msg = dbus_message_new_method_call(
587                         service_name,
588                         MA_CLIENT_SERVICE_OBJECT_PATH,
589                         MA_CLIENT_SERVICE_INTERFACE,
590                         MAS_METHOD_SERVICE_STATE_CHANGE);
591
592         if (NULL == msg) {
593                 MAS_LOGE(">>>> Request mas send service state message : Fail to make message");
594                 return -1; // MAS_ERROR_OPERATION_FAILED;
595         } else {
596                 MAS_LOGD(">>>> Request mas send service state message : %s", service_name);
597         }
598
599         if (true != dbus_message_append_args(msg,
600                 DBUS_TYPE_INT32, &state,
601                 DBUS_TYPE_INVALID)) {
602                 dbus_message_unref(msg);
603                 MAS_LOGE("[ERROR] Fail to append args");
604                 return -1;
605         }
606
607         dbus_message_set_no_reply(msg, TRUE);
608
609         if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
610                 MAS_LOGE("[Dbus ERROR] Fail to Send");
611                 return -1; // MAS_ERROR_OPERATION_FAILED;
612         } else {
613                 MAS_LOGI("[Dbus DEBUG] Success to Send service state message : %d %d", pid, state);
614                 dbus_connection_flush(mConnectionSender);
615         }
616
617         dbus_message_unref(msg);
618         return 0;
619 }
620
621 int CServiceIpcDbus::change_voice_key_status(pid_t pid, int status)
622 {
623         if (0 != __dbus_check()) {
624                 return -1; //MAS_ERROR_OPERATION_FAILED;
625         }
626
627         DBusMessage* msg;
628
629         DBusError err;
630         dbus_error_init(&err);
631
632         char service_name[64];
633         memset(service_name, '\0', 64);
634         snprintf(service_name, 64, "%s_%d", MA_CLIENT_SERVICE_NAME, pid);
635
636         msg = dbus_message_new_method_call(
637                         service_name,
638                         MA_CLIENT_SERVICE_OBJECT_PATH,
639                         MA_CLIENT_SERVICE_INTERFACE,
640                         MAS_METHOD_VOICE_KEY_STATUS_CHANGE);
641
642         if (NULL == msg) {
643                 MAS_LOGE(">>>> Request mas send voice key status change message : Fail to make message");
644                 return -1; // MAS_ERROR_OPERATION_FAILED;
645         } else {
646                 MAS_LOGD(">>>> Request mas send voice key status change message : %s", service_name);
647         }
648
649         if (true != dbus_message_append_args(msg,
650                 DBUS_TYPE_INT32, &status,
651                 DBUS_TYPE_INVALID)) {
652                 dbus_message_unref(msg);
653                 MAS_LOGE("[ERROR] Fail to append args");
654                 return -1;
655         }
656
657         dbus_message_set_no_reply(msg, TRUE);
658
659         if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
660                 MAS_LOGE("[Dbus ERROR] Fail to Send");
661                 return -1; // MAS_ERROR_OPERATION_FAILED;
662         } else {
663                 MAS_LOGI("[Dbus DEBUG] Success to Send voice key status change : %d %d", pid, status);
664                 dbus_connection_flush(mConnectionSender);
665         }
666
667         dbus_message_unref(msg);
668         return 0;
669 }
670
671 int CServiceIpcDbus::masc_ui_dbus_send_hello(void)
672 {
673         if (0 != __dbus_check()) {
674                 return -1; //MAS_ERROR_OPERATION_FAILED;
675         }
676
677         DBusMessage* msg;
678
679         DBusError err;
680         dbus_error_init(&err);
681
682         msg = dbus_message_new_method_call(
683                         MA_UI_CLIENT_SERVICE_NAME,
684                         MA_UI_CLIENT_SERVICE_OBJECT_PATH,
685                         MA_UI_CLIENT_SERVICE_INTERFACE,
686                         MAS_METHOD_HELLO);
687
688         if (NULL == msg) {
689                 MAS_LOGE("[DBus ERROR] Request masc hello : Fail to make message");
690                 return -1;
691         }
692
693         DBusMessage* result_msg = NULL;
694         int result = 0;
695
696         result_msg = dbus_connection_send_with_reply_and_block(mConnectionSender, msg, 500, &err);
697
698         if (dbus_error_is_set(&err)) {
699                 MAS_LOGE("[Dbus ERROR] Dbus Error (%s)", err.message);
700                 dbus_error_free(&err);
701         }
702
703         dbus_message_unref(msg);
704
705         if (NULL != result_msg) {
706                 dbus_message_unref(result_msg);
707                 result = 0;
708         } else {
709                 result = -1; //ERROR_TIMED_OUT;
710         }
711
712         return result;
713 }
714
715 int CServiceIpcDbus::masc_ui_dbus_send_asr_result(pid_t pid, int event, const char* asr_result)
716 {
717         if (0 != __dbus_check()) {
718                 return -1; //MAS_ERROR_OPERATION_FAILED;
719         }
720
721         DBusMessage* msg;
722
723         msg = dbus_message_new_method_call(
724                         MA_UI_CLIENT_SERVICE_NAME,
725                         MA_UI_CLIENT_SERVICE_OBJECT_PATH,
726                         MA_UI_CLIENT_SERVICE_INTERFACE,
727                         MAS_UI_METHOD_SEND_ASR_RESULT);
728
729         if (NULL == msg) {
730                 MAS_LOGE("@@ Request multi-assistant send ASR result : Fail to make message");
731                 return -1; //MA_ERROR_OPERATION_FAILED;
732         } else {
733                 MAS_LOGD("[DEBUG] multi-assistant send ASR result, asr_result(%p)", asr_result);
734         }
735
736         char* temp_asr_result = NULL;
737         if (!asr_result)
738                 temp_asr_result = strdup("#NULL");
739         else
740                 temp_asr_result = strdup(asr_result);
741
742         dbus_message_append_args(msg,
743                 DBUS_TYPE_INT32, &pid,
744                 DBUS_TYPE_INT32, &event,
745                 DBUS_TYPE_STRING, &temp_asr_result,
746                 DBUS_TYPE_INVALID);
747
748         dbus_message_set_no_reply(msg, TRUE);
749
750         if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
751                 MAS_LOGE("[Dbus ERROR] Fail to Send");
752                 if (NULL != temp_asr_result) {
753                         free(temp_asr_result);
754                         temp_asr_result = NULL;
755                 }
756                 return -1; // MAS_ERROR_OPERATION_FAILED;
757         } else {
758                 MAS_LOGD("[Dbus DEBUG] Success to Send ASR result");
759                 dbus_connection_flush(mConnectionSender);
760         }
761
762         dbus_message_unref(msg);
763
764         if (temp_asr_result)
765                 free(temp_asr_result);
766         return 0;
767 }
768
769 int CServiceIpcDbus::masc_ui_dbus_send_result(pid_t pid, const char* display_text, const char* utterance_text, const char* result_json)
770 {
771         if (0 != __dbus_check()) {
772                 return -1; //MA_ERROR_OPERATION_FAILED;
773         }
774
775         DBusMessage* msg;
776
777         msg = dbus_message_new_method_call(
778                         MA_UI_CLIENT_SERVICE_NAME,
779                         MA_UI_CLIENT_SERVICE_OBJECT_PATH,
780                         MA_UI_CLIENT_SERVICE_INTERFACE,
781                         MAS_UI_METHOD_SEND_RESULT);
782
783         if (NULL == msg) {
784                 MAS_LOGE("@@ Request multi-assistant send result : Fail to make message");
785                 return -1; //MA_ERROR_OPERATION_FAILED;
786         } else {
787                 MAS_LOGD("[DEBUG] multi-assistant send result");
788         }
789         char* temp_display_text = NULL;
790         char* temp_utterance_text = NULL;
791         char* temp_result_json = NULL;
792
793 #if 0
794         dbus_message_append_args(msg,
795                 DBUS_TYPE_INT32, &pid,
796                 DBUS_TYPE_STRING, &display_text,
797                 DBUS_TYPE_STRING, &utterance_text,
798                 DBUS_TYPE_STRING, &result_json,
799                 DBUS_TYPE_INVALID);
800
801         dbus_message_set_no_reply(msg, TRUE);
802
803         if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
804                 MAS_LOGE("[Dbus ERROR] Fail to Send");
805                 return -1; //MA_ERROR_OPERATION_FAILED;
806         } else {
807                 MAS_LOGD("[Dbus DEBUG] Success to Send result");
808                 dbus_connection_flush(mConnectionSender);
809         }
810
811         dbus_message_unref(msg);
812 #else
813         if (!display_text)
814                 temp_display_text = strdup("#NULL");
815         else
816                 temp_display_text = strdup(display_text);
817         if (!utterance_text)
818                 temp_utterance_text = strdup("#NULL");
819         else
820                 temp_utterance_text = strdup(utterance_text);
821         if (!result_json)
822                 temp_result_json = strdup("#NULL");
823         else
824                 temp_result_json = strdup(result_json);
825
826         dbus_message_append_args(msg,
827                 DBUS_TYPE_INT32, &pid,
828                 DBUS_TYPE_STRING, &temp_display_text,
829                 DBUS_TYPE_STRING, &temp_utterance_text,
830                 DBUS_TYPE_STRING, &temp_result_json,
831                 DBUS_TYPE_INVALID);
832
833         dbus_message_set_no_reply(msg, TRUE);
834
835         if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
836                 MAS_LOGE("[Dbus ERROR] Fail to Send");
837                 if (temp_display_text)
838                         free(temp_display_text);
839                 if (temp_utterance_text)
840                         free(temp_utterance_text);
841                 if (temp_result_json)
842                         free(temp_result_json);
843                 return -1; //MA_ERROR_OPERATION_FAILED;
844         } else {
845                 MAS_LOGD("[Dbus DEBUG] Success to Send result");
846                 dbus_connection_flush(mConnectionSender);
847         }
848
849         dbus_message_unref(msg);
850
851         if (temp_display_text)
852                 free(temp_display_text);
853         if (temp_utterance_text)
854                 free(temp_utterance_text);
855         if (temp_result_json)
856                 free(temp_result_json);
857 #endif
858         return 0;
859 }
860
861 int CServiceIpcDbus::masc_ui_dbus_change_assistant(const char* app_id)
862 {
863         if (0 != __dbus_check()) {
864                 return -1; //MAS_ERROR_OPERATION_FAILED;
865         }
866
867         if (NULL == app_id) {
868                 MAS_LOGE("@@ Request multi-assistant send change assistant request : Fail to make message");
869                 return -1; //MA_ERROR_OPERATION_FAILED;
870         } else {
871                 MAS_LOGD("[DEBUG] multi-assistant send change assistant request app_id(%s)", app_id);
872         }
873
874         DBusMessage* msg;
875
876         msg = dbus_message_new_method_call(
877                         MA_UI_CLIENT_SERVICE_NAME,
878                         MA_UI_CLIENT_SERVICE_OBJECT_PATH,
879                         MA_UI_CLIENT_SERVICE_INTERFACE,
880                         MAS_UI_METHOD_CHANGE_ASSISTANT);
881
882         dbus_message_append_args(msg,
883                 DBUS_TYPE_STRING, &app_id,
884                 DBUS_TYPE_INVALID);
885
886         dbus_message_set_no_reply(msg, TRUE);
887
888         if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
889                 MAS_LOGE("[Dbus ERROR] Fail to Send");
890                 return -1; // MAS_ERROR_OPERATION_FAILED;
891         } else {
892                 MAS_LOGD("[Dbus DEBUG] Success to Send change assistant request");
893                 dbus_connection_flush(mConnectionSender);
894         }
895
896         dbus_message_unref(msg);
897
898         return 0;
899 }
900
901 int CServiceIpcDbus::masc_ui_dbus_send_error_message(int reason, const char* err_msg)
902 {
903         if (NULL == mConnectionSender) {
904                 MAS_LOGE("[Dbus ERROR] Dbus connection is not available");
905                 return -1;
906         }
907
908         DBusMessage* msg = NULL;
909
910         /* create a message */
911         msg = dbus_message_new_signal(
912                 MA_UI_CLIENT_SERVICE_OBJECT_PATH,       /* object name of the signal */
913                 MA_UI_CLIENT_SERVICE_INTERFACE,         /* interface name of the signal */
914                 MAS_UI_METHOD_ERROR);                           /* name of the signal */
915
916         if (NULL == msg) {
917                 MAS_LOGE("[Dbus ERROR] Fail to create error message");
918                 return -1;
919         }
920
921         char* temp_err_msg = NULL;
922
923         if (err_msg)
924                 temp_err_msg = strdup(err_msg);
925         else
926                 temp_err_msg = strdup("#NULL");
927
928         dbus_message_append_args(msg,
929                 DBUS_TYPE_INT32, &reason,
930                 DBUS_TYPE_STRING, &temp_err_msg,
931                 DBUS_TYPE_INVALID);
932
933         dbus_message_set_no_reply(msg, TRUE);
934
935         if (!dbus_connection_send(mConnectionSender, msg, NULL)) {
936                 MAS_LOGE("[Dbus ERROR] <<<< error message : Out Of Memory !");
937         } else {
938                 MAS_LOGD("<<<< Send error message : reason(%d), err_msg(%s)", reason, temp_err_msg);
939                 dbus_connection_flush(mConnectionSender);
940         }
941
942         dbus_message_unref(msg);
943
944         if (temp_err_msg)
945                 free(temp_err_msg);
946         return 0;
947 }
948
949 int CServiceIpcDbus::masc_ui_dbus_send_recognition_result(pid_t pid, int result)
950 {
951         if (0 != __dbus_check()) {
952                 return -1; //MAS_ERROR_OPERATION_FAILED;
953         }
954
955         DBusMessage* msg;
956
957         msg = dbus_message_new_method_call(
958                         MA_UI_CLIENT_SERVICE_NAME,
959                         MA_UI_CLIENT_SERVICE_OBJECT_PATH,
960                         MA_UI_CLIENT_SERVICE_INTERFACE,
961                         MAS_UI_METHOD_SEND_RECOGNITION_RESULT);
962
963         if (NULL == msg) {
964                 MAS_LOGE("@@ Request multi-assistant send recognition result : Fail to make message");
965                 return -1; //MA_ERROR_OPERATION_FAILED;
966         } else {
967                 MAS_LOGD("[DEBUG] multi-assistant send recognition result(%d)", result);
968         }
969
970         dbus_message_append_args(msg,
971                 DBUS_TYPE_INT32, &pid,
972                 DBUS_TYPE_INT32, &result,
973                 DBUS_TYPE_INVALID);
974
975         dbus_message_set_no_reply(msg, TRUE);
976
977         if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
978                 MAS_LOGE("[Dbus ERROR] Fail to Send");
979                 return -1; // MAS_ERROR_OPERATION_FAILED;
980         } else {
981                 MAS_LOGD("[Dbus DEBUG] Success to Send ASR result");
982                 dbus_connection_flush(mConnectionSender);
983         }
984
985         dbus_message_unref(msg);
986
987         return 0;
988 }
989
990 int CServiceIpcDbus::masc_ui_dbus_enable_common_ui(int enable)
991 {
992         if (0 != __dbus_check()) {
993                 return -1; //MAS_ERROR_OPERATION_FAILED;
994         }
995
996         DBusMessage* msg;
997
998         msg = dbus_message_new_method_call(
999                         MA_UI_CLIENT_SERVICE_NAME,
1000                         MA_UI_CLIENT_SERVICE_OBJECT_PATH,
1001                         MA_UI_CLIENT_SERVICE_INTERFACE,
1002                         MAS_UI_METHOD_ENABLE_COMMON_UI);
1003
1004         if (NULL == msg) {
1005                 MAS_LOGE("@@ Request multi-assistant enable common ui : Fail to make message");
1006                 return -1; //MA_ERROR_OPERATION_FAILED;
1007         } else {
1008                 MAS_LOGD("[DEBUG] multi-assistant enable common ui (%d)", enable);
1009         }
1010
1011         dbus_message_append_args(msg,
1012                 DBUS_TYPE_INT32, &enable,
1013                 DBUS_TYPE_INVALID);
1014
1015         dbus_message_set_no_reply(msg, TRUE);
1016
1017         if (1 != dbus_connection_send(mConnectionSender, msg, NULL)) {
1018                 MAS_LOGE("[Dbus ERROR] Fail to Send");
1019                 return -1; // MAS_ERROR_OPERATION_FAILED;
1020         } else {
1021                 MAS_LOGD("[Dbus DEBUG] Success to Send ASR result");
1022                 dbus_connection_flush(mConnectionSender);
1023         }
1024
1025         dbus_message_unref(msg);
1026
1027         return 0;
1028 }
1029
1030 static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handler)
1031 {
1032         CServiceIpcDbus* service_ipc = static_cast<CServiceIpcDbus*>(data);
1033         if (NULL == service_ipc) {
1034                 MAS_LOGE("Error : service_ipc NULL");
1035                 return ECORE_CALLBACK_RENEW;
1036         }
1037
1038         DBusConnection* mConnectionListener = service_ipc->get_connection_listener();
1039         if (NULL == mConnectionListener) {
1040                 MAS_LOGE("Error : mConnectionListener NULL");
1041                 return ECORE_CALLBACK_RENEW;
1042         }
1043
1044         CServiceIpcDbusDispatcher* dispatcher = service_ipc->get_dispatcher();
1045         if (NULL == dispatcher) {
1046                 MAS_LOGE("Error : dispatcher NULL");
1047                 return ECORE_CALLBACK_RENEW;
1048         }
1049
1050         dbus_connection_read_write_dispatch(mConnectionListener, 50);
1051
1052         while (1) {
1053                 DBusMessage* msg = NULL;
1054                 msg = dbus_connection_pop_message(mConnectionListener);
1055
1056                 if (true != dbus_connection_get_is_connected(mConnectionListener)) {
1057                         MAS_LOGE("[ERROR] Connection is disconnected");
1058                         return ECORE_CALLBACK_RENEW;
1059                 }
1060
1061                 /* loop again if we haven't read a message */
1062                 if (NULL == msg) {
1063                         return ECORE_CALLBACK_RENEW;
1064                 }
1065
1066                 /* client event */
1067                 if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_HELLO)) {
1068                         dispatcher->on_hello(mConnectionListener, msg);
1069
1070                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_INITIALIZE)) {
1071                         dispatcher->on_initialize(mConnectionListener, msg);
1072
1073                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_DEINITIALIZE)) {
1074                         dispatcher->on_deinitialize(mConnectionListener, msg);
1075
1076                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_GET_RECORDING_AUDIO_FORMAT)) {
1077                         dispatcher->on_get_audio_format(mConnectionListener, msg);
1078
1079                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_GET_RECORDING_AUDIO_SOURCE_TYPE)) {
1080                         dispatcher->on_get_audio_source_type(mConnectionListener, msg);
1081
1082                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_ASR_RESULT)) {
1083                         dispatcher->on_send_asr_result(mConnectionListener, msg);
1084
1085                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_RESULT)) {
1086                         dispatcher->on_send_result(mConnectionListener, msg);
1087
1088                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_RECOGNITION_RESULT)) {
1089                         dispatcher->on_send_recognition_result(mConnectionListener, msg);
1090
1091                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_START_STREAMING_AUDIO_DATA)) {
1092                         dispatcher->on_start_streaming_audio_data(mConnectionListener, msg);
1093
1094                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_STOP_STREAMING_AUDIO_DATA)) {
1095                         dispatcher->on_stop_streaming_audio_data(mConnectionListener, msg);
1096
1097                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_UPDATE_VOICE_FEEDBACK_STATE)) {
1098                         dispatcher->on_update_voice_feedback_state(mConnectionListener, msg);
1099
1100                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_ASSISTANT_SPECIFIC_COMMAND)) {
1101                         dispatcher->on_send_assistant_specific_command(mConnectionListener, msg);
1102
1103                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SET_BACKGROUND_VOLUME)) {
1104                         dispatcher->on_set_background_volume(mConnectionListener, msg);
1105
1106                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SET_PREPROCESSING_ALLOW_MODE)) {
1107                         dispatcher->on_set_preprocessing_allow_mode(mConnectionListener, msg);
1108
1109                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_PREPROCESSING_RESULT)) {
1110                         dispatcher->on_send_preprocessing_result(mConnectionListener, msg);
1111
1112                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SET_WAKE_WORD_AUDIO_REQUIRE_FLAG)) {
1113                         dispatcher->on_set_wake_word_audio_require_flag(mConnectionListener, msg);
1114
1115                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SET_ASSISTANT_WAKEUP_LANGUAGE)) {
1116                         dispatcher->on_set_assistant_language(mConnectionListener, msg);
1117
1118                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_ADD_WAKE_WORD)) {
1119                         dispatcher->on_add_wake_word(mConnectionListener, msg);
1120
1121                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_REMOVE_WAKE_WORD)) {
1122                         dispatcher->on_remove_wake_word(mConnectionListener, msg);
1123
1124                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_UI_METHOD_INITIALIZE)) {
1125                         dispatcher->on_ui_initialize(mConnectionListener, msg);
1126
1127                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_UI_METHOD_DEINITIALIZE)) {
1128                         dispatcher->on_ui_deinitialize(mConnectionListener, msg);
1129
1130                 } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_UI_METHOD_CHANGE_ASSISTANT)) {
1131                         dispatcher->on_ui_change_assistant(mConnectionListener, msg);
1132
1133                 } else {
1134                         MAS_LOGD("Message is NOT valid");
1135                         /* Invalid method */
1136                 }
1137                 /* free the message */
1138                 dbus_message_unref(msg);
1139         }
1140
1141         return ECORE_CALLBACK_RENEW;
1142 }
1143
1144 void CServiceIpcDbus::connection_free()
1145 {
1146         if (NULL != mConnectionListener) {
1147                 dbus_connection_close(mConnectionListener);
1148                 dbus_connection_unref(mConnectionListener);
1149                 mConnectionListener = NULL;
1150         }
1151         if (NULL != mConnectionSender) {
1152                 dbus_connection_close(mConnectionSender);
1153                 dbus_connection_unref(mConnectionSender);
1154                 mConnectionSender = NULL;
1155         }
1156 }
1157
1158 int CServiceIpcDbus::open_connection()
1159 {
1160         DBusError err;
1161         dbus_error_init(&err);
1162
1163         int ret;
1164
1165         /* Create connection for sender */
1166         mConnectionSender = dbus_bus_get_private(DBUS_BUS_SESSION, &err);
1167
1168         if (dbus_error_is_set(&err)) {
1169                 MAS_LOGE("[Dbus ERROR] Fail dbus_bus_get : %s", err.message);
1170                 dbus_error_free(&err);
1171         }
1172
1173         if (NULL == mConnectionSender) {
1174                 MAS_LOGE("[Dbus ERROR] Fail to get dbus connection");
1175                 return -1;
1176         }
1177
1178         dbus_connection_set_exit_on_disconnect(mConnectionSender, false);
1179
1180         /* connect to the bus and check for errors */
1181         mConnectionListener = dbus_bus_get_private(DBUS_BUS_SESSION, &err);
1182
1183         if (dbus_error_is_set(&err)) {
1184                 MAS_LOGE("[Dbus ERROR] Fail dbus_bus_get : %s", err.message);
1185                 dbus_error_free(&err);
1186         }
1187
1188         if (NULL == mConnectionListener) {
1189                 MAS_LOGE("[Dbus ERROR] Fail to get dbus connection");
1190                 connection_free();
1191                 return -1;
1192         }
1193
1194         dbus_connection_set_exit_on_disconnect(mConnectionListener, false);
1195
1196         /* request our name on the bus and check for errors */
1197         ret = dbus_bus_request_name(mConnectionListener, MA_SERVER_SERVICE_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
1198
1199         if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
1200                 printf("Fail to be primary owner in dbus request.");
1201                 MAS_LOGE("[Dbus ERROR] Fail to be primary owner");
1202                 connection_free();
1203                 return -1;
1204         }
1205
1206         if (dbus_error_is_set(&err)) {
1207                 MAS_LOGE("[Dbus ERROR] dbus_bus_request_name() : %s", err.message);
1208                 dbus_error_free(&err);
1209                 connection_free();
1210                 return -1;
1211         }
1212
1213         /* Flush messages which are received before fd event handler registration */
1214         while (DBUS_DISPATCH_DATA_REMAINS == dbus_connection_get_dispatch_status(mConnectionListener)) {
1215                 listener_event_callback(this, NULL);
1216         }
1217
1218         /* add a rule for getting signal */
1219         char rule[128];
1220         snprintf(rule, 128, "type='signal',interface='%s'", MA_SERVER_SERVICE_INTERFACE);
1221
1222         /* add a rule for which messages we want to see */
1223         dbus_bus_add_match(mConnectionListener, rule, &err);/* see signals from the given interface */
1224
1225         if (dbus_error_is_set(&err)) {
1226                 MAS_LOGE("[Dbus ERROR] dbus_bus_add_match() : %s", err.message);
1227                 dbus_error_free(&err);
1228                 connection_free();
1229                 return -1;
1230         }
1231
1232         int fd = 0;
1233         if (1 != dbus_connection_get_unix_fd(mConnectionListener, &fd)) {
1234                 MAS_LOGE("fail to get fd from dbus ");
1235                 connection_free();
1236                 return -1;
1237         } else {
1238                 MAS_LOGD("Get fd from dbus : %d", fd);
1239         }
1240
1241         mFdHandler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)listener_event_callback, this, NULL, NULL);
1242
1243         if (NULL == mFdHandler) {
1244                 MAS_LOGE("[Dbus ERROR] Fail to get fd handler");
1245                 connection_free();
1246                 return -1;
1247         }
1248
1249         return 0;
1250 }
1251
1252 int CServiceIpcDbus::close_connection()
1253 {
1254         DBusError err;
1255         dbus_error_init(&err);
1256
1257         if (NULL != mFdHandler) {
1258                 ecore_main_fd_handler_del(mFdHandler);
1259                 mFdHandler = NULL;
1260         }
1261
1262         if (NULL != mConnectionListener) {
1263                 dbus_bus_release_name(mConnectionListener, MA_SERVER_SERVICE_NAME, &err);
1264                 if (dbus_error_is_set(&err)) {
1265                         MAS_LOGE("[Dbus ERROR] dbus_bus_release_name() : %s", err.message);
1266                         dbus_error_free(&err);
1267                 }
1268         } else {
1269                 MAS_LOGE("mConnectionListener is NULL!!");
1270         }
1271
1272         connection_free();
1273
1274         return 0;
1275 }