Release version 1.3.4
[platform/core/appfw/message-port.git] / src / message-port.c
1 /*
2  * Message Port
3  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 /**
19  * @file        message-port.cpp
20  * @brief       This is the implementation file for the MessagePort.
21  */
22 #define _GNU_SOURCE
23
24 #include <sys/socket.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <glib.h>
28 #include <gio/gio.h>
29 #include <aul/aul.h>
30 #include <openssl/md5.h>
31 #include <bundle.h>
32 #include <bundle_internal.h>
33 #include <pkgmgr-info.h>
34 #include <aul.h>
35 #include <gio/gio.h>
36 #include <gio/gunixfdlist.h>
37 #include <pthread.h>
38 #include <glib-unix.h>
39 #include <poll.h>
40
41 #include "message-port.h"
42 #include "message-port-log.h"
43
44 #define MAX_PACKAGE_STR_SIZE 512
45 #define MESSAGEPORT_BUS_NAME_PREFIX "org.tizen.messageport._"
46 #define MESSAGEPORT_OBJECT_PATH "/org/tizen/messageport"
47 #define MESSAGEPORT_INTERFACE_PREFIX "org.tizen.messageport._"
48
49 #define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
50 #define DBUS_PATH_DBUS "/org/freedesktop/DBus"
51 #define DBUS_INTERFACE_DBUS "org.freedesktop.DBus"
52
53 #define DBUS_RELEASE_NAME_REPLY_RELEASED        1 /* *< Service was released from the given name */
54 #define DBUS_RELEASE_NAME_REPLY_NON_EXISTENT    2 /* *< The given name does not exist on the bus */
55 #define DBUS_RELEASE_NAME_REPLY_NOT_OWNER       3 /* *< Service is not an owner of the given name */
56 #define HEADER_LEN 8
57 #define MAX_RETRY_CNT 10
58 #define SOCK_PAIR_SENDER 0
59 #define SOCK_PAIR_RECEIVER 1
60
61
62 #define retvm_if(expr, val, fmt, arg...) do { \
63         if (expr) { \
64                 _LOGE(fmt, ##arg); \
65                 _LOGE("(%s) -> %s() return", #expr, __func__); \
66                 return val; \
67         } \
68 } while (0)
69
70 #define retv_if(expr, val) do { \
71         if (expr) { \
72                 _LOGE("(%s) -> %s() return", #expr, __func__); \
73                 return val; \
74         } \
75 } while (0)
76
77 #define FREE_AND_NULL(ptr) do { \
78         if (ptr) { \
79                 free((void *)ptr); \
80                 ptr = NULL; \
81         } \
82 } while (0)
83
84 static bool _initialized = false;
85 static GDBusConnection *__gdbus_conn;
86 static char *__app_id;
87 static GHashTable *__local_port_info;
88 static GHashTable *__remote_app_info;
89 static GHashTable *__sender_appid_hash;
90 static GHashTable *__trusted_app_list_hash;
91 static GHashTable *__callback_info_hash;
92 static GHashTable *__registered_callback_info_hash;
93 static const int MAX_MESSAGE_SIZE = 16 * 1024;
94
95 enum __certificate_info_type {
96         UNKNOWN = 0,
97         CERTIFICATE_MATCH,
98         CERTIFICATE_NOT_MATCH,
99 };
100
101 typedef struct message_port_pkt {
102         int remote_port_name_len;
103         char *remote_port_name;
104         bool is_bidirection;
105         bool is_trusted;
106         int data_len;
107         unsigned char *data;
108 } message_port_pkt_s;
109
110 typedef struct message_port_callback_info {
111         messageport_message_cb callback;
112         int local_id;
113         char *remote_app_id;
114         GIOChannel *gio_read;
115         int g_src_id;
116 } message_port_callback_info_s;
117
118 typedef struct message_port_local_port_info {
119         messageport_message_cb callback;
120         bool is_trusted;
121         char *port_name;
122         int local_id;
123 } message_port_local_port_info_s;
124
125 typedef struct message_port_remote_port_info {
126         char *remote_app_id;
127         int certificate_info;
128         GList *port_list;
129 } message_port_remote_app_info_s;
130
131 typedef struct port_list_info {
132         message_port_remote_app_info_s *remote_app_info;
133         char *port_name;
134         char *encoded_bus_name;
135         bool is_trusted;
136         int send_sock_fd;
137         bool exist;
138         GIOChannel *gio_read;
139         int g_src_id;
140         GList *delayed_message_list;
141         unsigned int delayed_message_size;
142         int delay_src_id;
143 } port_list_info_s;
144
145 typedef struct registered_callback_info {
146         char *remote_app_id;
147         char *remote_port;
148         bool is_trusted;
149         int watcher_id;
150         void *user_data;
151         messageport_registration_event_cb registered_cb;
152         messageport_registration_event_cb unregistered_cb;
153 } registered_callback_info_s;
154
155 enum transmission_sequence {
156         SEQUENCE_START = 0,
157         SEQUENCE_PORT_LEN,
158         SEQUENCE_PORT_NAME,
159         SEQUENCE_BIDIRECTION,
160         SEQUENCE_TRUSTED,
161         SEQUENCE_DTAT_LEN,
162         SEQUENCE_DATA,
163         SEQUENCE_END
164 };
165
166 typedef struct delay_message {
167         unsigned int size;
168         unsigned int sent_bytes;
169         int sequence;
170         int local_port_len;
171         char *local_port_name;
172         bool is_bidirection;
173         bool local_trusted;
174         int data_len;
175         bundle_raw *data;
176 } delay_message_info_s;
177
178
179 extern pthread_mutex_t mutex;
180 static void __free_list_delay_message_info(gpointer data);
181
182
183 static void __callback_info_free(gpointer data)
184 {
185         message_port_callback_info_s *callback_info = (message_port_callback_info_s *)data;
186         GError *error = NULL;
187         if (callback_info == NULL)
188                 return;
189
190         if (callback_info->remote_app_id)
191                 FREE_AND_NULL(callback_info->remote_app_id);
192
193         if (callback_info->gio_read != NULL) {
194                 g_io_channel_shutdown(callback_info->gio_read, TRUE, &error);
195                 if (error) {
196                         _LOGE("g_io_channel_shutdown error : %s", error->message);
197                         g_error_free(error);
198                 }
199                 g_io_channel_unref(callback_info->gio_read);
200                 callback_info->gio_read = NULL;
201         }
202
203         if (callback_info->g_src_id != 0) {
204                 g_source_remove(callback_info->g_src_id);
205                 callback_info->g_src_id = 0;
206         }
207
208         FREE_AND_NULL(callback_info);
209 }
210
211 static void __callback_info_free_by_info(message_port_callback_info_s *callback_info)
212 {
213         GList *callback_info_list = g_hash_table_lookup(__callback_info_hash, GUINT_TO_POINTER(callback_info->local_id));
214         GList *find_list;
215
216         if (callback_info_list == NULL)
217                 return;
218
219         find_list = g_list_find(callback_info_list, callback_info);
220         if (find_list == NULL)
221                 return;
222
223         callback_info_list = g_list_remove_link(callback_info_list, find_list);
224         __callback_info_free(callback_info);
225         g_list_free(find_list);
226 }
227
228 static void __registered_callback_info_free(gpointer data)
229 {
230         registered_callback_info_s *callback_info = (registered_callback_info_s *)data;
231         if (callback_info == NULL)
232                 return;
233
234         if (callback_info->remote_app_id)
235                 free(callback_info->remote_app_id);
236
237         if (callback_info->remote_port)
238                 free(callback_info->remote_port);
239
240         free(callback_info);
241 }
242
243
244 static void __hash_destroy_callback_info(gpointer data)
245 {
246
247         GList *callback_list = (GList *)data;
248         if (callback_list != NULL)
249                 g_list_free_full(callback_list, __callback_info_free);
250 }
251
252 static char *__get_encoded_name(const char *remote_app_id, const char *port_name, bool is_trusted)
253 {
254
255         int prefix_len = strlen(MESSAGEPORT_BUS_NAME_PREFIX);
256         int postfix_len = 1;
257         char *postfix = is_trusted ? "1" : "0";
258
259         unsigned char c[MD5_DIGEST_LENGTH] = {0};
260         char *md5_interface = NULL;
261         char *temp;
262         int index = 0;
263         MD5_CTX mdContext;
264         int encoded_bus_name_len = prefix_len + postfix_len + (MD5_DIGEST_LENGTH * 2) + 2;
265         int bus_name_len = strlen(remote_app_id) + strlen(port_name) + 2;
266         char *bus_name = (char *)calloc(bus_name_len, sizeof(char));
267         if (bus_name == NULL) {
268                 _LOGE("bus_name calloc failed");
269                 return 0;
270         }
271
272         snprintf(bus_name, bus_name_len, "%s_%s", remote_app_id, port_name);
273
274         MD5_Init(&mdContext);
275         MD5_Update(&mdContext, bus_name, bus_name_len);
276         MD5_Final(c, &mdContext);
277
278         md5_interface = (char *)calloc(encoded_bus_name_len , sizeof(char));
279         if (md5_interface == NULL) {
280                 if (bus_name)
281                         free(bus_name);
282
283                 _LOGE("md5_interface calloc failed!!");
284                 return 0;
285         }
286
287         snprintf(md5_interface, encoded_bus_name_len, "%s", MESSAGEPORT_BUS_NAME_PREFIX);
288         temp = md5_interface;
289         temp += prefix_len;
290
291         for (index = 0; index < MD5_DIGEST_LENGTH; index++) {
292                 snprintf(temp, 3, "%02x", c[index]);
293                 temp += 2;
294         }
295
296         if (postfix && postfix_len > 0)
297                 snprintf(temp, encoded_bus_name_len - (temp - md5_interface), "%s", postfix);
298         if (bus_name)
299                 free(bus_name);
300
301         _LOGD("encoded_bus_name : %s ", md5_interface);
302
303         return md5_interface;
304 }
305
306 static int __remote_port_compare_cb(gconstpointer a, gconstpointer b)
307 {
308         port_list_info_s *key1 = (port_list_info_s *)a;
309         port_list_info_s *key2 = (port_list_info_s *)b;
310
311         if (key1->is_trusted == key2->is_trusted)
312                 return strcmp(key1->port_name, key2->port_name);
313
314         return 1;
315 }
316
317
318 static bool __is_preloaded(const char *local_appid, const char *remote_appid)
319 {
320         _LOGD("IsPreloaded");
321
322         bool preload_local = false;
323         bool preload_remote = false;
324
325         pkgmgrinfo_appinfo_h handle = NULL;
326         int ret = pkgmgrinfo_appinfo_get_usr_appinfo(local_appid, getuid(), &handle);
327         if (ret != PMINFO_R_OK) {
328                 _LOGE("Failed to get the appinfo. %d", ret);
329                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
330                 return false;
331         }
332         ret = pkgmgrinfo_appinfo_is_preload(handle, &preload_local);
333         if (ret != PMINFO_R_OK) {
334                 _LOGE("Failed to check the preloaded application. %d", ret);
335                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
336                 return false;
337         }
338         pkgmgrinfo_appinfo_destroy_appinfo(handle);
339
340         ret = pkgmgrinfo_appinfo_get_usr_appinfo(remote_appid, getuid(), &handle);
341         if (ret != PMINFO_R_OK) {
342                 _LOGE("Failed to get the appinfo. %d", ret);
343                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
344                 return false;
345         }
346         ret = pkgmgrinfo_appinfo_is_preload(handle, &preload_remote);
347         if (ret != PMINFO_R_OK) {
348                 _LOGE("Failed to check the preloaded application. %d", ret);
349                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
350                 return false;
351         }
352
353         if (preload_local && preload_remote) {
354                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
355                 return true;
356         }
357         pkgmgrinfo_appinfo_destroy_appinfo(handle);
358         return false;
359 }
360
361 static int __check_certificate(const char *local_appid, const char *remote_appid)
362 {
363         _LOGD("CheckCertificate");
364
365         pkgmgrinfo_cert_compare_result_type_e res;
366         int ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(local_appid, remote_appid, getuid(), &res);
367         if (ret < 0) {
368                 _LOGE(":CheckCertificate() Failed");
369                 return MESSAGEPORT_ERROR_IO_ERROR;
370         }
371         if (res != PMINFO_CERT_COMPARE_MATCH) {
372                 _LOGE("CheckCertificate() Failed : MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH");
373                 return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
374         }
375
376         return MESSAGEPORT_ERROR_NONE;
377 }
378
379 static int __get_local_port_info(int id, message_port_local_port_info_s **info)
380 {
381         message_port_local_port_info_s *mi = (message_port_local_port_info_s *)g_hash_table_lookup(__local_port_info, GINT_TO_POINTER(id));
382
383         if (mi == NULL)
384                 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
385         *info = mi;
386
387         return MESSAGEPORT_ERROR_NONE;
388 }
389
390 static port_list_info_s *__set_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
391 {
392         int ret_val = MESSAGEPORT_ERROR_NONE;
393         port_list_info_s *port_info = (port_list_info_s *)calloc(1, sizeof(port_list_info_s));
394
395         if (!port_info) {
396                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
397                 goto out;
398         }
399         port_info->port_name = strdup(remote_port);
400         if (!port_info->port_name) {
401                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
402                 goto out;
403         }
404         port_info->is_trusted = is_trusted;
405         port_info->encoded_bus_name = __get_encoded_name(remote_app_id, remote_port, is_trusted);
406         if (port_info->encoded_bus_name == NULL) {
407                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
408                 goto out;
409         }
410         port_info->send_sock_fd = 0;
411 out:
412         if (ret_val != MESSAGEPORT_ERROR_NONE) {
413                 if (port_info) {
414                         FREE_AND_NULL(port_info->port_name);
415                         FREE_AND_NULL(port_info->encoded_bus_name);
416                         free(port_info);
417                 }
418                 return NULL;
419         }
420         return port_info;
421 }
422
423 static message_port_remote_app_info_s *__set_remote_app_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
424 {
425         message_port_remote_app_info_s *remote_app_info = NULL;
426         int ret_val = MESSAGEPORT_ERROR_NONE;
427
428         remote_app_info = (message_port_remote_app_info_s *)calloc(1, sizeof(message_port_remote_app_info_s));
429         if (!remote_app_info) {
430                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
431                 goto out;
432         }
433
434         remote_app_info->remote_app_id = strdup(remote_app_id);
435         if (remote_app_info->remote_app_id == NULL) {
436                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;;
437                 goto out;
438         }
439
440 out:
441         if (ret_val != MESSAGEPORT_ERROR_NONE) {
442                 if (remote_app_info) {
443                         FREE_AND_NULL(remote_app_info->remote_app_id);
444                         FREE_AND_NULL(remote_app_info);
445                 }
446                 return NULL;
447         }
448         return remote_app_info;
449 }
450
451 static void __clear_disconnect_socket(port_list_info_s *port_info)
452 {
453         GError *error = NULL;
454
455         if (port_info == NULL)
456                 return;
457
458         if (port_info->gio_read != NULL) {
459                 g_io_channel_shutdown(port_info->gio_read, TRUE, &error);
460                 if (error) {
461                         _LOGE("g_io_channel_shutdown error : %s", error->message);
462                         g_error_free(error);
463                 }
464                 g_io_channel_unref(port_info->gio_read);
465                 port_info->gio_read = NULL;
466         }
467
468         if (port_info->g_src_id != 0) {
469                 g_source_remove(port_info->g_src_id);
470                 port_info->g_src_id = 0;
471         }
472
473         if (port_info->delay_src_id != 0) {
474                 g_source_remove(port_info->delay_src_id);
475                 port_info->delay_src_id = 0;
476         }
477
478         if (port_info->delayed_message_list != NULL) {
479                 g_list_free_full(port_info->delayed_message_list, __free_list_delay_message_info);
480                 /* can be reused */
481                 port_info->delayed_message_list = NULL;
482         }
483
484         port_info->delayed_message_size = 0;
485         port_info->send_sock_fd = 0;
486 }
487
488 /* LCOV_EXCL_START */
489 void __free_port_info(gpointer data)
490 {
491         port_list_info_s *port_info = (port_list_info_s *)data;
492         message_port_remote_app_info_s *remote_app_info;
493
494         if (port_info == NULL)
495                 return;
496
497         remote_app_info = port_info->remote_app_info;
498
499         _LOGI("__free_port_info : remote_app_id : %s port_name : %s",
500                         remote_app_info->remote_app_id,
501                         port_info->port_name);
502
503         remote_app_info->port_list = g_list_remove(remote_app_info->port_list,
504                         port_info);
505
506         __clear_disconnect_socket(port_info);
507
508         if (port_info->encoded_bus_name)
509                 free(port_info->encoded_bus_name);
510         if (port_info->port_name)
511                 free(port_info->port_name);
512
513         free(port_info);
514
515         if (g_list_length(remote_app_info->port_list) == 0) {
516                 g_hash_table_remove(__remote_app_info,
517                                 remote_app_info->remote_app_id);
518         }
519 }
520 /* LCOV_EXCL_STOP */
521
522 static gboolean __socket_disconnect_handler(GIOChannel *gio,
523                 GIOCondition cond,
524                 gpointer data)
525 {
526         _LOGI("__socket_disconnect_handler %d", cond);
527         __free_port_info(data);
528
529         return FALSE;
530 }
531
532 static int __get_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted,
533                 message_port_remote_app_info_s **mri, port_list_info_s **pli)
534 {
535         message_port_remote_app_info_s *remote_app_info = NULL;
536         port_list_info_s port_info;
537         GList *cb_list = NULL;
538         int ret_val = MESSAGEPORT_ERROR_NONE;
539
540         remote_app_info = (message_port_remote_app_info_s *)g_hash_table_lookup(__remote_app_info, remote_app_id);
541
542         if (remote_app_info == NULL) {
543                 remote_app_info = __set_remote_app_info(remote_app_id, remote_port, is_trusted);
544
545                 if (remote_app_info == NULL) {
546                         ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
547                         goto out;
548                 }
549                 g_hash_table_insert(__remote_app_info, remote_app_info->remote_app_id, remote_app_info);
550         }
551         *mri = remote_app_info;
552
553         port_info.port_name = strdup(remote_port);
554         if (port_info.port_name == NULL) {
555                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
556                 goto out;
557         }
558         port_info.is_trusted = is_trusted;
559         cb_list = g_list_find_custom(remote_app_info->port_list, &port_info,
560                                         (GCompareFunc)__remote_port_compare_cb);
561         if (port_info.port_name)
562                 free(port_info.port_name);
563         if (cb_list == NULL) {
564                 port_list_info_s *tmp = __set_remote_port_info(remote_app_id, remote_port, is_trusted);
565                 if (tmp == NULL) {
566                         ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
567                         goto out;
568                 }
569                 remote_app_info->port_list = g_list_append(remote_app_info->port_list, tmp);
570                 tmp->remote_app_info = remote_app_info;
571                 *pli = tmp;
572         } else {
573                 *pli = (port_list_info_s *)cb_list->data;
574         }
575 out:
576
577         return ret_val;
578 }
579
580 static bool __is_local_port_registed(const char *local_port, bool trusted, int *local_id, message_port_local_port_info_s **lpi)
581 {
582         GHashTableIter iter;
583         gpointer key, value;
584
585         g_hash_table_iter_init(&iter, __local_port_info);
586         while (g_hash_table_iter_next(&iter, &key, &value)) {
587                 message_port_local_port_info_s *mi = (message_port_local_port_info_s *)value;
588
589                 if ((mi->is_trusted == trusted) && strcmp(mi->port_name, local_port) == 0) {
590                         *local_id = mi->local_id;
591                         if (lpi != NULL)
592                                 *lpi = mi;
593                         return true;
594                 }
595         }
596         return false;
597 }
598
599 static int __get_sender_pid(GDBusConnection *conn, const char *sender_name)
600 {
601         GDBusMessage *msg = NULL;
602         GDBusMessage *reply = NULL;
603         GError *err = NULL;
604         GVariant *body;
605         int pid = 0;
606
607         msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
608                         "org.freedesktop.DBus", "GetConnectionUnixProcessID");
609         if (!msg) {
610                 _LOGE("Can't allocate new method call");
611                 goto out;
612         }
613
614         g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
615         reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
616                                                         G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
617
618         if (!reply) {
619                 if (err != NULL) {
620                         _LOGE("Failed to get pid [%s]", err->message);
621                         g_error_free(err);
622                 }
623                 goto out;
624         }
625
626         body = g_dbus_message_get_body(reply);
627         g_variant_get(body, "(u)", &pid);
628
629 out:
630         if (msg)
631                 g_object_unref(msg);
632         if (reply)
633                 g_object_unref(reply);
634
635         return pid;
636 }
637
638 static int __write_socket(int fd,
639                 const char *buffer,
640                 unsigned int nbytes,
641                 unsigned int *bytes_write,
642                 int *sequence)
643 {
644 #define SEND_TIMEOUT 500 /* milliseconds */
645
646         unsigned int left = nbytes;
647         ssize_t nb;
648         int retry_cnt = 0;
649         struct pollfd fds[1];
650         int ret;
651
652         *sequence += 1;
653         *bytes_write = 0;
654
655         fds[0].fd = fd;
656         fds[0].events = POLLOUT;
657         fds[0].revents = 0;
658
659         ret = poll(fds, 1, SEND_TIMEOUT);
660         if (ret == 0) {
661                 LOGE("__write_socket: : fd %d poll timeout", fd);
662                 return MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE;
663         }
664
665         while (left && (retry_cnt < MAX_RETRY_CNT)) {
666                 nb = write(fd, buffer, left);
667                 if (nb == -1) {
668                         if (errno == EINTR) {
669                                 LOGE("__write_socket: EINTR error continue ...");
670                                 retry_cnt++;
671                                 continue;
672                         }
673                         LOGE("__write_socket: ...error fd %d: errno %d\n", fd, errno);
674
675                         if (errno == EWOULDBLOCK || errno == EAGAIN)
676                                 return MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE;
677
678                         return MESSAGEPORT_ERROR_IO_ERROR;
679                 }
680
681                 left -= nb;
682                 buffer += nb;
683                 *bytes_write += nb;
684                 retry_cnt = 0;
685         }
686         return MESSAGEPORT_ERROR_NONE;
687 }
688
689 static int __write_string_to_socket(int fd,
690                 const char *buffer,
691                 int string_len,
692                 unsigned int *bytes_write,
693                 int *sequence)
694 {
695         int ret;
696
697         ret = __write_socket(fd, (char *)&string_len, sizeof(string_len),
698                         bytes_write, sequence);
699         if (ret != MESSAGEPORT_ERROR_NONE) {
700                 _LOGE("write string_len fail");
701                 return ret;
702         }
703
704         if (string_len > 0) {
705                 ret = __write_socket(fd, buffer, string_len, bytes_write, sequence);
706                 if (ret != MESSAGEPORT_ERROR_NONE) {
707                         _LOGE("wirte buffer fail");
708                         return ret;
709                 }
710         } else {
711                 *sequence += 1;
712         }
713
714         return MESSAGEPORT_ERROR_NONE;
715 }
716
717 static int __read_socket(int fd,
718                 char *buffer,
719                 unsigned int nbytes,
720                 unsigned int *bytes_read)
721 {
722         unsigned int left = nbytes;
723         ssize_t nb;
724         int retry_cnt = 0;
725         const struct timespec TRY_SLEEP_TIME = { 0, 500 * 1000 * 1000 };
726
727         *bytes_read = 0;
728         while (left && (retry_cnt < MAX_RETRY_CNT)) {
729                 nb = read(fd, buffer, left);
730                 if (nb == 0) {
731                         LOGE("__read_socket: ...read EOF, socket closed %d: nb %d\n", fd, nb);
732                         return MESSAGEPORT_ERROR_IO_ERROR;
733                 } else if (nb == -1) {
734                         /*  wrt(nodejs) could change socket to none-blocking socket :-( */
735                         if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
736                                 LOGE("__read_socket: %d errno, sleep and retry ...", errno);
737                                 retry_cnt++;
738                                 nanosleep(&TRY_SLEEP_TIME, 0);
739                                 continue;
740                         }
741                         LOGE("__read_socket: ...error fd %d: errno %d\n", fd, errno);
742                         return MESSAGEPORT_ERROR_IO_ERROR;
743                 }
744
745                 left -= nb;
746                 buffer += nb;
747                 *bytes_read += nb;
748                 retry_cnt = 0;
749         }
750         return MESSAGEPORT_ERROR_NONE;
751 }
752
753 static int __read_string_from_socket(int fd, char **buffer, int *string_len)
754 {
755         unsigned int nb;
756         if (__read_socket(fd, (char *)string_len, sizeof(*string_len), &nb) != MESSAGEPORT_ERROR_NONE) {
757                 LOGE("read socket fail");
758                 return MESSAGEPORT_ERROR_IO_ERROR;
759         }
760         if (*string_len > 0 && *string_len < MAX_MESSAGE_SIZE) {
761                 *buffer = (char *)calloc(*string_len, sizeof(char));
762                 if (*buffer == NULL) {
763                         LOGE("Out of memory.");
764                         return MESSAGEPORT_ERROR_IO_ERROR;
765                 }
766                 if (__read_socket(fd, *buffer, *string_len, &nb) != MESSAGEPORT_ERROR_NONE) {
767                         LOGE("read socket fail");
768                         return MESSAGEPORT_ERROR_IO_ERROR;
769                 }
770         } else {
771                 LOGE("Invalid string len %d", *string_len);
772                 return MESSAGEPORT_ERROR_IO_ERROR;
773         }
774         return MESSAGEPORT_ERROR_NONE;
775 }
776
777 message_port_pkt_s *__message_port_recv_raw(int fd)
778 {
779         message_port_pkt_s *pkt = NULL;
780         unsigned int nb;
781
782         pkt = (message_port_pkt_s *)calloc(sizeof(message_port_pkt_s), 1);
783         if (pkt == NULL) {
784                 close(fd);
785                 return NULL;
786         }
787
788         if (__read_string_from_socket(fd, (char **)&pkt->remote_port_name, &pkt->remote_port_name_len) != MESSAGEPORT_ERROR_NONE) {
789                 LOGE("read socket fail: port_name");
790                 free(pkt->remote_port_name);
791                 free(pkt);
792                 return NULL;
793         }
794
795         if (__read_socket(fd, (char *)&pkt->is_bidirection, sizeof(pkt->is_bidirection), &nb) != MESSAGEPORT_ERROR_NONE) {
796                 LOGE("read socket fail: is_bidirection");
797                 free(pkt->remote_port_name);
798                 free(pkt);
799                 return NULL;
800         }
801
802         if (__read_socket(fd, (char *)&pkt->is_trusted, sizeof(pkt->is_trusted), &nb) != MESSAGEPORT_ERROR_NONE) {
803                 LOGE("read socket fail: is_trusted");
804                 free(pkt->remote_port_name);
805                 free(pkt);
806                 return NULL;
807         }
808
809         if (__read_string_from_socket(fd, (char **)&pkt->data, &pkt->data_len) != MESSAGEPORT_ERROR_NONE) {
810                 LOGE("read socket fail: data");
811                 if (pkt->data)
812                         free(pkt->data);
813                 free(pkt->remote_port_name);
814                 free(pkt);
815                 return NULL;
816         }
817
818         return pkt;
819 }
820
821 static gboolean __socket_request_handler(GIOChannel *gio,
822                 GIOCondition cond,
823                 gpointer data)
824 {
825         int fd = 0;
826         message_port_callback_info_s *mi;
827         message_port_pkt_s *pkt;
828         bundle *kb = NULL;
829         GError *error = NULL;
830
831         mi = (message_port_callback_info_s *)data;
832         if (mi == NULL) {
833
834                 g_io_channel_shutdown(gio, TRUE, &error);
835                 if (error) {
836                         _LOGE("g_io_channel_shutdown error : %s", error->message);
837                         g_error_free(error);
838                 }
839                 g_io_channel_unref(gio);
840                 return FALSE;
841         }
842
843         if (cond == G_IO_HUP) {
844
845                 _LOGI("socket G_IO_HUP");
846                 __callback_info_free_by_info(mi);
847                 return FALSE;
848
849         } else {
850
851                 if ((fd = g_io_channel_unix_get_fd(gio)) < 0) {
852                         _LOGE("fail to get fd from io channel");
853                         __callback_info_free_by_info(mi);
854                         return FALSE;
855                 }
856
857                 if ((pkt = __message_port_recv_raw(fd)) == NULL) {
858                         _LOGE("recv error on SOCKET");
859                         __callback_info_free_by_info(mi);
860                         return FALSE;
861                 }
862
863                 kb = bundle_decode(pkt->data, pkt->data_len);
864                 if (pkt->is_bidirection)
865                         mi->callback(mi->local_id, mi->remote_app_id, pkt->remote_port_name, pkt->is_trusted, kb, NULL);
866                 else
867                         mi->callback(mi->local_id, mi->remote_app_id, NULL, pkt->is_trusted, kb, NULL);
868
869                 bundle_free(kb);
870                 if (pkt) {
871                         if (pkt->remote_port_name)
872                                 free(pkt->remote_port_name);
873                         if (pkt->data)
874                                 free(pkt->data);
875                         free(pkt);
876                 }
877         }
878
879         return TRUE;
880 }
881
882 static bool send_message(GVariant *parameters, GDBusMethodInvocation *invocation)
883 {
884         char *local_port = NULL;
885         char *local_appid = NULL;
886         char *remote_appid = NULL;
887         char *remote_port = NULL;
888         gboolean local_trusted = false;
889         gboolean remote_trusted = false;
890         gboolean bi_dir = false;
891         int len = 0;
892
893         bundle *data = NULL;
894         bundle_raw *raw = NULL;
895         message_port_local_port_info_s *mi;
896         int local_reg_id = 0;
897         message_port_callback_info_s *callback_info = NULL;
898         message_port_callback_info_s *head_callback_info;
899         GList *callback_info_list = NULL;
900
901         char buf[1024];
902         GDBusMessage *msg;
903         GUnixFDList *fd_list;
904         int fd_len;
905         int *returned_fds = NULL;
906         int fd;
907         bool ret = false;
908
909         g_variant_get(parameters, "(&s&sbb&s&sbu&s)", &local_appid, &local_port, &local_trusted, &bi_dir,
910                         &remote_appid, &remote_port, &remote_trusted, &len, &raw);
911
912         if (!remote_port) {
913                 _LOGE("Invalid argument : remote_port is NULL");
914                 goto out;
915         }
916         if (!remote_appid) {
917                 _LOGE("Invalid argument : remote_appid is NULL");
918                 goto out;
919         }
920         if (!__is_local_port_registed(remote_port, remote_trusted, &local_reg_id, &mi)) {
921                 _LOGE("Invalid argument : remote_port:(%s) trusted(%d)", remote_port, remote_trusted);
922                 goto out;
923         }
924         if (!local_appid) {
925                 _LOGE("Invalid argument : local_appid");
926                 goto out;
927         }
928         if (!local_port) {
929                 _LOGE("Invalid argument : local_port");
930                 goto out;
931         }
932         if (strcmp(remote_appid, __app_id) != 0) {
933                 _LOGE("Invalid argument : remote_appid (%s)", remote_appid);
934                 goto out;
935         }
936         if (strcmp(remote_port, mi->port_name) != 0) {
937                 _LOGE("Invalid argument : remote_port (%s)", remote_port);
938                 goto out;
939         }
940         if (!len) {
941                 _LOGE("Invalid argument : data_len");
942                 goto out;
943         }
944         if (remote_trusted) {
945                 if (g_hash_table_lookup(__trusted_app_list_hash, (gpointer)local_appid) == NULL) {
946                         if (!__is_preloaded(local_appid, remote_appid)) {
947                                 int ret = __check_certificate(local_appid, remote_appid);
948                                 if (ret == MESSAGEPORT_ERROR_NONE)
949                                         g_hash_table_insert(__trusted_app_list_hash, local_appid, "TRUE");
950                                 else {
951                                         _LOGE("The application (%s) is not signed with the same certificate",
952                                                         local_appid);
953                                         goto out;
954                                 }
955                         }
956                 }
957         }
958
959         callback_info = (message_port_callback_info_s *)calloc(1, sizeof(message_port_callback_info_s));
960         if (callback_info == NULL)
961                 goto out;
962
963         callback_info->local_id = mi->local_id;
964         callback_info->remote_app_id = strdup(local_appid);
965         if (callback_info->remote_app_id == NULL) {
966                 _LOGE("out of memory");
967                 goto out;
968         }
969         callback_info->callback = mi->callback;
970
971         msg = g_dbus_method_invocation_get_message(invocation);
972         fd_list = g_dbus_message_get_unix_fd_list(msg);
973
974         /* When application send message to self fd_list is NULL */
975         if (fd_list != NULL) {
976                 returned_fds = g_unix_fd_list_steal_fds(fd_list, &fd_len);
977                 if (returned_fds == NULL) {
978                         _LOGE("fail to get fds");
979                         goto out;
980                 }
981                 fd = returned_fds[0];
982
983                 LOGI("g_unix_fd_list_get %d fd: [%d]", fd_len, fd);
984                 if (fd > 0) {
985
986                         callback_info->gio_read = g_io_channel_unix_new(fd);
987                         if (!callback_info->gio_read) {
988                                 _LOGE("Error is %s\n", strerror_r(errno, buf, sizeof(buf)));
989                                 goto out;
990                         }
991
992                         callback_info->g_src_id = g_io_add_watch(callback_info->gio_read, G_IO_IN | G_IO_HUP,
993                                         __socket_request_handler, (gpointer)callback_info);
994                         if (callback_info->g_src_id == 0) {
995                                 _LOGE("fail to add watch on socket");
996                                 goto out;
997                         }
998
999                         callback_info_list = g_hash_table_lookup(__callback_info_hash, GUINT_TO_POINTER(mi->local_id));
1000                         if (callback_info_list == NULL) {
1001                                 head_callback_info = (message_port_callback_info_s *)calloc(1, sizeof(message_port_callback_info_s));
1002                                 if (head_callback_info == NULL) {
1003                                         _LOGE("fail to alloc head_callback_info");
1004                                         goto out;
1005                                 }
1006                                 head_callback_info->local_id = 0;
1007                                 head_callback_info->remote_app_id = NULL;
1008                                 head_callback_info->callback = NULL;
1009                                 head_callback_info->gio_read = NULL;
1010                                 head_callback_info->g_src_id = 0;
1011                                 callback_info_list = g_list_append(callback_info_list, head_callback_info);
1012                                 callback_info_list = g_list_append(callback_info_list, callback_info);
1013                                 g_hash_table_insert(__callback_info_hash, GUINT_TO_POINTER(mi->local_id), callback_info_list);
1014                         } else {
1015                                 callback_info_list = g_list_append(callback_info_list, callback_info);
1016                         }
1017                 }
1018         }
1019
1020         data = bundle_decode(raw, len);
1021         if (!data) {
1022                 _LOGE("Invalid argument : message");
1023                 goto out;
1024         }
1025
1026         LOGD("call calback %s", local_appid);
1027         if (bi_dir)
1028                 mi->callback(mi->local_id, local_appid, local_port, local_trusted, data, NULL);
1029         else
1030                 mi->callback(mi->local_id, local_appid, NULL, false, data, NULL);
1031         bundle_free(data);
1032
1033         ret = true;
1034 out:
1035         if (ret == false)
1036                 __callback_info_free(callback_info);
1037
1038         if (returned_fds)
1039                 free(returned_fds);
1040
1041         return ret;
1042 }
1043
1044 static int __check_remote_port(const char *remote_app_id, const char *remote_port, bool is_trusted, bool *exist)
1045 {
1046         _LOGD("Check a remote port : [%s:%s]", remote_app_id, remote_port);
1047
1048         GVariant *result = NULL;
1049         GError *err = NULL;
1050         int ret_val = MESSAGEPORT_ERROR_NONE;
1051         char *bus_name = NULL;
1052         message_port_remote_app_info_s *remote_app_info = NULL;
1053         port_list_info_s *port_info = NULL;
1054         int local_reg_id = 0;
1055         message_port_local_port_info_s *mi = NULL;
1056         gboolean name_exist = false;
1057
1058         _LOGD("remote_app_id, app_id :[%s : %s] ", remote_app_id, __app_id);
1059
1060         ret_val = __get_remote_port_info(remote_app_id, remote_port, is_trusted, &remote_app_info, &port_info);
1061         if (ret_val != MESSAGEPORT_ERROR_NONE)
1062                 return ret_val;
1063
1064         /* self check */
1065         if (strcmp(remote_app_id, __app_id) == 0) {
1066
1067                 _LOGD("__is_local_port_registed ");
1068                 if (!__is_local_port_registed(remote_port, is_trusted, &local_reg_id, &mi))
1069                         *exist = false;
1070                 else
1071                         *exist = true;
1072
1073                 _LOGD("__is_local_port_registed : %d ", *exist);
1074                 return MESSAGEPORT_ERROR_NONE;
1075         }
1076
1077         port_info->exist = false;
1078         bus_name = port_info->encoded_bus_name;
1079
1080         result = g_dbus_connection_call_sync(
1081                         __gdbus_conn,
1082                         DBUS_SERVICE_DBUS,
1083                         DBUS_PATH_DBUS,
1084                         DBUS_INTERFACE_DBUS,
1085                         "NameHasOwner",
1086                         g_variant_new("(s)", bus_name),
1087                         G_VARIANT_TYPE("(b)"),
1088                         G_DBUS_CALL_FLAGS_NONE,
1089                         -1,
1090                         NULL,
1091                         &err);
1092
1093         if (err || (result == NULL)) {
1094                 if (err) {
1095                         _LOGE("No reply. error = %s", err->message);
1096                         g_error_free(err);
1097                 }
1098                 ret_val = MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE;
1099         } else {
1100                 g_variant_get(result, "(b)", &name_exist);
1101
1102                 if (!name_exist) {
1103                         _LOGI("Name not exist %s", bus_name);
1104                         *exist = false;
1105                         ret_val = MESSAGEPORT_ERROR_NONE;
1106                 } else {
1107
1108                         if (is_trusted) {
1109                                 if (remote_app_info->certificate_info != CERTIFICATE_MATCH) {
1110                                         if (!__is_preloaded(__app_id, remote_app_id)) {
1111                                                 if (__check_certificate(__app_id, remote_app_id) != MESSAGEPORT_ERROR_NONE) {
1112                                                         ret_val = MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
1113                                                         goto out;
1114                                                 }
1115                                         }
1116                                         remote_app_info->certificate_info = CERTIFICATE_MATCH;
1117                                 }
1118                         }
1119                         port_info->exist = true;
1120                         *exist = true;
1121                         ret_val = MESSAGEPORT_ERROR_NONE;
1122                 }
1123         }
1124 out:
1125         if (result)
1126                 g_variant_unref(result);
1127
1128         if (ret_val != MESSAGEPORT_ERROR_NONE || !name_exist)
1129                 __free_port_info((gpointer)port_info);
1130
1131         return ret_val;
1132 }
1133
1134 static void __on_sender_name_appeared(GDBusConnection *connection,
1135                 const gchar     *name,
1136                 const gchar     *name_owner,
1137                 gpointer         user_data)
1138 {
1139         _LOGI("sender name appeared : %s", name);
1140 }
1141
1142 static void __on_sender_name_vanished(GDBusConnection *connection,
1143                 const gchar     *name,
1144                 gpointer         user_data)
1145 {
1146         gboolean remove_result = FALSE;
1147         int *watcher_id = (int *)user_data;
1148         remove_result = g_hash_table_remove(__sender_appid_hash, (gpointer)name);
1149         if (!remove_result)
1150                 _LOGE("Fail to remove sender appid from hash : %s", name);
1151
1152         if (watcher_id) {
1153                 if (*watcher_id > 0)
1154                         g_bus_unwatch_name(*watcher_id);
1155                 else
1156                         LOGE("Invalid watcher_id %d", *watcher_id);
1157                 free(watcher_id);
1158         } else {
1159                 LOGE("watcher_id is NULL");
1160         }
1161 }
1162
1163 static bool __check_sender_validation(GVariant *parameters, const char *sender, GDBusConnection *conn)
1164 {
1165         int ret = 0;
1166         char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
1167         char *local_appid = NULL;
1168         int pid = __get_sender_pid(conn, sender);
1169         int *watcher_id = (int *)calloc(1, sizeof(int));
1170         char *_sender;
1171         retvm_if(!watcher_id, false, "Malloc failed");
1172
1173         ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
1174         if (ret != AUL_R_OK) {
1175                 _LOGE("Failed to get the sender ID: (%s) (%d)", sender, pid);
1176                 free(watcher_id);
1177                 return false;
1178         }
1179
1180         g_variant_get_child(parameters, 0, "&s", &local_appid);
1181         if (local_appid == NULL) {
1182                 _LOGE("appid is NULL : (%s) (%d)", sender, pid);
1183                 free(watcher_id);
1184                 return false;
1185         }
1186
1187         if (strncmp(buffer, local_appid, MAX_PACKAGE_STR_SIZE) == 0) {
1188                 _LOGD("insert sender !!!!! %s", sender);
1189                 _sender = strdup(sender);
1190                 if (_sender == NULL) {
1191                         _LOGE("out of memory");
1192                         free(watcher_id);
1193                         return false;
1194                 }
1195                 g_hash_table_insert(__sender_appid_hash, (gpointer)_sender, GINT_TO_POINTER(pid));
1196                 *watcher_id = g_bus_watch_name_on_connection(
1197                                         __gdbus_conn,
1198                                         sender,
1199                                         G_BUS_NAME_WATCHER_FLAGS_NONE,
1200                                         __on_sender_name_appeared,
1201                                         __on_sender_name_vanished,
1202                                         watcher_id,
1203                                         NULL);
1204         } else {
1205                 free(watcher_id);
1206                 return false;
1207         }
1208         return true;
1209 }
1210
1211 static void __dbus_method_call_handler(GDBusConnection *conn,
1212                                 const gchar *sender, const gchar *object_path,
1213                                 const gchar *iface_name, const gchar *method_name,
1214                                 GVariant *parameters, GDBusMethodInvocation *invocation,
1215                                 gpointer user_data)
1216 {
1217         _LOGI("method_name: %s, sender: %s", method_name, sender);
1218         gpointer sender_pid = g_hash_table_lookup(__sender_appid_hash, sender);
1219         if (sender_pid == NULL) {
1220                 if (!__check_sender_validation(parameters, sender, conn))
1221                         goto out;
1222         }
1223         if (g_strcmp0(method_name, "send_message") == 0)
1224                 send_message(parameters, invocation);
1225 out:
1226         g_dbus_method_invocation_return_value(invocation, NULL);
1227 }
1228
1229 static const GDBusInterfaceVTable interface_vtable = {
1230         __dbus_method_call_handler,
1231         NULL,
1232         NULL
1233 };
1234
1235 static int __dbus_init(void)
1236 {
1237         bool ret = false;
1238         GError *error = NULL;
1239
1240         __gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
1241         if (__gdbus_conn == NULL) {
1242                 if (error != NULL) {
1243                         _LOGE("Failed to get dbus [%s]", error->message);
1244                         g_error_free(error);
1245                 }
1246                 goto out;
1247         }
1248
1249         ret = true;
1250
1251 out:
1252         if (!__gdbus_conn)
1253                 g_object_unref(__gdbus_conn);
1254
1255         return ret;
1256
1257 }
1258
1259 int __register_dbus_interface(const char *port_name, bool is_trusted)
1260 {
1261
1262         GDBusNodeInfo *introspection_data = NULL;
1263         int registration_id = 0;
1264
1265         static gchar introspection_prefix[] =
1266                 "<node>"
1267                 "  <interface name='";
1268
1269         static gchar introspection_postfix[] =
1270                 "'>"
1271                 "        <method name='send_message'>"
1272                 "          <arg type='s' name='local_appid' direction='in'/>"
1273                 "          <arg type='s' name='local_port' direction='in'/>"
1274                 "          <arg type='b' name='local_trusted' direction='in'/>"
1275                 "          <arg type='b' name='bi_dir' direction='in'/>"
1276                 "          <arg type='s' name='remote_appid' direction='in'/>"
1277                 "          <arg type='s' name='remote_port' direction='in'/>"
1278                 "          <arg type='b' name='remote_trusted' direction='in'/>"
1279                 "          <arg type='u' name='data_len' direction='in'/>"
1280                 "          <arg type='s' name='data' direction='in'/>"
1281                 "        </method>"
1282                 "  </interface>"
1283                 "</node>";
1284
1285         char *introspection_xml = NULL;
1286         int introspection_xml_len = 0;
1287
1288
1289         int owner_id = 0;
1290         GError *error = NULL;
1291         char *bus_name = NULL;
1292         char *interface_name = NULL;
1293         GVariant *result = NULL;
1294
1295         bus_name = __get_encoded_name(__app_id, port_name, is_trusted);
1296         if (!bus_name) {
1297                 _LOGE("Fail to get bus name");
1298                 goto out;
1299         }
1300         interface_name = bus_name;
1301
1302         introspection_xml_len = strlen(introspection_prefix) + strlen(interface_name) +
1303                 strlen(introspection_postfix) + 1;
1304
1305         introspection_xml = (char *)calloc(introspection_xml_len, sizeof(char));
1306         if (!introspection_xml) {
1307                 _LOGE("out of memory");
1308                 goto out;
1309         }
1310
1311
1312         result = g_dbus_connection_call_sync(
1313                         __gdbus_conn,
1314                         DBUS_SERVICE_DBUS,
1315                         DBUS_PATH_DBUS,
1316                         DBUS_INTERFACE_DBUS,
1317                         "RequestName",
1318                         g_variant_new("(su)", bus_name, G_BUS_NAME_OWNER_FLAGS_NONE),
1319                         G_VARIANT_TYPE("(u)"),
1320                         G_DBUS_CALL_FLAGS_NONE,
1321                         -1,
1322                         NULL,
1323                         &error);
1324         if (error) {
1325                 _LOGE("RequestName fail : %s", error->message);
1326                 g_error_free(error);
1327                 goto out;
1328         }
1329         if (result == NULL) {
1330                 _LOGE("fail to get name NULL");
1331                 goto out;
1332         }
1333         g_variant_get(result, "(u)", &owner_id);
1334         if (owner_id == 0) {
1335                 _LOGE("Acquiring the own name is failed");
1336                 goto out;
1337         }
1338
1339         _LOGD("Acquiring the own name : %d", owner_id);
1340
1341         snprintf(introspection_xml, introspection_xml_len, "%s%s%s", introspection_prefix, interface_name, introspection_postfix);
1342
1343         introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
1344         if (!introspection_data) {
1345                 _LOGE("g_dbus_node_info_new_for_xml() is failed.");
1346                 goto out;
1347         }
1348
1349         registration_id = g_dbus_connection_register_object(__gdbus_conn,
1350                                                 MESSAGEPORT_OBJECT_PATH, introspection_data->interfaces[0],
1351                                                 &interface_vtable, NULL, NULL, NULL);
1352
1353         _LOGD("registration_id %d", registration_id);
1354
1355         if (registration_id == 0) {
1356                 _LOGE("Failed to g_dbus_connection_register_object");
1357                 goto out;
1358         }
1359
1360 out:
1361         if (introspection_data)
1362                 g_dbus_node_info_unref(introspection_data);
1363         if (introspection_xml)
1364                 free(introspection_xml);
1365         if (bus_name)
1366                 free(bus_name);
1367         if (result)
1368                 g_variant_unref(result);
1369
1370
1371         return registration_id;
1372 }
1373
1374 /* LCOV_EXCL_START */
1375 static void __hash_destory_local_value(gpointer data)
1376 {
1377         message_port_local_port_info_s *mli = (message_port_local_port_info_s *)data;
1378         if (mli) {
1379                 if (mli->port_name)
1380                         free(mli->port_name);
1381                 free(mli);
1382         }
1383 }
1384 /* LCOV_EXCL_STOP */
1385
1386 /* LCOV_EXCL_START */
1387 static void __hash_destory_remote_value(gpointer data)
1388 {
1389         message_port_remote_app_info_s *mri = (message_port_remote_app_info_s *)data;
1390         if (mri) {
1391                 FREE_AND_NULL(mri->remote_app_id);
1392                 if (mri->port_list)
1393                         g_list_free_full(mri->port_list, __free_port_info);
1394
1395                 free(mri);
1396         }
1397 }
1398 /* LCOV_EXCL_STOP */
1399
1400 static bool __initialize(void)
1401 {
1402
1403 #if !GLIB_CHECK_VERSION(2, 35, 0)
1404         g_type_init();
1405 #endif
1406
1407         int pid = getpid();
1408         int ret = 0;
1409         char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
1410
1411         ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
1412         retvm_if(ret != AUL_R_OK, false, "Failed to get the application ID: %d", ret);
1413
1414         __app_id = strdup(buffer);
1415         retvm_if(!__app_id, false, "Malloc failed");
1416         _LOGI("init : %s", __app_id);
1417
1418         if (__local_port_info == NULL) {
1419                 __local_port_info = g_hash_table_new_full(g_direct_hash,  g_direct_equal, NULL, __hash_destory_local_value);
1420                 retvm_if(!__local_port_info, false, "fail to create __local_port_info");
1421         }
1422
1423         if (__remote_app_info == NULL) {
1424                 __remote_app_info = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __hash_destory_remote_value);
1425                 retvm_if(!__remote_app_info, false, "fail to create __remote_app_info");
1426         }
1427
1428         if (__sender_appid_hash == NULL) {
1429                 __sender_appid_hash = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
1430                 retvm_if(!__sender_appid_hash, false, "fail to create __sender_appid_hash");
1431         }
1432
1433         if (__trusted_app_list_hash == NULL) {
1434                 __trusted_app_list_hash = g_hash_table_new(g_str_hash, g_str_equal);
1435                 retvm_if(!__trusted_app_list_hash, false, "fail to create __trusted_app_list_hash");
1436         }
1437
1438         if (__callback_info_hash == NULL) {
1439                 __callback_info_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __hash_destroy_callback_info);
1440                 retvm_if(!__callback_info_hash, false, "fail to create __callback_info_hash");
1441         }
1442
1443         if (!__dbus_init())
1444                 return false;
1445         _initialized = true;
1446
1447         return true;
1448 }
1449
1450
1451 static bool __message_port_register_port(const int local_id, const char *local_port, bool is_trusted, messageport_message_cb callback)
1452 {
1453         message_port_local_port_info_s *mi = (message_port_local_port_info_s *)calloc(1, sizeof(message_port_local_port_info_s));
1454         retvm_if(!mi, false, "Malloc failed");
1455
1456         mi->callback = callback;
1457         mi->is_trusted = is_trusted;
1458         mi->port_name = strdup(local_port);
1459         if (mi->port_name == NULL) {
1460                 _LOGE("Malloc failed (%s)", local_port);
1461                 free(mi);
1462                 return false;
1463         }
1464         mi->local_id = local_id;
1465
1466         g_hash_table_insert(__local_port_info, GINT_TO_POINTER(mi->local_id), mi);
1467         return true;
1468 }
1469
1470 static int __register_message_port(const char *local_port, bool is_trusted, messageport_message_cb callback)
1471 {
1472         _SECURE_LOGI("local_port : [%s:%s]", local_port, is_trusted ? "trusted" : "non-trusted");
1473
1474         int local_id = 0;
1475
1476         /* Check the message port is already registed */
1477         if (__is_local_port_registed(local_port, is_trusted, &local_id, NULL))
1478                 return local_id;
1479
1480         local_id = __register_dbus_interface(local_port, is_trusted);
1481         if (local_id < 1) {
1482                 _LOGE("register_dbus_interface fail !!");
1483                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1484         }
1485
1486         if (!__message_port_register_port(local_id, local_port, is_trusted, callback))
1487                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1488
1489         return local_id;
1490 }
1491
1492 static void __free_delay_message_info(delay_message_info_s *message)
1493 {
1494         if (message != NULL) {
1495                 FREE_AND_NULL(message->local_port_name);
1496                 FREE_AND_NULL(message->data);
1497                 FREE_AND_NULL(message);
1498         }
1499 }
1500
1501 static void __free_list_delay_message_info(gpointer data)
1502 {
1503         delay_message_info_s *message = (delay_message_info_s *)data;
1504
1505         if (message != NULL)
1506                 __free_delay_message_info(message);
1507 }
1508
1509 static int __send_delayed_message(int sockfd, delay_message_info_s *message)
1510 {
1511         unsigned int nb = 0;
1512         int sequence = message->sequence - 1;
1513         int ret = MESSAGEPORT_ERROR_NONE;
1514         bool is_startline = true;
1515         int offset = 0;
1516
1517         _LOGI("send_delayed_message : sockfd (%d) sequence(%d) sent byte(%d)",
1518                 sockfd, message->sequence, message->sent_bytes);
1519
1520         switch (message->sequence) {
1521         case SEQUENCE_START:
1522                 sequence++;
1523                 is_startline = false;
1524
1525         case SEQUENCE_PORT_LEN:
1526                 if (is_startline)
1527                         offset = message->sent_bytes;
1528
1529                 ret = __write_socket(sockfd, ((char *)&message->local_port_len) + offset,
1530                                 sizeof(message->local_port_len) - offset, &nb, &sequence);
1531                 if (ret != MESSAGEPORT_ERROR_NONE) {
1532                         _LOGE("write local_port_len fail");
1533                         goto out;
1534                 }
1535                 offset = 0;
1536                 is_startline = false;
1537
1538         case SEQUENCE_PORT_NAME:
1539                 if (is_startline)
1540                         offset = message->sent_bytes;
1541
1542                 if (message->local_port_len > 0)
1543                         ret = __write_socket(sockfd, message->local_port_name + offset,
1544                                 message->local_port_len - offset , &nb, &sequence);
1545                 else
1546                         sequence++;
1547
1548                 if (ret != MESSAGEPORT_ERROR_NONE) {
1549                         _LOGE("write local_port fail");
1550                         goto out;
1551                 }
1552                 offset = 0;
1553                 is_startline = false;
1554
1555         case SEQUENCE_BIDIRECTION:
1556                 if (is_startline)
1557                         offset = message->sent_bytes;
1558
1559                 ret = __write_socket(sockfd, ((char *)&message->is_bidirection) + offset,
1560                                 sizeof(message->is_bidirection) - offset, &nb, &sequence);
1561                 if (ret != MESSAGEPORT_ERROR_NONE) {
1562                         _LOGE("write is_bidirection fail");
1563                         goto out;
1564                 }
1565                 offset = 0;
1566                 is_startline = false;
1567
1568         case SEQUENCE_TRUSTED:
1569                 if (is_startline)
1570                         offset = message->sent_bytes;
1571
1572                 ret = __write_socket(sockfd, ((char *)&message->local_trusted) + offset,
1573                                 sizeof(message->local_trusted) - offset, &nb, &sequence);
1574                 if (ret != MESSAGEPORT_ERROR_NONE) {
1575                         _LOGE("write local_trusted fail");
1576                         goto out;
1577                 }
1578                 offset = 0;
1579                 is_startline = false;
1580
1581         case SEQUENCE_DTAT_LEN:
1582                 if (is_startline)
1583                         offset = message->sent_bytes;
1584
1585                 ret = __write_socket(sockfd, ((char *)&message->data_len) + offset,
1586                                 sizeof(message->data_len) - offset, &nb, &sequence);
1587                 if (ret != MESSAGEPORT_ERROR_NONE) {
1588                         _LOGE("write data_len fail");
1589                         goto out;
1590                 }
1591                 offset = 0;
1592                 is_startline = false;
1593
1594         case SEQUENCE_DATA:
1595                 if (is_startline)
1596                         offset = message->sent_bytes;
1597
1598                 ret = __write_socket(sockfd, (char *)message->data + offset,
1599                         message->data_len -offset, &nb, &sequence);
1600
1601                 if (ret != MESSAGEPORT_ERROR_NONE) {
1602                         _LOGE("write data fail");
1603                         goto out;
1604                 }
1605                 offset = 0;
1606                 is_startline = false;
1607
1608         default:
1609                 ret = MESSAGEPORT_ERROR_NONE;
1610
1611         }
1612
1613 out:
1614         if (ret == MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE) {
1615                 if (is_startline)
1616                          message->sent_bytes += nb;
1617                 else
1618                          message->sent_bytes = nb;
1619
1620                 message->sequence = sequence;
1621                 _LOGE("send_delayed_message fail : sockfd (%d) sequence(%d) sent byte(%d)",
1622                         sockfd, message->sequence, message->sent_bytes);
1623         }
1624
1625         return ret;
1626
1627 }
1628
1629 static gboolean __process_delayed_message(gint fd, GIOCondition cond, gpointer data)
1630 {
1631         port_list_info_s *port_info = (port_list_info_s *)data;
1632         delay_message_info_s *message;
1633         int ret;
1634
1635         if (port_info == NULL)
1636                 return G_SOURCE_REMOVE;
1637
1638         pthread_mutex_lock(&mutex);
1639
1640         if (port_info->delayed_message_list == NULL) {
1641                 port_info->delayed_message_size = 0;
1642                 port_info->delay_src_id = 0;
1643                 pthread_mutex_unlock(&mutex);
1644                 return G_SOURCE_REMOVE;
1645         } else {
1646                 message = g_list_nth_data(port_info->delayed_message_list, 0);
1647                 ret = __send_delayed_message(port_info->send_sock_fd, message);
1648
1649                 if (ret == MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE) {
1650                         pthread_mutex_unlock(&mutex);
1651                         return G_SOURCE_CONTINUE;
1652                 } else if (ret == MESSAGEPORT_ERROR_IO_ERROR) {
1653                         __free_port_info((gpointer)port_info);
1654                         pthread_mutex_unlock(&mutex);
1655                         return G_SOURCE_REMOVE;
1656                 }
1657
1658                 port_info->delayed_message_size -= message->size;
1659
1660                 port_info->delayed_message_list = g_list_remove(port_info->delayed_message_list, message);
1661                 __free_delay_message_info(message);
1662         }
1663
1664         pthread_mutex_unlock(&mutex);
1665
1666         return G_SOURCE_CONTINUE;
1667 }
1668
1669 static int __insert_delayed_message(port_list_info_s *port_info,
1670         int sequence,
1671         bundle_raw *kb_data,
1672         int data_len,
1673         unsigned int sent_bytes,
1674         const char *local_port,
1675         bool local_trusted,
1676         bool is_bidirection)
1677 {
1678 #define QUEUE_SIZE_MAX (1024 * 1024) /* 1MB per remote port (MAX) */
1679
1680         unsigned int tmp_size;
1681         unsigned int message_size;
1682         int ret = MESSAGEPORT_ERROR_NONE;
1683
1684         if (port_info->delayed_message_size >= QUEUE_SIZE_MAX) {
1685                 _LOGE("cache fail : delayed_message_size (%d), count(%d)",
1686                         port_info->delayed_message_size, g_list_length(port_info->delayed_message_list));
1687                 return MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE;
1688         }
1689
1690         delay_message_info_s *message = (delay_message_info_s *)calloc(1, sizeof(delay_message_info_s));
1691         retvm_if(!message, MESSAGEPORT_ERROR_OUT_OF_MEMORY, "Malloc failed");
1692
1693         message_size = sizeof(delay_message_info_s);
1694
1695         message->sequence = sequence;
1696         tmp_size = strlen(local_port) + 1;
1697         message_size += tmp_size;
1698         message->local_port_len = tmp_size;
1699         message->local_port_name = strdup(local_port);
1700         if (message->local_port_name == NULL) {
1701                 _LOGE("local_port_name strdup fail");
1702                 ret = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1703                 goto out;
1704         }
1705         message->is_bidirection = is_bidirection;
1706         message->local_trusted = local_trusted;
1707         message_size += data_len;
1708         message->data_len = data_len;
1709         message->data = (bundle_raw *)strdup((const char *)kb_data);
1710         if (message->data == NULL) {
1711                 _LOGE("data strdup fail");
1712                 ret = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1713                 goto out;
1714         }
1715
1716
1717         message->sent_bytes = sent_bytes;
1718         message->size = message_size;
1719         port_info->delayed_message_size += message_size;
1720
1721         port_info->delayed_message_list = g_list_append(port_info->delayed_message_list, message);
1722
1723         if (port_info->delay_src_id == 0) {
1724                         port_info->delay_src_id = g_unix_fd_add_full(G_PRIORITY_DEFAULT,
1725                                                         port_info->send_sock_fd, G_IO_OUT, __process_delayed_message,
1726                                                         port_info, NULL);
1727         }
1728
1729         _LOGE("inserted : pm(%s) fd(%d) ms(%d) ds(%d) dlc(%d) sqn(%d) sb (%d)",
1730                 port_info->port_name, port_info->send_sock_fd, message_size,
1731                 port_info->delayed_message_size,
1732                 g_list_length(port_info->delayed_message_list), sequence, sent_bytes);
1733
1734
1735
1736 out:
1737         if (ret != MESSAGEPORT_ERROR_NONE)
1738                 __free_delay_message_info(message);
1739
1740         return ret;
1741 }
1742
1743 int __message_port_send_async(port_list_info_s *port_info, bundle *kb, const char *local_port,
1744                 bool local_trusted, bool is_bidirection)
1745 {
1746         int ret = 0;
1747         int data_len;
1748         int local_port_len = 0;
1749         unsigned int nb = 0;
1750         bundle_raw *kb_data = NULL;
1751         int sequence = SEQUENCE_START;
1752
1753         bundle_encode(kb, &kb_data, &data_len);
1754         if (kb_data == NULL) {
1755                 _LOGE("bundle encode fail");
1756                 ret = MESSAGEPORT_ERROR_INVALID_PARAMETER;
1757                 goto out;
1758         }
1759
1760         if (data_len > MAX_MESSAGE_SIZE) {
1761                 _LOGE("bigger than max size\n");
1762                 ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
1763                 goto out;
1764         }
1765
1766         if (g_list_length(port_info->delayed_message_list) > 0) {
1767                 ret = MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE;
1768                 _LOGE("There are messages in the delayed_message_list (count %d)",
1769                         g_list_length(port_info->delayed_message_list));
1770                 goto out;
1771         }
1772
1773         if (local_port != NULL)
1774                 local_port_len = strlen(local_port) + 1;
1775
1776         ret = __write_string_to_socket(port_info->send_sock_fd, local_port,
1777                         local_port_len, &nb, &sequence);
1778         if (ret != MESSAGEPORT_ERROR_NONE) {
1779                 _LOGE("write local_port fail");
1780                 goto out;
1781         }
1782
1783         ret = __write_socket(port_info->send_sock_fd, (char *)&is_bidirection,
1784                         sizeof(is_bidirection), &nb, &sequence);
1785         if (ret != MESSAGEPORT_ERROR_NONE) {
1786                 _LOGE("write is_bidirection fail");
1787                 goto out;
1788         }
1789
1790         ret = __write_socket(port_info->send_sock_fd, (char *)&local_trusted,
1791                         sizeof(local_trusted), &nb, &sequence);
1792         if (ret != MESSAGEPORT_ERROR_NONE) {
1793                 _LOGE("write local_trusted fail");
1794                 goto out;
1795         }
1796
1797         ret = __write_string_to_socket(port_info->send_sock_fd, (void *)kb_data,
1798                         data_len, &nb, &sequence);
1799         if (ret != MESSAGEPORT_ERROR_NONE) {
1800                 _LOGE("write kb_data fail");
1801                 goto out;
1802         }
1803
1804 out:
1805         if (ret == MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE) {
1806                 ret = __insert_delayed_message(port_info, sequence, kb_data, data_len, nb,
1807                         local_port, local_trusted, is_bidirection);
1808                 if (ret != MESSAGEPORT_ERROR_NONE)
1809                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1810         }
1811
1812         if (kb_data)
1813                 free(kb_data);
1814
1815         return ret;
1816 }
1817
1818 static int __message_port_send_message(const char *remote_appid, const char *remote_port,
1819                 const char *local_port, bool trusted_message, bool local_trusted, bool bi_dir, bundle *message)
1820 {
1821
1822         int ret = MESSAGEPORT_ERROR_NONE;
1823         GUnixFDList *fd_list = NULL;
1824
1825         int len = 0;
1826         bundle_raw *raw = NULL;
1827         char *bus_name = NULL;
1828         char *interface_name = NULL;
1829
1830         message_port_remote_app_info_s *remote_app_info = NULL;
1831         port_list_info_s *port_info = NULL;
1832         GDBusMessage *msg = NULL;
1833         GError *err = NULL;
1834         GVariant *body = NULL;
1835         int sock_pair[2] = {0,};
1836         char buf[1024];
1837
1838         ret = __get_remote_port_info(remote_appid, remote_port, trusted_message, &remote_app_info, &port_info);
1839         if (ret != MESSAGEPORT_ERROR_NONE)
1840                 return ret;
1841
1842         if (port_info->exist == false) {
1843                 bool exist = false;
1844                 _LOGD("port exist check !!");
1845                 ret =  __check_remote_port(remote_appid, remote_port, trusted_message, &exist);
1846                 if (ret != MESSAGEPORT_ERROR_NONE)
1847                         return ret;
1848                 else if (!exist)
1849                         return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1850         }
1851
1852         if (port_info->send_sock_fd > 0) {
1853                 ret = __message_port_send_async(port_info, message,
1854                                 (local_port) ? local_port : "", local_trusted, bi_dir);
1855         } else {
1856
1857                 bus_name = port_info->encoded_bus_name;
1858                 interface_name = bus_name;
1859
1860                 if (bundle_encode(message, &raw, &len) != BUNDLE_ERROR_NONE) {
1861                         ret = MESSAGEPORT_ERROR_INVALID_PARAMETER;
1862                         goto out;
1863                 }
1864
1865                 if (MAX_MESSAGE_SIZE < len) {
1866                         _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
1867                         ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
1868                         goto out;
1869                 }
1870
1871                 body = g_variant_new("(ssbbssbus)", __app_id, (local_port) ? local_port : "", local_trusted, bi_dir,
1872                                 remote_appid, remote_port, trusted_message, len, raw);
1873                 if (strcmp(remote_appid, __app_id) != 0) { /* self send */
1874
1875                         /*  if message-port fail to get socket pair, communicate using GDBus */
1876                         if (aul_request_message_port_socket_pair(sock_pair) != AUL_R_OK) {
1877                                 _LOGE("error create socket pair");
1878                         } else {
1879
1880                                 _LOGI("sock pair : %d, %d",
1881                                                 sock_pair[SOCK_PAIR_SENDER], sock_pair[SOCK_PAIR_RECEIVER]);
1882                                 fd_list = g_unix_fd_list_new();
1883                                 g_unix_fd_list_append(fd_list, sock_pair[SOCK_PAIR_RECEIVER], &err);
1884                                 if (err != NULL) {
1885                                         _LOGE("g_unix_fd_list_append [%s]", err->message);
1886                                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1887                                         g_error_free(err);
1888                                         goto out;
1889                                 }
1890
1891                                 port_info->send_sock_fd = sock_pair[SOCK_PAIR_SENDER];
1892                                 close(sock_pair[SOCK_PAIR_RECEIVER]);
1893                                 sock_pair[SOCK_PAIR_RECEIVER] = 0;
1894
1895                                 port_info->gio_read = g_io_channel_unix_new(port_info->send_sock_fd);
1896                                 if (!port_info->gio_read) {
1897                                         _LOGE("Error is %s\n", strerror_r(errno, buf, sizeof(buf)));
1898                                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1899                                         goto out;
1900                                 }
1901
1902                                 port_info->g_src_id = g_io_add_watch(
1903                                                 port_info->gio_read,
1904                                                 G_IO_IN | G_IO_HUP,
1905                                                 __socket_disconnect_handler,
1906                                                 (gpointer)port_info);
1907                                 if (port_info->g_src_id == 0) {
1908                                         _LOGE("fail to add watch on socket");
1909                                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1910                                         goto out;
1911                                 }
1912
1913                         }
1914                 }
1915
1916                 msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, interface_name, "send_message");
1917                 if (!msg) {
1918                         _LOGE("Can't allocate new method call");
1919                         ret = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1920                         goto out;
1921                 }
1922
1923                 g_dbus_message_set_unix_fd_list(msg, fd_list);
1924                 g_dbus_message_set_body(msg, body);
1925                 g_dbus_connection_send_message(__gdbus_conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err);
1926                 if (err != NULL) {
1927                         _LOGE("No reply. error = %s", err->message);
1928                         g_error_free(err);
1929                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1930                         goto out;
1931                 }
1932         }
1933
1934 out:
1935         if (msg)
1936                 g_object_unref(msg);
1937         if (raw)
1938                 bundle_free_encoded_rawdata(&raw);
1939         if (fd_list)
1940                 g_object_unref(fd_list);
1941
1942         if (ret != MESSAGEPORT_ERROR_NONE) {
1943                 __free_port_info((gpointer)port_info);
1944                 if (sock_pair[SOCK_PAIR_SENDER])
1945                         close(sock_pair[SOCK_PAIR_SENDER]);
1946                 if (sock_pair[SOCK_PAIR_RECEIVER])
1947                         close(sock_pair[SOCK_PAIR_RECEIVER]);
1948         }
1949
1950         return ret;
1951 }
1952
1953 int __message_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port,  bool trusted_message, bundle *message)
1954 {
1955         message_port_local_port_info_s *local_info;
1956         int ret = __get_local_port_info(id, &local_info);
1957         if (ret != MESSAGEPORT_ERROR_NONE)
1958                 return ret;
1959
1960         _LOGD("bidirectional_message %s", local_info->port_name);
1961         return __message_port_send_message(remote_app_id, remote_port,
1962                         local_info->port_name, trusted_message, local_info->is_trusted, true, message);
1963 }
1964
1965 static void __name_registered(GDBusConnection *connection,
1966                 const gchar *name,
1967                 const gchar *name_owner,
1968                 gpointer user_data)
1969 {
1970
1971         registered_callback_info_s *info = (registered_callback_info_s *)user_data;
1972         if (info == NULL) {
1973                 LOGE("NULL registered_callback_info");
1974                 return;
1975         }
1976
1977         _LOGI("watcher_id : %d, appeared name : %s , name_owner : %s\n", info->watcher_id, name, name_owner);
1978         if (info->registered_cb)
1979                 info->registered_cb(info->remote_app_id, info->remote_port, info->is_trusted, info->user_data);
1980 }
1981
1982 static void __name_unregistered(GDBusConnection *connection,
1983                 const gchar *name,
1984                 gpointer user_data)
1985 {
1986
1987         registered_callback_info_s *info = (registered_callback_info_s *)user_data;
1988         if (info == NULL) {
1989                 LOGE("NULL registered_callback_info");
1990                 return;
1991         }
1992
1993         _LOGI("watcher_id : %d, vanished name : %s\n", info->watcher_id, name);
1994         if (info->unregistered_cb)
1995                 info->unregistered_cb(info->remote_app_id, info->remote_port, info->is_trusted, info->user_data);
1996 }
1997
1998 int __messageport_watch_remote_port(int *watcher_id, const char *remote_app_id, const char *remote_port, bool trusted_remote_port, messageport_registration_event_cb registered_cb, messageport_registration_event_cb unregistered_cb, void *user_data)
1999 {
2000         int ret_val = MESSAGEPORT_ERROR_NONE;
2001         message_port_remote_app_info_s *remote_app_info = NULL;
2002         port_list_info_s *port_info = NULL;
2003
2004         _LOGI("remote_app_id, app_id :[%s : %s] ", remote_app_id, __app_id);
2005
2006         ret_val = __get_remote_port_info(remote_app_id, remote_port, trusted_remote_port, &remote_app_info, &port_info);
2007         if (ret_val != MESSAGEPORT_ERROR_NONE)
2008                 return ret_val;
2009
2010         if (__registered_callback_info_hash == NULL)
2011                 __registered_callback_info_hash = g_hash_table_new_full(g_direct_hash,  g_direct_equal, NULL, __registered_callback_info_free);
2012
2013         registered_callback_info_s *registered_cb_info = (registered_callback_info_s *)calloc(1, sizeof(registered_callback_info_s));
2014         retvm_if(!registered_cb_info, MESSAGEPORT_ERROR_OUT_OF_MEMORY, "Malloc failed");
2015
2016         registered_cb_info->registered_cb = registered_cb;
2017         registered_cb_info->unregistered_cb = unregistered_cb;
2018         registered_cb_info->user_data = user_data;
2019         registered_cb_info->remote_app_id = strdup(remote_app_info->remote_app_id);
2020         if (registered_cb_info->remote_app_id == NULL) {
2021                 free(registered_cb_info);
2022                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
2023         }
2024         registered_cb_info->remote_port = strdup(port_info->port_name);
2025         if (registered_cb_info->remote_port == NULL) {
2026                 free(registered_cb_info->remote_app_id);
2027                 free(registered_cb_info);
2028                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
2029         }
2030
2031         registered_cb_info->watcher_id = g_bus_watch_name_on_connection(
2032                         __gdbus_conn,
2033                         port_info->encoded_bus_name,
2034                         G_BUS_NAME_WATCHER_FLAGS_NONE,
2035                         __name_registered,
2036                         __name_unregistered,
2037                         registered_cb_info,
2038                         NULL);
2039         if (registered_cb_info->watcher_id == 0) {
2040                 free(registered_cb_info->remote_app_id);
2041                 free(registered_cb_info->remote_port);
2042                 free(registered_cb_info);
2043                 return MESSAGEPORT_ERROR_IO_ERROR;
2044         }
2045
2046         g_hash_table_insert(__registered_callback_info_hash,
2047                         GINT_TO_POINTER(registered_cb_info->watcher_id), registered_cb_info);
2048
2049         *watcher_id = registered_cb_info->watcher_id;
2050         return MESSAGEPORT_ERROR_NONE;
2051 }
2052
2053 int messageport_unregister_local_port(int local_port_id, bool trusted_port)
2054 {
2055
2056         GVariant *result;
2057         char *bus_name = NULL;
2058         GError *err = NULL;
2059         int ret = 0;
2060
2061         _LOGI("unregister : %d", local_port_id);
2062
2063         message_port_local_port_info_s *mi =
2064                 (message_port_local_port_info_s *)
2065                 g_hash_table_lookup(__local_port_info, GINT_TO_POINTER(local_port_id));
2066         if (mi == NULL)
2067                 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
2068
2069         if (mi->is_trusted != trusted_port)
2070                 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
2071
2072         g_hash_table_remove(__callback_info_hash, GUINT_TO_POINTER(local_port_id));
2073
2074         bus_name = __get_encoded_name(__app_id, mi->port_name, mi->is_trusted);
2075         if (bus_name == NULL)
2076                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
2077
2078         g_dbus_connection_unregister_object(__gdbus_conn, local_port_id);
2079
2080         result = g_dbus_connection_call_sync(
2081                         __gdbus_conn,
2082                         DBUS_SERVICE_DBUS,
2083                         DBUS_PATH_DBUS,
2084                         DBUS_INTERFACE_DBUS,
2085                         "ReleaseName",
2086                         g_variant_new("(s)", bus_name),
2087                         G_VARIANT_TYPE("(u)"),
2088                         G_DBUS_CALL_FLAGS_NONE,
2089                         -1,
2090                         NULL,
2091                         &err);
2092
2093         if (bus_name)
2094                 free(bus_name);
2095
2096         if (err) {
2097                 _LOGE("RequestName fail : %s", err->message);
2098                 g_error_free(err);
2099                 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
2100         }
2101         g_variant_get(result, "(u)", &ret);
2102
2103         if (result)
2104                 g_variant_unref(result);
2105
2106         if (ret != DBUS_RELEASE_NAME_REPLY_RELEASED) {
2107
2108                 if (ret == DBUS_RELEASE_NAME_REPLY_NON_EXISTENT) {
2109                         _LOGE("Port Not exist");
2110                         return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
2111                 } else if (ret == DBUS_RELEASE_NAME_REPLY_NOT_OWNER) {
2112                         _LOGE("Try to release not owned name. MESSAGEPORT_ERROR_INVALID_PARAMETER");
2113                         return MESSAGEPORT_ERROR_INVALID_PARAMETER;
2114                 }
2115         }
2116
2117
2118         g_hash_table_remove(__local_port_info, GINT_TO_POINTER(local_port_id));
2119
2120         return MESSAGEPORT_ERROR_NONE;
2121 }
2122
2123 int messageport_register_local_port(const char *local_port, messageport_message_cb callback)
2124 {
2125         if (!_initialized) {
2126                 if (!__initialize())
2127                         return MESSAGEPORT_ERROR_IO_ERROR;
2128         }
2129
2130         return __register_message_port(local_port, false, callback);
2131 }
2132
2133 int messageport_register_trusted_local_port(const char *local_port, messageport_message_cb callback)
2134 {
2135         if (!_initialized) {
2136                 if (!__initialize())
2137                         return MESSAGEPORT_ERROR_IO_ERROR;
2138         }
2139
2140         return __register_message_port(local_port, true, callback);
2141
2142 }
2143
2144 int messageport_check_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
2145 {
2146         if (!_initialized) {
2147                 if (!__initialize())
2148                         return MESSAGEPORT_ERROR_IO_ERROR;
2149         }
2150
2151         int ret = __check_remote_port(remote_app_id, remote_port, false, exist);
2152         if (ret == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND) {
2153                 *exist = false;
2154                 ret = MESSAGEPORT_ERROR_NONE;
2155         }
2156
2157         return ret;
2158 }
2159
2160 int messageport_check_trusted_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
2161 {
2162         if (!_initialized) {
2163                 if (!__initialize())
2164                         return MESSAGEPORT_ERROR_IO_ERROR;
2165         }
2166
2167         int ret = __check_remote_port(remote_app_id, remote_port, true, exist);
2168         if (ret == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND) {
2169                 *exist = false;
2170                 ret = MESSAGEPORT_ERROR_NONE;
2171         }
2172
2173         return ret;
2174 }
2175
2176 int messageport_send_message(const char *remote_app_id, const char *remote_port, bundle *message)
2177 {
2178         if (!_initialized) {
2179                 if (!__initialize())
2180                         return MESSAGEPORT_ERROR_IO_ERROR;
2181         }
2182
2183         return __message_port_send_message(remote_app_id, remote_port, NULL, false, false, false, message);
2184 }
2185
2186 int messageport_send_trusted_message(const char *remote_app_id, const char *remote_port, bundle *message)
2187 {
2188         if (!_initialized) {
2189                 if (!__initialize())
2190                         return MESSAGEPORT_ERROR_IO_ERROR;
2191         }
2192
2193         return __message_port_send_message(remote_app_id, remote_port, NULL, true, false, false, message);
2194 }
2195
2196 int messageport_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port,
2197                 bundle *message)
2198 {
2199         if (!_initialized) {
2200                 if (!__initialize())
2201                         return MESSAGEPORT_ERROR_IO_ERROR;
2202         }
2203
2204         return __message_send_bidirectional_message(id, remote_app_id, remote_port, false, message);
2205 }
2206
2207 int messageport_send_bidirectional_trusted_message(int id, const char *remote_app_id, const char *remote_port,
2208                 bundle *message)
2209 {
2210         if (!_initialized) {
2211                 if (!__initialize())
2212                         return MESSAGEPORT_ERROR_IO_ERROR;
2213         }
2214         return __message_send_bidirectional_message(id, remote_app_id, remote_port, true, message);
2215 }
2216
2217 int messageport_add_registered_cb(const char *remote_app_id, const char *remote_port, bool is_trusted, messageport_registration_event_cb registered_cb, void *user_data, int *watcher_id)
2218 {
2219         if (!_initialized) {
2220                 if (!__initialize())
2221                         return MESSAGEPORT_ERROR_IO_ERROR;
2222         }
2223         return __messageport_watch_remote_port(watcher_id, remote_app_id, remote_port, is_trusted, registered_cb, NULL, user_data);
2224 }
2225
2226 int messageport_add_unregistered_cb(const char *remote_app_id, const char *remote_port, bool is_trusted, messageport_registration_event_cb unregistered_cb, void *user_data, int *watcher_id)
2227 {
2228         if (!_initialized) {
2229                 if (!__initialize())
2230                         return MESSAGEPORT_ERROR_IO_ERROR;
2231         }
2232         return __messageport_watch_remote_port(watcher_id, remote_app_id, remote_port, is_trusted, NULL, unregistered_cb, user_data);
2233 }
2234
2235
2236 int messageport_remove_registration_event_cb(int watcher_id)
2237 {
2238         registered_callback_info_s *registered_cb_info = NULL;
2239         gboolean remove_result = FALSE;
2240
2241         if (watcher_id < 1)
2242                 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
2243
2244         registered_cb_info = g_hash_table_lookup(__registered_callback_info_hash, GINT_TO_POINTER(watcher_id));
2245         if (registered_cb_info == NULL)
2246                 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
2247
2248         remove_result = g_hash_table_remove(__registered_callback_info_hash, GINT_TO_POINTER(watcher_id));
2249         if (!remove_result)
2250                 return MESSAGEPORT_ERROR_IO_ERROR;
2251
2252         g_bus_unwatch_name(watcher_id);
2253
2254         return MESSAGEPORT_ERROR_NONE;
2255 }