Adjust coding rules
[platform/core/appfw/message-port.git] / src / message-port.c
1 /*
2  * Message Port
3  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 /**
19  * @file        message-port.cpp
20  * @brief       This is the implementation file for the MessagePort.
21  */
22
23 #include <sys/socket.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <glib.h>
27 #include <gio/gio.h>
28 #include <aul/aul.h>
29 #include <openssl/md5.h>
30 #include <bundle.h>
31 #include <bundle_internal.h>
32 #include <pkgmgr-info.h>
33 #include <aul.h>
34 #include <gio/gio.h>
35 #include <gio/gunixfdlist.h>
36
37 #include "message-port.h"
38 #include "message-port-log.h"
39
40 #define MAX_PACKAGE_STR_SIZE 512
41 #define MESSAGEPORT_BUS_NAME_PREFIX "org.tizen.messageport._"
42 #define MESSAGEPORT_OBJECT_PATH "/org/tizen/messageport"
43 #define MESSAGEPORT_INTERFACE_PREFIX "org.tizen.messageport._"
44
45 #define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
46 #define DBUS_PATH_DBUS "/org/freedesktop/DBus"
47 #define DBUS_INTERFACE_DBUS "org.freedesktop.DBus"
48
49 #define DBUS_RELEASE_NAME_REPLY_RELEASED        1 /* *< Service was released from the given name */
50 #define DBUS_RELEASE_NAME_REPLY_NON_EXISTENT    2 /* *< The given name does not exist on the bus */
51 #define DBUS_RELEASE_NAME_REPLY_NOT_OWNER       3 /* *< Service is not an owner of the given name */
52 #define HEADER_LEN 8
53 #define MAX_RETRY_CNT 2
54
55 #define retvm_if(expr, val, fmt, arg...) do { \
56         if (expr) { \
57                 _LOGE(fmt, ##arg); \
58                 _LOGE("(%s) -> %s() return", #expr, __func__); \
59                 return val; \
60         } \
61 } while (0)
62
63 #define retv_if(expr, val) do { \
64         if (expr) { \
65                 _LOGE("(%s) -> %s() return", #expr, __func__); \
66                 return val; \
67         } \
68 } while (0)
69
70 #define FREE_AND_NULL(ptr) do { \
71         if (ptr) { \
72                 free((void *)ptr); \
73                 ptr = NULL; \
74         } \
75 } while (0)
76
77 static bool _initialized = false;
78 static GDBusConnection *__gdbus_conn = NULL;
79 static char *__app_id;
80 static GHashTable *__local_port_info = NULL;
81 static GHashTable *__remote_port_info = NULL;;
82 static GHashTable *__sender_appid_hash = NULL;;
83 static GHashTable *__trusted_app_list_hash = NULL;
84 static const int MAX_MESSAGE_SIZE = 16 * 1024;
85
86 enum __certificate_info_type {
87         UNKNOWN = 0,
88         CERTIFICATE_MATCH,
89         CERTIFICATE_NOT_MATCH,
90 };
91
92 typedef struct message_port_pkt {
93         int remote_port_name_len;
94         char *remote_port_name;
95         bool is_bidirection;
96         bool is_trusted;
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         int local_id;
104         char *remote_app_id;
105         GIOChannel *gio_read;
106         int g_src_id;
107 } message_port_callback_info_s;
108
109 typedef struct message_port_local_port_info {
110         messageport_message_cb callback;
111         bool is_trusted;
112         char *port_name;
113         int local_id;
114 } message_port_local_port_info_s;
115
116 typedef struct message_port_remote_port_info {
117         char *sender_id;
118         char *remote_app_id;
119         int certificate_info;
120         GList *port_list;
121 } message_port_remote_app_info_s;
122
123 typedef struct port_list_info {
124         char *port_name;
125         char *encoded_bus_name;
126         bool is_trusted;
127         int sock_pair[2];
128         int watcher_id;
129         bool exist;
130 } port_list_info_s;
131
132 static void __callback_info_free(message_port_callback_info_s *callback_info)
133 {
134         GError *error = NULL;
135         if (callback_info == NULL)
136                 return;
137
138         if (callback_info->remote_app_id)
139                 free(callback_info->remote_app_id);
140
141         if (callback_info->gio_read != NULL) {
142                 g_io_channel_shutdown(callback_info->gio_read, FALSE, &error);
143                 if (error) {
144                         _LOGE("g_io_channel_shutdown error : %s", error->message);
145                         g_error_free(error);
146                 }
147                 g_io_channel_unref(callback_info->gio_read);
148                 callback_info->gio_read = NULL;
149         }
150
151         if (callback_info->g_src_id != 0) {
152                 g_source_remove(callback_info->g_src_id);
153                 callback_info->g_src_id = 0;
154         }
155
156         free(callback_info);
157 }
158
159 static char *__get_encoded_name(const char *remote_app_id, const char *port_name, bool is_trusted)
160 {
161
162         int prefix_len = strlen(MESSAGEPORT_BUS_NAME_PREFIX);
163         int postfix_len = 1;
164         char *postfix = is_trusted ? "1" : "0";
165
166         unsigned char c[MD5_DIGEST_LENGTH] = {0};
167         char *md5_interface = NULL;
168         char *temp;
169         int index = 0;
170         MD5_CTX mdContext;
171         int encoded_bus_name_len = prefix_len + postfix_len + (MD5_DIGEST_LENGTH * 2) + 2;
172         int bus_name_len = strlen(remote_app_id) + strlen(port_name) + 2;
173         char *bus_name = (char *)calloc(bus_name_len, sizeof(char));
174         if (bus_name == NULL) {
175                 _LOGE("bus_name calloc failed");
176                 return 0;
177         }
178
179         snprintf(bus_name, bus_name_len, "%s_%s", remote_app_id, port_name);
180
181         MD5_Init(&mdContext);
182         MD5_Update(&mdContext, bus_name, bus_name_len);
183         MD5_Final(c, &mdContext);
184
185         md5_interface = (char *)calloc(encoded_bus_name_len , sizeof(char));
186         if (md5_interface == NULL) {
187                 if (bus_name)
188                         free(bus_name);
189
190                 _LOGE("md5_interface calloc failed!!");
191                 return 0;
192         }
193
194         snprintf(md5_interface, encoded_bus_name_len, "%s", MESSAGEPORT_BUS_NAME_PREFIX);
195         temp = md5_interface;
196         temp += prefix_len;
197
198         for (index = 0; index < MD5_DIGEST_LENGTH; index++) {
199                 snprintf(temp, 3, "%02x", c[index]);
200                 temp += 2;
201         }
202
203         if (postfix && postfix_len > 0)
204                 snprintf(temp, encoded_bus_name_len - (temp - md5_interface), "%s", postfix);
205         if (bus_name)
206                 free(bus_name);
207
208         _LOGI("encoded_bus_name : %s ", md5_interface);
209
210         return md5_interface;
211 }
212
213 static int __remote_port_compare_cb(gconstpointer a, gconstpointer b)
214 {
215         port_list_info_s *key1 = (port_list_info_s *)a;
216         port_list_info_s *key2 = (port_list_info_s *)b;
217
218         if (key1->is_trusted == key2->is_trusted)
219                 return strcmp(key1->port_name, key2->port_name);
220
221         return 1;
222 }
223
224
225 static bool __is_preloaded(const char *local_appid, const char *remote_appid)
226 {
227         _LOGI("IsPreloaded");
228
229         bool preload_local = false;
230         bool preload_remote = false;
231
232         pkgmgrinfo_appinfo_h handle = NULL;
233         int ret = pkgmgrinfo_appinfo_get_usr_appinfo(local_appid, getuid(), &handle);
234         if (ret != PMINFO_R_OK) {
235                 _LOGE("Failed to get the appinfo. %d", ret);
236                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
237                 return false;
238         }
239         ret = pkgmgrinfo_appinfo_is_preload(handle, &preload_local);
240         if (ret != PMINFO_R_OK) {
241                 _LOGE("Failed to check the preloaded application. %d", ret);
242                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
243                 return false;
244         }
245         ret = pkgmgrinfo_appinfo_get_usr_appinfo(remote_appid, getuid(), &handle);
246         if (ret != PMINFO_R_OK) {
247                 _LOGE("Failed to get the appinfo. %d", ret);
248                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
249                 return false;
250         }
251         ret = pkgmgrinfo_appinfo_is_preload(handle, &preload_remote);
252         if (ret != PMINFO_R_OK) {
253                 _LOGE("Failed to check the preloaded application. %d", ret);
254                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
255                 return false;
256         }
257
258         if (preload_local && preload_remote) {
259                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
260                 return true;
261         }
262         pkgmgrinfo_appinfo_destroy_appinfo(handle);
263         return false;
264 }
265
266 static int __check_certificate(const char *local_appid, const char *remote_appid)
267 {
268         _LOGI("CheckCertificate");
269
270         pkgmgrinfo_cert_compare_result_type_e res;
271         int ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(local_appid, remote_appid, getuid(), &res);
272         if (ret < 0) {
273                 _LOGE(":CheckCertificate() Failed");
274                 return MESSAGEPORT_ERROR_IO_ERROR;
275         }
276         if (res != PMINFO_CERT_COMPARE_MATCH) {
277                 _LOGE("CheckCertificate() Failed : MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH");
278                 return MESSAGEPORT_ERROR_CERTIFICATE_NOT_MATCH;
279         }
280
281         return MESSAGEPORT_ERROR_NONE;
282 }
283
284 static void on_name_appeared(GDBusConnection *connection,
285                 const gchar     *name,
286                 const gchar     *name_owner,
287                 gpointer         user_data)
288 {
289         _LOGI("name appeared : %s %s", __app_id, name);
290 }
291
292 static void on_name_vanished(GDBusConnection *connection,
293                 const gchar     *name,
294                 gpointer         user_data)
295 {
296         _LOGI("name vanished : %s", name);
297         port_list_info_s *pli = (port_list_info_s *)user_data;
298         g_bus_unwatch_name(pli->watcher_id);
299         pli->exist = false;
300 }
301
302 static int __get_local_port_info(int id, message_port_local_port_info_s **info)
303 {
304         message_port_local_port_info_s *mi = (message_port_local_port_info_s *)g_hash_table_lookup(__local_port_info, GINT_TO_POINTER(id));
305
306         if (mi == NULL)
307                 return MESSAGEPORT_ERROR_INVALID_PARAMETER;
308         *info = mi;
309
310         return MESSAGEPORT_ERROR_NONE;
311 }
312
313 static port_list_info_s *__set_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
314 {
315         int ret_val = MESSAGEPORT_ERROR_NONE;
316         port_list_info_s *port_info = (port_list_info_s *)calloc(1, sizeof(port_list_info_s));
317
318         if (!port_info) {
319                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
320                 goto out;
321         }
322         port_info->port_name = strdup(remote_port);
323         if (!port_info->port_name) {
324                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
325                 goto out;
326         }
327         port_info->is_trusted = is_trusted;
328
329         port_info->encoded_bus_name = __get_encoded_name(remote_app_id, remote_port, is_trusted);
330         if (port_info->encoded_bus_name == NULL) {
331                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
332                 goto out;
333         }
334
335         port_info->sock_pair[0] = 0;
336         port_info->sock_pair[1] = 0;
337
338 out:
339         if (ret_val != MESSAGEPORT_ERROR_NONE) {
340                 if (port_info) {
341                         FREE_AND_NULL(port_info->port_name);
342                         FREE_AND_NULL(port_info->encoded_bus_name);
343                         free(port_info);
344                 }
345                 return NULL;
346         }
347         return port_info;
348 }
349
350 static message_port_remote_app_info_s *__set_remote_app_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
351 {
352         port_list_info_s *port_info = NULL;
353         message_port_remote_app_info_s *remote_app_info = NULL;
354         int ret_val = MESSAGEPORT_ERROR_NONE;
355
356         remote_app_info = (message_port_remote_app_info_s *)calloc(1, sizeof(message_port_remote_app_info_s));
357         if (!remote_app_info) {
358                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
359                 goto out;
360         }
361
362         remote_app_info->remote_app_id = strdup(remote_app_id);
363         if (remote_app_info->remote_app_id == NULL) {
364                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;;
365                 goto out;
366         }
367
368         port_info = __set_remote_port_info(remote_app_id, remote_port, is_trusted);
369         if (port_info == NULL) {
370                 ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
371                 goto out;
372         }
373
374         remote_app_info->port_list = g_list_append(remote_app_info->port_list, port_info);
375
376 out:
377         if (ret_val != MESSAGEPORT_ERROR_NONE) {
378                 if (remote_app_info) {
379                         FREE_AND_NULL(remote_app_info->remote_app_id);
380                         FREE_AND_NULL(remote_app_info);
381                 }
382                 return NULL;
383         }
384         return remote_app_info;
385 }
386
387 static int __get_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted,
388                 message_port_remote_app_info_s **mri, port_list_info_s **pli)
389 {
390         message_port_remote_app_info_s *remote_app_info = NULL;
391         port_list_info_s port_info;
392         GList *cb_list = NULL;
393         int ret_val = MESSAGEPORT_ERROR_NONE;
394
395         remote_app_info = (message_port_remote_app_info_s *)g_hash_table_lookup(__remote_port_info, remote_app_id);
396
397         if (remote_app_info == NULL) {
398                 remote_app_info = __set_remote_app_info(remote_app_id, remote_port, is_trusted);
399
400                 if (remote_app_info == NULL) {
401                         ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
402                         goto out;
403                 }
404                 g_hash_table_insert(__remote_port_info, remote_app_info->remote_app_id, remote_app_info);
405
406         }
407         *mri = remote_app_info;
408
409         port_info.port_name = strdup(remote_port);
410         port_info.is_trusted = is_trusted;
411         cb_list = g_list_find_custom(remote_app_info->port_list, &port_info,
412                                         (GCompareFunc)__remote_port_compare_cb);
413         if (port_info.port_name)
414                 free(port_info.port_name);
415         if (cb_list == NULL) {
416                 port_list_info_s *tmp = __set_remote_port_info(remote_app_id, remote_port, is_trusted);
417
418                 if (tmp == NULL) {
419                         ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
420                         goto out;
421                 }
422                 remote_app_info->port_list = g_list_append(remote_app_info->port_list, tmp);
423                 *pli = tmp;
424                 g_hash_table_insert(__remote_port_info, (*pli)->encoded_bus_name, *pli);
425         } else {
426                 *pli = (port_list_info_s *)cb_list->data;
427         }
428
429 out:
430
431         return ret_val;
432 }
433
434 static bool __is_local_port_registed(const char *local_port, bool trusted, int *local_id, message_port_local_port_info_s **lpi)
435 {
436         GHashTableIter iter;
437         gpointer key, value;
438
439         g_hash_table_iter_init(&iter, __local_port_info);
440
441         while (g_hash_table_iter_next(&iter, &key, &value)) {
442                 message_port_local_port_info_s *mi = (message_port_local_port_info_s *)value;
443
444                 if ((mi->is_trusted == trusted) && strcmp(mi->port_name, local_port) == 0) {
445                         *local_id = mi->local_id;
446                         if (lpi != NULL)
447                                 *lpi = mi;
448                         return true;
449                 }
450         }
451         return false;
452 }
453
454 static int __get_sender_pid(GDBusConnection *conn, const char *sender_name)
455 {
456         GDBusMessage *msg = NULL;
457         GDBusMessage *reply = NULL;
458         GError *err = NULL;
459         GVariant *body;
460         int pid = 0;
461
462         msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
463                         "org.freedesktop.DBus", "GetConnectionUnixProcessID");
464         if (!msg) {
465                 _LOGE("Can't allocate new method call");
466                 goto out;
467         }
468
469         g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
470         reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
471                                                         G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
472
473         if (!reply) {
474                 if (err != NULL) {
475                         _LOGE("Failed to get pid [%s]", err->message);
476                         g_error_free(err);
477                 }
478                 goto out;
479         }
480
481         body = g_dbus_message_get_body(reply);
482         g_variant_get(body, "(u)", &pid);
483
484 out:
485         if (msg)
486                 g_object_unref(msg);
487         if (reply)
488                 g_object_unref(reply);
489
490         return pid;
491 }
492
493 static int __write_socket(int fd,
494                 const char *buffer,
495                 unsigned int nbytes,
496                 unsigned int *bytes_write)
497 {
498         unsigned int left = nbytes;
499         ssize_t nb;
500         int retry_cnt = 0;
501
502         *bytes_write = 0;
503         while (left && (retry_cnt < MAX_RETRY_CNT)) {
504                 nb = write(fd, buffer, left);
505                 if (nb == -1) {
506                         if (errno == EINTR) {
507                                 LOGE("__write_socket: EINTR error continue ...");
508                                 retry_cnt++;
509                                 continue;
510                         }
511                         LOGE("__write_socket: ...error fd %d: errno %d\n", fd, errno);
512                         return MESSAGEPORT_ERROR_IO_ERROR;
513                 }
514
515                 left -= nb;
516                 buffer += nb;
517                 *bytes_write += nb;
518                 retry_cnt = 0;
519         }
520         return MESSAGEPORT_ERROR_NONE;
521 }
522
523 static int __write_string_to_socket(int fd, const char *buffer, int string_len)
524 {
525         unsigned int nb;
526         if (__write_socket(fd, (char *)&string_len, sizeof(string_len), &nb) != MESSAGEPORT_ERROR_NONE) {
527                 _LOGE("write string_len fail");
528                 return MESSAGEPORT_ERROR_IO_ERROR;
529         }
530
531         if (string_len > 0) {
532                 if (__write_socket(fd, buffer, string_len, &nb) != MESSAGEPORT_ERROR_NONE) {
533                         _LOGE("wirte buffer fail");
534                         return MESSAGEPORT_ERROR_IO_ERROR;
535                 }
536         }
537         return MESSAGEPORT_ERROR_NONE;
538 }
539
540 static int __read_socket(int fd,
541                 char *buffer,
542                 unsigned int nbytes,
543                 unsigned int *bytes_read)
544 {
545         unsigned int left = nbytes;
546         ssize_t nb;
547         int retry_cnt = 0;
548
549         *bytes_read = 0;
550         while (left && (retry_cnt < MAX_RETRY_CNT)) {
551                 nb = read(fd, buffer, left);
552                 if (nb == 0) {
553                         LOGE("__read_socket: ...read EOF, socket closed %d: nb %d\n", fd, nb);
554                         return MESSAGEPORT_ERROR_IO_ERROR;
555                 } else if (nb == -1) {
556                         if (errno == EINTR) {
557                                 LOGE("__read_socket: EINTR error continue ...");
558                                 retry_cnt++;
559                                 continue;
560                         }
561                         LOGE("__read_socket: ...error fd %d: errno %d\n", fd, errno);
562                         return MESSAGEPORT_ERROR_IO_ERROR;
563                 }
564
565                 left -= nb;
566                 buffer += nb;
567                 *bytes_read += nb;
568                 retry_cnt = 0;
569         }
570         return MESSAGEPORT_ERROR_NONE;
571 }
572
573 static int __read_string_from_socket(int fd, char **buffer, int *string_len)
574 {
575         unsigned int nb;
576         if (__read_socket(fd, (char *)string_len, sizeof(*string_len), &nb) != MESSAGEPORT_ERROR_NONE) {
577                 LOGE("read socket fail");
578                 return MESSAGEPORT_ERROR_IO_ERROR;
579         }
580         if (*string_len > 0) {
581                 *buffer = (char *)calloc(*string_len, sizeof(char));
582                 if (*buffer == NULL) {
583                         LOGE("Out of memory.");
584                         return MESSAGEPORT_ERROR_IO_ERROR;
585                 }
586                 if (__read_socket(fd, *buffer, *string_len, &nb) != MESSAGEPORT_ERROR_NONE) {
587                         LOGE("read socket fail");
588                         return MESSAGEPORT_ERROR_IO_ERROR;
589                 }
590         }
591         return MESSAGEPORT_ERROR_NONE;
592 }
593
594 message_port_pkt_s *__message_port_recv_raw(int fd)
595 {
596         message_port_pkt_s *pkt = NULL;
597         unsigned int nb;
598
599         pkt = (message_port_pkt_s *)calloc(sizeof(message_port_pkt_s), 1);
600         if (pkt == NULL) {
601                 close(fd);
602                 return NULL;
603         }
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
613         if (__read_socket(fd, (char *)&pkt->is_bidirection, sizeof(pkt->is_bidirection), &nb) != MESSAGEPORT_ERROR_NONE) {
614                 LOGE("read socket fail: is_bidirection");
615                 free(pkt->remote_port_name);
616                 free(pkt);
617                 close(fd);
618                 return NULL;
619         }
620
621         if (__read_socket(fd, (char *)&pkt->is_trusted, sizeof(pkt->is_trusted), &nb) != MESSAGEPORT_ERROR_NONE) {
622                 LOGE("read socket fail: is_trusted");
623                 free(pkt->remote_port_name);
624                 free(pkt);
625                 close(fd);
626                 return NULL;
627         }
628
629         if (__read_string_from_socket(fd, (char **)&pkt->data, &pkt->data_len) != MESSAGEPORT_ERROR_NONE) {
630                 LOGE("read socket fail: data");
631                 free(pkt->remote_port_name);
632                 free(pkt);
633                 close(fd);
634                 return NULL;
635         }
636
637         return pkt;
638 }
639
640 static gboolean __socket_request_handler(GIOChannel *gio,
641                 GIOCondition cond,
642                 gpointer data)
643 {
644         int fd = 0;
645         message_port_callback_info_s *mi;
646         message_port_pkt_s *pkt;
647         bundle *kb = NULL;
648         GError *error = NULL;
649
650         mi = (message_port_callback_info_s *)data;
651         if (mi == NULL) {
652
653                 g_io_channel_shutdown(gio, FALSE, &error);
654                 if (error) {
655                         _LOGE("g_io_channel_shutdown error : %s", error->message);
656                         g_error_free(error);
657                 }
658                 g_io_channel_unref(gio);
659                 return FALSE;
660         }
661
662         if (cond == G_IO_HUP) {
663
664                 _LOGI("socket G_IO_HUP");
665                 __callback_info_free(mi);
666                 return FALSE;
667
668         } else {
669
670                 if ((fd = g_io_channel_unix_get_fd(gio)) < 0) {
671                         _LOGE("fail to get fd from io channel");
672                         __callback_info_free(mi);
673                         return FALSE;
674                 }
675
676                 if ((pkt = __message_port_recv_raw(fd)) == NULL) {
677                         _LOGE("recv error on SOCKET");
678                         __callback_info_free(mi);
679                         return FALSE;
680                 }
681
682                 kb = bundle_decode(pkt->data, pkt->data_len);
683
684                 if (pkt->is_bidirection)
685                         mi->callback(mi->local_id, mi->remote_app_id, pkt->remote_port_name, pkt->is_trusted, kb, NULL);
686                 else
687                         mi->callback(mi->local_id, mi->remote_app_id, NULL, pkt->is_trusted, kb, NULL);
688
689                 if (pkt) {
690                         if (pkt->remote_port_name)
691                                 free(pkt->remote_port_name);
692                         if (pkt->data)
693                                 free(pkt->data);
694                         free(pkt);
695                 }
696         }
697
698         return TRUE;
699 }
700
701 static bool send_message(GVariant *parameters, GDBusMethodInvocation *invocation)
702 {
703         char *local_port = NULL;
704         char *local_appid = NULL;
705         char *remote_appid = NULL;
706         char *remote_port = NULL;
707         gboolean local_trusted = false;
708         gboolean remote_trusted = false;
709         gboolean bi_dir = false;
710         int len = 0;
711
712         bundle *data = NULL;
713         bundle_raw *raw = NULL;
714         message_port_local_port_info_s *mi;
715         message_port_callback_info_s *callback_info;
716         int local_reg_id = 0;
717         char buf[1024];
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_r(errno, buf, sizeof(buf)));
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