Release memory for remote app info
[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         port_info.is_trusted = is_trusted;
555         cb_list = g_list_find_custom(remote_app_info->port_list, &port_info,
556                                         (GCompareFunc)__remote_port_compare_cb);
557         if (port_info.port_name)
558                 free(port_info.port_name);
559         if (cb_list == NULL) {
560                 port_list_info_s *tmp = __set_remote_port_info(remote_app_id, remote_port, is_trusted);
561                 if (tmp == NULL) {
562                         ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
563                         goto out;
564                 }
565                 remote_app_info->port_list = g_list_append(remote_app_info->port_list, tmp);
566                 tmp->remote_app_info = remote_app_info;
567                 *pli = tmp;
568         } else {
569                 *pli = (port_list_info_s *)cb_list->data;
570         }
571 out:
572
573         return ret_val;
574 }
575
576 static bool __is_local_port_registed(const char *local_port, bool trusted, int *local_id, message_port_local_port_info_s **lpi)
577 {
578         GHashTableIter iter;
579         gpointer key, value;
580
581         g_hash_table_iter_init(&iter, __local_port_info);
582         while (g_hash_table_iter_next(&iter, &key, &value)) {
583                 message_port_local_port_info_s *mi = (message_port_local_port_info_s *)value;
584
585                 if ((mi->is_trusted == trusted) && strcmp(mi->port_name, local_port) == 0) {
586                         *local_id = mi->local_id;
587                         if (lpi != NULL)
588                                 *lpi = mi;
589                         return true;
590                 }
591         }
592         return false;
593 }
594
595 static int __get_sender_pid(GDBusConnection *conn, const char *sender_name)
596 {
597         GDBusMessage *msg = NULL;
598         GDBusMessage *reply = NULL;
599         GError *err = NULL;
600         GVariant *body;
601         int pid = 0;
602
603         msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
604                         "org.freedesktop.DBus", "GetConnectionUnixProcessID");
605         if (!msg) {
606                 _LOGE("Can't allocate new method call");
607                 goto out;
608         }
609
610         g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
611         reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
612                                                         G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
613
614         if (!reply) {
615                 if (err != NULL) {
616                         _LOGE("Failed to get pid [%s]", err->message);
617                         g_error_free(err);
618                 }
619                 goto out;
620         }
621
622         body = g_dbus_message_get_body(reply);
623         g_variant_get(body, "(u)", &pid);
624
625 out:
626         if (msg)
627                 g_object_unref(msg);
628         if (reply)
629                 g_object_unref(reply);
630
631         return pid;
632 }
633
634 static int __write_socket(int fd,
635                 const char *buffer,
636                 unsigned int nbytes,
637                 unsigned int *bytes_write,
638                 int *sequence)
639 {
640 #define SEND_TIMEOUT 500 /* milliseconds */
641
642         unsigned int left = nbytes;
643         ssize_t nb;
644         int retry_cnt = 0;
645         struct pollfd fds[1];
646         int ret;
647
648         *sequence += 1;
649         *bytes_write = 0;
650
651         fds[0].fd = fd;
652         fds[0].events = POLLOUT;
653         fds[0].revents = 0;
654
655         ret = poll(fds, 1, SEND_TIMEOUT);
656         if (ret == 0) {
657                 LOGE("__write_socket: : fd %d poll timeout", fd);
658                 return MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE;
659         }
660
661         while (left && (retry_cnt < MAX_RETRY_CNT)) {
662                 nb = write(fd, buffer, left);
663                 if (nb == -1) {
664                         if (errno == EINTR) {
665                                 LOGE("__write_socket: EINTR error continue ...");
666                                 retry_cnt++;
667                                 continue;
668                         }
669                         LOGE("__write_socket: ...error fd %d: errno %d\n", fd, errno);
670
671                         if (errno == EWOULDBLOCK || errno == EAGAIN)
672                                 return MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE;
673
674                         return MESSAGEPORT_ERROR_IO_ERROR;
675                 }
676
677                 left -= nb;
678                 buffer += nb;
679                 *bytes_write += nb;
680                 retry_cnt = 0;
681         }
682         return MESSAGEPORT_ERROR_NONE;
683 }
684
685 static int __write_string_to_socket(int fd,
686                 const char *buffer,
687                 int string_len,
688                 unsigned int *bytes_write,
689                 int *sequence)
690 {
691         int ret;
692
693         ret = __write_socket(fd, (char *)&string_len, sizeof(string_len),
694                         bytes_write, sequence);
695         if (ret != MESSAGEPORT_ERROR_NONE) {
696                 _LOGE("write string_len fail");
697                 return ret;
698         }
699
700         if (string_len > 0) {
701                 ret = __write_socket(fd, buffer, string_len, bytes_write, sequence);
702                 if (ret != MESSAGEPORT_ERROR_NONE) {
703                         _LOGE("wirte buffer fail");
704                         return ret;
705                 }
706         } else {
707                 *sequence += 1;
708         }
709
710         return MESSAGEPORT_ERROR_NONE;
711 }
712
713 static int __read_socket(int fd,
714                 char *buffer,
715                 unsigned int nbytes,
716                 unsigned int *bytes_read)
717 {
718         unsigned int left = nbytes;
719         ssize_t nb;
720         int retry_cnt = 0;
721         const struct timespec TRY_SLEEP_TIME = { 0, 500 * 1000 * 1000 };
722
723         *bytes_read = 0;
724         while (left && (retry_cnt < MAX_RETRY_CNT)) {
725                 nb = read(fd, buffer, left);
726                 if (nb == 0) {
727                         LOGE("__read_socket: ...read EOF, socket closed %d: nb %d\n", fd, nb);
728                         return MESSAGEPORT_ERROR_IO_ERROR;
729                 } else if (nb == -1) {
730                         /*  wrt(nodejs) could change socket to none-blocking socket :-( */
731                         if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
732                                 LOGE("__read_socket: %d errno, sleep and retry ...", errno);
733                                 retry_cnt++;
734                                 nanosleep(&TRY_SLEEP_TIME, 0);
735                                 continue;
736                         }
737                         LOGE("__read_socket: ...error fd %d: errno %d\n", fd, errno);
738                         return MESSAGEPORT_ERROR_IO_ERROR;
739                 }
740
741                 left -= nb;
742                 buffer += nb;
743                 *bytes_read += nb;
744                 retry_cnt = 0;
745         }
746         return MESSAGEPORT_ERROR_NONE;
747 }
748
749 static int __read_string_from_socket(int fd, char **buffer, int *string_len)
750 {
751         unsigned int nb;
752         if (__read_socket(fd, (char *)string_len, sizeof(*string_len), &nb) != MESSAGEPORT_ERROR_NONE) {
753                 LOGE("read socket fail");
754                 return MESSAGEPORT_ERROR_IO_ERROR;
755         }
756         if (*string_len > 0 && *string_len < MAX_MESSAGE_SIZE) {
757                 *buffer = (char *)calloc(*string_len, sizeof(char));
758                 if (*buffer == NULL) {
759                         LOGE("Out of memory.");
760                         return MESSAGEPORT_ERROR_IO_ERROR;
761                 }
762                 if (__read_socket(fd, *buffer, *string_len, &nb) != MESSAGEPORT_ERROR_NONE) {
763                         LOGE("read socket fail");
764                         return MESSAGEPORT_ERROR_IO_ERROR;
765                 }
766         } else {
767                 LOGE("Invalid string len %d", *string_len);
768                 return MESSAGEPORT_ERROR_IO_ERROR;
769         }
770         return MESSAGEPORT_ERROR_NONE;
771 }
772
773 message_port_pkt_s *__message_port_recv_raw(int fd)
774 {
775         message_port_pkt_s *pkt = NULL;
776         unsigned int nb;
777
778         pkt = (message_port_pkt_s *)calloc(sizeof(message_port_pkt_s), 1);
779         if (pkt == NULL) {
780                 close(fd);
781                 return NULL;
782         }
783
784         if (__read_string_from_socket(fd, (char **)&pkt->remote_port_name, &pkt->remote_port_name_len) != MESSAGEPORT_ERROR_NONE) {
785                 LOGE("read socket fail: port_name");
786                 free(pkt->remote_port_name);
787                 free(pkt);
788                 return NULL;
789         }
790
791         if (__read_socket(fd, (char *)&pkt->is_bidirection, sizeof(pkt->is_bidirection), &nb) != MESSAGEPORT_ERROR_NONE) {
792                 LOGE("read socket fail: is_bidirection");
793                 free(pkt->remote_port_name);
794                 free(pkt);
795                 return NULL;
796         }
797
798         if (__read_socket(fd, (char *)&pkt->is_trusted, sizeof(pkt->is_trusted), &nb) != MESSAGEPORT_ERROR_NONE) {
799                 LOGE("read socket fail: is_trusted");
800                 free(pkt->remote_port_name);
801                 free(pkt);
802                 return NULL;
803         }
804
805         if (__read_string_from_socket(fd, (char **)&pkt->data, &pkt->data_len) != MESSAGEPORT_ERROR_NONE) {
806                 LOGE("read socket fail: data");
807                 if (pkt->data)
808                         free(pkt->data);
809                 free(pkt->remote_port_name);
810                 free(pkt);
811                 return NULL;
812         }
813
814         return pkt;
815 }
816
817 static gboolean __socket_request_handler(GIOChannel *gio,
818                 GIOCondition cond,
819                 gpointer data)
820 {
821         int fd = 0;
822         message_port_callback_info_s *mi;
823         message_port_pkt_s *pkt;
824         bundle *kb = NULL;
825         GError *error = NULL;
826
827         mi = (message_port_callback_info_s *)data;
828         if (mi == NULL) {
829
830                 g_io_channel_shutdown(gio, TRUE, &error);
831                 if (error) {
832                         _LOGE("g_io_channel_shutdown error : %s", error->message);
833                         g_error_free(error);
834                 }
835                 g_io_channel_unref(gio);
836                 return FALSE;
837         }
838
839         if (cond == G_IO_HUP) {
840
841                 _LOGI("socket G_IO_HUP");
842                 __callback_info_free_by_info(mi);
843                 return FALSE;
844
845         } else {
846
847                 if ((fd = g_io_channel_unix_get_fd(gio)) < 0) {
848                         _LOGE("fail to get fd from io channel");
849                         __callback_info_free_by_info(mi);
850                         return FALSE;
851                 }
852
853                 if ((pkt = __message_port_recv_raw(fd)) == NULL) {
854                         _LOGE("recv error on SOCKET");
855                         __callback_info_free_by_info(mi);
856                         return FALSE;
857                 }
858
859                 kb = bundle_decode(pkt->data, pkt->data_len);
860                 if (pkt->is_bidirection)
861                         mi->callback(mi->local_id, mi->remote_app_id, pkt->remote_port_name, pkt->is_trusted, kb, NULL);
862                 else
863                         mi->callback(mi->local_id, mi->remote_app_id, NULL, pkt->is_trusted, kb, NULL);
864
865                 bundle_free(kb);
866                 if (pkt) {
867                         if (pkt->remote_port_name)
868                                 free(pkt->remote_port_name);
869                         if (pkt->data)
870                                 free(pkt->data);
871                         free(pkt);
872                 }
873         }
874
875         return TRUE;
876 }
877
878 static bool send_message(GVariant *parameters, GDBusMethodInvocation *invocation)
879 {
880         char *local_port = NULL;
881         char *local_appid = NULL;
882         char *remote_appid = NULL;
883         char *remote_port = NULL;
884         gboolean local_trusted = false;
885         gboolean remote_trusted = false;
886         gboolean bi_dir = false;
887         int len = 0;
888
889         bundle *data = NULL;
890         bundle_raw *raw = NULL;
891         message_port_local_port_info_s *mi;
892         int local_reg_id = 0;
893         message_port_callback_info_s *callback_info;
894         message_port_callback_info_s *head_callback_info;
895         GList *callback_info_list = NULL;
896
897         char buf[1024];
898         GDBusMessage *msg;
899         GUnixFDList *fd_list;
900         int fd_len;
901         int *returned_fds = NULL;
902         int fd;
903
904         g_variant_get(parameters, "(&s&sbb&s&sbu&s)", &local_appid, &local_port, &local_trusted, &bi_dir,
905                         &remote_appid, &remote_port, &remote_trusted, &len, &raw);
906
907         if (!remote_port) {
908                 _LOGE("Invalid argument : remote_port is NULL");
909                 goto out;
910         }
911         if (!remote_appid) {
912                 _LOGE("Invalid argument : remote_appid is NULL");
913                 goto out;
914         }
915         if (!__is_local_port_registed(remote_port, remote_trusted, &local_reg_id, &mi)) {
916                 _LOGE("Invalid argument : remote_port:(%s) trusted(%d)", remote_port, remote_trusted);
917                 goto out;
918         }
919         if (!local_appid) {
920                 _LOGE("Invalid argument : local_appid");
921                 goto out;
922         }
923         if (!local_port) {
924                 _LOGE("Invalid argument : local_port");
925                 goto out;
926         }
927         if (strcmp(remote_appid, __app_id) != 0) {
928                 _LOGE("Invalid argument : remote_appid (%s)", remote_appid);
929                 goto out;
930         }
931         if (strcmp(remote_port, mi->port_name) != 0) {
932                 _LOGE("Invalid argument : remote_port (%s)", remote_port);
933                 goto out;
934         }
935         if (!len) {
936                 _LOGE("Invalid argument : data_len");
937                 goto out;
938         }
939         if (remote_trusted) {
940                 if (g_hash_table_lookup(__trusted_app_list_hash, (gpointer)local_appid) == NULL) {
941                         if (!__is_preloaded(local_appid, remote_appid)) {
942                                 int ret = __check_certificate(local_appid, remote_appid);
943                                 if (ret == MESSAGEPORT_ERROR_NONE)
944                                         g_hash_table_insert(__trusted_app_list_hash, local_appid, "TRUE");
945                                 else {
946                                         _LOGE("The application (%s) is not signed with the same certificate",
947                                                         local_appid);
948                                         goto out;
949                                 }
950                         }
951                 }
952         }
953
954         callback_info = (message_port_callback_info_s *)calloc(1, sizeof(message_port_callback_info_s));
955         if (callback_info == NULL)
956                 goto out;
957
958         callback_info->local_id = mi->local_id;
959         callback_info->remote_app_id = strdup(local_appid);
960         callback_info->callback = mi->callback;
961
962         msg = g_dbus_method_invocation_get_message(invocation);
963         fd_list = g_dbus_message_get_unix_fd_list(msg);
964
965         /* When application send message to self fd_list is NULL */
966         if (fd_list != NULL) {
967                 returned_fds = g_unix_fd_list_steal_fds(fd_list, &fd_len);
968                 if (returned_fds == NULL) {
969                         _LOGE("fail to get fds");
970                         __callback_info_free(callback_info);
971                         return false;
972                 }
973                 fd = returned_fds[0];
974
975                 LOGI("g_unix_fd_list_get %d fd: [%d]", fd_len, fd);
976                 if (fd > 0) {
977
978                         callback_info->gio_read = g_io_channel_unix_new(fd);
979                         if (!callback_info->gio_read) {
980                                 _LOGE("Error is %s\n", strerror_r(errno, buf, sizeof(buf)));
981                                 __callback_info_free(callback_info);
982                                 return false;
983                         }
984
985                         callback_info->g_src_id = g_io_add_watch(callback_info->gio_read, G_IO_IN | G_IO_HUP,
986                                         __socket_request_handler, (gpointer)callback_info);
987                         if (callback_info->g_src_id == 0) {
988                                 _LOGE("fail to add watch on socket");
989                                 __callback_info_free(callback_info);
990                                 return false;
991                         }
992
993                         callback_info_list = g_hash_table_lookup(__callback_info_hash, GUINT_TO_POINTER(mi->local_id));
994                         if (callback_info_list == NULL) {
995                                 head_callback_info = (message_port_callback_info_s *)calloc(1, sizeof(message_port_callback_info_s));
996                                 if (head_callback_info == NULL) {
997                                         _LOGE("fail to alloc head_callback_info");
998                                         __callback_info_free(callback_info);
999                                         return false;
1000                                 }
1001                                 head_callback_info->local_id = 0;
1002                                 head_callback_info->remote_app_id = NULL;
1003                                 head_callback_info->callback = NULL;
1004                                 head_callback_info->gio_read = NULL;
1005                                 head_callback_info->g_src_id = 0;
1006                                 callback_info_list = g_list_append(callback_info_list, head_callback_info);
1007                                 callback_info_list = g_list_append(callback_info_list, callback_info);
1008                                 g_hash_table_insert(__callback_info_hash, GUINT_TO_POINTER(mi->local_id), callback_info_list);
1009                         } else {
1010                                 callback_info_list = g_list_append(callback_info_list, callback_info);
1011                         }
1012                 }
1013         }
1014
1015         data = bundle_decode(raw, len);
1016         if (!data) {
1017                 _LOGE("Invalid argument : message");
1018                 goto out;
1019         }
1020
1021         LOGD("call calback %s", local_appid);
1022         if (bi_dir)
1023                 mi->callback(mi->local_id, local_appid, local_port, local_trusted, data, NULL);
1024         else
1025                 mi->callback(mi->local_id, local_appid, NULL, false, data, NULL);
1026         bundle_free(data);
1027 out:
1028         if (returned_fds)
1029                 free(returned_fds);
1030
1031         return true;
1032 }
1033
1034 static int __check_remote_port(const char *remote_app_id, const char *remote_port, bool is_trusted, bool *exist)
1035 {
1036         _LOGD("Check a remote port : [%s:%s]", remote_app_id, remote_port);
1037
1038         GVariant *result = NULL;
1039         GError *err = NULL;
1040         int ret_val = MESSAGEPORT_ERROR_NONE;
1041         char *bus_name = NULL;
1042         message_port_remote_app_info_s *remote_app_info = NULL;
1043         port_list_info_s *port_info = NULL;
1044         int local_reg_id = 0;
1045         message_port_local_port_info_s *mi = NULL;
1046         gboolean name_exist = false;
1047
1048         _LOGD("remote_app_id, app_id :[%s : %s] ", remote_app_id, __app_id);
1049
1050         ret_val = __get_remote_port_info(remote_app_id, remote_port, is_trusted, &remote_app_info, &port_info);
1051         if (ret_val != MESSAGEPORT_ERROR_NONE)
1052                 return ret_val;
1053
1054         /* self check */
1055         if (strcmp(remote_app_id, __app_id) == 0) {
1056
1057                 _LOGD("__is_local_port_registed ");
1058                 if (!__is_local_port_registed(remote_port, is_trusted, &local_reg_id, &mi))
1059                         *exist = false;
1060                 else
1061                         *exist = true;
1062
1063                 _LOGD("__is_local_port_registed : %d ", *exist);
1064                 return MESSAGEPORT_ERROR_NONE;
1065         }
1066
1067         port_info->exist = false;
1068         bus_name = port_info->encoded_bus_name;
1069
1070         result = g_dbus_connection_call_sync(
1071                         __gdbus_conn,
1072                         DBUS_SERVICE_DBUS,
1073                         DBUS_PATH_DBUS,
1074                         DBUS_INTERFACE_DBUS,
1075                         "NameHasOwner",
1076                         g_variant_new("(s)", bus_name),
1077                         G_VARIANT_TYPE("(b)"),
1078                         G_DBUS_CALL_FLAGS_NONE,
1079                         -1,
1080                         NULL,
1081                         &err);
1082
1083         if (err || (result == NULL)) {
1084                 if (err) {
1085                         _LOGE("No reply. error = %s", err->message);
1086                         g_error_free(err);
1087                 }
1088                 ret_val = MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE;
1089         } else {
1090                 g_variant_get(result, "(b)", &name_exist);
1091
1092                 if (!name_exist) {
1093                         _LOGI("Name not exist %s", bus_name);
1094                         *exist = false;
1095                         ret_val = MESSAGEPORT_ERROR_NONE;
1096                 } else {
1097
1098                         if (is_trusted) {
1099                                 if (remote_app_info->certificate_info != CERTIFICATE_MATCH) {
1100                                         if (!__is_preloaded(__app_id, remote_app_id)) {
1101                                                 if (__check_certificate(__app_id, remote_app_id) != MESSAGEPORT_ERROR_NONE) {
1102                                                         ret_val = MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
1103                                                         goto out;
1104                                                 }
1105                                         }
1106                                         remote_app_info->certificate_info = CERTIFICATE_MATCH;
1107                                 }
1108                         }
1109                         port_info->exist = true;
1110                         *exist = true;
1111                         ret_val = MESSAGEPORT_ERROR_NONE;
1112                 }
1113         }
1114 out:
1115         if (result)
1116                 g_variant_unref(result);
1117
1118         if (ret_val != MESSAGEPORT_ERROR_NONE || !name_exist)
1119                 __free_port_info((gpointer)port_info);
1120
1121         return ret_val;
1122 }
1123
1124 static void __on_sender_name_appeared(GDBusConnection *connection,
1125                 const gchar     *name,
1126                 const gchar     *name_owner,
1127                 gpointer         user_data)
1128 {
1129         _LOGI("sender name appeared : %s", name);
1130 }
1131
1132 static void __on_sender_name_vanished(GDBusConnection *connection,
1133                 const gchar     *name,
1134                 gpointer         user_data)
1135 {
1136         gboolean remove_result = FALSE;
1137         int *watcher_id = (int *)user_data;
1138         remove_result = g_hash_table_remove(__sender_appid_hash, (gpointer)name);
1139         if (!remove_result)
1140                 _LOGE("Fail to remove sender appid from hash : %s", name);
1141
1142         if (watcher_id) {
1143                 if (*watcher_id > 0)
1144                         g_bus_unwatch_name(*watcher_id);
1145                 else
1146                         LOGE("Invalid watcher_id %d", *watcher_id);
1147                 free(watcher_id);
1148         } else {
1149                 LOGE("watcher_id is NULL");
1150         }
1151 }
1152
1153 static bool __check_sender_validation(GVariant *parameters, const char *sender, GDBusConnection *conn)
1154 {
1155         int ret = 0;
1156         char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
1157         char *local_appid = NULL;
1158         int pid = __get_sender_pid(conn, sender);
1159         int *watcher_id = (int *)calloc(1, sizeof(int));
1160         retvm_if(!watcher_id, false, "Malloc failed");
1161
1162         ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
1163         if (ret != AUL_R_OK) {
1164                 _LOGE("Failed to get the sender ID: (%s) (%d)", sender, pid);
1165                 free(watcher_id);
1166                 return false;
1167         }
1168
1169         g_variant_get_child(parameters, 0, "&s", &local_appid);
1170         if (local_appid == NULL) {
1171                 _LOGE("appid is NULL : (%s) (%d)", sender, pid);
1172                 free(watcher_id);
1173                 return false;
1174         }
1175
1176         if (strncmp(buffer, local_appid, MAX_PACKAGE_STR_SIZE) == 0) {
1177                 _LOGD("insert sender !!!!! %s", sender);
1178                 g_hash_table_insert(__sender_appid_hash, (gpointer)strdup(sender), GINT_TO_POINTER(pid));
1179                 *watcher_id = g_bus_watch_name_on_connection(
1180                                         __gdbus_conn,
1181                                         sender,
1182                                         G_BUS_NAME_WATCHER_FLAGS_NONE,
1183                                         __on_sender_name_appeared,
1184                                         __on_sender_name_vanished,
1185                                         watcher_id,
1186                                         NULL);
1187         } else {
1188                 free(watcher_id);
1189                 return false;
1190         }
1191         return true;
1192 }
1193
1194 static void __dbus_method_call_handler(GDBusConnection *conn,
1195                                 const gchar *sender, const gchar *object_path,
1196                                 const gchar *iface_name, const gchar *method_name,
1197                                 GVariant *parameters, GDBusMethodInvocation *invocation,
1198                                 gpointer user_data)
1199 {
1200         _LOGI("method_name: %s, sender: %s", method_name, sender);
1201         gpointer sender_pid = g_hash_table_lookup(__sender_appid_hash, sender);
1202         if (sender_pid == NULL) {
1203                 if (!__check_sender_validation(parameters, sender, conn))
1204                         goto out;
1205         }
1206         if (g_strcmp0(method_name, "send_message") == 0)
1207                 send_message(parameters, invocation);
1208 out:
1209         g_dbus_method_invocation_return_value(invocation, NULL);
1210 }
1211
1212 static const GDBusInterfaceVTable interface_vtable = {
1213         __dbus_method_call_handler,
1214         NULL,
1215         NULL
1216 };
1217
1218 static int __dbus_init(void)
1219 {
1220         bool ret = false;
1221         GError *error = NULL;
1222
1223         __gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
1224         if (__gdbus_conn == NULL) {
1225                 if (error != NULL) {
1226                         _LOGE("Failed to get dbus [%s]", error->message);
1227                         g_error_free(error);
1228                 }
1229                 goto out;
1230         }
1231
1232         ret = true;
1233
1234 out:
1235         if (!__gdbus_conn)
1236                 g_object_unref(__gdbus_conn);
1237
1238         return ret;
1239
1240 }
1241
1242 int __register_dbus_interface(const char *port_name, bool is_trusted)
1243 {
1244
1245         GDBusNodeInfo *introspection_data = NULL;
1246         int registration_id = 0;
1247
1248         static gchar introspection_prefix[] =
1249                 "<node>"
1250                 "  <interface name='";
1251
1252         static gchar introspection_postfix[] =
1253                 "'>"
1254                 "        <method name='send_message'>"
1255                 "          <arg type='s' name='local_appid' direction='in'/>"
1256                 "          <arg type='s' name='local_port' direction='in'/>"
1257                 "          <arg type='b' name='local_trusted' direction='in'/>"
1258                 "          <arg type='b' name='bi_dir' direction='in'/>"
1259                 "          <arg type='s' name='remote_appid' direction='in'/>"
1260                 "          <arg type='s' name='remote_port' direction='in'/>"
1261                 "          <arg type='b' name='remote_trusted' direction='in'/>"
1262                 "          <arg type='u' name='data_len' direction='in'/>"
1263                 "          <arg type='s' name='data' direction='in'/>"
1264                 "        </method>"
1265                 "  </interface>"
1266                 "</node>";
1267
1268         char *introspection_xml = NULL;
1269         int introspection_xml_len = 0;
1270
1271
1272         int owner_id = 0;
1273         GError *error = NULL;
1274         char *bus_name = NULL;
1275         char *interface_name = NULL;
1276         GVariant *result = NULL;
1277
1278         bus_name = __get_encoded_name(__app_id, port_name, is_trusted);
1279         if (!bus_name) {
1280                 _LOGE("Fail to get bus name");
1281                 goto out;
1282         }
1283         interface_name = bus_name;
1284
1285         introspection_xml_len = strlen(introspection_prefix) + strlen(interface_name) +
1286                 strlen(introspection_postfix) + 1;
1287
1288         introspection_xml = (char *)calloc(introspection_xml_len, sizeof(char));
1289         if (!introspection_xml) {
1290                 _LOGE("out of memory");
1291                 goto out;
1292         }
1293
1294
1295         result = g_dbus_connection_call_sync(
1296                         __gdbus_conn,
1297                         DBUS_SERVICE_DBUS,
1298                         DBUS_PATH_DBUS,
1299                         DBUS_INTERFACE_DBUS,
1300                         "RequestName",
1301                         g_variant_new("(su)", bus_name, G_BUS_NAME_OWNER_FLAGS_NONE),
1302                         G_VARIANT_TYPE("(u)"),
1303                         G_DBUS_CALL_FLAGS_NONE,
1304                         -1,
1305                         NULL,
1306                         &error);
1307         if (error) {
1308                 _LOGE("RequestName fail : %s", error->message);
1309                 g_error_free(error);
1310                 goto out;
1311         }
1312         if (result == NULL) {
1313                 _LOGE("fail to get name NULL");
1314                 goto out;
1315         }
1316         g_variant_get(result, "(u)", &owner_id);
1317         if (owner_id == 0) {
1318                 _LOGE("Acquiring the own name is failed");
1319                 goto out;
1320         }
1321
1322         _LOGD("Acquiring the own name : %d", owner_id);
1323
1324         snprintf(introspection_xml, introspection_xml_len, "%s%s%s", introspection_prefix, interface_name, introspection_postfix);
1325
1326         introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
1327         if (!introspection_data) {
1328                 _LOGE("g_dbus_node_info_new_for_xml() is failed.");
1329                 goto out;
1330         }
1331
1332         registration_id = g_dbus_connection_register_object(__gdbus_conn,
1333                                                 MESSAGEPORT_OBJECT_PATH, introspection_data->interfaces[0],
1334                                                 &interface_vtable, NULL, NULL, NULL);
1335
1336         _LOGD("registration_id %d", registration_id);
1337
1338         if (registration_id == 0) {
1339                 _LOGE("Failed to g_dbus_connection_register_object");
1340                 goto out;
1341         }
1342
1343 out:
1344         if (introspection_data)
1345                 g_dbus_node_info_unref(introspection_data);
1346         if (introspection_xml)
1347                 free(introspection_xml);
1348         if (bus_name)
1349                 free(bus_name);
1350         if (result)
1351                 g_variant_unref(result);
1352
1353
1354         return registration_id;
1355 }
1356
1357 /* LCOV_EXCL_START */
1358 static void __hash_destory_local_value(gpointer data)
1359 {
1360         message_port_local_port_info_s *mli = (message_port_local_port_info_s *)data;
1361         if (mli) {
1362                 if (mli->port_name)
1363                         free(mli->port_name);
1364                 free(mli);
1365         }
1366 }
1367 /* LCOV_EXCL_STOP */
1368
1369 /* LCOV_EXCL_START */
1370 static void __hash_destory_remote_value(gpointer data)
1371 {
1372         message_port_remote_app_info_s *mri = (message_port_remote_app_info_s *)data;
1373         if (mri) {
1374                 FREE_AND_NULL(mri->remote_app_id);
1375                 if (mri->port_list)
1376                         g_list_free_full(mri->port_list, __free_port_info);
1377
1378                 free(mri);
1379         }
1380 }
1381 /* LCOV_EXCL_STOP */
1382
1383 static bool __initialize(void)
1384 {
1385
1386 #if !GLIB_CHECK_VERSION(2, 35, 0)
1387         g_type_init();
1388 #endif
1389
1390         int pid = getpid();
1391         int ret = 0;
1392         char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
1393
1394         ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
1395         retvm_if(ret != AUL_R_OK, false, "Failed to get the application ID: %d", ret);
1396
1397         __app_id = strdup(buffer);
1398         retvm_if(!__app_id, false, "Malloc failed");
1399         _LOGI("init : %s", __app_id);
1400
1401         if (__local_port_info == NULL) {
1402                 __local_port_info = g_hash_table_new_full(g_direct_hash,  g_direct_equal, NULL, __hash_destory_local_value);
1403                 retvm_if(!__local_port_info, false, "fail to create __local_port_info");
1404         }
1405
1406         if (__remote_app_info == NULL) {
1407                 __remote_app_info = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __hash_destory_remote_value);
1408                 retvm_if(!__remote_app_info, false, "fail to create __remote_app_info");
1409         }
1410
1411         if (__sender_appid_hash == NULL) {
1412                 __sender_appid_hash = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
1413                 retvm_if(!__sender_appid_hash, false, "fail to create __sender_appid_hash");
1414         }
1415
1416         if (__trusted_app_list_hash == NULL) {
1417                 __trusted_app_list_hash = g_hash_table_new(g_str_hash, g_str_equal);
1418                 retvm_if(!__trusted_app_list_hash, false, "fail to create __trusted_app_list_hash");
1419         }
1420
1421         if (__callback_info_hash == NULL) {
1422                 __callback_info_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __hash_destroy_callback_info);
1423                 retvm_if(!__callback_info_hash, false, "fail to create __callback_info_hash");
1424         }
1425
1426         if (!__dbus_init())
1427                 return false;
1428         _initialized = true;
1429
1430         return true;
1431 }
1432
1433
1434 static bool __message_port_register_port(const int local_id, const char *local_port, bool is_trusted, messageport_message_cb callback)
1435 {
1436         message_port_local_port_info_s *mi = (message_port_local_port_info_s *)calloc(1, sizeof(message_port_local_port_info_s));
1437         retvm_if(!mi, false, "Malloc failed");
1438
1439         mi->callback = callback;
1440         mi->is_trusted = is_trusted;
1441         mi->port_name = strdup(local_port);
1442         if (mi->port_name == NULL) {
1443                 _LOGE("Malloc failed (%s)", local_port);
1444                 free(mi);
1445                 return false;
1446         }
1447         mi->local_id = local_id;
1448
1449         g_hash_table_insert(__local_port_info, GINT_TO_POINTER(mi->local_id), mi);
1450         return true;
1451 }
1452
1453 static int __register_message_port(const char *local_port, bool is_trusted, messageport_message_cb callback)
1454 {
1455         _SECURE_LOGI("local_port : [%s:%s]", local_port, is_trusted ? "trusted" : "non-trusted");
1456
1457         int local_id = 0;
1458
1459         /* Check the message port is already registed */
1460         if (__is_local_port_registed(local_port, is_trusted, &local_id, NULL))
1461                 return local_id;
1462
1463         local_id = __register_dbus_interface(local_port, is_trusted);
1464         if (local_id < 1) {
1465                 _LOGE("register_dbus_interface fail !!");
1466                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1467         }
1468
1469         if (!__message_port_register_port(local_id, local_port, is_trusted, callback))
1470                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1471
1472         return local_id;
1473 }
1474
1475 static void __free_delay_message_info(delay_message_info_s *message)
1476 {
1477         if (message != NULL) {
1478                 FREE_AND_NULL(message->local_port_name);
1479                 FREE_AND_NULL(message->data);
1480                 FREE_AND_NULL(message);
1481         }
1482 }
1483
1484 static void __free_list_delay_message_info(gpointer data)
1485 {
1486         delay_message_info_s *message = (delay_message_info_s *)data;
1487
1488         if (message != NULL)
1489                 __free_delay_message_info(message);
1490 }
1491
1492 static int __send_delayed_message(int sockfd, delay_message_info_s *message)
1493 {
1494         unsigned int nb = 0;
1495         int sequence = message->sequence - 1;
1496         int ret = MESSAGEPORT_ERROR_NONE;
1497         bool is_startline = true;
1498         int offset = 0;
1499
1500         _LOGI("send_delayed_message : sockfd (%d) sequence(%d) sent byte(%d)",
1501                 sockfd, message->sequence, message->sent_bytes);
1502
1503         switch (message->sequence) {
1504         case SEQUENCE_START:
1505                 sequence++;
1506                 is_startline = false;
1507
1508         case SEQUENCE_PORT_LEN:
1509                 if (is_startline)
1510                         offset = message->sent_bytes;
1511
1512                 ret = __write_socket(sockfd, ((char *)&message->local_port_len) + offset,
1513                                 sizeof(message->local_port_len) - offset, &nb, &sequence);
1514                 if (ret != MESSAGEPORT_ERROR_NONE) {
1515                         _LOGE("write local_port_len fail");
1516                         goto out;
1517                 }
1518                 offset = 0;
1519                 is_startline = false;
1520
1521         case SEQUENCE_PORT_NAME:
1522                 if (is_startline)
1523                         offset = message->sent_bytes;
1524
1525                 if (message->local_port_len > 0)
1526                         ret = __write_socket(sockfd, message->local_port_name + offset,
1527                                 message->local_port_len - offset , &nb, &sequence);
1528                 else
1529                         sequence++;
1530
1531                 if (ret != MESSAGEPORT_ERROR_NONE) {
1532                         _LOGE("write local_port fail");
1533                         goto out;
1534                 }
1535                 offset = 0;
1536                 is_startline = false;
1537
1538         case SEQUENCE_BIDIRECTION:
1539                 if (is_startline)
1540                         offset = message->sent_bytes;
1541
1542                 ret = __write_socket(sockfd, ((char *)&message->is_bidirection) + offset,
1543                                 sizeof(message->is_bidirection) - offset, &nb, &sequence);
1544                 if (ret != MESSAGEPORT_ERROR_NONE) {
1545                         _LOGE("write is_bidirection fail");
1546                         goto out;
1547                 }
1548                 offset = 0;
1549                 is_startline = false;
1550
1551         case SEQUENCE_TRUSTED:
1552                 if (is_startline)
1553                         offset = message->sent_bytes;
1554
1555                 ret = __write_socket(sockfd, ((char *)&message->local_trusted) + offset,
1556                                 sizeof(message->local_trusted) - offset, &nb, &sequence);
1557                 if (ret != MESSAGEPORT_ERROR_NONE) {
1558                         _LOGE("write local_trusted fail");
1559                         goto out;
1560                 }
1561                 offset = 0;
1562                 is_startline = false;
1563
1564         case SEQUENCE_DTAT_LEN:
1565                 if (is_startline)
1566                         offset = message->sent_bytes;
1567
1568                 ret = __write_socket(sockfd, ((char *)&message->data_len) + offset,
1569                                 sizeof(message->data_len) - offset, &nb, &sequence);
1570                 if (ret != MESSAGEPORT_ERROR_NONE) {
1571                         _LOGE("write data_len fail");
1572                         goto out;
1573                 }
1574                 offset = 0;
1575                 is_startline = false;
1576
1577         case SEQUENCE_DATA:
1578                 if (is_startline)
1579                         offset = message->sent_bytes;
1580
1581                 ret = __write_socket(sockfd, (char *)message->data + offset,
1582                         message->data_len -offset, &nb, &sequence);
1583
1584                 if (ret != MESSAGEPORT_ERROR_NONE) {
1585                         _LOGE("write data fail");
1586                         goto out;
1587                 }
1588                 offset = 0;
1589                 is_startline = false;
1590
1591         default:
1592                 ret = MESSAGEPORT_ERROR_NONE;
1593
1594         }
1595
1596 out:
1597         if (ret == MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE) {
1598                 if (is_startline)
1599                          message->sent_bytes += nb;
1600                 else
1601                          message->sent_bytes = nb;
1602
1603                 message->sequence = sequence;
1604                 _LOGE("send_delayed_message fail : sockfd (%d) sequence(%d) sent byte(%d)",
1605                         sockfd, message->sequence, message->sent_bytes);
1606         }
1607
1608         return ret;
1609
1610 }
1611
1612 static gboolean __process_delayed_message(gint fd, GIOCondition cond, gpointer data)
1613 {
1614         port_list_info_s *port_info = (port_list_info_s *)data;
1615         delay_message_info_s *message;
1616         int ret;
1617
1618         if (port_info == NULL)
1619                 return G_SOURCE_REMOVE;
1620
1621         pthread_mutex_lock(&mutex);
1622
1623         if (port_info->delayed_message_list == NULL) {
1624                 port_info->delayed_message_size = 0;
1625                 port_info->delay_src_id = 0;
1626                 pthread_mutex_unlock(&mutex);
1627                 return G_SOURCE_REMOVE;
1628         } else {
1629                 message = g_list_nth_data(port_info->delayed_message_list, 0);
1630                 ret = __send_delayed_message(port_info->send_sock_fd, message);
1631
1632                 if (ret == MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE) {
1633                         pthread_mutex_unlock(&mutex);
1634                         return G_SOURCE_CONTINUE;
1635                 } else if (ret == MESSAGEPORT_ERROR_IO_ERROR) {
1636                         __free_port_info((gpointer)port_info);
1637                         pthread_mutex_unlock(&mutex);
1638                         return G_SOURCE_REMOVE;
1639                 }
1640
1641                 port_info->delayed_message_size -= message->size;
1642
1643                 port_info->delayed_message_list = g_list_remove(port_info->delayed_message_list, message);
1644                 __free_delay_message_info(message);
1645         }
1646
1647         pthread_mutex_unlock(&mutex);
1648
1649         return G_SOURCE_CONTINUE;
1650 }
1651
1652 static int __insert_delayed_message(port_list_info_s *port_info,
1653         int sequence,
1654         bundle_raw *kb_data,
1655         int data_len,
1656         unsigned int sent_bytes,
1657         const char *local_port,
1658         bool local_trusted,
1659         bool is_bidirection)
1660 {
1661 #define QUEUE_SIZE_MAX (1024 * 1024) /* 1MB per remote port (MAX) */
1662
1663         unsigned int tmp_size;
1664         unsigned int message_size;
1665         int ret = MESSAGEPORT_ERROR_NONE;
1666
1667         if (port_info->delayed_message_size >= QUEUE_SIZE_MAX) {
1668                 _LOGE("cache fail : delayed_message_size (%d), count(%d)",
1669                         port_info->delayed_message_size, g_list_length(port_info->delayed_message_list));
1670                 return MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE;
1671         }
1672
1673         delay_message_info_s *message = (delay_message_info_s *)calloc(1, sizeof(delay_message_info_s));
1674         retvm_if(!message, MESSAGEPORT_ERROR_OUT_OF_MEMORY, "Malloc failed");
1675
1676         message_size = sizeof(delay_message_info_s);
1677
1678         message->sequence = sequence;
1679         tmp_size = strlen(local_port) + 1;
1680         message_size += tmp_size;
1681         message->local_port_len = tmp_size;
1682         message->local_port_name = strdup(local_port);
1683         if (message->local_port_name == NULL) {
1684                 _LOGE("local_port_name strdup fail");
1685                 ret = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1686                 goto out;
1687         }
1688         message->is_bidirection = is_bidirection;
1689         message->local_trusted = local_trusted;
1690         message_size += data_len;
1691         message->data_len = data_len;
1692         message->data = (bundle_raw *)strdup((const char *)kb_data);
1693         if (message->data == NULL) {
1694                 _LOGE("data strdup fail");
1695                 ret = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1696                 goto out;
1697         }
1698
1699
1700         message->sent_bytes = sent_bytes;
1701         message->size = message_size;
1702         port_info->delayed_message_size += message_size;
1703
1704         port_info->delayed_message_list = g_list_append(port_info->delayed_message_list, message);
1705
1706         if (port_info->delay_src_id == 0) {
1707                         port_info->delay_src_id = g_unix_fd_add_full(G_PRIORITY_DEFAULT,
1708                                                         port_info->send_sock_fd, G_IO_OUT, __process_delayed_message,
1709                                                         port_info, NULL);
1710         }
1711
1712         _LOGE("inserted : pm(%s) fd(%d) ms(%d) ds(%d) dlc(%d) sqn(%d) sb (%d)",
1713                 port_info->port_name, port_info->send_sock_fd, message_size,
1714                 port_info->delayed_message_size,
1715                 g_list_length(port_info->delayed_message_list), sequence, sent_bytes);
1716
1717
1718
1719 out:
1720         if (ret != MESSAGEPORT_ERROR_NONE)
1721                 __free_delay_message_info(message);
1722
1723         return ret;
1724 }
1725
1726 int __message_port_send_async(port_list_info_s *port_info, bundle *kb, const char *local_port,
1727                 bool local_trusted, bool is_bidirection)
1728 {
1729         int ret = 0;
1730         int data_len;
1731         int local_port_len = 0;
1732         unsigned int nb = 0;
1733         bundle_raw *kb_data = NULL;
1734         int sequence = SEQUENCE_START;
1735
1736         bundle_encode(kb, &kb_data, &data_len);
1737         if (kb_data == NULL) {
1738                 _LOGE("bundle encode fail");
1739                 ret = MESSAGEPORT_ERROR_INVALID_PARAMETER;
1740                 goto out;
1741         }
1742
1743         if (data_len > MAX_MESSAGE_SIZE) {
1744                 _LOGE("bigger than max size\n");
1745                 ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
1746                 goto out;
1747         }
1748
1749         if (g_list_length(port_info->delayed_message_list) > 0) {
1750                 ret = MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE;
1751                 _LOGE("There are messages in the delayed_message_list (count %d)",
1752                         g_list_length(port_info->delayed_message_list));
1753                 goto out;
1754         }
1755
1756         if (local_port != NULL)
1757                 local_port_len = strlen(local_port) + 1;
1758
1759         ret = __write_string_to_socket(port_info->send_sock_fd, local_port,
1760                         local_port_len, &nb, &sequence);
1761         if (ret != MESSAGEPORT_ERROR_NONE) {
1762                 _LOGE("write local_port fail");
1763                 goto out;
1764         }
1765
1766         ret = __write_socket(port_info->send_sock_fd, (char *)&is_bidirection,
1767                         sizeof(is_bidirection), &nb, &sequence);
1768         if (ret != MESSAGEPORT_ERROR_NONE) {
1769                 _LOGE("write is_bidirection fail");
1770                 goto out;
1771         }
1772
1773         ret = __write_socket(port_info->send_sock_fd, (char *)&local_trusted,
1774                         sizeof(local_trusted), &nb, &sequence);
1775         if (ret != MESSAGEPORT_ERROR_NONE) {
1776                 _LOGE("write local_trusted fail");
1777                 goto out;
1778         }
1779
1780         ret = __write_string_to_socket(port_info->send_sock_fd, (void *)kb_data,
1781                         data_len, &nb, &sequence);
1782         if (ret != MESSAGEPORT_ERROR_NONE) {
1783                 _LOGE("write kb_data fail");
1784                 goto out;
1785         }
1786
1787 out:
1788         if (ret == MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE) {
1789                 ret = __insert_delayed_message(port_info, sequence, kb_data, data_len, nb,
1790                         local_port, local_trusted, is_bidirection);
1791                 if (ret != MESSAGEPORT_ERROR_NONE)
1792                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1793         }
1794
1795         if (kb_data)
1796                 free(kb_data);
1797
1798         return ret;
1799 }
1800
1801 static int __message_port_send_message(const char *remote_appid, const char *remote_port,
1802                 const char *local_port, bool trusted_message, bool local_trusted, bool bi_dir, bundle *message)
1803 {
1804
1805         int ret = MESSAGEPORT_ERROR_NONE;
1806         GUnixFDList *fd_list = NULL;
1807
1808         int len = 0;
1809         bundle_raw *raw = NULL;
1810         char *bus_name = NULL;
1811         char *interface_name = NULL;
1812
1813         message_port_remote_app_info_s *remote_app_info = NULL;
1814         port_list_info_s *port_info = NULL;
1815         GDBusMessage *msg = NULL;
1816         GError *err = NULL;
1817         GVariant *body = NULL;
1818         int sock_pair[2] = {0,};
1819         char buf[1024];
1820
1821         ret = __get_remote_port_info(remote_appid, remote_port, trusted_message, &remote_app_info, &port_info);
1822         if (ret != MESSAGEPORT_ERROR_NONE)
1823                 return ret;
1824
1825         if (port_info->exist == false) {
1826                 bool exist = false;
1827                 _LOGD("port exist check !!");
1828                 ret =  __check_remote_port(remote_appid, remote_port, trusted_message, &exist);
1829                 if (ret != MESSAGEPORT_ERROR_NONE)
1830                         return ret;
1831                 else if (!exist)
1832                         return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1833         }
1834
1835         if (port_info->send_sock_fd > 0) {
1836                 ret = __message_port_send_async(port_info, message,
1837                                 (local_port) ? local_port : "", local_trusted, bi_dir);
1838         } else {
1839
1840                 bus_name = port_info->encoded_bus_name;
1841                 interface_name = bus_name;
1842
1843                 if (bundle_encode(message, &raw, &len) != BUNDLE_ERROR_NONE) {
1844                         ret = MESSAGEPORT_ERROR_INVALID_PARAMETER;
1845                         goto out;
1846                 }
1847
1848                 if (MAX_MESSAGE_SIZE < len) {
1849                         _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
1850                         ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
1851                         goto out;
1852                 }
1853
1854                 body = g_variant_new("(ssbbssbus)", __app_id, (local_port) ? local_port : "", local_trusted, bi_dir,
1855                                 remote_appid, remote_port, trusted_message, len, raw);
1856                 if (strcmp(remote_appid, __app_id) != 0) { /* self send */
1857
1858                         /*  if message-port fail to get socket pair, communicate using GDBus */
1859                         if (aul_request_message_port_socket_pair(sock_pair) != AUL_R_OK) {
1860                                 _LOGE("error create socket pair");
1861                         } else {
1862
1863                                 _LOGI("sock pair : %d, %d",
1864                                                 sock_pair[SOCK_PAIR_SENDER], sock_pair[SOCK_PAIR_RECEIVER]);
1865                                 fd_list = g_unix_fd_list_new();
1866                                 g_unix_fd_list_append(fd_list, sock_pair[SOCK_PAIR_RECEIVER], &err);
1867                                 if (err != NULL) {
1868                                         _LOGE("g_unix_fd_list_append [%s]", err->message);
1869                                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1870                                         g_error_free(err);
1871                                         goto out;
1872                                 }
1873
1874                                 port_info->send_sock_fd = sock_pair[SOCK_PAIR_SENDER];
1875                                 close(sock_pair[SOCK_PAIR_RECEIVER]);
1876                                 sock_pair[SOCK_PAIR_RECEIVER] = 0;
1877
1878                                 port_info->gio_read = g_io_channel_unix_new(port_info->send_sock_fd);
1879                                 if (!port_info->gio_read) {
1880                                         _LOGE("Error is %s\n", strerror_r(errno, buf, sizeof(buf)));
1881                                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1882                                         goto out;
1883                                 }
1884
1885                                 port_info->g_src_id = g_io_add_watch(
1886                                                 port_info->gio_read,
1887                                                 G_IO_IN | G_IO_HUP,
1888                                                 __socket_disconnect_handler,
1889                                                 (gpointer)port_info);
1890                                 if (port_info->g_src_id == 0) {
1891                                         _LOGE("fail to add watch on socket");
1892                                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1893                                         goto out;
1894                                 }
1895
1896                         }
1897                 }
1898
1899                 msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, interface_name, "send_message");
1900                 if (!msg) {
1901                         _LOGE("Can't allocate new method call");
1902                         ret = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1903                         goto out;
1904                 }
1905
1906                 g_dbus_message_set_unix_fd_list(msg, fd_list);
1907                 g_dbus_message_set_body(msg, body);
1908                 g_dbus_connection_send_message(__gdbus_conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err);
1909                 if (err != NULL) {
1910                         _LOGE("No reply. error = %s", err->message);
1911                         g_error_free(err);
1912                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1913                         goto out;
1914                 }
1915         }
1916
1917 out:
1918         if (msg)
1919                 g_object_unref(msg);
1920         if (raw)
1921                 bundle_free_encoded_rawdata(&raw);
1922         if (fd_list)
1923                 g_object_unref(fd_list);
1924
1925         if (ret != MESSAGEPORT_ERROR_NONE) {
1926                 __free_port_info((gpointer)port_info);
1927                 if (sock_pair[SOCK_PAIR_SENDER])
1928                         close(sock_pair[SOCK_PAIR_SENDER]);
1929                 if (sock_pair[SOCK_PAIR_RECEIVER])
1930                         close(sock_pair[SOCK_PAIR_RECEIVER]);
1931         }
1932
1933         return ret;
1934 }
1935
1936 int __message_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port,  bool trusted_message, bundle *message)
1937 {
1938         message_port_local_port_info_s *local_info;
1939         int ret = __get_local_port_info(id, &local_info);
1940         if (ret != MESSAGEPORT_ERROR_NONE)
1941                 return ret;
1942
1943         _LOGD("bidirectional_message %s", local_info->port_name);
1944         return __message_port_send_message(remote_app_id, remote_port,
1945                         local_info->port_name, trusted_message, local_info->is_trusted, true, message);
1946 }
1947
1948 static void __name_registered(GDBusConnection *connection,
1949                 const gchar *name,
1950                 const gchar *name_owner,
1951                 gpointer user_data)
1952 {
1953
1954         registered_callback_info_s *info = (registered_callback_info_s *)user_data;
1955         if (info == NULL) {
1956                 LOGE("NULL registered_callback_info");
1957                 return;
1958         }
1959
1960         _LOGI("watcher_id : %d, appeared name : %s , name_owner : %s\n", info->watcher_id, name, name_owner);
1961         if (info->registered_cb)
1962                 info->registered_cb(info->remote_app_id, info->remote_port, info->is_trusted, info->user_data);
1963 }
1964
1965 static void __name_unregistered(GDBusConnection *connection,
1966                 const gchar *name,
1967                 gpointer user_data)
1968 {
1969
1970         registered_callback_info_s *info = (registered_callback_info_s *)user_data;
1971         if (info == NULL) {
1972                 LOGE("NULL registered_callback_info");
1973                 return;
1974         }
1975
1976         _LOGI("watcher_id : %d, vanished name : %s\n", info->watcher_id, name);
1977         if (info->unregistered_cb)
1978                 info->unregistered_cb(info->remote_app_id, info->remote_port, info->is_trusted, info->user_data);
1979 }
1980
1981 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)
1982 {
1983         int ret_val = MESSAGEPORT_ERROR_NONE;
1984         message_port_remote_app_info_s *remote_app_info = NULL;
1985         port_list_info_s *port_info = NULL;
1986
1987         _LOGI("remote_app_id, app_id :[%s : %s] ", remote_app_id, __app_id);
1988
1989         ret_val = __get_remote_port_info(remote_app_id, remote_port, trusted_remote_port, &remote_app_info, &port_info);
1990         if (ret_val != MESSAGEPORT_ERROR_NONE)
1991                 return ret_val;
1992
1993         if (__registered_callback_info_hash == NULL)
1994                 __registered_callback_info_hash = g_hash_table_new_full(g_direct_hash,  g_direct_equal, NULL, __registered_callback_info_free);
1995
1996         registered_callback_info_s *registered_cb_info = (registered_callback_info_s *)calloc(1, sizeof(registered_callback_info_s));
1997         retvm_if(!registered_cb_info, MESSAGEPORT_ERROR_OUT_OF_MEMORY, "Malloc failed");
1998
1999         registered_cb_info->registered_cb = registered_cb;
2000         registered_cb_info->unregistered_cb = unregistered_cb;
2001         registered_cb_info->user_data = user_data;
2002         registered_cb_info->remote_app_id = strdup(remote_app_info->remote_app_id);
2003         if (registered_cb_info->remote_app_id == NULL) {
2004                 free(registered_cb_info);
2005                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
2006         }
2007         registered_cb_info->remote_port = strdup(port_info->port_name);
2008         if (registered_cb_info->remote_port == NULL) {
2009                 free(registered_cb_info->remote_app_id);
2010                 free(registered_cb_info);
2011                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
2012         }
2013
2014         registered_cb_info->watcher_id = g_bus_watch_name_on_connection(
2015                         __gdbus_conn,
2016                         port_info->encoded_bus_name,
2017                         G_BUS_NAME_WATCHER_FLAGS_NONE,
2018                         __name_registered,
2019                         __name_unregistered,
2020                         registered_cb_info,
2021                         NULL);
2022         if (registered_cb_info->watcher_id == 0) {
2023                 free(registered_cb_info->remote_app_id);
2024                 free(registered_cb_info->remote_port);
2025                 free(registered_cb_info);
2026                 return MESSAGEPORT_ERROR_IO_ERROR;
2027         }
2028
2029         g_hash_table_insert(__registered_callback_info_hash,
2030                         GINT_TO_POINTER(registered_cb_info->watcher_id), registered_cb_info);
2031
2032         *watcher_id = registered_cb_info->watcher_id;
2033         return MESSAGEPORT_ERROR_NONE;
2034 }
2035
2036 int messageport_unregister_local_port(int local_port_id, bool trusted_port)
2037 {
2038
2039         GVariant *result;
2040         char *bus_name = NULL;
2041         GError *err = NULL;
2042         int ret = 0;
2043
2044         _LOGI("unregister : %d", local_port_id);
2045
2046         message_port_local_port_info_s *mi =
2047                 (message_port_local_port_info_s *)
2048                 g_hash_table_lookup(__local_port_info, GINT_TO_POINTER(local_port_id));
2049         if (mi == NULL)
2050                 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
2051
2052         if (mi->is_trusted != trusted_port)
2053                 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
2054
2055         g_hash_table_remove(__callback_info_hash, GUINT_TO_POINTER(local_port_id));
2056
2057         bus_name = __get_encoded_name(__app_id, mi->port_name, mi->is_trusted);
2058         if (bus_name == NULL)
2059                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
2060
2061         g_dbus_connection_unregister_object(__gdbus_conn, local_port_id);
2062
2063         result = g_dbus_connection_call_sync(
2064                         __gdbus_conn,
2065                         DBUS_SERVICE_DBUS,
2066                         DBUS_PATH_DBUS,
2067                         DBUS_INTERFACE_DBUS,
2068                         "ReleaseName",
2069                         g_variant_new("(s)", bus_name),
2070                         G_VARIANT_TYPE("(u)"),
2071                         G_DBUS_CALL_FLAGS_NONE,
2072                         -1,
2073                         NULL,
2074                         &err);
2075
2076         if (bus_name)
2077                 free(bus_name);
2078
2079         if (err) {
2080                 _LOGE("RequestName fail : %s", err->message);
2081                 g_error_free(err);
2082                 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
2083         }
2084         g_variant_get(result, "(u)", &ret);
2085
2086         if (result)
2087                 g_variant_unref(result);
2088
2089         if (ret != DBUS_RELEASE_NAME_REPLY_RELEASED) {
2090
2091                 if (ret == DBUS_RELEASE_NAME_REPLY_NON_EXISTENT) {
2092                         _LOGE("Port Not exist");
2093                         return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
2094                 } else if (ret == DBUS_RELEASE_NAME_REPLY_NOT_OWNER) {
2095                         _LOGE("Try to release not owned name. MESSAGEPORT_ERROR_INVALID_PARAMETER");
2096                         return MESSAGEPORT_ERROR_INVALID_PARAMETER;
2097                 }
2098         }
2099
2100
2101         g_hash_table_remove(__local_port_info, GINT_TO_POINTER(local_port_id));
2102
2103         return MESSAGEPORT_ERROR_NONE;
2104 }
2105
2106 int messageport_register_local_port(const char *local_port, messageport_message_cb callback)
2107 {
2108         if (!_initialized) {
2109                 if (!__initialize())
2110                         return MESSAGEPORT_ERROR_IO_ERROR;
2111         }
2112
2113         return __register_message_port(local_port, false, callback);
2114 }
2115
2116 int messageport_register_trusted_local_port(const char *local_port, messageport_message_cb callback)
2117 {
2118         if (!_initialized) {
2119                 if (!__initialize())
2120                         return MESSAGEPORT_ERROR_IO_ERROR;
2121         }
2122
2123         return __register_message_port(local_port, true, callback);
2124
2125 }
2126
2127 int messageport_check_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
2128 {
2129         if (!_initialized) {
2130                 if (!__initialize())
2131                         return MESSAGEPORT_ERROR_IO_ERROR;
2132         }
2133
2134         int ret = __check_remote_port(remote_app_id, remote_port, false, exist);
2135         if (ret == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND) {
2136                 *exist = false;
2137                 ret = MESSAGEPORT_ERROR_NONE;
2138         }
2139
2140         return ret;
2141 }
2142
2143 int messageport_check_trusted_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
2144 {
2145         if (!_initialized) {
2146                 if (!__initialize())
2147                         return MESSAGEPORT_ERROR_IO_ERROR;
2148         }
2149
2150         int ret = __check_remote_port(remote_app_id, remote_port, true, exist);
2151         if (ret == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND) {
2152                 *exist = false;
2153                 ret = MESSAGEPORT_ERROR_NONE;
2154         }
2155
2156         return ret;
2157 }
2158
2159 int messageport_send_message(const char *remote_app_id, const char *remote_port, bundle *message)
2160 {
2161         if (!_initialized) {
2162                 if (!__initialize())
2163                         return MESSAGEPORT_ERROR_IO_ERROR;
2164         }
2165
2166         return __message_port_send_message(remote_app_id, remote_port, NULL, false, false, false, message);
2167 }
2168
2169 int messageport_send_trusted_message(const char *remote_app_id, const char *remote_port, bundle *message)
2170 {
2171         if (!_initialized) {
2172                 if (!__initialize())
2173                         return MESSAGEPORT_ERROR_IO_ERROR;
2174         }
2175
2176         return __message_port_send_message(remote_app_id, remote_port, NULL, true, false, false, message);
2177 }
2178
2179 int messageport_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port,
2180                 bundle *message)
2181 {
2182         if (!_initialized) {
2183                 if (!__initialize())
2184                         return MESSAGEPORT_ERROR_IO_ERROR;
2185         }
2186
2187         return __message_send_bidirectional_message(id, remote_app_id, remote_port, false, message);
2188 }
2189
2190 int messageport_send_bidirectional_trusted_message(int id, const char *remote_app_id, const char *remote_port,
2191                 bundle *message)
2192 {
2193         if (!_initialized) {
2194                 if (!__initialize())
2195                         return MESSAGEPORT_ERROR_IO_ERROR;
2196         }
2197         return __message_send_bidirectional_message(id, remote_app_id, remote_port, true, message);
2198 }
2199
2200 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)
2201 {
2202         if (!_initialized) {
2203                 if (!__initialize())
2204                         return MESSAGEPORT_ERROR_IO_ERROR;
2205         }
2206         return __messageport_watch_remote_port(watcher_id, remote_app_id, remote_port, is_trusted, registered_cb, NULL, user_data);
2207 }
2208
2209 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)
2210 {
2211         if (!_initialized) {
2212                 if (!__initialize())
2213                         return MESSAGEPORT_ERROR_IO_ERROR;
2214         }
2215         return __messageport_watch_remote_port(watcher_id, remote_app_id, remote_port, is_trusted, NULL, unregistered_cb, user_data);
2216 }
2217
2218
2219 int messageport_remove_registration_event_cb(int watcher_id)
2220 {
2221         registered_callback_info_s *registered_cb_info = NULL;
2222         gboolean remove_result = FALSE;
2223
2224         if (watcher_id < 1)
2225                 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
2226
2227         registered_cb_info = g_hash_table_lookup(__registered_callback_info_hash, GINT_TO_POINTER(watcher_id));
2228         if (registered_cb_info == NULL)
2229                 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
2230
2231         remove_result = g_hash_table_remove(__registered_callback_info_hash, GINT_TO_POINTER(watcher_id));
2232         if (!remove_result)
2233                 return MESSAGEPORT_ERROR_IO_ERROR;
2234
2235         g_bus_unwatch_name(watcher_id);
2236
2237         return MESSAGEPORT_ERROR_NONE;
2238 }