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