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