Fix message_port_send_message_with_local_port NULL port name bug
[platform/core/appfw/message-port.git] / src / message-port.c
1
2 /*
3  Message Port
4  Copyright (c) 2015 Samsung Electronics Co., Ltd.
5
6  Licensed under the Apache License, Version 2.0 (the License);
7  you may not use this file except in compliance with the License.
8  You may obtain a copy of the License at
9
10      http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  See the License for the specific language governing permissions and
16  limitations under the License.
17 */
18
19 /**
20  * @file        message-port.cpp
21  * @brief       This is the implementation file for the MessagePort.
22  */
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
38 #include "message-port.h"
39 #include "message-port-log.h"
40
41 #define MAX_PACKAGE_STR_SIZE 512
42 #define MESSAGEPORT_BUS_NAME_PREFIX "org.tizen.messageport._"
43 #define MESSAGEPORT_OBJECT_PATH "/org/tizen/messageport"
44 #define MESSAGEPORT_INTERFACE_PREFIX "org.tizen.messageport._"
45
46 #define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
47 #define DBUS_PATH_DBUS "/org/freedesktop/DBus"
48 #define DBUS_INTERFACE_DBUS "org.freedesktop.DBus"
49
50 #define DBUS_RELEASE_NAME_REPLY_RELEASED        1 /* *< Service was released from the given name */
51 #define DBUS_RELEASE_NAME_REPLY_NON_EXISTENT    2 /* *< The given name does not exist on the bus */
52 #define DBUS_RELEASE_NAME_REPLY_NOT_OWNER       3 /* *< Service is not an owner of the given name */
53 #define HEADER_LEN 8
54 #define MAX_RETRY_CNT 2
55
56 #define retvm_if(expr, val, fmt, arg...) do { \
57         if (expr) { \
58                 _LOGE(fmt, ##arg); \
59                 _LOGE("(%s) -> %s() return", #expr, __func__); \
60                 return val; \
61         } \
62 } while (0)
63
64 #define retv_if(expr, val) do { \
65         if (expr) { \
66                 _LOGE("(%s) -> %s() return", #expr, __func__); \
67                 return val; \
68         } \
69 } while (0)
70
71 #define FREE_AND_NULL(ptr) do { \
72         if (ptr) { \
73                 free((void *)ptr); \
74                 ptr = NULL; \
75         } \
76 } while (0)
77
78 static bool _initialized = false;
79 static GDBusConnection *__gdbus_conn = NULL;
80 static char *__app_id;
81 static GHashTable *__local_port_info = NULL;
82 static GHashTable *__remote_port_info = NULL;;
83 static GHashTable *__sender_appid_hash = NULL;;
84 static GHashTable *__trusted_app_list_hash = NULL;
85 static const int MAX_MESSAGE_SIZE = 16 * 1024;
86
87 enum __certificate_info_type {
88         UNKNOWN = 0,
89         CERTIFICATE_MATCH,
90         CERTIFICATE_NOT_MATCH,
91 };
92
93 typedef struct message_port_pkt {
94         int remote_port_name_len;
95         char *remote_port_name;
96         bool is_bidirection;
97         int data_len;
98         unsigned char *data;
99 } message_port_pkt_s;
100
101 typedef struct message_port_callback_info {
102         messageport_message_cb callback;
103         bool is_trusted;
104         int local_id;
105         char *remote_app_id;
106         GIOChannel *gio_read;
107         int g_src_id;
108 } message_port_callback_info_s;
109
110 typedef struct message_port_local_port_info {
111         messageport_message_cb callback;
112         bool is_trusted;
113         char *port_name;
114         int local_id;
115 } message_port_local_port_info_s;
116
117 typedef struct message_port_remote_port_info {
118         char *sender_id;
119         char *remote_app_id;
120         int certificate_info;
121         GList *port_list;
122 } message_port_remote_app_info_s;
123
124 typedef struct port_list_info {
125         char *port_name;
126         char *encoded_bus_name;
127         bool is_trusted;
128         int sock_pair[2];
129         int watcher_id;
130         bool exist;
131 } port_list_info_s;
132
133 static void __callback_info_free(message_port_callback_info_s *callback_info)
134 {
135         GError *error = NULL;
136         if (callback_info == NULL)
137                 return;
138
139         if (callback_info->remote_app_id)
140                 free(callback_info->remote_app_id);
141
142         if (callback_info->gio_read != NULL) {
143                 g_io_channel_shutdown(callback_info->gio_read, FALSE, &error);
144                 if (error) {
145                         _LOGE("g_io_channel_shutdown error : %s", error->message);
146                         g_error_free(error);
147                 }
148                 g_io_channel_unref(callback_info->gio_read);
149                 callback_info->gio_read = NULL;
150         }
151
152         if (callback_info->g_src_id != 0) {
153                 g_source_remove(callback_info->g_src_id);
154                 callback_info->g_src_id = 0;
155         }
156
157         free(callback_info);
158 }
159
160 static char *__get_encoded_name(const char *remote_app_id, const char *port_name, bool is_trusted)
161 {
162
163         int prefix_len = strlen(MESSAGEPORT_BUS_NAME_PREFIX);
164         int postfix_len = 1;
165         char *postfix = is_trusted ? "1" : "0";
166
167         unsigned char c[MD5_DIGEST_LENGTH] = {0};
168         char *md5_interface = NULL;
169         char *temp;
170         int index = 0;
171         MD5_CTX mdContext;
172         int encoded_bus_name_len = prefix_len + postfix_len + (MD5_DIGEST_LENGTH * 2) + 2;
173         int bus_name_len = strlen(remote_app_id) + strlen(port_name) + 2;
174         char *bus_name = (char *)calloc(bus_name_len, sizeof(char));
175         if (bus_name == NULL) {
176                 _LOGE("bus_name calloc failed");
177                 return 0;
178         }
179
180         snprintf(bus_name, bus_name_len, "%s_%s", remote_app_id, port_name);
181
182         MD5_Init(&mdContext);
183         MD5_Update(&mdContext, bus_name, bus_name_len);
184         MD5_Final(c, &mdContext);
185
186         md5_interface = (char *)calloc(encoded_bus_name_len , sizeof(char));
187         if (md5_interface == NULL) {
188                 if (bus_name)
189                         free(bus_name);
190
191                 _LOGE("md5_interface calloc failed!!");
192                 return 0;
193         }
194
195         snprintf(md5_interface, encoded_bus_name_len, "%s", MESSAGEPORT_BUS_NAME_PREFIX);
196         temp = md5_interface;
197         temp += prefix_len;
198
199         for (index = 0; index < MD5_DIGEST_LENGTH; index++) {
200                 snprintf(temp, 3, "%02x", c[index]);
201                 temp += 2;
202         }
203
204         if (postfix && postfix_len > 0)
205                 snprintf(temp, encoded_bus_name_len - (temp - md5_interface), "%s", postfix);
206         if (bus_name)
207                 free(bus_name);
208
209         _LOGI("encoded_bus_name : %s ", md5_interface);
210
211         return md5_interface;
212 }
213
214 static int __remote_port_compare_cb(gconstpointer a, gconstpointer b)
215 {
216         port_list_info_s *key1 = (port_list_info_s *)a;
217         port_list_info_s *key2 = (port_list_info_s *)b;
218
219         if (key1->is_trusted == key2->is_trusted)
220                 return strcmp(key1->port_name, key2->port_name);
221
222         return 1;
223 }
224
225
226 static bool __is_preloaded(const char *local_appid, const char *remote_appid)
227 {
228         _LOGI("IsPreloaded");
229
230         bool preload_local = false;
231         bool preload_remote = false;
232
233         pkgmgrinfo_appinfo_h handle = NULL;
234         int ret = pkgmgrinfo_appinfo_get_usr_appinfo(local_appid, getuid(), &handle);
235         if (ret != PMINFO_R_OK) {
236                 _LOGE("Failed to get the appinfo. %d", ret);
237                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
238                 return false;
239         }
240         ret = pkgmgrinfo_appinfo_is_preload(handle, &preload_local);
241         if (ret != PMINFO_R_OK) {
242                 _LOGE("Failed to check the preloaded application. %d", ret);
243                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
244                 return false;
245         }
246         ret = pkgmgrinfo_appinfo_get_usr_appinfo(remote_appid, getuid(), &handle);
247         if (ret != PMINFO_R_OK) {
248                 _LOGE("Failed to get the appinfo. %d", ret);
249                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
250                 return false;
251         }
252         ret = pkgmgrinfo_appinfo_is_preload(handle, &preload_remote);
253         if (ret != PMINFO_R_OK) {
254                 _LOGE("Failed to check the preloaded application. %d", ret);
255                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
256                 return false;
257         }
258
259         if (preload_local && preload_remote) {
260                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
261                 return true;
262         }
263         pkgmgrinfo_appinfo_destroy_appinfo(handle);
264         return false;
265 }
266
267 static int __check_certificate(const char *local_appid, const char *remote_appid)
268 {
269         _LOGI("CheckCertificate");
270
271         pkgmgrinfo_cert_compare_result_type_e res;
272         int ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(local_appid, remote_appid, getuid(), &res);
273         if (ret < 0) {
274                 _LOGE(":CheckCertificate() Failed");
275                 return MESSAGEPORT_ERROR_IO_ERROR;
276         }
277         if (res != PMINFO_CERT_COMPARE_MATCH) {
278                 _LOGE("CheckCertificate() Failed : MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH");
279                 return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
280         }
281
282         return MESSAGEPORT_ERROR_NONE;
283 }
284
285 static void on_name_appeared(GDBusConnection *connection,
286                 const gchar     *name,
287                 const gchar     *name_owner,
288                 gpointer         user_data)
289 {
290         _LOGI("name appeared : %s %s", __app_id, name);
291 }
292
293 static void on_name_vanished(GDBusConnection *connection,
294                 const gchar     *name,
295                 gpointer         user_data)
296 {
297         _LOGI("name vanished : %s", name);
298         port_list_info_s *pli = (port_list_info_s *)user_data;
299         g_bus_unwatch_name(pli->watcher_id);
300         pli->exist = false;
301 }
302
303 static int __get_local_port_info(int id, message_port_local_port_info_s **info)
304 {
305         message_port_local_port_info_s *mi = (message_port_local_port_info_s *)g_hash_table_lookup(__local_port_info, GINT_TO_POINTER(id));
306
307         if (mi == NULL)
308                 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
309         *info = mi;
310
311         return MESSAGEPORT_ERROR_NONE;
312 }
313
314 static port_list_info_s *__set_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
315 {
316         int ret_val = MESSAGEPORT_ERROR_NONE;
317         port_list_info_s *port_info = (port_list_info_s *)calloc(1, sizeof(port_list_info_s));
318
319         if (!port_info) {
320                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
321                 goto out;
322         }
323         port_info->port_name = strdup(remote_port);
324         if (!port_info->port_name) {
325                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
326                 goto out;
327         }
328         port_info->is_trusted = is_trusted;
329
330         port_info->encoded_bus_name = __get_encoded_name(remote_app_id, remote_port, is_trusted);
331         if (port_info->encoded_bus_name == NULL) {
332                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
333                 goto out;
334         }
335
336         port_info->sock_pair[0] = 0;
337         port_info->sock_pair[1] = 0;
338
339 out:
340         if (ret_val != MESSAGEPORT_ERROR_NONE) {
341                 if (port_info) {
342                         FREE_AND_NULL(port_info->port_name);
343                         FREE_AND_NULL(port_info->encoded_bus_name);
344                         free(port_info);
345                 }
346                 return NULL;
347         }
348         return port_info;
349 }
350
351 static message_port_remote_app_info_s *__set_remote_app_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
352 {
353         port_list_info_s *port_info = NULL;
354         message_port_remote_app_info_s *remote_app_info = NULL;
355         int ret_val = MESSAGEPORT_ERROR_NONE;
356
357         remote_app_info = (message_port_remote_app_info_s *)calloc(1, sizeof(message_port_remote_app_info_s));
358         if (!remote_app_info) {
359                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
360                 goto out;
361         }
362
363         remote_app_info->remote_app_id = strdup(remote_app_id);
364         if (remote_app_info->remote_app_id == NULL) {
365                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;;
366                 goto out;
367         }
368
369         port_info = __set_remote_port_info(remote_app_id, remote_port, is_trusted);
370         if (port_info == NULL) {
371                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
372                 goto out;
373         }
374
375         remote_app_info->port_list = g_list_append(remote_app_info->port_list, port_info);
376
377 out:
378         if (ret_val != MESSAGEPORT_ERROR_NONE) {
379                 if (remote_app_info) {
380                         FREE_AND_NULL(remote_app_info->remote_app_id);
381                         FREE_AND_NULL(remote_app_info);
382                 }
383                 return NULL;
384         }
385         return remote_app_info;
386 }
387
388 static int __get_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted,
389                 message_port_remote_app_info_s **mri, port_list_info_s **pli)
390 {
391         message_port_remote_app_info_s *remote_app_info = NULL;
392         port_list_info_s port_info;
393         GList *cb_list = NULL;
394         int ret_val = MESSAGEPORT_ERROR_NONE;
395
396         remote_app_info = (message_port_remote_app_info_s *)g_hash_table_lookup(__remote_port_info, remote_app_id);
397
398         if (remote_app_info == NULL) {
399                 remote_app_info = __set_remote_app_info(remote_app_id, remote_port, is_trusted);
400
401                 if (remote_app_info == NULL) {
402                         ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
403                         goto out;
404                 }
405                 g_hash_table_insert(__remote_port_info, remote_app_info->remote_app_id, remote_app_info);
406
407         }
408         *mri = remote_app_info;
409
410         port_info.port_name = strdup(remote_port);
411         port_info.is_trusted = is_trusted;
412         cb_list = g_list_find_custom(remote_app_info->port_list, &port_info,
413                                         (GCompareFunc)__remote_port_compare_cb);
414         if (port_info.port_name)
415                 free(port_info.port_name);
416         if (cb_list == NULL) {
417                 port_list_info_s *tmp = __set_remote_port_info(remote_app_id, remote_port, is_trusted);
418
419                 if (tmp == NULL) {
420                         ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
421                         goto out;
422                 }
423                 remote_app_info->port_list = g_list_append(remote_app_info->port_list, tmp);
424                 *pli = tmp;
425                 g_hash_table_insert(__remote_port_info, (*pli)->encoded_bus_name, *pli);
426         } else {
427                 *pli = (port_list_info_s *)cb_list->data;
428         }
429
430 out:
431
432         return ret_val;
433 }
434
435 static bool __is_local_port_registed(const char *local_port, bool trusted, int *local_id, message_port_local_port_info_s **lpi)
436 {
437         GHashTableIter iter;
438         gpointer key, value;
439
440         g_hash_table_iter_init(&iter, __local_port_info);
441
442         while (g_hash_table_iter_next(&iter, &key, &value)) {
443                 message_port_local_port_info_s *mi = (message_port_local_port_info_s *)value;
444
445                 if ((mi->is_trusted == trusted) && strcmp(mi->port_name, local_port) == 0) {
446                         *local_id = mi->local_id;
447                         if (lpi != NULL)
448                                 *lpi = mi;
449                         return true;
450                 }
451         }
452         return false;
453 }
454
455 static int __get_sender_pid(GDBusConnection *conn, const char *sender_name)
456 {
457         GDBusMessage *msg = NULL;
458         GDBusMessage *reply = NULL;
459         GError *err = NULL;
460         GVariant *body;
461         int pid = 0;
462
463         msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
464                         "org.freedesktop.DBus", "GetConnectionUnixProcessID");
465         if (!msg) {
466                 _LOGE("Can't allocate new method call");
467                 goto out;
468         }
469
470         g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
471         reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
472                                                         G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
473
474         if (!reply) {
475                 if (err != NULL) {
476                         _LOGE("Failed to get pid [%s]", err->message);
477                         g_error_free(err);
478                 }
479                 goto out;
480         }
481
482         body = g_dbus_message_get_body(reply);
483         g_variant_get(body, "(u)", &pid);
484
485 out:
486         if (msg)
487                 g_object_unref(msg);
488         if (reply)
489                 g_object_unref(reply);
490
491         return pid;
492 }
493
494 static int __write_socket(int fd,
495                 const char *buffer,
496                 unsigned int nbytes,
497                 unsigned int *bytes_write)
498 {
499         unsigned int left = nbytes;
500         ssize_t nb;
501         int retry_cnt = 0;
502
503         *bytes_write = 0;
504         while (left && (retry_cnt < MAX_RETRY_CNT)) {
505                 nb = write(fd, buffer, left);
506                 if (nb == -1) {
507                         if (errno == EINTR) {
508                                 LOGE("__write_socket: EINTR error continue ...");
509                                 retry_cnt++;
510                                 continue;
511                         }
512                         LOGE("__write_socket: ...error fd %d: errno %d\n", fd, errno);
513                         return MESSAGEPORT_ERROR_IO_ERROR;
514                 }
515
516                 left -= nb;
517                 buffer += nb;
518                 *bytes_write += nb;
519                 retry_cnt = 0;
520         }
521         return MESSAGEPORT_ERROR_NONE;
522 }
523
524 static int __write_string_to_socket(int fd, const char *buffer, int string_len)
525 {
526         unsigned int nb;
527         if (__write_socket(fd, (char *)&string_len, sizeof(string_len), &nb) != MESSAGEPORT_ERROR_NONE) {
528                 _LOGE("write string_len fail");
529                 return MESSAGEPORT_ERROR_IO_ERROR;
530         }
531
532         if (string_len > 0) {
533                 if (__write_socket(fd, buffer, string_len, &nb) != MESSAGEPORT_ERROR_NONE) {
534                         _LOGE("wirte buffer fail");
535                         return MESSAGEPORT_ERROR_IO_ERROR;
536                 }
537         }
538         return MESSAGEPORT_ERROR_NONE;
539 }
540
541 static int __read_socket(int fd,
542                 char *buffer,
543                 unsigned int nbytes,
544                 unsigned int *bytes_read)
545 {
546         unsigned int left = nbytes;
547         ssize_t nb;
548         int retry_cnt = 0;
549
550         *bytes_read = 0;
551         while (left && (retry_cnt < MAX_RETRY_CNT)) {
552                 nb = read(fd, buffer, left);
553                 if (nb == 0) {
554                         LOGE("__read_socket: ...read EOF, socket closed %d: nb %d\n", fd, nb);
555                         return MESSAGEPORT_ERROR_IO_ERROR;
556                 } else if (nb == -1) {
557                         if (errno == EINTR) {
558                                 LOGE("__read_socket: EINTR error continue ...");
559                                 retry_cnt++;
560                                 continue;
561                         }
562                         LOGE("__read_socket: ...error fd %d: errno %d\n", fd, errno);
563                         return MESSAGEPORT_ERROR_IO_ERROR;
564                 }
565
566                 left -= nb;
567                 buffer += nb;
568                 *bytes_read += nb;
569                 retry_cnt = 0;
570         }
571         return MESSAGEPORT_ERROR_NONE;
572 }
573
574 static int __read_string_from_socket(int fd, char **buffer, int *string_len)
575 {
576         unsigned int nb;
577         if (__read_socket(fd, (char *)string_len, sizeof(*string_len), &nb) != MESSAGEPORT_ERROR_NONE) {
578                 LOGE("read socket fail");
579                 return MESSAGEPORT_ERROR_IO_ERROR;
580         }
581         if (*string_len > 0) {
582                 *buffer = (char *)calloc(*string_len, sizeof(char));
583                 if (*buffer == NULL) {
584                         LOGE("Out of memory.");
585                         return MESSAGEPORT_ERROR_IO_ERROR;
586                 }
587                 if (__read_socket(fd, *buffer, *string_len, &nb) != MESSAGEPORT_ERROR_NONE) {
588                         LOGE("read socket fail");
589                         return MESSAGEPORT_ERROR_IO_ERROR;
590                 }
591         }
592         return MESSAGEPORT_ERROR_NONE;
593 }
594
595 message_port_pkt_s *__message_port_recv_raw(int fd)
596 {
597         message_port_pkt_s *pkt = NULL;
598         unsigned int nb;
599
600         pkt = (message_port_pkt_s *)calloc(sizeof(message_port_pkt_s), 1);
601         if (pkt == NULL) {
602                 close(fd);
603                 return NULL;
604         }
605         if (__read_string_from_socket(fd, (char **)&pkt->remote_port_name, &pkt->remote_port_name_len) != MESSAGEPORT_ERROR_NONE) {
606                 LOGE("read socket fail: port_name");
607                 free(pkt->remote_port_name);
608                 free(pkt);
609                 close(fd);
610                 return NULL;
611         }
612         if (__read_socket(fd, (char *)&pkt->is_bidirection, sizeof(pkt->is_bidirection), &nb) != MESSAGEPORT_ERROR_NONE) {
613                 LOGE("read socket fail: is_bidirection");
614                 free(pkt->remote_port_name);
615                 free(pkt);
616                 close(fd);
617                 return NULL;
618         }
619         if (__read_string_from_socket(fd, (char **)&pkt->data, &pkt->data_len) != MESSAGEPORT_ERROR_NONE) {
620                 LOGE("read socket fail: data");
621                 free(pkt->remote_port_name);
622                 free(pkt);
623                 close(fd);
624                 return NULL;
625         }
626         return pkt;
627 }
628
629 static gboolean __socket_request_handler(GIOChannel *gio,
630                 GIOCondition cond,
631                 gpointer data)
632 {
633         int fd = 0;
634         message_port_callback_info_s *mi;
635         message_port_pkt_s *pkt;
636         bundle *kb = NULL;
637         GError *error = NULL;
638
639         mi = (message_port_callback_info_s *)data;
640         if (mi == NULL) {
641
642                 g_io_channel_shutdown(gio, FALSE, &error);
643                 if (error) {
644                         _LOGE("g_io_channel_shutdown error : %s", error->message);
645                         g_error_free(error);
646                 }
647                 g_io_channel_unref(gio);
648                 return FALSE;
649         }
650
651         if (cond == G_IO_HUP) {
652
653                 _LOGI("socket G_IO_HUP");
654                 __callback_info_free(mi);
655                 return FALSE;
656
657         } else {
658
659                 if ((fd = g_io_channel_unix_get_fd(gio)) < 0) {
660                         _LOGE("fail to get fd from io channel");
661                         __callback_info_free(mi);
662                         return FALSE;
663                 }
664
665                 if ((pkt = __message_port_recv_raw(fd)) == NULL) {
666                         _LOGE("recv error on SOCKET");
667                         __callback_info_free(mi);
668                         return FALSE;
669                 }
670
671                 kb = bundle_decode(pkt->data, pkt->data_len);
672
673                 if (pkt->is_bidirection)
674                         mi->callback(mi->local_id, mi->remote_app_id, pkt->remote_port_name, mi->is_trusted, kb, NULL);
675                 else
676                         mi->callback(mi->local_id, mi->remote_app_id, NULL, mi->is_trusted, kb, NULL);
677
678                 if (pkt) {
679                         if (pkt->remote_port_name)
680                                 free(pkt->remote_port_name);
681                         if (pkt->data)
682                                 free(pkt->data);
683                         free(pkt);
684                 }
685         }
686
687         return TRUE;
688 }
689
690 static bool send_message(GVariant *parameters, GDBusMethodInvocation *invocation)
691 {
692         char *local_port = NULL;
693         char *local_appid = NULL;
694         char *remote_appid = NULL;
695         char *remote_port = NULL;
696         gboolean local_trusted = false;
697         gboolean remote_trusted = false;
698         gboolean bi_dir = false;
699         int len = 0;
700
701         bundle *data = NULL;
702         bundle_raw *raw = NULL;
703         message_port_local_port_info_s *mi;
704         message_port_callback_info_s *callback_info;
705         int local_reg_id = 0;
706
707         g_variant_get(parameters, "(ssbbssbus)", &local_appid, &local_port, &local_trusted, &bi_dir,
708                         &remote_appid, &remote_port, &remote_trusted, &len, &raw);
709
710         if (!remote_port) {
711                 _LOGE("Invalid argument : remote_port is NULL");
712                 goto out;
713         }
714         if (!remote_appid) {
715                 _LOGE("Invalid argument : remote_appid is NULL");
716                 goto out;
717         }
718         if (!__is_local_port_registed(remote_port, remote_trusted, &local_reg_id, &mi)) {
719                 _LOGE("Invalid argument : remote_port:(%s) trusted(%d)", remote_port, remote_trusted);
720                 goto out;
721         }
722         if (!local_appid) {
723                 _LOGE("Invalid argument : local_appid");
724                 goto out;
725         }
726         if (!local_port) {
727                 _LOGE("Invalid argument : local_port");
728                 goto out;
729         }
730         if (strcmp(remote_appid, __app_id) != 0) {
731                 _LOGE("Invalid argument : remote_appid (%s)", remote_appid);
732                 goto out;
733         }
734         if (strcmp(remote_port, mi->port_name) != 0) {
735                 _LOGE("Invalid argument : remote_port (%s)", remote_port);
736                 goto out;
737         }
738         if (!len) {
739                 _LOGE("Invalid argument : data_len");
740                 goto out;
741         }
742         if (remote_trusted) {
743                 if (g_hash_table_lookup(__trusted_app_list_hash, (gpointer)local_appid) == NULL) {
744                         if (!__is_preloaded(local_appid, remote_appid)) {
745                                 /* Check the certificate */
746                                 int ret = __check_certificate(local_appid, remote_appid);
747                                 if (ret == MESSAGEPORT_ERROR_NONE)
748                                         g_hash_table_insert(__trusted_app_list_hash, local_appid, "TRUE");
749                                 else {
750                                         _LOGE("The application (%s) is not signed with the same certificate",
751                                                         local_appid);
752                                         goto out;
753                                 }
754                         }
755                 }
756         }
757
758         callback_info = (message_port_callback_info_s *)calloc(1, sizeof(message_port_callback_info_s));
759         if (callback_info == NULL)
760                 goto out;
761
762         callback_info->local_id = mi->local_id;
763         callback_info->remote_app_id = strdup(local_appid);
764         callback_info->callback = mi->callback;
765         callback_info->is_trusted = local_trusted;
766
767         GError *error = NULL;
768         GDBusMessage *msg = g_dbus_method_invocation_get_message(invocation);
769
770         GUnixFDList *fd_list = g_dbus_message_get_unix_fd_list(msg);
771         int fd = g_unix_fd_list_get(fd_list, 0, &error);
772         if (error) {
773                 LOGE("g_unix_fd_list_get fail : %s", error->message);
774                 g_error_free(error);
775         }
776
777         LOGI("g_unix_fd_list_get fd: [%d]", fd);
778
779         if (fd > 0) {
780
781                 callback_info->gio_read = g_io_channel_unix_new(fd);
782                 if (!callback_info->gio_read) {
783                         _LOGE("Error is %s\n", strerror(errno));
784                         __callback_info_free(callback_info);
785                         return -1;
786                 }
787
788                 callback_info->g_src_id = g_io_add_watch(callback_info->gio_read, G_IO_IN | G_IO_HUP,
789                                 __socket_request_handler, (gpointer)callback_info);
790                 if (callback_info->g_src_id == 0) {
791                         _LOGE("fail to add watch on socket");
792                         __callback_info_free(callback_info);
793                         return -1;
794                 }
795
796         }
797
798         data = bundle_decode(raw, len);
799         bundle_free_encoded_rawdata(&raw);
800
801         if (!data) {
802                 _LOGE("Invalid argument : message");
803                 goto out;
804         }
805
806         LOGI("call calback %s", local_appid);
807         if (bi_dir)
808                 mi->callback(mi->local_id, local_appid, local_port, local_trusted, data, NULL);
809         else
810                 mi->callback(mi->local_id, local_appid, NULL, false, data, NULL);
811
812 out:
813
814         return true;
815 }
816
817 static int __check_remote_port(const char *remote_app_id, const char *remote_port, bool is_trusted, bool *exist)
818 {
819         _LOGI("Check a remote port : [%s:%s]", remote_app_id, remote_port);
820
821         GVariant *result = NULL;
822         GError *err = NULL;
823         int ret_val = MESSAGEPORT_ERROR_NONE;
824         char *bus_name = NULL;
825         message_port_remote_app_info_s *remote_app_info = NULL;
826         port_list_info_s *port_info = NULL;
827         int local_reg_id = 0;
828         message_port_local_port_info_s *mi = NULL;
829         gboolean name_exist = false;
830
831         _LOGI("remote_app_id, app_id :[%s : %s] ", remote_app_id, __app_id);
832
833         ret_val = __get_remote_port_info(remote_app_id, remote_port, is_trusted, &remote_app_info, &port_info);
834         if (ret_val != MESSAGEPORT_ERROR_NONE)
835                 return ret_val;
836
837
838         /* self check */
839         if (strcmp(remote_app_id, __app_id) == 0) {
840
841                 _LOGI("__is_local_port_registed ");
842                 if (!__is_local_port_registed(remote_port, is_trusted, &local_reg_id, &mi))
843                         *exist = false;
844                 else
845                         *exist = true;
846
847                 _LOGI("__is_local_port_registed : %d ", *exist);
848                 return MESSAGEPORT_ERROR_NONE;
849         }
850
851         port_info->exist = false;
852         bus_name = port_info->encoded_bus_name;
853
854         result = g_dbus_connection_call_sync(
855                         __gdbus_conn,
856                         DBUS_SERVICE_DBUS,
857                         DBUS_PATH_DBUS,
858                         DBUS_INTERFACE_DBUS,
859                         "NameHasOwner",
860                         g_variant_new("(s)", bus_name),
861                         G_VARIANT_TYPE("(b)"),
862                         G_DBUS_CALL_FLAGS_NONE,
863                         -1,
864                         NULL,
865                         &err);
866
867         if (err || (result == NULL)) {
868                 if (err) {
869                         _LOGE("No reply. error = %s", err->message);
870                         g_error_free(err);
871                 }
872                 ret_val = MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE;
873         } else {
874                 g_variant_get(result, "(b)", &name_exist);
875
876                 if (!name_exist) {
877                         LOGE("Name not exist %s", bus_name);
878                         *exist = false;
879                         ret_val = MESSAGEPORT_ERROR_NONE;
880                 } else {
881
882                         if (is_trusted) {
883                                 if (remote_app_info->certificate_info != CERTIFICATE_MATCH) {
884                                         if (!__is_preloaded(__app_id, remote_app_id)) {
885                                                 if (__check_certificate(__app_id, remote_app_id) != MESSAGEPORT_ERROR_NONE) {
886                                                         ret_val = MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
887                                                         goto out;
888                                                 }
889                                         }
890                                         remote_app_info->certificate_info = CERTIFICATE_MATCH;
891                                 }
892                         }
893
894                         port_info->watcher_id = g_bus_watch_name_on_connection(
895                                         __gdbus_conn,
896                                         port_info->encoded_bus_name,
897                                         G_BUS_NAME_WATCHER_FLAGS_NONE,
898                                         on_name_appeared,
899                                         on_name_vanished,
900                                         port_info,
901                                         NULL);
902
903                         port_info->exist = true;
904                         *exist = true;
905                         ret_val = MESSAGEPORT_ERROR_NONE;
906                         _LOGI("Exist port: %s", bus_name);
907                 }
908
909         }
910 out:
911         if (result)
912                 g_variant_unref(result);
913
914         return ret_val;
915 }
916
917 static bool __check_sender_validation(GVariant *parameters, const char *sender, GDBusConnection *conn)
918 {
919         int ret = 0;
920         char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
921         char *local_appid = NULL;
922         int pid = __get_sender_pid(conn, sender);
923
924         ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
925         retvm_if(ret != AUL_R_OK, false, "Failed to get the sender ID: (%s) (%d)", sender, pid);
926
927         g_variant_get_child(parameters, 0, "s", &local_appid);
928         retvm_if(!local_appid, false, "remote_appid is NULL (%s) (%d)", sender, pid);
929
930         if (strncmp(buffer, local_appid, MAX_PACKAGE_STR_SIZE) == 0) {
931                 g_hash_table_insert(__sender_appid_hash, strdup(sender), GINT_TO_POINTER(pid));
932                 g_free(local_appid);
933         } else {
934                 g_free(local_appid);
935                 return false;
936         }
937         return true;
938 }
939
940 static void __dbus_method_call_handler(GDBusConnection *conn,
941                                 const gchar *sender, const gchar *object_path,
942                                 const gchar *iface_name, const gchar *method_name,
943                                 GVariant *parameters, GDBusMethodInvocation *invocation,
944                                 gpointer user_data)
945 {
946         _LOGI("method_name: %s", method_name);
947         gpointer sender_pid = g_hash_table_lookup(__sender_appid_hash, sender);
948         if (sender_pid == NULL) {
949                 if (!__check_sender_validation(parameters, sender, conn))
950                         return;
951         }
952
953         if (g_strcmp0(method_name, "send_message") == 0)
954                 send_message(parameters, invocation);
955
956 }
957
958 static const GDBusInterfaceVTable interface_vtable = {
959         __dbus_method_call_handler,
960         NULL,
961         NULL
962 };
963
964 static int __dbus_init(void)
965 {
966         bool ret = false;
967         GError *error = NULL;
968
969         __gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
970         if (__gdbus_conn == NULL) {
971                 if (error != NULL) {
972                         _LOGE("Failed to get dbus [%s]", error->message);
973                         g_error_free(error);
974                 }
975                 goto out;
976         }
977
978         ret = true;
979
980 out:
981         if (!__gdbus_conn)
982                 g_object_unref(__gdbus_conn);
983
984         return ret;
985
986 }
987
988
989 int __register_dbus_interface(const char *port_name, bool is_trusted)
990 {
991
992         GDBusNodeInfo *introspection_data = NULL;
993         int registration_id = 0;
994
995         static gchar introspection_prefix[] =
996                 "<node>"
997                 "  <interface name='";
998
999         static gchar introspection_postfix[] =
1000                 "'>"
1001                 "        <method name='send_message'>"
1002                 "          <arg type='s' name='local_appid' direction='in'/>"
1003                 "          <arg type='s' name='local_port' direction='in'/>"
1004                 "          <arg type='b' name='local_trusted' direction='in'/>"
1005                 "          <arg type='b' name='bi_dir' direction='in'/>"
1006                 "          <arg type='s' name='remote_appid' direction='in'/>"
1007                 "          <arg type='s' name='remote_port' direction='in'/>"
1008                 "          <arg type='b' name='remote_trusted' direction='in'/>"
1009                 "          <arg type='u' name='data_len' direction='in'/>"
1010                 "          <arg type='s' name='data' direction='in'/>"
1011                 "        </method>"
1012                 "  </interface>"
1013                 "</node>";
1014
1015         char *introspection_xml = NULL;
1016         int introspection_xml_len = 0;
1017
1018
1019         int owner_id = 0;
1020         GError *error = NULL;
1021         char *bus_name = NULL;
1022         char *interface_name = NULL;
1023         GVariant *result = NULL;
1024
1025         bus_name = __get_encoded_name(__app_id, port_name, is_trusted);
1026         if (!bus_name) {
1027                 _LOGE("Fail to get bus name");
1028                 goto out;
1029         }
1030         interface_name = bus_name;
1031
1032         introspection_xml_len = strlen(introspection_prefix) + strlen(interface_name) +
1033                 strlen(introspection_postfix) + 1;
1034
1035         introspection_xml = (char *)calloc(introspection_xml_len, sizeof(char));
1036         if (!introspection_xml) {
1037                 _LOGE("out of memory");
1038                 goto out;
1039         }
1040
1041
1042         result = g_dbus_connection_call_sync(
1043                         __gdbus_conn,
1044                         DBUS_SERVICE_DBUS,
1045                         DBUS_PATH_DBUS,
1046                         DBUS_INTERFACE_DBUS,
1047                         "RequestName",
1048                         g_variant_new("(su)", bus_name, G_BUS_NAME_OWNER_FLAGS_NONE),
1049                         G_VARIANT_TYPE("(u)"),
1050                         G_DBUS_CALL_FLAGS_NONE,
1051                         -1,
1052                         NULL,
1053                         &error);
1054         if (error) {
1055                 _LOGE("RequestName fail : %s", error->message);
1056                 goto out;
1057         }
1058         if (result == NULL) {
1059                 _LOGE("fail to get name NULL");
1060                 goto out;
1061         }
1062         g_variant_get(result, "(u)", &owner_id);
1063         if (owner_id == 0) {
1064                 _LOGE("Acquiring the own name is failed");
1065                 goto out;
1066         }
1067
1068         _LOGI("Acquiring the own name : %d", owner_id);
1069
1070         snprintf(introspection_xml, introspection_xml_len, "%s%s%s", introspection_prefix, interface_name, introspection_postfix);
1071
1072         introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
1073         if (!introspection_data) {
1074                 _LOGE("g_dbus_node_info_new_for_xml() is failed.");
1075                 goto out;
1076         }
1077
1078         registration_id = g_dbus_connection_register_object(__gdbus_conn,
1079                                                 MESSAGEPORT_OBJECT_PATH, introspection_data->interfaces[0],
1080                                                 &interface_vtable, NULL, NULL, NULL);
1081
1082         _LOGI("registration_id %d", registration_id);
1083
1084         if (registration_id == 0) {
1085                 _LOGE("Failed to g_dbus_connection_register_object");
1086                 goto out;
1087         }
1088
1089 out:
1090         if (introspection_data)
1091                 g_dbus_node_info_unref(introspection_data);
1092         if (introspection_xml)
1093                 free(introspection_xml);
1094         if (bus_name)
1095                 free(bus_name);
1096         if (result)
1097                 g_variant_unref(result);
1098
1099
1100         return registration_id;
1101 }
1102
1103
1104 void __list_free_port_list(gpointer data)
1105 {
1106         port_list_info_s *n = (port_list_info_s *)data;
1107
1108         FREE_AND_NULL(n->encoded_bus_name);
1109         FREE_AND_NULL(n->port_name);
1110         FREE_AND_NULL(n);
1111 }
1112
1113 static void __hash_destory_local_value(gpointer data)
1114 {
1115         message_port_local_port_info_s *mli = (message_port_local_port_info_s *)data;
1116         if (mli->port_name)
1117                 free(mli->port_name);
1118 }
1119 static void __hash_destory_remote_value(gpointer data)
1120 {
1121         message_port_remote_app_info_s *mri = (message_port_remote_app_info_s *)data;
1122
1123         if (mri) {
1124                 FREE_AND_NULL(mri->sender_id);
1125                 FREE_AND_NULL(mri->remote_app_id);
1126                 if (mri->port_list)
1127                         g_list_free_full(mri->port_list, __list_free_port_list);
1128         }
1129 }
1130
1131 static bool __initialize(void)
1132 {
1133
1134 #if !GLIB_CHECK_VERSION(2, 35, 0)
1135         g_type_init();
1136 #endif
1137
1138         int pid = getpid();
1139         int ret = 0;
1140         char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
1141
1142         _LOGI("initialize");
1143         ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
1144         retvm_if(ret != AUL_R_OK, false, "Failed to get the application ID: %d", ret);
1145
1146         __app_id = strdup(buffer);
1147         retvm_if(!__app_id, false, "Malloc failed");
1148         _LOGI("init : %s", __app_id);
1149
1150         if (__local_port_info == NULL) {
1151                 __local_port_info = g_hash_table_new_full(g_direct_hash,  g_direct_equal, NULL, __hash_destory_local_value);
1152                 retvm_if(!__local_port_info, false, "fail to create __local_port_info");
1153         }
1154
1155         if (__remote_port_info == NULL) {
1156                 __remote_port_info = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __hash_destory_remote_value);
1157                 retvm_if(!__remote_port_info, false, "fail to create __remote_port_info");
1158         }
1159
1160         if (__sender_appid_hash == NULL) {
1161                 __sender_appid_hash = g_hash_table_new(g_str_hash, g_str_equal);
1162                 retvm_if(!__sender_appid_hash, false, "fail to create __sender_appid_hash");
1163         }
1164
1165         if (__trusted_app_list_hash == NULL) {
1166                 __trusted_app_list_hash = g_hash_table_new(g_str_hash, g_str_equal);
1167                 retvm_if(!__trusted_app_list_hash, false, "fail to create __trusted_app_list_hash");
1168         }
1169
1170         if (!__dbus_init())
1171                 return false;
1172         _initialized = true;
1173
1174         return true;
1175 }
1176
1177
1178 static bool __message_port_register_port(const int local_id, const char *local_port, bool is_trusted, messageport_message_cb callback)
1179 {
1180         message_port_local_port_info_s *mi = (message_port_local_port_info_s *)calloc(1, sizeof(message_port_local_port_info_s));
1181         retvm_if(!mi, false, "Malloc failed");
1182
1183         mi->callback = callback;
1184         mi->is_trusted = is_trusted;
1185         mi->port_name = strdup(local_port);
1186         if (mi->port_name == NULL) {
1187                 _LOGE("Malloc failed (%s)", local_port);
1188                 free(mi);
1189                 return false;
1190         }
1191         mi->local_id = local_id;
1192
1193         g_hash_table_insert(__local_port_info, GINT_TO_POINTER(mi->local_id), mi);
1194         return true;
1195 }
1196
1197 static int __register_message_port(const char *local_port, bool is_trusted, messageport_message_cb callback)
1198 {
1199         _SECURE_LOGI("Register a message port : [%s:%s]", __app_id, local_port);
1200
1201         int local_id = 0;
1202
1203         /* Check the message port is already registed */
1204         if (__is_local_port_registed(local_port, is_trusted, &local_id, NULL))
1205                 return local_id;
1206
1207         local_id = __register_dbus_interface(local_port, is_trusted);
1208         if (local_id < 1) {
1209                 _LOGE("register_dbus_interface fail !!");
1210                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1211         }
1212
1213         if (!__message_port_register_port(local_id, local_port, is_trusted, callback))
1214                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1215
1216         return local_id;
1217 }
1218
1219 int __message_port_send_async(int sockfd, bundle *kb, const char *local_port,
1220                 bool local_trusted, bool is_bidirection)
1221 {
1222         int ret = 0;
1223         int data_len;
1224         int local_port_len = 0;
1225         unsigned int nb;
1226         bundle_raw *kb_data = NULL;
1227
1228         if (local_port != NULL)
1229                 local_port_len = strlen(local_port) + 1;
1230
1231         if (__write_string_to_socket(sockfd, local_port, local_port_len) != MESSAGEPORT_ERROR_NONE) {
1232                 _LOGE("write local_port fail");
1233                 return MESSAGEPORT_ERROR_IO_ERROR;
1234         }
1235         if (__write_socket(sockfd, (char *)&is_bidirection, sizeof(is_bidirection), &nb) != MESSAGEPORT_ERROR_NONE) {
1236                 _LOGE("write is_bidirection fail");
1237                 return MESSAGEPORT_ERROR_IO_ERROR;
1238         }
1239
1240         bundle_encode(kb, &kb_data, &data_len);
1241         if (kb_data == NULL) {
1242                 _LOGE("bundle encode fail");
1243                 ret = MESSAGEPORT_ERROR_IO_ERROR;
1244                 goto out;
1245         }
1246         if (data_len > MAX_MESSAGE_SIZE) {
1247                 _LOGE("bigger than max size\n");
1248                 ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
1249                 goto out;
1250         }
1251
1252         if (__write_string_to_socket(sockfd, (void *)kb_data, data_len) != MESSAGEPORT_ERROR_NONE) {
1253                 _LOGE("write kb_data fail");
1254                 ret = MESSAGEPORT_ERROR_IO_ERROR;
1255         }
1256 out:
1257         if (kb_data)
1258                 free(kb_data);
1259
1260         return ret;
1261 }
1262
1263 static int __message_port_send_message(const char *remote_appid, const char *remote_port,
1264                 const char *local_port, bool trusted_message, bool local_trusted, bool bi_dir, bundle *message)
1265 {
1266
1267         int ret = MESSAGEPORT_ERROR_NONE;
1268         GUnixFDList *fd_list = NULL;
1269         GError *error = NULL;
1270
1271         int len = 0;
1272         bundle_raw *raw = NULL;
1273         char *bus_name = NULL;
1274         char *interface_name = NULL;
1275
1276         message_port_remote_app_info_s *remote_app_info = NULL;
1277         port_list_info_s *port_info = NULL;
1278         GDBusMessage *msg = NULL;
1279         GError *err = NULL;
1280         GVariant *body = NULL;
1281
1282         ret = __get_remote_port_info(remote_appid, remote_port, trusted_message, &remote_app_info, &port_info);
1283         if (ret != MESSAGEPORT_ERROR_NONE)
1284                 return ret;
1285
1286         if (port_info->exist == false) {
1287                 bool exist = false;
1288                 _LOGI("port exist check !!");
1289                 ret =  __check_remote_port(remote_appid, remote_port, trusted_message, &exist);
1290                 if (ret != MESSAGEPORT_ERROR_NONE) {
1291                         goto out;
1292                 } else if (!exist) {
1293                         ret = MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1294                         goto out;
1295                 }
1296         }
1297
1298         if (port_info->sock_pair[0] > 0) {
1299                 ret = __message_port_send_async(port_info->sock_pair[0], message,
1300                                 (local_port) ? local_port : "", local_trusted, bi_dir);
1301         } else {
1302
1303                 bus_name = port_info->encoded_bus_name;
1304                 interface_name = bus_name;
1305
1306                 if (bundle_encode(message, &raw, &len) != BUNDLE_ERROR_NONE) {
1307                         ret = MESSAGEPORT_ERROR_INVALID_PARAMETER;
1308                         goto out;
1309                 }
1310
1311                 if (MAX_MESSAGE_SIZE < len) {
1312                         _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
1313                         ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
1314                 }
1315
1316                 body = g_variant_new("(ssbbssbus)", __app_id, (local_port) ? local_port : "", local_trusted, bi_dir,
1317                                 remote_appid, remote_port, trusted_message, len, raw);
1318
1319
1320                 if (strcmp(remote_appid, __app_id) != 0) { /* self send */
1321
1322                         /*  if message-port fail to get socket pair, communicate using GDBus */
1323                         if (aul_request_message_port_socket_pair(port_info->sock_pair) != AUL_R_OK) {
1324                                 _LOGE("error create socket pair");
1325                         } else {
1326
1327                                 _LOGI("sock pair : %d, %d", port_info->sock_pair[0], port_info->sock_pair[1]);
1328
1329                                 fd_list = g_unix_fd_list_new();
1330                                 g_unix_fd_list_append(fd_list, port_info->sock_pair[1], &err);
1331                                 g_unix_fd_list_append(fd_list, port_info->sock_pair[0], &err);
1332
1333                                 if (err != NULL) {
1334                                         _LOGE("g_unix_fd_list_append [%s]", error->message);
1335                                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1336                                         g_error_free(err);
1337                                         goto out;
1338                                 }
1339                         }
1340
1341                 }
1342
1343                 msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, interface_name, "send_message");
1344                 if (!msg) {
1345                         _LOGE("Can't allocate new method call");
1346                         ret = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1347                         goto out;
1348                 }
1349
1350                 g_dbus_message_set_unix_fd_list(msg, fd_list);
1351                 g_dbus_message_set_body(msg, body);
1352                 g_dbus_message_set_flags(msg, G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED);
1353                 g_dbus_connection_send_message(__gdbus_conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err);
1354                 if (err != NULL) {
1355                         _LOGE("No reply. error = %s", err->message);
1356                         g_error_free(err);
1357                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1358                         goto out;
1359                 }
1360
1361
1362         }
1363
1364 out:
1365         if (msg)
1366                 g_object_unref(msg);
1367         if (raw)
1368                 bundle_free_encoded_rawdata(&raw);
1369         if (fd_list)
1370                 g_object_unref(fd_list);
1371
1372
1373         return ret;
1374 }
1375
1376 int __message_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port,  bool trusted_message, bundle *message)
1377 {
1378         message_port_local_port_info_s *local_info;
1379         int ret = __get_local_port_info(id, &local_info);
1380         if (ret != MESSAGEPORT_ERROR_NONE)
1381                 return ret;
1382
1383         _LOGI("bidirectional_message %s", local_info->port_name);
1384         return __message_port_send_message(remote_app_id, remote_port,
1385                         local_info->port_name, trusted_message, local_info->is_trusted, true, message);
1386 }
1387
1388 int messageport_unregister_local_port(int local_port_id, bool trusted_port)
1389 {
1390
1391         GVariant *result;
1392         char *bus_name = NULL;
1393         GError *err = NULL;
1394         int ret = 0;
1395
1396         _LOGI("unregister : %d", local_port_id);
1397
1398         message_port_local_port_info_s *mi =
1399                 (message_port_local_port_info_s *)
1400                 g_hash_table_lookup(__local_port_info, GINT_TO_POINTER(local_port_id));
1401         if (mi == NULL)
1402                 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1403
1404         if (mi->is_trusted != trusted_port)
1405                 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
1406
1407         bus_name = __get_encoded_name(__app_id, mi->port_name, mi->is_trusted);
1408         if (bus_name == NULL)
1409                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1410
1411         g_dbus_connection_unregister_object(__gdbus_conn, local_port_id);
1412
1413         result = g_dbus_connection_call_sync(
1414                         __gdbus_conn,
1415                         DBUS_SERVICE_DBUS,
1416                         DBUS_PATH_DBUS,
1417                         DBUS_INTERFACE_DBUS,
1418                         "ReleaseName",
1419                         g_variant_new("(s)", bus_name),
1420                         G_VARIANT_TYPE("(u)"),
1421                         G_DBUS_CALL_FLAGS_NONE,
1422                         -1,
1423                         NULL,
1424                         &err);
1425
1426         if (bus_name)
1427                 free(bus_name);
1428
1429         if (err) {
1430                 _LOGE("RequestName fail : %s", err->message);
1431                 g_error_free(err);
1432                 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1433         }
1434         g_variant_get(result, "(u)", &ret);
1435
1436         if (result)
1437                 g_variant_unref(result);
1438
1439         if (ret != DBUS_RELEASE_NAME_REPLY_RELEASED) {
1440
1441                 if (ret == DBUS_RELEASE_NAME_REPLY_NON_EXISTENT) {
1442                         _LOGE("Port Not exist");
1443                         return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1444                 } else if (ret == DBUS_RELEASE_NAME_REPLY_NOT_OWNER) {
1445                         _LOGE("Try to release not owned name. MESSAGEPORT_ERROR_INVALID_PARAMETER");
1446                         return MESSAGEPORT_ERROR_INVALID_PARAMETER;
1447                 }
1448         }
1449
1450
1451         g_hash_table_remove(__local_port_info, GINT_TO_POINTER(local_port_id));
1452
1453         return MESSAGEPORT_ERROR_NONE;
1454 }
1455
1456 int messageport_register_local_port(const char *local_port, messageport_message_cb callback)
1457 {
1458         if (!_initialized) {
1459                 if (!__initialize())
1460                         return MESSAGEPORT_ERROR_IO_ERROR;
1461         }
1462
1463         return __register_message_port(local_port, false, callback);
1464 }
1465
1466 int messageport_register_trusted_local_port(const char *local_port, messageport_message_cb callback)
1467 {
1468         if (!_initialized) {
1469                 if (!__initialize())
1470                         return MESSAGEPORT_ERROR_IO_ERROR;
1471         }
1472
1473         return __register_message_port(local_port, true, callback);
1474
1475 }
1476
1477 int messageport_check_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
1478 {
1479         if (!_initialized) {
1480                 if (!__initialize())
1481                         return MESSAGEPORT_ERROR_IO_ERROR;
1482         }
1483
1484         int ret = __check_remote_port(remote_app_id, remote_port, false, exist);
1485         if (ret == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND) {
1486                 *exist = false;
1487                 ret = MESSAGEPORT_ERROR_NONE;
1488         }
1489
1490         return ret;
1491 }
1492
1493 int messageport_check_trusted_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
1494 {
1495         if (!_initialized) {
1496                 if (!__initialize())
1497                         return MESSAGEPORT_ERROR_IO_ERROR;
1498         }
1499
1500         int ret = __check_remote_port(remote_app_id, remote_port, true, exist);
1501         if (ret == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND) {
1502                 *exist = false;
1503                 ret = MESSAGEPORT_ERROR_NONE;
1504         }
1505
1506         return ret;
1507 }
1508
1509 int messageport_send_message(const char *remote_app_id, const char *remote_port, bundle *message)
1510 {
1511         if (!_initialized) {
1512                 if (!__initialize())
1513                         return MESSAGEPORT_ERROR_IO_ERROR;
1514         }
1515
1516         return __message_port_send_message(remote_app_id, remote_port, NULL, false, false, false, message);
1517 }
1518
1519 int messageport_send_trusted_message(const char *remote_app_id, const char *remote_port, bundle *message)
1520 {
1521         if (!_initialized) {
1522                 if (!__initialize())
1523                         return MESSAGEPORT_ERROR_IO_ERROR;
1524         }
1525
1526         return __message_port_send_message(remote_app_id, remote_port, NULL, true, false, false, message);
1527 }
1528
1529 int messageport_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port,
1530                 bundle *message)
1531 {
1532         if (!_initialized) {
1533                 if (!__initialize())
1534                         return MESSAGEPORT_ERROR_IO_ERROR;
1535         }
1536
1537         return __message_send_bidirectional_message(id, remote_app_id, remote_port, false, message);
1538 }
1539
1540 int messageport_send_bidirectional_trusted_message(int id, const char *remote_app_id, const char *remote_port,
1541                 bundle *message)
1542 {
1543         if (!_initialized) {
1544                 if (!__initialize())
1545                         return MESSAGEPORT_ERROR_IO_ERROR;
1546         }
1547         return __message_send_bidirectional_message(id, remote_app_id, remote_port, true, message);
1548 }
1549
1550 int messageport_get_local_port_name(int id, char **name)
1551 {
1552         message_port_local_port_info_s *local_info;
1553         int ret = __get_local_port_info(id, &local_info);
1554
1555         if (ret != MESSAGEPORT_ERROR_NONE)
1556                 return ret;
1557
1558         *name = strdup(local_info->port_name);
1559
1560         if (*name == NULL)
1561                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1562
1563         return MESSAGEPORT_ERROR_NONE;
1564 }
1565
1566 int messageport_check_trusted_local_port(int id, bool *trusted)
1567 {
1568         message_port_local_port_info_s *local_info;
1569         int ret = __get_local_port_info(id, &local_info);
1570
1571         if (ret != MESSAGEPORT_ERROR_NONE)
1572                 return ret;
1573
1574         *trusted = local_info->is_trusted;
1575
1576         return MESSAGEPORT_ERROR_NONE;;
1577 }
1578