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