Change the socket to non-blocking mode.
[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         _LOGI("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         _LOGI("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         _LOGI("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         _LOGI("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         _LOGI("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                 LOGI("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         LOGI("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         _LOGI("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         _LOGI("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                 _LOGI("__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                 _LOGI("__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                 _LOGI("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         _LOGI("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         _LOGI("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         _LOGI("initialize");
1421         ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
1422         retvm_if(ret != AUL_R_OK, false, "Failed to get the application ID: %d", ret);
1423
1424         __app_id = strdup(buffer);
1425         retvm_if(!__app_id, false, "Malloc failed");
1426         _LOGI("init : %s", __app_id);
1427
1428         if (__local_port_info == NULL) {
1429                 __local_port_info = g_hash_table_new_full(g_direct_hash,  g_direct_equal, NULL, __hash_destory_local_value);
1430                 retvm_if(!__local_port_info, false, "fail to create __local_port_info");
1431         }
1432
1433         if (__remote_app_info == NULL) {
1434                 __remote_app_info = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __hash_destory_remote_value);
1435                 retvm_if(!__remote_app_info, false, "fail to create __remote_app_info");
1436         }
1437
1438         if (__sender_appid_hash == NULL) {
1439                 __sender_appid_hash = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
1440                 retvm_if(!__sender_appid_hash, false, "fail to create __sender_appid_hash");
1441         }
1442
1443         if (__trusted_app_list_hash == NULL) {
1444                 __trusted_app_list_hash = g_hash_table_new(g_str_hash, g_str_equal);
1445                 retvm_if(!__trusted_app_list_hash, false, "fail to create __trusted_app_list_hash");
1446         }
1447
1448         if (__callback_info_hash == NULL) {
1449                 __callback_info_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __hash_destroy_callback_info);
1450                 retvm_if(!__trusted_app_list_hash, false, "fail to create __trusted_app_list_hash");
1451         }
1452
1453         if (!__dbus_init())
1454                 return false;
1455         _initialized = true;
1456
1457         return true;
1458 }
1459
1460
1461 static bool __message_port_register_port(const int local_id, const char *local_port, bool is_trusted, messageport_message_cb callback)
1462 {
1463         message_port_local_port_info_s *mi = (message_port_local_port_info_s *)calloc(1, sizeof(message_port_local_port_info_s));
1464         retvm_if(!mi, false, "Malloc failed");
1465
1466         mi->callback = callback;
1467         mi->is_trusted = is_trusted;
1468         mi->port_name = strdup(local_port);
1469         if (mi->port_name == NULL) {
1470                 _LOGE("Malloc failed (%s)", local_port);
1471                 free(mi);
1472                 return false;
1473         }
1474         mi->local_id = local_id;
1475
1476         g_hash_table_insert(__local_port_info, GINT_TO_POINTER(mi->local_id), mi);
1477         return true;
1478 }
1479
1480 static int __register_message_port(const char *local_port, bool is_trusted, messageport_message_cb callback)
1481 {
1482         _SECURE_LOGI("Register a message port : [%s:%s]", __app_id, local_port);
1483
1484         int local_id = 0;
1485
1486         /* Check the message port is already registed */
1487         if (__is_local_port_registed(local_port, is_trusted, &local_id, NULL))
1488                 return local_id;
1489
1490         local_id = __register_dbus_interface(local_port, is_trusted);
1491         if (local_id < 1) {
1492                 _LOGE("register_dbus_interface fail !!");
1493                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1494         }
1495
1496         if (!__message_port_register_port(local_id, local_port, is_trusted, callback))
1497                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1498
1499         return local_id;
1500 }
1501
1502 static void __free_delay_message_info(delay_message_info_s *message)
1503 {
1504         if (message != NULL) {
1505                 FREE_AND_NULL(message->local_port_name);
1506                 FREE_AND_NULL(message->data);
1507                 FREE_AND_NULL(message);
1508         }
1509 }
1510
1511 static void __free_list_delay_message_info(gpointer data)
1512 {
1513         delay_message_info_s *message = (delay_message_info_s *)data;
1514
1515         if (message != NULL)
1516                 __free_delay_message_info(message);
1517 }
1518
1519 static int __send_delayed_message(int sockfd, delay_message_info_s *message)
1520 {
1521         unsigned int nb = 0;
1522         int sequence = message->sequence - 1;
1523         int ret = MESSAGEPORT_ERROR_NONE;
1524         bool is_startline = true;
1525         int offset = 0;
1526
1527         _LOGI("send_delayed_message : sockfd (%d) sequence(%d) sent byte(%d)",
1528                 sockfd, message->sequence, message->sent_bytes);
1529
1530         switch (message->sequence) {
1531         case SEQUENCE_START:
1532                 sequence++;
1533                 is_startline = false;
1534
1535         case SEQUENCE_PORT_LEN:
1536                 if (is_startline)
1537                         offset = message->sent_bytes;
1538
1539                 ret = __write_socket(sockfd, ((char *)&message->local_port_len) + offset,
1540                                 sizeof(message->local_port_len) - offset, &nb, &sequence);
1541                 if (ret != MESSAGEPORT_ERROR_NONE) {
1542                         _LOGE("write local_port_len fail");
1543                         goto out;
1544                 }
1545                 offset = 0;
1546                 is_startline = false;
1547
1548         case SEQUENCE_PORT_NAME:
1549                 if (is_startline)
1550                         offset = message->sent_bytes;
1551
1552                 if (message->local_port_len > 0)
1553                         ret = __write_socket(sockfd, message->local_port_name + offset,
1554                                 message->local_port_len - offset , &nb, &sequence);
1555                 else
1556                         sequence++;
1557
1558                 if (ret != MESSAGEPORT_ERROR_NONE) {
1559                         _LOGE("write local_port fail");
1560                         goto out;
1561                 }
1562                 offset = 0;
1563                 is_startline = false;
1564
1565         case SEQUENCE_BIDIRECTION:
1566                 if (is_startline)
1567                         offset = message->sent_bytes;
1568
1569                 ret = __write_socket(sockfd, ((char *)&message->is_bidirection) + offset,
1570                                 sizeof(message->is_bidirection) - offset, &nb, &sequence);
1571                 if (ret != MESSAGEPORT_ERROR_NONE) {
1572                         _LOGE("write is_bidirection fail");
1573                         goto out;
1574                 }
1575                 offset = 0;
1576                 is_startline = false;
1577
1578         case SEQUENCE_TRUSTED:
1579                 if (is_startline)
1580                         offset = message->sent_bytes;
1581
1582                 ret = __write_socket(sockfd, ((char *)&message->local_trusted) + offset,
1583                                 sizeof(message->local_trusted) - offset, &nb, &sequence);
1584                 if (ret != MESSAGEPORT_ERROR_NONE) {
1585                         _LOGE("write local_trusted fail");
1586                         goto out;
1587                 }
1588                 offset = 0;
1589                 is_startline = false;
1590
1591         case SEQUENCE_DTAT_LEN:
1592                 if (is_startline)
1593                         offset = message->sent_bytes;
1594
1595                 ret = __write_socket(sockfd, ((char *)&message->data_len) + offset,
1596                                 sizeof(message->data_len) - offset, &nb, &sequence);
1597                 if (ret != MESSAGEPORT_ERROR_NONE) {
1598                         _LOGE("write data_len fail");
1599                         goto out;
1600                 }
1601                 offset = 0;
1602                 is_startline = false;
1603
1604         case SEQUENCE_DATA:
1605                 if (is_startline)
1606                         offset = message->sent_bytes;
1607
1608                 ret = __write_socket(sockfd, (char *)message->data + offset,
1609                         message->data_len -offset, &nb, &sequence);
1610
1611                 if (ret != MESSAGEPORT_ERROR_NONE) {
1612                         _LOGE("write data fail");
1613                         goto out;
1614                 }
1615                 offset = 0;
1616                 is_startline = false;
1617
1618         default:
1619                 ret = MESSAGEPORT_ERROR_NONE;
1620
1621         }
1622
1623 out:
1624         if (ret == MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE) {
1625                 if (is_startline)
1626                          message->sent_bytes += nb;
1627                 else
1628                          message->sent_bytes = nb;
1629
1630                 message->sequence = sequence;
1631                 _LOGE("send_delayed_message fail : sockfd (%d) sequence(%d) sent byte(%d)",
1632                         sockfd, message->sequence, message->sent_bytes);
1633         }
1634
1635         return ret;
1636
1637 }
1638
1639 static gboolean __process_delayed_message(gint fd, GIOCondition cond, gpointer data)
1640 {
1641         port_list_info_s *port_info = (port_list_info_s *)data;
1642         delay_message_info_s *message;
1643         int ret;
1644
1645         if (port_info == NULL)
1646                 return G_SOURCE_REMOVE;
1647
1648         pthread_mutex_lock(&mutex);
1649
1650         if (port_info->delayed_message_list == NULL) {
1651                 port_info->delayed_message_size = 0;
1652                 port_info->delay_src_id = 0;
1653                 pthread_mutex_unlock(&mutex);
1654                 return G_SOURCE_REMOVE;
1655         } else {
1656                 message = g_list_nth_data(port_info->delayed_message_list, 0);
1657                 ret = __send_delayed_message(port_info->send_sock_fd, message);
1658
1659                 if (ret == MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE) {
1660                         pthread_mutex_unlock(&mutex);
1661                         return G_SOURCE_CONTINUE;
1662                 } else if (ret == MESSAGEPORT_ERROR_IO_ERROR) {
1663                         __clear_disconnect_socket(port_info);
1664                         pthread_mutex_unlock(&mutex);
1665                         return G_SOURCE_REMOVE;
1666                 }
1667
1668                 port_info->delayed_message_size -= message->size;
1669
1670                 port_info->delayed_message_list = g_list_remove(port_info->delayed_message_list, message);
1671                 __free_delay_message_info(message);
1672         }
1673
1674         pthread_mutex_unlock(&mutex);
1675
1676         return G_SOURCE_CONTINUE;
1677 }
1678
1679 static int __insert_delayed_message(port_list_info_s *port_info,
1680         int sequence,
1681         bundle_raw *kb_data,
1682         int data_len,
1683         unsigned int sent_bytes,
1684         const char *local_port,
1685         bool local_trusted,
1686         bool is_bidirection)
1687 {
1688 #define QUEUE_SIZE_MAX (1024 * 1024) /* 1MB per remote port (MAX) */
1689
1690         unsigned int tmp_size;
1691         unsigned int message_size;
1692         int ret = MESSAGEPORT_ERROR_NONE;
1693
1694         if (port_info->delayed_message_size >= QUEUE_SIZE_MAX) {
1695                 _LOGE("cache fail : delayed_message_size (%d), count(%d)",
1696                         port_info->delayed_message_size, g_list_length(port_info->delayed_message_list));
1697                 return MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE;
1698         }
1699
1700         delay_message_info_s *message = (delay_message_info_s *)calloc(1, sizeof(delay_message_info_s));
1701         retvm_if(!message, MESSAGEPORT_ERROR_OUT_OF_MEMORY, "Malloc failed");
1702
1703         message_size = sizeof(delay_message_info_s);
1704
1705         message->sequence = sequence;
1706         tmp_size = strlen(local_port) + 1;
1707         message_size += tmp_size;
1708         message->local_port_len = tmp_size;
1709         message->local_port_name = strdup(local_port);
1710         if (message->local_port_name == NULL) {
1711                 _LOGE("local_port_name strdup fail");
1712                 ret = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1713                 goto out;
1714         }
1715         message->is_bidirection = is_bidirection;
1716         message->local_trusted = local_trusted;
1717         message_size += data_len;
1718         message->data_len = data_len;
1719         message->data = (bundle_raw *)strdup((const char *)kb_data);
1720         if (message->data == NULL) {
1721                 _LOGE("data strdup fail");
1722                 ret = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1723                 goto out;
1724         }
1725
1726
1727         message->sent_bytes = sent_bytes;
1728         message->size = message_size;
1729         port_info->delayed_message_size += message_size;
1730
1731         port_info->delayed_message_list = g_list_append(port_info->delayed_message_list, message);
1732
1733         if (port_info->delay_src_id == 0) {
1734                         port_info->delay_src_id = g_unix_fd_add_full(G_PRIORITY_DEFAULT,
1735                                                         port_info->send_sock_fd, G_IO_OUT, __process_delayed_message,
1736                                                         port_info, NULL);
1737         }
1738
1739         _LOGE("inserted : pm(%s) fd(%d) ms(%d) ds(%d) dlc(%d) sqn(%d) sb (%d)",
1740                 port_info->port_name, port_info->send_sock_fd, message_size,
1741                 port_info->delayed_message_size,
1742                 g_list_length(port_info->delayed_message_list), sequence, sent_bytes);
1743
1744
1745
1746 out:
1747         if (ret != MESSAGEPORT_ERROR_NONE)
1748                 __free_delay_message_info(message);
1749
1750         return ret;
1751 }
1752
1753 int __message_port_send_async(port_list_info_s *port_info, bundle *kb, const char *local_port,
1754                 bool local_trusted, bool is_bidirection)
1755 {
1756         int ret = 0;
1757         int data_len;
1758         int local_port_len = 0;
1759         unsigned int nb = 0;
1760         bundle_raw *kb_data = NULL;
1761         int sequence = SEQUENCE_START;
1762
1763         bundle_encode(kb, &kb_data, &data_len);
1764         if (kb_data == NULL) {
1765                 _LOGE("bundle encode fail");
1766                 ret = MESSAGEPORT_ERROR_INVALID_PARAMETER;
1767                 goto out;
1768         }
1769
1770         if (data_len > MAX_MESSAGE_SIZE) {
1771                 _LOGE("bigger than max size\n");
1772                 ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
1773                 goto out;
1774         }
1775
1776         if (g_list_length(port_info->delayed_message_list) > 0) {
1777                 ret = MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE;
1778                 _LOGE("There are messages in the delayed_message_list (count %d)",
1779                         g_list_length(port_info->delayed_message_list));
1780                 goto out;
1781         }
1782
1783         if (local_port != NULL)
1784                 local_port_len = strlen(local_port) + 1;
1785
1786         ret = __write_string_to_socket(port_info->send_sock_fd, local_port,
1787                         local_port_len, &nb, &sequence);
1788         if (ret != MESSAGEPORT_ERROR_NONE) {
1789                 _LOGE("write local_port fail");
1790                 goto out;
1791         }
1792
1793         ret = __write_socket(port_info->send_sock_fd, (char *)&is_bidirection,
1794                         sizeof(is_bidirection), &nb, &sequence);
1795         if (ret != MESSAGEPORT_ERROR_NONE) {
1796                 _LOGE("write is_bidirection fail");
1797                 goto out;
1798         }
1799
1800         ret = __write_socket(port_info->send_sock_fd, (char *)&local_trusted,
1801                         sizeof(local_trusted), &nb, &sequence);
1802         if (ret != MESSAGEPORT_ERROR_NONE) {
1803                 _LOGE("write local_trusted fail");
1804                 goto out;
1805         }
1806
1807         ret = __write_string_to_socket(port_info->send_sock_fd, (void *)kb_data,
1808                         data_len, &nb, &sequence);
1809         if (ret != MESSAGEPORT_ERROR_NONE) {
1810                 _LOGE("write kb_data fail");
1811                 goto out;
1812         }
1813
1814 out:
1815         if (ret == MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE) {
1816                 ret = __insert_delayed_message(port_info, sequence, kb_data, data_len, nb,
1817                         local_port, local_trusted, is_bidirection);
1818                 if (ret != MESSAGEPORT_ERROR_NONE)
1819                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1820         }
1821
1822         if (kb_data)
1823                 free(kb_data);
1824
1825         return ret;
1826 }
1827
1828 static int __message_port_send_message(const char *remote_appid, const char *remote_port,
1829                 const char *local_port, bool trusted_message, bool local_trusted, bool bi_dir, bundle *message)
1830 {
1831
1832         int ret = MESSAGEPORT_ERROR_NONE;
1833         GUnixFDList *fd_list = NULL;
1834
1835         int len = 0;
1836         bundle_raw *raw = NULL;
1837         char *bus_name = NULL;
1838         char *interface_name = NULL;
1839
1840         message_port_remote_app_info_s *remote_app_info = NULL;
1841         port_list_info_s *port_info = NULL;
1842         GDBusMessage *msg = NULL;
1843         GError *err = NULL;
1844         GVariant *body = NULL;
1845         int sock_pair[2] = {0,};
1846         char buf[1024];
1847
1848         ret = __get_remote_port_info(remote_appid, remote_port, trusted_message, &remote_app_info, &port_info);
1849         if (ret != MESSAGEPORT_ERROR_NONE)
1850                 return ret;
1851
1852         if (port_info->exist == false) {
1853                 bool exist = false;
1854                 _LOGI("port exist check !!");
1855                 ret =  __check_remote_port(remote_appid, remote_port, trusted_message, &exist);
1856                 if (ret != MESSAGEPORT_ERROR_NONE) {
1857                         goto out;
1858                 } else if (!exist) {
1859                         ret = MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1860                         goto out;
1861                 }
1862         }
1863
1864         if (port_info->send_sock_fd > 0) {
1865                 ret = __message_port_send_async(port_info, message,
1866                                 (local_port) ? local_port : "", local_trusted, bi_dir);
1867         } else {
1868
1869                 bus_name = port_info->encoded_bus_name;
1870                 interface_name = bus_name;
1871
1872                 if (bundle_encode(message, &raw, &len) != BUNDLE_ERROR_NONE) {
1873                         ret = MESSAGEPORT_ERROR_INVALID_PARAMETER;
1874                         goto out;
1875                 }
1876
1877                 if (MAX_MESSAGE_SIZE < len) {
1878                         _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
1879                         ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
1880                         goto out;
1881                 }
1882
1883                 body = g_variant_new("(ssbbssbus)", __app_id, (local_port) ? local_port : "", local_trusted, bi_dir,
1884                                 remote_appid, remote_port, trusted_message, len, raw);
1885                 if (strcmp(remote_appid, __app_id) != 0) { /* self send */
1886
1887                         /*  if message-port fail to get socket pair, communicate using GDBus */
1888                         if (aul_request_message_port_socket_pair(sock_pair) != AUL_R_OK) {
1889                                 _LOGE("error create socket pair");
1890                         } else {
1891
1892                                 _LOGI("sock pair : %d, %d",
1893                                                 sock_pair[SOCK_PAIR_SENDER], sock_pair[SOCK_PAIR_RECEIVER]);
1894                                 fd_list = g_unix_fd_list_new();
1895                                 g_unix_fd_list_append(fd_list, sock_pair[SOCK_PAIR_RECEIVER], &err);
1896                                 if (err != NULL) {
1897                                         _LOGE("g_unix_fd_list_append [%s]", err->message);
1898                                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1899                                         g_error_free(err);
1900                                         goto out;
1901                                 }
1902
1903                                 port_info->send_sock_fd = sock_pair[SOCK_PAIR_SENDER];
1904                                 close(sock_pair[SOCK_PAIR_RECEIVER]);
1905                                 sock_pair[SOCK_PAIR_RECEIVER] = 0;
1906
1907                                 port_info->gio_read = g_io_channel_unix_new(port_info->send_sock_fd);
1908                                 if (!port_info->gio_read) {
1909                                         _LOGE("Error is %s\n", strerror_r(errno, buf, sizeof(buf)));
1910                                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1911                                         goto out;
1912                                 }
1913
1914                                 port_info->g_src_id = g_io_add_watch(port_info->gio_read, G_IO_IN | G_IO_HUP,
1915                                                 __socket_disconnect_handler, (gpointer)port_info);
1916                                 if (port_info->g_src_id == 0) {
1917                                         _LOGE("fail to add watch on socket");
1918                                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1919                                         goto out;
1920                                 }
1921
1922                         }
1923                 }
1924
1925                 msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, interface_name, "send_message");
1926                 if (!msg) {
1927                         _LOGE("Can't allocate new method call");
1928                         ret = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1929                         goto out;
1930                 }
1931
1932                 g_dbus_message_set_unix_fd_list(msg, fd_list);
1933                 g_dbus_message_set_body(msg, body);
1934                 g_dbus_connection_send_message(__gdbus_conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err);
1935                 if (err != NULL) {
1936                         _LOGE("No reply. error = %s", err->message);
1937                         g_error_free(err);
1938                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1939                         goto out;
1940                 }
1941                 __watch_remote_port_info(port_info);
1942
1943         }
1944
1945 out:
1946         if (msg)
1947                 g_object_unref(msg);
1948         if (raw)
1949                 bundle_free_encoded_rawdata(&raw);
1950         if (fd_list)
1951                 g_object_unref(fd_list);
1952
1953         if (ret != MESSAGEPORT_ERROR_NONE) {
1954                 __clear_disconnect_socket(port_info);
1955                 if (sock_pair[SOCK_PAIR_SENDER])
1956                         close(sock_pair[SOCK_PAIR_SENDER]);
1957                 if (sock_pair[SOCK_PAIR_RECEIVER])
1958                         close(sock_pair[SOCK_PAIR_RECEIVER]);
1959         }
1960
1961         return ret;
1962 }
1963
1964 int __message_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port,  bool trusted_message, bundle *message)
1965 {
1966         message_port_local_port_info_s *local_info;
1967         int ret = __get_local_port_info(id, &local_info);
1968         if (ret != MESSAGEPORT_ERROR_NONE)
1969                 return ret;
1970
1971         _LOGI("bidirectional_message %s", local_info->port_name);
1972         return __message_port_send_message(remote_app_id, remote_port,
1973                         local_info->port_name, trusted_message, local_info->is_trusted, true, message);
1974 }
1975
1976 static void __name_registered(GDBusConnection *connection,
1977                 const gchar *name,
1978                 const gchar *name_owner,
1979                 gpointer user_data)
1980 {
1981
1982         registered_callback_info_s *info = (registered_callback_info_s *)user_data;
1983         if (info == NULL) {
1984                 LOGE("NULL registered_callback_info");
1985                 return;
1986         }
1987
1988         _LOGI("watcher_id : %d, appeared name : %s , name_owner : %s\n", info->watcher_id, name, name_owner);
1989         if (info->registered_cb)
1990                 info->registered_cb(info->remote_app_id, info->remote_port, info->is_trusted, info->user_data);
1991 }
1992
1993 static void __name_unregistered(GDBusConnection *connection,
1994                 const gchar *name,
1995                 gpointer user_data)
1996 {
1997
1998         registered_callback_info_s *info = (registered_callback_info_s *)user_data;
1999         if (info == NULL) {
2000                 LOGE("NULL registered_callback_info");
2001                 return;
2002         }
2003
2004         _LOGI("watcher_id : %d, vanished name : %s\n", info->watcher_id, name);
2005         if (info->unregistered_cb)
2006                 info->unregistered_cb(info->remote_app_id, info->remote_port, info->is_trusted, info->user_data);
2007 }
2008
2009 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)
2010 {
2011         int ret_val = MESSAGEPORT_ERROR_NONE;
2012         message_port_remote_app_info_s *remote_app_info = NULL;
2013         port_list_info_s *port_info = NULL;
2014
2015         _LOGI("remote_app_id, app_id :[%s : %s] ", remote_app_id, __app_id);
2016
2017         ret_val = __get_remote_port_info(remote_app_id, remote_port, trusted_remote_port, &remote_app_info, &port_info);
2018         if (ret_val != MESSAGEPORT_ERROR_NONE)
2019                 return ret_val;
2020
2021         if (__registered_callback_info_hash == NULL)
2022                 __registered_callback_info_hash = g_hash_table_new_full(g_direct_hash,  g_direct_equal, NULL, __registered_callback_info_free);
2023
2024         registered_callback_info_s *registered_cb_info = (registered_callback_info_s *)calloc(1, sizeof(registered_callback_info_s));
2025         registered_cb_info->registered_cb = registered_cb;
2026         registered_cb_info->unregistered_cb = unregistered_cb;
2027         registered_cb_info->user_data = user_data;
2028         registered_cb_info->remote_app_id = strdup(remote_app_info->remote_app_id);
2029         if (registered_cb_info->remote_app_id == NULL) {
2030                 free(registered_cb_info);
2031                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
2032         }
2033         registered_cb_info->remote_port = strdup(port_info->port_name);
2034         if (registered_cb_info->remote_port == NULL) {
2035                 free(registered_cb_info->remote_app_id);
2036                 free(registered_cb_info);
2037                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
2038         }
2039
2040         registered_cb_info->watcher_id = g_bus_watch_name_on_connection(
2041                         __gdbus_conn,
2042                         port_info->encoded_bus_name,
2043                         G_BUS_NAME_WATCHER_FLAGS_NONE,
2044                         __name_registered,
2045                         __name_unregistered,
2046                         registered_cb_info,
2047                         NULL);
2048         if (registered_cb_info->watcher_id == 0) {
2049                 free(registered_cb_info->remote_app_id);
2050                 free(registered_cb_info->remote_port);
2051                 free(registered_cb_info);
2052                 return MESSAGEPORT_ERROR_IO_ERROR;
2053         }
2054
2055         g_hash_table_insert(__registered_callback_info_hash,
2056                         GINT_TO_POINTER(registered_cb_info->watcher_id), registered_cb_info);
2057
2058         *watcher_id = registered_cb_info->watcher_id;
2059         return MESSAGEPORT_ERROR_NONE;
2060 }
2061
2062 int messageport_unregister_local_port(int local_port_id, bool trusted_port)
2063 {
2064
2065         GVariant *result;
2066         char *bus_name = NULL;
2067         GError *err = NULL;
2068         int ret = 0;
2069
2070         _LOGI("unregister : %d", local_port_id);
2071
2072         message_port_local_port_info_s *mi =
2073                 (message_port_local_port_info_s *)
2074                 g_hash_table_lookup(__local_port_info, GINT_TO_POINTER(local_port_id));
2075         if (mi == NULL)
2076                 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
2077
2078         if (mi->is_trusted != trusted_port)
2079                 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
2080
2081         g_hash_table_remove(__callback_info_hash, GUINT_TO_POINTER(local_port_id));
2082
2083         bus_name = __get_encoded_name(__app_id, mi->port_name, mi->is_trusted);
2084         if (bus_name == NULL)
2085                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
2086
2087         g_dbus_connection_unregister_object(__gdbus_conn, local_port_id);
2088
2089         result = g_dbus_connection_call_sync(
2090                         __gdbus_conn,
2091                         DBUS_SERVICE_DBUS,
2092                         DBUS_PATH_DBUS,
2093                         DBUS_INTERFACE_DBUS,
2094                         "ReleaseName",
2095                         g_variant_new("(s)", bus_name),
2096                         G_VARIANT_TYPE("(u)"),
2097                         G_DBUS_CALL_FLAGS_NONE,
2098                         -1,
2099                         NULL,
2100                         &err);
2101
2102         if (bus_name)
2103                 free(bus_name);
2104
2105         if (err) {
2106                 _LOGE("RequestName fail : %s", err->message);
2107                 g_error_free(err);
2108                 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
2109         }
2110         g_variant_get(result, "(u)", &ret);
2111
2112         if (result)
2113                 g_variant_unref(result);
2114
2115         if (ret != DBUS_RELEASE_NAME_REPLY_RELEASED) {
2116
2117                 if (ret == DBUS_RELEASE_NAME_REPLY_NON_EXISTENT) {
2118                         _LOGE("Port Not exist");
2119                         return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
2120                 } else if (ret == DBUS_RELEASE_NAME_REPLY_NOT_OWNER) {
2121                         _LOGE("Try to release not owned name. MESSAGEPORT_ERROR_INVALID_PARAMETER");
2122                         return MESSAGEPORT_ERROR_INVALID_PARAMETER;
2123                 }
2124         }
2125
2126
2127         g_hash_table_remove(__local_port_info, GINT_TO_POINTER(local_port_id));
2128
2129         return MESSAGEPORT_ERROR_NONE;
2130 }
2131
2132 int messageport_register_local_port(const char *local_port, messageport_message_cb callback)
2133 {
2134         if (!_initialized) {
2135                 if (!__initialize())
2136                         return MESSAGEPORT_ERROR_IO_ERROR;
2137         }
2138
2139         return __register_message_port(local_port, false, callback);
2140 }
2141
2142 int messageport_register_trusted_local_port(const char *local_port, messageport_message_cb callback)
2143 {
2144         if (!_initialized) {
2145                 if (!__initialize())
2146                         return MESSAGEPORT_ERROR_IO_ERROR;
2147         }
2148
2149         return __register_message_port(local_port, true, callback);
2150
2151 }
2152
2153 int messageport_check_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
2154 {
2155         if (!_initialized) {
2156                 if (!__initialize())
2157                         return MESSAGEPORT_ERROR_IO_ERROR;
2158         }
2159
2160         int ret = __check_remote_port(remote_app_id, remote_port, false, exist);
2161         if (ret == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND) {
2162                 *exist = false;
2163                 ret = MESSAGEPORT_ERROR_NONE;
2164         }
2165
2166         return ret;
2167 }
2168
2169 int messageport_check_trusted_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
2170 {
2171         if (!_initialized) {
2172                 if (!__initialize())
2173                         return MESSAGEPORT_ERROR_IO_ERROR;
2174         }
2175
2176         int ret = __check_remote_port(remote_app_id, remote_port, true, exist);
2177         if (ret == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND) {
2178                 *exist = false;
2179                 ret = MESSAGEPORT_ERROR_NONE;
2180         }
2181
2182         return ret;
2183 }
2184
2185 int messageport_send_message(const char *remote_app_id, const char *remote_port, bundle *message)
2186 {
2187         if (!_initialized) {
2188                 if (!__initialize())
2189                         return MESSAGEPORT_ERROR_IO_ERROR;
2190         }
2191
2192         return __message_port_send_message(remote_app_id, remote_port, NULL, false, false, false, message);
2193 }
2194
2195 int messageport_send_trusted_message(const char *remote_app_id, const char *remote_port, bundle *message)
2196 {
2197         if (!_initialized) {
2198                 if (!__initialize())
2199                         return MESSAGEPORT_ERROR_IO_ERROR;
2200         }
2201
2202         return __message_port_send_message(remote_app_id, remote_port, NULL, true, false, false, message);
2203 }
2204
2205 int messageport_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port,
2206                 bundle *message)
2207 {
2208         if (!_initialized) {
2209                 if (!__initialize())
2210                         return MESSAGEPORT_ERROR_IO_ERROR;
2211         }
2212
2213         return __message_send_bidirectional_message(id, remote_app_id, remote_port, false, message);
2214 }
2215
2216 int messageport_send_bidirectional_trusted_message(int id, const char *remote_app_id, const char *remote_port,
2217                 bundle *message)
2218 {
2219         if (!_initialized) {
2220                 if (!__initialize())
2221                         return MESSAGEPORT_ERROR_IO_ERROR;
2222         }
2223         return __message_send_bidirectional_message(id, remote_app_id, remote_port, true, message);
2224 }
2225
2226 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)
2227 {
2228         if (!_initialized) {
2229                 if (!__initialize())
2230                         return MESSAGEPORT_ERROR_IO_ERROR;
2231         }
2232         return __messageport_watch_remote_port(watcher_id, remote_app_id, remote_port, is_trusted, registered_cb, NULL, user_data);
2233 }
2234
2235 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)
2236 {
2237         if (!_initialized) {
2238                 if (!__initialize())
2239                         return MESSAGEPORT_ERROR_IO_ERROR;
2240         }
2241         return __messageport_watch_remote_port(watcher_id, remote_app_id, remote_port, is_trusted, NULL, unregistered_cb, user_data);
2242 }
2243
2244
2245 int messageport_remove_registration_event_cb(int watcher_id)
2246 {
2247         registered_callback_info_s *registered_cb_info = NULL;
2248         gboolean remove_result = FALSE;
2249
2250         if (watcher_id < 1)
2251                 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
2252
2253         registered_cb_info = g_hash_table_lookup(__registered_callback_info_hash, GINT_TO_POINTER(watcher_id));
2254         if (registered_cb_info == NULL)
2255                 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
2256
2257         remove_result = g_hash_table_remove(__registered_callback_info_hash, GINT_TO_POINTER(watcher_id));
2258         if (!remove_result)
2259                 return MESSAGEPORT_ERROR_IO_ERROR;
2260
2261         g_bus_unwatch_name(watcher_id);
2262
2263         return MESSAGEPORT_ERROR_NONE;
2264 }