Fix wrong callback called 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         bool is_trusted;
98         int data_len;
99         unsigned char *data;
100 } message_port_pkt_s;
101
102 typedef struct message_port_callback_info {
103         messageport_message_cb callback;
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
606         if (__read_string_from_socket(fd, (char **)&pkt->remote_port_name, &pkt->remote_port_name_len) != MESSAGEPORT_ERROR_NONE) {
607                 LOGE("read socket fail: port_name");
608                 free(pkt->remote_port_name);
609                 free(pkt);
610                 close(fd);
611                 return NULL;
612         }
613
614         if (__read_socket(fd, (char *)&pkt->is_bidirection, sizeof(pkt->is_bidirection), &nb) != MESSAGEPORT_ERROR_NONE) {
615                 LOGE("read socket fail: is_bidirection");
616                 free(pkt->remote_port_name);
617                 free(pkt);
618                 close(fd);
619                 return NULL;
620         }
621
622         if (__read_socket(fd, (char *)&pkt->is_trusted, sizeof(pkt->is_trusted), &nb) != MESSAGEPORT_ERROR_NONE) {
623                 LOGE("read socket fail: is_trusted");
624                 free(pkt->remote_port_name);
625                 free(pkt);
626                 close(fd);
627                 return NULL;
628         }
629
630         if (__read_string_from_socket(fd, (char **)&pkt->data, &pkt->data_len) != MESSAGEPORT_ERROR_NONE) {
631                 LOGE("read socket fail: data");
632                 free(pkt->remote_port_name);
633                 free(pkt);
634                 close(fd);
635                 return NULL;
636         }
637
638         return pkt;
639 }
640
641 static gboolean __socket_request_handler(GIOChannel *gio,
642                 GIOCondition cond,
643                 gpointer data)
644 {
645         int fd = 0;
646         message_port_callback_info_s *mi;
647         message_port_pkt_s *pkt;
648         bundle *kb = NULL;
649         GError *error = NULL;
650
651         mi = (message_port_callback_info_s *)data;
652         if (mi == NULL) {
653
654                 g_io_channel_shutdown(gio, FALSE, &error);
655                 if (error) {
656                         _LOGE("g_io_channel_shutdown error : %s", error->message);
657                         g_error_free(error);
658                 }
659                 g_io_channel_unref(gio);
660                 return FALSE;
661         }
662
663         if (cond == G_IO_HUP) {
664
665                 _LOGI("socket G_IO_HUP");
666                 __callback_info_free(mi);
667                 return FALSE;
668
669         } else {
670
671                 if ((fd = g_io_channel_unix_get_fd(gio)) < 0) {
672                         _LOGE("fail to get fd from io channel");
673                         __callback_info_free(mi);
674                         return FALSE;
675                 }
676
677                 if ((pkt = __message_port_recv_raw(fd)) == NULL) {
678                         _LOGE("recv error on SOCKET");
679                         __callback_info_free(mi);
680                         return FALSE;
681                 }
682
683                 kb = bundle_decode(pkt->data, pkt->data_len);
684
685                 if (pkt->is_bidirection)
686                         mi->callback(mi->local_id, mi->remote_app_id, pkt->remote_port_name, pkt->is_trusted, kb, NULL);
687                 else
688                         mi->callback(mi->local_id, mi->remote_app_id, NULL, pkt->is_trusted, kb, NULL);
689
690                 if (pkt) {
691                         if (pkt->remote_port_name)
692                                 free(pkt->remote_port_name);
693                         if (pkt->data)
694                                 free(pkt->data);
695                         free(pkt);
696                 }
697         }
698
699         return TRUE;
700 }
701
702 static bool send_message(GVariant *parameters, GDBusMethodInvocation *invocation)
703 {
704         char *local_port = NULL;
705         char *local_appid = NULL;
706         char *remote_appid = NULL;
707         char *remote_port = NULL;
708         gboolean local_trusted = false;
709         gboolean remote_trusted = false;
710         gboolean bi_dir = false;
711         int len = 0;
712
713         bundle *data = NULL;
714         bundle_raw *raw = NULL;
715         message_port_local_port_info_s *mi;
716         message_port_callback_info_s *callback_info;
717         int local_reg_id = 0;
718
719         g_variant_get(parameters, "(ssbbssbus)", &local_appid, &local_port, &local_trusted, &bi_dir,
720                         &remote_appid, &remote_port, &remote_trusted, &len, &raw);
721
722         if (!remote_port) {
723                 _LOGE("Invalid argument : remote_port is NULL");
724                 goto out;
725         }
726         if (!remote_appid) {
727                 _LOGE("Invalid argument : remote_appid is NULL");
728                 goto out;
729         }
730         if (!__is_local_port_registed(remote_port, remote_trusted, &local_reg_id, &mi)) {
731                 _LOGE("Invalid argument : remote_port:(%s) trusted(%d)", remote_port, remote_trusted);
732                 goto out;
733         }
734         if (!local_appid) {
735                 _LOGE("Invalid argument : local_appid");
736                 goto out;
737         }
738         if (!local_port) {
739                 _LOGE("Invalid argument : local_port");
740                 goto out;
741         }
742         if (strcmp(remote_appid, __app_id) != 0) {
743                 _LOGE("Invalid argument : remote_appid (%s)", remote_appid);
744                 goto out;
745         }
746         if (strcmp(remote_port, mi->port_name) != 0) {
747                 _LOGE("Invalid argument : remote_port (%s)", remote_port);
748                 goto out;
749         }
750         if (!len) {
751                 _LOGE("Invalid argument : data_len");
752                 goto out;
753         }
754         if (remote_trusted) {
755                 if (g_hash_table_lookup(__trusted_app_list_hash, (gpointer)local_appid) == NULL) {
756                         if (!__is_preloaded(local_appid, remote_appid)) {
757                                 /* Check the certificate */
758                                 int ret = __check_certificate(local_appid, remote_appid);
759                                 if (ret == MESSAGEPORT_ERROR_NONE)
760                                         g_hash_table_insert(__trusted_app_list_hash, local_appid, "TRUE");
761                                 else {
762                                         _LOGE("The application (%s) is not signed with the same certificate",
763                                                         local_appid);
764                                         goto out;
765                                 }
766                         }
767                 }
768         }
769
770         callback_info = (message_port_callback_info_s *)calloc(1, sizeof(message_port_callback_info_s));
771         if (callback_info == NULL)
772                 goto out;
773
774         callback_info->local_id = mi->local_id;
775         callback_info->remote_app_id = strdup(local_appid);
776         callback_info->callback = mi->callback;
777
778         GError *error = NULL;
779         GDBusMessage *msg = g_dbus_method_invocation_get_message(invocation);
780
781         GUnixFDList *fd_list = g_dbus_message_get_unix_fd_list(msg);
782         int fd = g_unix_fd_list_get(fd_list, 0, &error);
783         if (error) {
784                 LOGE("g_unix_fd_list_get fail : %s", error->message);
785                 g_error_free(error);
786         }
787
788         LOGI("g_unix_fd_list_get fd: [%d]", fd);
789
790         if (fd > 0) {
791
792                 callback_info->gio_read = g_io_channel_unix_new(fd);
793                 if (!callback_info->gio_read) {
794                         _LOGE("Error is %s\n", strerror(errno));
795                         __callback_info_free(callback_info);
796                         return -1;
797                 }
798
799                 callback_info->g_src_id = g_io_add_watch(callback_info->gio_read, G_IO_IN | G_IO_HUP,
800                                 __socket_request_handler, (gpointer)callback_info);
801                 if (callback_info->g_src_id == 0) {
802                         _LOGE("fail to add watch on socket");
803                         __callback_info_free(callback_info);
804                         return -1;
805                 }
806
807         }
808
809         data = bundle_decode(raw, len);
810         bundle_free_encoded_rawdata(&raw);
811
812         if (!data) {
813                 _LOGE("Invalid argument : message");
814                 goto out;
815         }
816
817         LOGI("call calback %s", local_appid);
818         if (bi_dir)
819                 mi->callback(mi->local_id, local_appid, local_port, local_trusted, data, NULL);
820         else
821                 mi->callback(mi->local_id, local_appid, NULL, false, data, NULL);
822
823 out:
824
825         return true;
826 }
827
828 static int __check_remote_port(const char *remote_app_id, const char *remote_port, bool is_trusted, bool *exist)
829 {
830         _LOGI("Check a remote port : [%s:%s]", remote_app_id, remote_port);
831
832         GVariant *result = NULL;
833         GError *err = NULL;
834         int ret_val = MESSAGEPORT_ERROR_NONE;
835         char *bus_name = NULL;
836         message_port_remote_app_info_s *remote_app_info = NULL;
837         port_list_info_s *port_info = NULL;
838         int local_reg_id = 0;
839         message_port_local_port_info_s *mi = NULL;
840         gboolean name_exist = false;
841
842         _LOGI("remote_app_id, app_id :[%s : %s] ", remote_app_id, __app_id);
843
844         ret_val = __get_remote_port_info(remote_app_id, remote_port, is_trusted, &remote_app_info, &port_info);
845         if (ret_val != MESSAGEPORT_ERROR_NONE)
846                 return ret_val;
847
848
849         /* self check */
850         if (strcmp(remote_app_id, __app_id) == 0) {
851
852                 _LOGI("__is_local_port_registed ");
853                 if (!__is_local_port_registed(remote_port, is_trusted, &local_reg_id, &mi))
854                         *exist = false;
855                 else
856                         *exist = true;
857
858                 _LOGI("__is_local_port_registed : %d ", *exist);
859                 return MESSAGEPORT_ERROR_NONE;
860         }
861
862         port_info->exist = false;
863         bus_name = port_info->encoded_bus_name;
864
865         result = g_dbus_connection_call_sync(
866                         __gdbus_conn,
867                         DBUS_SERVICE_DBUS,
868                         DBUS_PATH_DBUS,
869                         DBUS_INTERFACE_DBUS,
870                         "NameHasOwner",
871                         g_variant_new("(s)", bus_name),
872                         G_VARIANT_TYPE("(b)"),
873                         G_DBUS_CALL_FLAGS_NONE,
874                         -1,
875                         NULL,
876                         &err);
877
878         if (err || (result == NULL)) {
879                 if (err) {
880                         _LOGE("No reply. error = %s", err->message);
881                         g_error_free(err);
882                 }
883                 ret_val = MESSAGEPORT_ERROR_RESOURCE_UNAVAILABLE;
884         } else {
885                 g_variant_get(result, "(b)", &name_exist);
886
887                 if (!name_exist) {
888                         LOGE("Name not exist %s", bus_name);
889                         *exist = false;
890                         ret_val = MESSAGEPORT_ERROR_NONE;
891                 } else {
892
893                         if (is_trusted) {
894                                 if (remote_app_info->certificate_info != CERTIFICATE_MATCH) {
895                                         if (!__is_preloaded(__app_id, remote_app_id)) {
896                                                 if (__check_certificate(__app_id, remote_app_id) != MESSAGEPORT_ERROR_NONE) {
897                                                         ret_val = MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
898                                                         goto out;
899                                                 }
900                                         }
901                                         remote_app_info->certificate_info = CERTIFICATE_MATCH;
902                                 }
903                         }
904
905                         port_info->watcher_id = g_bus_watch_name_on_connection(
906                                         __gdbus_conn,
907                                         port_info->encoded_bus_name,
908                                         G_BUS_NAME_WATCHER_FLAGS_NONE,
909                                         on_name_appeared,
910                                         on_name_vanished,
911                                         port_info,
912                                         NULL);
913
914                         port_info->exist = true;
915                         *exist = true;
916                         ret_val = MESSAGEPORT_ERROR_NONE;
917                         _LOGI("Exist port: %s", bus_name);
918                 }
919
920         }
921 out:
922         if (result)
923                 g_variant_unref(result);
924
925         return ret_val;
926 }
927
928 static bool __check_sender_validation(GVariant *parameters, const char *sender, GDBusConnection *conn)
929 {
930         int ret = 0;
931         char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
932         char *local_appid = NULL;
933         int pid = __get_sender_pid(conn, sender);
934
935         ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
936         retvm_if(ret != AUL_R_OK, false, "Failed to get the sender ID: (%s) (%d)", sender, pid);
937
938         g_variant_get_child(parameters, 0, "s", &local_appid);
939         retvm_if(!local_appid, false, "remote_appid is NULL (%s) (%d)", sender, pid);
940
941         if (strncmp(buffer, local_appid, MAX_PACKAGE_STR_SIZE) == 0) {
942                 g_hash_table_insert(__sender_appid_hash, strdup(sender), GINT_TO_POINTER(pid));
943                 g_free(local_appid);
944         } else {
945                 g_free(local_appid);
946                 return false;
947         }
948         return true;
949 }
950
951 static void __dbus_method_call_handler(GDBusConnection *conn,
952                                 const gchar *sender, const gchar *object_path,
953                                 const gchar *iface_name, const gchar *method_name,
954                                 GVariant *parameters, GDBusMethodInvocation *invocation,
955                                 gpointer user_data)
956 {
957         _LOGI("method_name: %s", method_name);
958         gpointer sender_pid = g_hash_table_lookup(__sender_appid_hash, sender);
959         if (sender_pid == NULL) {
960                 if (!__check_sender_validation(parameters, sender, conn))
961                         return;
962         }
963
964         if (g_strcmp0(method_name, "send_message") == 0)
965                 send_message(parameters, invocation);
966
967 }
968
969 static const GDBusInterfaceVTable interface_vtable = {
970         __dbus_method_call_handler,
971         NULL,
972         NULL
973 };
974
975 static int __dbus_init(void)
976 {
977         bool ret = false;
978         GError *error = NULL;
979
980         __gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
981         if (__gdbus_conn == NULL) {
982                 if (error != NULL) {
983                         _LOGE("Failed to get dbus [%s]", error->message);
984                         g_error_free(error);
985                 }
986                 goto out;
987         }
988
989         ret = true;
990
991 out:
992         if (!__gdbus_conn)
993                 g_object_unref(__gdbus_conn);
994
995         return ret;
996
997 }
998
999
1000 int __register_dbus_interface(const char *port_name, bool is_trusted)
1001 {
1002
1003         GDBusNodeInfo *introspection_data = NULL;
1004         int registration_id = 0;
1005
1006         static gchar introspection_prefix[] =
1007                 "<node>"
1008                 "  <interface name='";
1009
1010         static gchar introspection_postfix[] =
1011                 "'>"
1012                 "        <method name='send_message'>"
1013                 "          <arg type='s' name='local_appid' direction='in'/>"
1014                 "          <arg type='s' name='local_port' direction='in'/>"
1015                 "          <arg type='b' name='local_trusted' direction='in'/>"
1016                 "          <arg type='b' name='bi_dir' direction='in'/>"
1017                 "          <arg type='s' name='remote_appid' direction='in'/>"
1018                 "          <arg type='s' name='remote_port' direction='in'/>"
1019                 "          <arg type='b' name='remote_trusted' direction='in'/>"
1020                 "          <arg type='u' name='data_len' direction='in'/>"
1021                 "          <arg type='s' name='data' direction='in'/>"
1022                 "        </method>"
1023                 "  </interface>"
1024                 "</node>";
1025
1026         char *introspection_xml = NULL;
1027         int introspection_xml_len = 0;
1028
1029
1030         int owner_id = 0;
1031         GError *error = NULL;
1032         char *bus_name = NULL;
1033         char *interface_name = NULL;
1034         GVariant *result = NULL;
1035
1036         bus_name = __get_encoded_name(__app_id, port_name, is_trusted);
1037         if (!bus_name) {
1038                 _LOGE("Fail to get bus name");
1039                 goto out;
1040         }
1041         interface_name = bus_name;
1042
1043         introspection_xml_len = strlen(introspection_prefix) + strlen(interface_name) +
1044                 strlen(introspection_postfix) + 1;
1045
1046         introspection_xml = (char *)calloc(introspection_xml_len, sizeof(char));
1047         if (!introspection_xml) {
1048                 _LOGE("out of memory");
1049                 goto out;
1050         }
1051
1052
1053         result = g_dbus_connection_call_sync(
1054                         __gdbus_conn,
1055                         DBUS_SERVICE_DBUS,
1056                         DBUS_PATH_DBUS,
1057                         DBUS_INTERFACE_DBUS,
1058                         "RequestName",
1059                         g_variant_new("(su)", bus_name, G_BUS_NAME_OWNER_FLAGS_NONE),
1060                         G_VARIANT_TYPE("(u)"),
1061                         G_DBUS_CALL_FLAGS_NONE,
1062                         -1,
1063                         NULL,
1064                         &error);
1065         if (error) {
1066                 _LOGE("RequestName fail : %s", error->message);
1067                 goto out;
1068         }
1069         if (result == NULL) {
1070                 _LOGE("fail to get name NULL");
1071                 goto out;
1072         }
1073         g_variant_get(result, "(u)", &owner_id);
1074         if (owner_id == 0) {
1075                 _LOGE("Acquiring the own name is failed");
1076                 goto out;
1077         }
1078
1079         _LOGI("Acquiring the own name : %d", owner_id);
1080
1081         snprintf(introspection_xml, introspection_xml_len, "%s%s%s", introspection_prefix, interface_name, introspection_postfix);
1082
1083         introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
1084         if (!introspection_data) {
1085                 _LOGE("g_dbus_node_info_new_for_xml() is failed.");
1086                 goto out;
1087         }
1088
1089         registration_id = g_dbus_connection_register_object(__gdbus_conn,
1090                                                 MESSAGEPORT_OBJECT_PATH, introspection_data->interfaces[0],
1091                                                 &interface_vtable, NULL, NULL, NULL);
1092
1093         _LOGI("registration_id %d", registration_id);
1094
1095         if (registration_id == 0) {
1096                 _LOGE("Failed to g_dbus_connection_register_object");
1097                 goto out;
1098         }
1099
1100 out:
1101         if (introspection_data)
1102                 g_dbus_node_info_unref(introspection_data);
1103         if (introspection_xml)
1104                 free(introspection_xml);
1105         if (bus_name)
1106                 free(bus_name);
1107         if (result)
1108                 g_variant_unref(result);
1109
1110
1111         return registration_id;
1112 }
1113
1114
1115 void __list_free_port_list(gpointer data)
1116 {
1117         port_list_info_s *n = (port_list_info_s *)data;
1118
1119         FREE_AND_NULL(n->encoded_bus_name);
1120         FREE_AND_NULL(n->port_name);
1121         FREE_AND_NULL(n);
1122 }
1123
1124 static void __hash_destory_local_value(gpointer data)
1125 {
1126         message_port_local_port_info_s *mli = (message_port_local_port_info_s *)data;
1127         if (mli->port_name)
1128                 free(mli->port_name);
1129 }
1130 static void __hash_destory_remote_value(gpointer data)
1131 {
1132         message_port_remote_app_info_s *mri = (message_port_remote_app_info_s *)data;
1133
1134         if (mri) {
1135                 FREE_AND_NULL(mri->sender_id);
1136                 FREE_AND_NULL(mri->remote_app_id);
1137                 if (mri->port_list)
1138                         g_list_free_full(mri->port_list, __list_free_port_list);
1139         }
1140 }
1141
1142 static bool __initialize(void)
1143 {
1144
1145 #if !GLIB_CHECK_VERSION(2, 35, 0)
1146         g_type_init();
1147 #endif
1148
1149         int pid = getpid();
1150         int ret = 0;
1151         char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
1152
1153         _LOGI("initialize");
1154         ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
1155         retvm_if(ret != AUL_R_OK, false, "Failed to get the application ID: %d", ret);
1156
1157         __app_id = strdup(buffer);
1158         retvm_if(!__app_id, false, "Malloc failed");
1159         _LOGI("init : %s", __app_id);
1160
1161         if (__local_port_info == NULL) {
1162                 __local_port_info = g_hash_table_new_full(g_direct_hash,  g_direct_equal, NULL, __hash_destory_local_value);
1163                 retvm_if(!__local_port_info, false, "fail to create __local_port_info");
1164         }
1165
1166         if (__remote_port_info == NULL) {
1167                 __remote_port_info = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __hash_destory_remote_value);
1168                 retvm_if(!__remote_port_info, false, "fail to create __remote_port_info");
1169         }
1170
1171         if (__sender_appid_hash == NULL) {
1172                 __sender_appid_hash = g_hash_table_new(g_str_hash, g_str_equal);
1173                 retvm_if(!__sender_appid_hash, false, "fail to create __sender_appid_hash");
1174         }
1175
1176         if (__trusted_app_list_hash == NULL) {
1177                 __trusted_app_list_hash = g_hash_table_new(g_str_hash, g_str_equal);
1178                 retvm_if(!__trusted_app_list_hash, false, "fail to create __trusted_app_list_hash");
1179         }
1180
1181         if (!__dbus_init())
1182                 return false;
1183         _initialized = true;
1184
1185         return true;
1186 }
1187
1188
1189 static bool __message_port_register_port(const int local_id, const char *local_port, bool is_trusted, messageport_message_cb callback)
1190 {
1191         message_port_local_port_info_s *mi = (message_port_local_port_info_s *)calloc(1, sizeof(message_port_local_port_info_s));
1192         retvm_if(!mi, false, "Malloc failed");
1193
1194         mi->callback = callback;
1195         mi->is_trusted = is_trusted;
1196         mi->port_name = strdup(local_port);
1197         if (mi->port_name == NULL) {
1198                 _LOGE("Malloc failed (%s)", local_port);
1199                 free(mi);
1200                 return false;
1201         }
1202         mi->local_id = local_id;
1203
1204         g_hash_table_insert(__local_port_info, GINT_TO_POINTER(mi->local_id), mi);
1205         return true;
1206 }
1207
1208 static int __register_message_port(const char *local_port, bool is_trusted, messageport_message_cb callback)
1209 {
1210         _SECURE_LOGI("Register a message port : [%s:%s]", __app_id, local_port);
1211
1212         int local_id = 0;
1213
1214         /* Check the message port is already registed */
1215         if (__is_local_port_registed(local_port, is_trusted, &local_id, NULL))
1216                 return local_id;
1217
1218         local_id = __register_dbus_interface(local_port, is_trusted);
1219         if (local_id < 1) {
1220                 _LOGE("register_dbus_interface fail !!");
1221                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1222         }
1223
1224         if (!__message_port_register_port(local_id, local_port, is_trusted, callback))
1225                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1226
1227         return local_id;
1228 }
1229
1230 int __message_port_send_async(int sockfd, bundle *kb, const char *local_port,
1231                 bool local_trusted, bool is_bidirection)
1232 {
1233         int ret = 0;
1234         int data_len;
1235         int local_port_len = 0;
1236         unsigned int nb;
1237         bundle_raw *kb_data = NULL;
1238
1239         if (local_port != NULL)
1240                 local_port_len = strlen(local_port) + 1;
1241
1242         if (__write_string_to_socket(sockfd, local_port, local_port_len) != MESSAGEPORT_ERROR_NONE) {
1243                 _LOGE("write local_port fail");
1244                 return MESSAGEPORT_ERROR_IO_ERROR;
1245         }
1246
1247         if (__write_socket(sockfd, (char *)&is_bidirection, sizeof(is_bidirection), &nb) != MESSAGEPORT_ERROR_NONE) {
1248                 _LOGE("write is_bidirection fail");
1249                 return MESSAGEPORT_ERROR_IO_ERROR;
1250         }
1251
1252         if (__write_socket(sockfd, (char *)&local_trusted, sizeof(local_trusted), &nb) != MESSAGEPORT_ERROR_NONE) {
1253                 _LOGE("write local_trusted fail");
1254                 return MESSAGEPORT_ERROR_IO_ERROR;
1255         }
1256
1257         bundle_encode(kb, &kb_data, &data_len);
1258         if (kb_data == NULL) {
1259                 _LOGE("bundle encode fail");
1260                 ret = MESSAGEPORT_ERROR_IO_ERROR;
1261                 goto out;
1262         }
1263
1264         if (data_len > MAX_MESSAGE_SIZE) {
1265                 _LOGE("bigger than max size\n");
1266                 ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
1267                 goto out;
1268         }
1269
1270         if (__write_string_to_socket(sockfd, (void *)kb_data, data_len) != MESSAGEPORT_ERROR_NONE) {
1271                 _LOGE("write kb_data fail");
1272                 ret = MESSAGEPORT_ERROR_IO_ERROR;
1273         }
1274 out:
1275         if (kb_data)
1276                 free(kb_data);
1277
1278         return ret;
1279 }
1280
1281 static int __message_port_send_message(const char *remote_appid, const char *remote_port,
1282                 const char *local_port, bool trusted_message, bool local_trusted, bool bi_dir, bundle *message)
1283 {
1284
1285         int ret = MESSAGEPORT_ERROR_NONE;
1286         GUnixFDList *fd_list = NULL;
1287         GError *error = NULL;
1288
1289         int len = 0;
1290         bundle_raw *raw = NULL;
1291         char *bus_name = NULL;
1292         char *interface_name = NULL;
1293
1294         message_port_remote_app_info_s *remote_app_info = NULL;
1295         port_list_info_s *port_info = NULL;
1296         GDBusMessage *msg = NULL;
1297         GError *err = NULL;
1298         GVariant *body = NULL;
1299
1300         ret = __get_remote_port_info(remote_appid, remote_port, trusted_message, &remote_app_info, &port_info);
1301         if (ret != MESSAGEPORT_ERROR_NONE)
1302                 return ret;
1303
1304         if (port_info->exist == false) {
1305                 bool exist = false;
1306                 _LOGI("port exist check !!");
1307                 ret =  __check_remote_port(remote_appid, remote_port, trusted_message, &exist);
1308                 if (ret != MESSAGEPORT_ERROR_NONE) {
1309                         goto out;
1310                 } else if (!exist) {
1311                         ret = MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1312                         goto out;
1313                 }
1314         }
1315
1316         if (port_info->sock_pair[0] > 0) {
1317                 ret = __message_port_send_async(port_info->sock_pair[0], message,
1318                                 (local_port) ? local_port : "", local_trusted, bi_dir);
1319         } else {
1320
1321                 bus_name = port_info->encoded_bus_name;
1322                 interface_name = bus_name;
1323
1324                 if (bundle_encode(message, &raw, &len) != BUNDLE_ERROR_NONE) {
1325                         ret = MESSAGEPORT_ERROR_INVALID_PARAMETER;
1326                         goto out;
1327                 }
1328
1329                 if (MAX_MESSAGE_SIZE < len) {
1330                         _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
1331                         ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
1332                 }
1333
1334                 body = g_variant_new("(ssbbssbus)", __app_id, (local_port) ? local_port : "", local_trusted, bi_dir,
1335                                 remote_appid, remote_port, trusted_message, len, raw);
1336
1337
1338                 if (strcmp(remote_appid, __app_id) != 0) { /* self send */
1339
1340                         /*  if message-port fail to get socket pair, communicate using GDBus */
1341                         if (aul_request_message_port_socket_pair(port_info->sock_pair) != AUL_R_OK) {
1342                                 _LOGE("error create socket pair");
1343                         } else {
1344
1345                                 _LOGI("sock pair : %d, %d", port_info->sock_pair[0], port_info->sock_pair[1]);
1346
1347                                 fd_list = g_unix_fd_list_new();
1348                                 g_unix_fd_list_append(fd_list, port_info->sock_pair[1], &err);
1349                                 g_unix_fd_list_append(fd_list, port_info->sock_pair[0], &err);
1350
1351                                 if (err != NULL) {
1352                                         _LOGE("g_unix_fd_list_append [%s]", error->message);
1353                                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1354                                         g_error_free(err);
1355                                         goto out;
1356                                 }
1357                         }
1358
1359                 }
1360
1361                 msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, interface_name, "send_message");
1362                 if (!msg) {
1363                         _LOGE("Can't allocate new method call");
1364                         ret = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1365                         goto out;
1366                 }
1367
1368                 g_dbus_message_set_unix_fd_list(msg, fd_list);
1369                 g_dbus_message_set_body(msg, body);
1370                 g_dbus_message_set_flags(msg, G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED);
1371                 g_dbus_connection_send_message(__gdbus_conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err);
1372                 if (err != NULL) {
1373                         _LOGE("No reply. error = %s", err->message);
1374                         g_error_free(err);
1375                         ret = MESSAGEPORT_ERROR_IO_ERROR;
1376                         goto out;
1377                 }
1378
1379
1380         }
1381
1382 out:
1383         if (msg)
1384                 g_object_unref(msg);
1385         if (raw)
1386                 bundle_free_encoded_rawdata(&raw);
1387         if (fd_list)
1388                 g_object_unref(fd_list);
1389
1390
1391         return ret;
1392 }
1393
1394 int __message_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port,  bool trusted_message, bundle *message)
1395 {
1396         message_port_local_port_info_s *local_info;
1397         int ret = __get_local_port_info(id, &local_info);
1398         if (ret != MESSAGEPORT_ERROR_NONE)
1399                 return ret;
1400
1401         _LOGI("bidirectional_message %s", local_info->port_name);
1402         return __message_port_send_message(remote_app_id, remote_port,
1403                         local_info->port_name, trusted_message, local_info->is_trusted, true, message);
1404 }
1405
1406 int messageport_unregister_local_port(int local_port_id, bool trusted_port)
1407 {
1408
1409         GVariant *result;
1410         char *bus_name = NULL;
1411         GError *err = NULL;
1412         int ret = 0;
1413
1414         _LOGI("unregister : %d", local_port_id);
1415
1416         message_port_local_port_info_s *mi =
1417                 (message_port_local_port_info_s *)
1418                 g_hash_table_lookup(__local_port_info, GINT_TO_POINTER(local_port_id));
1419         if (mi == NULL)
1420                 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1421
1422         if (mi->is_trusted != trusted_port)
1423                 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
1424
1425         bus_name = __get_encoded_name(__app_id, mi->port_name, mi->is_trusted);
1426         if (bus_name == NULL)
1427                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1428
1429         g_dbus_connection_unregister_object(__gdbus_conn, local_port_id);
1430
1431         result = g_dbus_connection_call_sync(
1432                         __gdbus_conn,
1433                         DBUS_SERVICE_DBUS,
1434                         DBUS_PATH_DBUS,
1435                         DBUS_INTERFACE_DBUS,
1436                         "ReleaseName",
1437                         g_variant_new("(s)", bus_name),
1438                         G_VARIANT_TYPE("(u)"),
1439                         G_DBUS_CALL_FLAGS_NONE,
1440                         -1,
1441                         NULL,
1442                         &err);
1443
1444         if (bus_name)
1445                 free(bus_name);
1446
1447         if (err) {
1448                 _LOGE("RequestName fail : %s", err->message);
1449                 g_error_free(err);
1450                 return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1451         }
1452         g_variant_get(result, "(u)", &ret);
1453
1454         if (result)
1455                 g_variant_unref(result);
1456
1457         if (ret != DBUS_RELEASE_NAME_REPLY_RELEASED) {
1458
1459                 if (ret == DBUS_RELEASE_NAME_REPLY_NON_EXISTENT) {
1460                         _LOGE("Port Not exist");
1461                         return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND;
1462                 } else if (ret == DBUS_RELEASE_NAME_REPLY_NOT_OWNER) {
1463                         _LOGE("Try to release not owned name. MESSAGEPORT_ERROR_INVALID_PARAMETER");
1464                         return MESSAGEPORT_ERROR_INVALID_PARAMETER;
1465                 }
1466         }
1467
1468
1469         g_hash_table_remove(__local_port_info, GINT_TO_POINTER(local_port_id));
1470
1471         return MESSAGEPORT_ERROR_NONE;
1472 }
1473
1474 int messageport_register_local_port(const char *local_port, messageport_message_cb callback)
1475 {
1476         if (!_initialized) {
1477                 if (!__initialize())
1478                         return MESSAGEPORT_ERROR_IO_ERROR;
1479         }
1480
1481         return __register_message_port(local_port, false, callback);
1482 }
1483
1484 int messageport_register_trusted_local_port(const char *local_port, messageport_message_cb callback)
1485 {
1486         if (!_initialized) {
1487                 if (!__initialize())
1488                         return MESSAGEPORT_ERROR_IO_ERROR;
1489         }
1490
1491         return __register_message_port(local_port, true, callback);
1492
1493 }
1494
1495 int messageport_check_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
1496 {
1497         if (!_initialized) {
1498                 if (!__initialize())
1499                         return MESSAGEPORT_ERROR_IO_ERROR;
1500         }
1501
1502         int ret = __check_remote_port(remote_app_id, remote_port, false, exist);
1503         if (ret == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND) {
1504                 *exist = false;
1505                 ret = MESSAGEPORT_ERROR_NONE;
1506         }
1507
1508         return ret;
1509 }
1510
1511 int messageport_check_trusted_remote_port(const char *remote_app_id, const char *remote_port, bool *exist)
1512 {
1513         if (!_initialized) {
1514                 if (!__initialize())
1515                         return MESSAGEPORT_ERROR_IO_ERROR;
1516         }
1517
1518         int ret = __check_remote_port(remote_app_id, remote_port, true, exist);
1519         if (ret == MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND) {
1520                 *exist = false;
1521                 ret = MESSAGEPORT_ERROR_NONE;
1522         }
1523
1524         return ret;
1525 }
1526
1527 int messageport_send_message(const char *remote_app_id, const char *remote_port, bundle *message)
1528 {
1529         if (!_initialized) {
1530                 if (!__initialize())
1531                         return MESSAGEPORT_ERROR_IO_ERROR;
1532         }
1533
1534         return __message_port_send_message(remote_app_id, remote_port, NULL, false, false, false, message);
1535 }
1536
1537 int messageport_send_trusted_message(const char *remote_app_id, const char *remote_port, bundle *message)
1538 {
1539         if (!_initialized) {
1540                 if (!__initialize())
1541                         return MESSAGEPORT_ERROR_IO_ERROR;
1542         }
1543
1544         return __message_port_send_message(remote_app_id, remote_port, NULL, true, false, false, message);
1545 }
1546
1547 int messageport_send_bidirectional_message(int id, const char *remote_app_id, const char *remote_port,
1548                 bundle *message)
1549 {
1550         if (!_initialized) {
1551                 if (!__initialize())
1552                         return MESSAGEPORT_ERROR_IO_ERROR;
1553         }
1554
1555         return __message_send_bidirectional_message(id, remote_app_id, remote_port, false, message);
1556 }
1557
1558 int messageport_send_bidirectional_trusted_message(int id, const char *remote_app_id, const char *remote_port,
1559                 bundle *message)
1560 {
1561         if (!_initialized) {
1562                 if (!__initialize())
1563                         return MESSAGEPORT_ERROR_IO_ERROR;
1564         }
1565         return __message_send_bidirectional_message(id, remote_app_id, remote_port, true, message);
1566 }
1567
1568 int messageport_get_local_port_name(int id, char **name)
1569 {
1570         message_port_local_port_info_s *local_info;
1571         int ret = __get_local_port_info(id, &local_info);
1572
1573         if (ret != MESSAGEPORT_ERROR_NONE)
1574                 return ret;
1575
1576         *name = strdup(local_info->port_name);
1577
1578         if (*name == NULL)
1579                 return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
1580
1581         return MESSAGEPORT_ERROR_NONE;
1582 }
1583
1584 int messageport_check_trusted_local_port(int id, bool *trusted)
1585 {
1586         message_port_local_port_info_s *local_info;
1587         int ret = __get_local_port_info(id, &local_info);
1588
1589         if (ret != MESSAGEPORT_ERROR_NONE)
1590                 return ret;
1591
1592         *trusted = local_info->is_trusted;
1593
1594         return MESSAGEPORT_ERROR_NONE;;
1595 }
1596