Fix watch on not exist name bug
[platform/core/appfw/message-port.git] / src / message-port.c
index b5a0364..eb86b2f 100755 (executable)
@@ -1,20 +1,19 @@
-
 /*
- Message Port
- Copyright (c) 2015 Samsung Electronics Co., Ltd.
-
- Licensed under the Apache License, Version 2.0 (the License);
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
Message Port
Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
Licensed under the Apache License, Version 2.0 (the License);
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
+ *
    http://www.apache.org/licenses/LICENSE-2.0
+ *
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+ */
 
 /**
  * @file       message-port.cpp
@@ -52,6 +51,9 @@
 #define DBUS_RELEASE_NAME_REPLY_NOT_OWNER       3 /* *< Service is not an owner of the given name */
 #define HEADER_LEN 8
 #define MAX_RETRY_CNT 2
+#define SOCK_PAIR_SENDER 0
+#define SOCK_PAIR_RECEIVER 1
+
 
 #define retvm_if(expr, val, fmt, arg...) do { \
        if (expr) { \
 } while (0)
 
 static bool _initialized = false;
-static GDBusConnection *__gdbus_conn = NULL;
+static GDBusConnection *__gdbus_conn;
 static char *__app_id;
-static GHashTable *__local_port_info = NULL;
-static GHashTable *__remote_port_info = NULL;;
-static GHashTable *__sender_appid_hash = NULL;;
-static GHashTable *__trusted_app_list_hash = NULL;
+static GHashTable *__local_port_info;
+static GHashTable *__remote_app_info;
+static GHashTable *__sender_appid_hash;
+static GHashTable *__trusted_app_list_hash;
+static GHashTable *__callback_info_hash;
 static const int MAX_MESSAGE_SIZE = 16 * 1024;
 
 enum __certificate_info_type {
@@ -94,13 +97,13 @@ typedef struct message_port_pkt {
        int remote_port_name_len;
        char *remote_port_name;
        bool is_bidirection;
+       bool is_trusted;
        int data_len;
        unsigned char *data;
 } message_port_pkt_s;
 
 typedef struct message_port_callback_info {
        messageport_message_cb callback;
-       bool is_trusted;
        int local_id;
        char *remote_app_id;
        GIOChannel *gio_read;
@@ -125,22 +128,23 @@ typedef struct port_list_info {
        char *port_name;
        char *encoded_bus_name;
        bool is_trusted;
-       int sock_pair[2];
+       int send_sock_fd;
        int watcher_id;
        bool exist;
 } port_list_info_s;
 
-static void __callback_info_free(message_port_callback_info_s *callback_info)
+static void __callback_info_free(gpointer data)
 {
+       message_port_callback_info_s *callback_info = (message_port_callback_info_s *)data;
        GError *error = NULL;
        if (callback_info == NULL)
                return;
 
        if (callback_info->remote_app_id)
-               free(callback_info->remote_app_id);
+               FREE_AND_NULL(callback_info->remote_app_id);
 
        if (callback_info->gio_read != NULL) {
-               g_io_channel_shutdown(callback_info->gio_read, FALSE, &error);
+               g_io_channel_shutdown(callback_info->gio_read, TRUE, &error);
                if (error) {
                        _LOGE("g_io_channel_shutdown error : %s", error->message);
                        g_error_free(error);
@@ -154,7 +158,32 @@ static void __callback_info_free(message_port_callback_info_s *callback_info)
                callback_info->g_src_id = 0;
        }
 
-       free(callback_info);
+       FREE_AND_NULL(callback_info);
+}
+
+static void __callback_info_free_by_info(message_port_callback_info_s *callback_info)
+{
+       GList *callback_info_list = g_hash_table_lookup(__callback_info_hash, GUINT_TO_POINTER(callback_info->local_id));
+       GList *find_list;
+
+       if (callback_info_list == NULL)
+               return;
+
+       find_list = g_list_find(callback_info_list, callback_info);
+       if (find_list == NULL)
+               return;
+
+       callback_info_list = g_list_remove_link(callback_info_list, find_list);
+       __callback_info_free(callback_info);
+       g_list_free(find_list);
+}
+
+static void __hash_destroy_callback_info(gpointer data)
+{
+
+       GList *callback_list = (GList *)data;
+       if (callback_list != NULL)
+               g_list_free_full(callback_list, __callback_info_free);
 }
 
 static char *__get_encoded_name(const char *remote_app_id, const char *port_name, bool is_trusted)
@@ -296,8 +325,24 @@ static void on_name_vanished(GDBusConnection *connection,
 {
        _LOGI("name vanished : %s", name);
        port_list_info_s *pli = (port_list_info_s *)user_data;
-       g_bus_unwatch_name(pli->watcher_id);
+       if (pli == NULL) {
+               LOGE("NULL port info");
+               return;
+       }
+
+       _LOGI("watcher_id :%d", pli->watcher_id);
+       if (pli->watcher_id > 0)
+               g_bus_unwatch_name(pli->watcher_id);
+       else
+               _LOGE("Invalid watcher_id %d", pli->watcher_id);
        pli->exist = false;
+       pli->watcher_id = 0;
+
+       _LOGI("name vanished socket : %d", pli->send_sock_fd);
+       if (pli->send_sock_fd > 0) {
+               close(pli->send_sock_fd);
+               pli->send_sock_fd = 0;
+       }
 }
 
 static int __get_local_port_info(int id, message_port_local_port_info_s **info)
@@ -326,16 +371,12 @@ static port_list_info_s *__set_remote_port_info(const char *remote_app_id, const
                goto out;
        }
        port_info->is_trusted = is_trusted;
-
        port_info->encoded_bus_name = __get_encoded_name(remote_app_id, remote_port, is_trusted);
        if (port_info->encoded_bus_name == NULL) {
                ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
                goto out;
        }
-
-       port_info->sock_pair[0] = 0;
-       port_info->sock_pair[1] = 0;
-
+       port_info->send_sock_fd = 0;
 out:
        if (ret_val != MESSAGEPORT_ERROR_NONE) {
                if (port_info) {
@@ -350,7 +391,6 @@ out:
 
 static message_port_remote_app_info_s *__set_remote_app_info(const char *remote_app_id, const char *remote_port, bool is_trusted)
 {
-       port_list_info_s *port_info = NULL;
        message_port_remote_app_info_s *remote_app_info = NULL;
        int ret_val = MESSAGEPORT_ERROR_NONE;
 
@@ -366,14 +406,6 @@ static message_port_remote_app_info_s *__set_remote_app_info(const char *remote_
                goto out;
        }
 
-       port_info = __set_remote_port_info(remote_app_id, remote_port, is_trusted);
-       if (port_info == NULL) {
-               ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
-               goto out;
-       }
-
-       remote_app_info->port_list = g_list_append(remote_app_info->port_list, port_info);
-
 out:
        if (ret_val != MESSAGEPORT_ERROR_NONE) {
                if (remote_app_info) {
@@ -385,6 +417,26 @@ out:
        return remote_app_info;
 }
 
+static void __watch_remote_port_info(port_list_info_s *port_info)
+{
+       if (port_info == NULL)
+               return;
+
+       if (port_info->watcher_id < 1) {
+               port_info->watcher_id = g_bus_watch_name_on_connection(
+                               __gdbus_conn,
+                               port_info->encoded_bus_name,
+                               G_BUS_NAME_WATCHER_FLAGS_NONE,
+                               on_name_appeared,
+                               on_name_vanished,
+                               port_info,
+                               NULL);
+       } else {
+               LOGI("Already watched port info");
+               return;
+       }
+}
+
 static int __get_remote_port_info(const char *remote_app_id, const char *remote_port, bool is_trusted,
                message_port_remote_app_info_s **mri, port_list_info_s **pli)
 {
@@ -393,7 +445,7 @@ static int __get_remote_port_info(const char *remote_app_id, const char *remote_
        GList *cb_list = NULL;
        int ret_val = MESSAGEPORT_ERROR_NONE;
 
-       remote_app_info = (message_port_remote_app_info_s *)g_hash_table_lookup(__remote_port_info, remote_app_id);
+       remote_app_info = (message_port_remote_app_info_s *)g_hash_table_lookup(__remote_app_info, remote_app_id);
 
        if (remote_app_info == NULL) {
                remote_app_info = __set_remote_app_info(remote_app_id, remote_port, is_trusted);
@@ -402,8 +454,7 @@ static int __get_remote_port_info(const char *remote_app_id, const char *remote_
                        ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
                        goto out;
                }
-               g_hash_table_insert(__remote_port_info, remote_app_info->remote_app_id, remote_app_info);
-
+               g_hash_table_insert(__remote_app_info, remote_app_info->remote_app_id, remote_app_info);
        }
        *mri = remote_app_info;
 
@@ -415,18 +466,15 @@ static int __get_remote_port_info(const char *remote_app_id, const char *remote_
                free(port_info.port_name);
        if (cb_list == NULL) {
                port_list_info_s *tmp = __set_remote_port_info(remote_app_id, remote_port, is_trusted);
-
                if (tmp == NULL) {
                        ret_val = MESSAGEPORT_ERROR_OUT_OF_MEMORY;
                        goto out;
                }
                remote_app_info->port_list = g_list_append(remote_app_info->port_list, tmp);
                *pli = tmp;
-               g_hash_table_insert(__remote_port_info, (*pli)->encoded_bus_name, *pli);
        } else {
                *pli = (port_list_info_s *)cb_list->data;
        }
-
 out:
 
        return ret_val;
@@ -438,7 +486,6 @@ static bool __is_local_port_registed(const char *local_port, bool trusted, int *
        gpointer key, value;
 
        g_hash_table_iter_init(&iter, __local_port_info);
-
        while (g_hash_table_iter_next(&iter, &key, &value)) {
                message_port_local_port_info_s *mi = (message_port_local_port_info_s *)value;
 
@@ -578,7 +625,7 @@ static int __read_string_from_socket(int fd, char **buffer, int *string_len)
                LOGE("read socket fail");
                return MESSAGEPORT_ERROR_IO_ERROR;
        }
-       if (*string_len > 0) {
+       if (*string_len > 0 && *string_len < MAX_MESSAGE_SIZE) {
                *buffer = (char *)calloc(*string_len, sizeof(char));
                if (*buffer == NULL) {
                        LOGE("Out of memory.");
@@ -588,6 +635,9 @@ static int __read_string_from_socket(int fd, char **buffer, int *string_len)
                        LOGE("read socket fail");
                        return MESSAGEPORT_ERROR_IO_ERROR;
                }
+       } else {
+               LOGE("Invalid string len %d", &string_len);
+               return MESSAGEPORT_ERROR_IO_ERROR;
        }
        return MESSAGEPORT_ERROR_NONE;
 }
@@ -602,27 +652,35 @@ message_port_pkt_s *__message_port_recv_raw(int fd)
                close(fd);
                return NULL;
        }
+
        if (__read_string_from_socket(fd, (char **)&pkt->remote_port_name, &pkt->remote_port_name_len) != MESSAGEPORT_ERROR_NONE) {
                LOGE("read socket fail: port_name");
                free(pkt->remote_port_name);
                free(pkt);
-               close(fd);
                return NULL;
        }
+
        if (__read_socket(fd, (char *)&pkt->is_bidirection, sizeof(pkt->is_bidirection), &nb) != MESSAGEPORT_ERROR_NONE) {
                LOGE("read socket fail: is_bidirection");
                free(pkt->remote_port_name);
                free(pkt);
-               close(fd);
                return NULL;
        }
+
+       if (__read_socket(fd, (char *)&pkt->is_trusted, sizeof(pkt->is_trusted), &nb) != MESSAGEPORT_ERROR_NONE) {
+               LOGE("read socket fail: is_trusted");
+               free(pkt->remote_port_name);
+               free(pkt);
+               return NULL;
+       }
+
        if (__read_string_from_socket(fd, (char **)&pkt->data, &pkt->data_len) != MESSAGEPORT_ERROR_NONE) {
                LOGE("read socket fail: data");
                free(pkt->remote_port_name);
                free(pkt);
-               close(fd);
                return NULL;
        }
+
        return pkt;
 }
 
@@ -639,7 +697,7 @@ static gboolean __socket_request_handler(GIOChannel *gio,
        mi = (message_port_callback_info_s *)data;
        if (mi == NULL) {
 
-               g_io_channel_shutdown(gio, FALSE, &error);
+               g_io_channel_shutdown(gio, TRUE, &error);
                if (error) {
                        _LOGE("g_io_channel_shutdown error : %s", error->message);
                        g_error_free(error);
@@ -651,30 +709,30 @@ static gboolean __socket_request_handler(GIOChannel *gio,
        if (cond == G_IO_HUP) {
 
                _LOGI("socket G_IO_HUP");
-               __callback_info_free(mi);
+               __callback_info_free_by_info(mi);
                return FALSE;
 
        } else {
 
                if ((fd = g_io_channel_unix_get_fd(gio)) < 0) {
                        _LOGE("fail to get fd from io channel");
-                       __callback_info_free(mi);
+                       __callback_info_free_by_info(mi);
                        return FALSE;
                }
 
                if ((pkt = __message_port_recv_raw(fd)) == NULL) {
                        _LOGE("recv error on SOCKET");
-                       __callback_info_free(mi);
+                       __callback_info_free_by_info(mi);
                        return FALSE;
                }
 
                kb = bundle_decode(pkt->data, pkt->data_len);
-
                if (pkt->is_bidirection)
-                       mi->callback(mi->local_id, mi->remote_app_id, pkt->remote_port_name, mi->is_trusted, kb, NULL);
+                       mi->callback(mi->local_id, mi->remote_app_id, pkt->remote_port_name, pkt->is_trusted, kb, NULL);
                else
-                       mi->callback(mi->local_id, mi->remote_app_id, NULL, mi->is_trusted, kb, NULL);
+                       mi->callback(mi->local_id, mi->remote_app_id, NULL, pkt->is_trusted, kb, NULL);
 
+               bundle_free(kb);
                if (pkt) {
                        if (pkt->remote_port_name)
                                free(pkt->remote_port_name);
@@ -701,10 +759,19 @@ static bool send_message(GVariant *parameters, GDBusMethodInvocation *invocation
        bundle *data = NULL;
        bundle_raw *raw = NULL;
        message_port_local_port_info_s *mi;
-       message_port_callback_info_s *callback_info;
        int local_reg_id = 0;
+       message_port_callback_info_s *callback_info;
+       message_port_callback_info_s *head_callback_info;
+       GList *callback_info_list = NULL;
 
-       g_variant_get(parameters, "(ssbbssbus)", &local_appid, &local_port, &local_trusted, &bi_dir,
+       char buf[1024];
+       GDBusMessage *msg;
+       GUnixFDList *fd_list;
+       int fd_len;
+       int *returned_fds = NULL;
+       int fd;
+
+       g_variant_get(parameters, "(&s&sbb&s&sbu&s)", &local_appid, &local_port, &local_trusted, &bi_dir,
                        &remote_appid, &remote_port, &remote_trusted, &len, &raw);
 
        if (!remote_port) {
@@ -742,7 +809,6 @@ static bool send_message(GVariant *parameters, GDBusMethodInvocation *invocation
        if (remote_trusted) {
                if (g_hash_table_lookup(__trusted_app_list_hash, (gpointer)local_appid) == NULL) {
                        if (!__is_preloaded(local_appid, remote_appid)) {
-                               /* Check the certificate */
                                int ret = __check_certificate(local_appid, remote_appid);
                                if (ret == MESSAGEPORT_ERROR_NONE)
                                        g_hash_table_insert(__trusted_app_list_hash, local_appid, "TRUE");
@@ -762,42 +828,61 @@ static bool send_message(GVariant *parameters, GDBusMethodInvocation *invocation
        callback_info->local_id = mi->local_id;
        callback_info->remote_app_id = strdup(local_appid);
        callback_info->callback = mi->callback;
-       callback_info->is_trusted = local_trusted;
-
-       GError *error = NULL;
-       GDBusMessage *msg = g_dbus_method_invocation_get_message(invocation);
-
-       GUnixFDList *fd_list = g_dbus_message_get_unix_fd_list(msg);
-       int fd = g_unix_fd_list_get(fd_list, 0, &error);
-       if (error) {
-               LOGE("g_unix_fd_list_get fail : %s", error->message);
-               g_error_free(error);
-       }
-
-       LOGI("g_unix_fd_list_get fd: [%d]", fd);
 
-       if (fd > 0) {
+       msg = g_dbus_method_invocation_get_message(invocation);
+       fd_list = g_dbus_message_get_unix_fd_list(msg);
 
-               callback_info->gio_read = g_io_channel_unix_new(fd);
-               if (!callback_info->gio_read) {
-                       _LOGE("Error is %s\n", strerror(errno));
+       /* When application send message to self fd_list is NULL */
+       if (fd_list != NULL) {
+               returned_fds = g_unix_fd_list_steal_fds(fd_list, &fd_len);
+               if (returned_fds == NULL) {
+                       _LOGE("fail to get fds");
                        __callback_info_free(callback_info);
                        return -1;
                }
+               fd = returned_fds[0];
 
-               callback_info->g_src_id = g_io_add_watch(callback_info->gio_read, G_IO_IN | G_IO_HUP,
-                               __socket_request_handler, (gpointer)callback_info);
-               if (callback_info->g_src_id == 0) {
-                       _LOGE("fail to add watch on socket");
-                       __callback_info_free(callback_info);
-                       return -1;
-               }
+               LOGI("g_unix_fd_list_get %d fd: [%d]", fd_len, fd);
+               if (fd > 0) {
+
+                       callback_info->gio_read = g_io_channel_unix_new(fd);
+                       if (!callback_info->gio_read) {
+                               _LOGE("Error is %s\n", strerror_r(errno, buf, sizeof(buf)));
+                               __callback_info_free(callback_info);
+                               return -1;
+                       }
 
+                       callback_info->g_src_id = g_io_add_watch(callback_info->gio_read, G_IO_IN | G_IO_HUP,
+                                       __socket_request_handler, (gpointer)callback_info);
+                       if (callback_info->g_src_id == 0) {
+                               _LOGE("fail to add watch on socket");
+                               __callback_info_free(callback_info);
+                               return -1;
+                       }
+
+                       callback_info_list = g_hash_table_lookup(__callback_info_hash, GUINT_TO_POINTER(mi->local_id));
+                       if (callback_info_list == NULL) {
+                               head_callback_info = (message_port_callback_info_s *)calloc(1, sizeof(message_port_callback_info_s));
+                               if (head_callback_info == NULL) {
+                                       _LOGE("fail to alloc head_callback_info");
+                                       __callback_info_free(callback_info);
+                                       return -1;
+                               }
+                               head_callback_info->local_id = 0;
+                               head_callback_info->remote_app_id = NULL;
+                               head_callback_info->callback = NULL;
+                               head_callback_info->gio_read = NULL;
+                               head_callback_info->g_src_id = 0;
+                               callback_info_list = g_list_append(callback_info_list, head_callback_info);
+                               callback_info_list = g_list_append(callback_info_list, callback_info);
+                               g_hash_table_insert(__callback_info_hash, GUINT_TO_POINTER(mi->local_id), callback_info_list);
+                       } else {
+                               callback_info_list = g_list_append(callback_info_list, callback_info);
+                       }
+               }
        }
 
        data = bundle_decode(raw, len);
-       bundle_free_encoded_rawdata(&raw);
-
        if (!data) {
                _LOGE("Invalid argument : message");
                goto out;
@@ -808,8 +893,10 @@ static bool send_message(GVariant *parameters, GDBusMethodInvocation *invocation
                mi->callback(mi->local_id, local_appid, local_port, local_trusted, data, NULL);
        else
                mi->callback(mi->local_id, local_appid, NULL, false, data, NULL);
-
+       bundle_free(data);
 out:
+       if (returned_fds)
+               free(returned_fds);
 
        return true;
 }
@@ -834,7 +921,6 @@ static int __check_remote_port(const char *remote_app_id, const char *remote_por
        if (ret_val != MESSAGEPORT_ERROR_NONE)
                return ret_val;
 
-
        /* self check */
        if (strcmp(remote_app_id, __app_id) == 0) {
 
@@ -890,22 +976,11 @@ static int __check_remote_port(const char *remote_app_id, const char *remote_por
                                        remote_app_info->certificate_info = CERTIFICATE_MATCH;
                                }
                        }
-
-                       port_info->watcher_id = g_bus_watch_name_on_connection(
-                                       __gdbus_conn,
-                                       port_info->encoded_bus_name,
-                                       G_BUS_NAME_WATCHER_FLAGS_NONE,
-                                       on_name_appeared,
-                                       on_name_vanished,
-                                       port_info,
-                                       NULL);
-
                        port_info->exist = true;
                        *exist = true;
                        ret_val = MESSAGEPORT_ERROR_NONE;
-                       _LOGI("Exist port: %s", bus_name);
+                       __watch_remote_port_info(port_info);
                }
-
        }
 out:
        if (result)
@@ -914,24 +989,70 @@ out:
        return ret_val;
 }
 
+static void __on_sender_name_appeared(GDBusConnection *connection,
+               const gchar     *name,
+               const gchar     *name_owner,
+               gpointer         user_data)
+{
+       _LOGI("sender name appeared : %s", name);
+}
+
+static void __on_sender_name_vanished(GDBusConnection *connection,
+               const gchar     *name,
+               gpointer         user_data)
+{
+       gboolean remove_result = FALSE;
+       int *watcher_id = (int *)user_data;
+       remove_result = g_hash_table_remove(__sender_appid_hash, (gpointer)name);
+       if (!remove_result)
+               _LOGE("Fail to remove sender appid from hash : %s", name);
+
+       if (watcher_id) {
+               if (*watcher_id > 0)
+                       g_bus_unwatch_name(*watcher_id);
+               else
+                       LOGE("Invalid watcher_id %d", *watcher_id);
+               free(watcher_id);
+       } else {
+               LOGE("watcher_id is NULL");
+       }
+}
+
 static bool __check_sender_validation(GVariant *parameters, const char *sender, GDBusConnection *conn)
 {
        int ret = 0;
        char buffer[MAX_PACKAGE_STR_SIZE] = {0, };
        char *local_appid = NULL;
        int pid = __get_sender_pid(conn, sender);
+       int *watcher_id = (int *)calloc(1, sizeof(int));
 
        ret = aul_app_get_appid_bypid(pid, buffer, sizeof(buffer));
-       retvm_if(ret != AUL_R_OK, false, "Failed to get the sender ID: (%s) (%d)", sender, pid);
+       if (ret != AUL_R_OK) {
+               _LOGE("Failed to get the sender ID: (%s) (%d)", sender, pid);
+               free(watcher_id);
+               return false;
+       }
 
-       g_variant_get_child(parameters, 0, "s", &local_appid);
-       retvm_if(!local_appid, false, "remote_appid is NULL (%s) (%d)", sender, pid);
+       g_variant_get_child(parameters, 0, "&s", &local_appid);
+       if (local_appid == NULL) {
+               _LOGE("appid is NULL : (%s) (%d)", sender, pid);
+               free(watcher_id);
+               return false;
+       }
 
        if (strncmp(buffer, local_appid, MAX_PACKAGE_STR_SIZE) == 0) {
-               g_hash_table_insert(__sender_appid_hash, strdup(sender), GINT_TO_POINTER(pid));
-               g_free(local_appid);
+               _LOGI("insert sender !!!!! %s", sender);
+               g_hash_table_insert(__sender_appid_hash, (gpointer)strdup(sender), GINT_TO_POINTER(pid));
+               *watcher_id = g_bus_watch_name_on_connection(
+                                       __gdbus_conn,
+                                       sender,
+                                       G_BUS_NAME_WATCHER_FLAGS_NONE,
+                                       __on_sender_name_appeared,
+                                       __on_sender_name_vanished,
+                                       watcher_id,
+                                       NULL);
        } else {
-               g_free(local_appid);
+               free(watcher_id);
                return false;
        }
        return true;
@@ -943,16 +1064,16 @@ static void __dbus_method_call_handler(GDBusConnection *conn,
                                GVariant *parameters, GDBusMethodInvocation *invocation,
                                gpointer user_data)
 {
-       _LOGI("method_name: %s", method_name);
+       _LOGI("method_name: %s, sender: %s", method_name, sender);
        gpointer sender_pid = g_hash_table_lookup(__sender_appid_hash, sender);
        if (sender_pid == NULL) {
                if (!__check_sender_validation(parameters, sender, conn))
-                       return;
+                       goto out;
        }
-
        if (g_strcmp0(method_name, "send_message") == 0)
                send_message(parameters, invocation);
-
+out:
+       g_dbus_method_invocation_return_value(invocation, NULL);
 }
 
 static const GDBusInterfaceVTable interface_vtable = {
@@ -985,7 +1106,6 @@ out:
 
 }
 
-
 int __register_dbus_interface(const char *port_name, bool is_trusted)
 {
 
@@ -1100,7 +1220,7 @@ out:
        return registration_id;
 }
 
-
+/* LCOV_EXCL_START */
 void __list_free_port_list(gpointer data)
 {
        port_list_info_s *n = (port_list_info_s *)data;
@@ -1109,24 +1229,34 @@ void __list_free_port_list(gpointer data)
        FREE_AND_NULL(n->port_name);
        FREE_AND_NULL(n);
 }
+/* LCOV_EXCL_STOP */
 
+/* LCOV_EXCL_START */
 static void __hash_destory_local_value(gpointer data)
 {
        message_port_local_port_info_s *mli = (message_port_local_port_info_s *)data;
-       if (mli->port_name)
-               free(mli->port_name);
+       if (mli) {
+               if (mli->port_name)
+                       free(mli->port_name);
+               free(mli);
+       }
 }
+/* LCOV_EXCL_STOP */
+
+/* LCOV_EXCL_START */
 static void __hash_destory_remote_value(gpointer data)
 {
        message_port_remote_app_info_s *mri = (message_port_remote_app_info_s *)data;
-
        if (mri) {
                FREE_AND_NULL(mri->sender_id);
                FREE_AND_NULL(mri->remote_app_id);
                if (mri->port_list)
                        g_list_free_full(mri->port_list, __list_free_port_list);
+
+               free(mri);
        }
 }
+/* LCOV_EXCL_STOP */
 
 static bool __initialize(void)
 {
@@ -1152,13 +1282,13 @@ static bool __initialize(void)
                retvm_if(!__local_port_info, false, "fail to create __local_port_info");
        }
 
-       if (__remote_port_info == NULL) {
-               __remote_port_info = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __hash_destory_remote_value);
-               retvm_if(!__remote_port_info, false, "fail to create __remote_port_info");
+       if (__remote_app_info == NULL) {
+               __remote_app_info = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __hash_destory_remote_value);
+               retvm_if(!__remote_app_info, false, "fail to create __remote_app_info");
        }
 
        if (__sender_appid_hash == NULL) {
-               __sender_appid_hash = g_hash_table_new(g_str_hash, g_str_equal);
+               __sender_appid_hash = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
                retvm_if(!__sender_appid_hash, false, "fail to create __sender_appid_hash");
        }
 
@@ -1167,6 +1297,11 @@ static bool __initialize(void)
                retvm_if(!__trusted_app_list_hash, false, "fail to create __trusted_app_list_hash");
        }
 
+       if (__callback_info_hash == NULL) {
+               __callback_info_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __hash_destroy_callback_info);
+               retvm_if(!__trusted_app_list_hash, false, "fail to create __trusted_app_list_hash");
+       }
+
        if (!__dbus_init())
                return false;
        _initialized = true;
@@ -1232,17 +1367,24 @@ int __message_port_send_async(int sockfd, bundle *kb, const char *local_port,
                _LOGE("write local_port fail");
                return MESSAGEPORT_ERROR_IO_ERROR;
        }
+
        if (__write_socket(sockfd, (char *)&is_bidirection, sizeof(is_bidirection), &nb) != MESSAGEPORT_ERROR_NONE) {
                _LOGE("write is_bidirection fail");
                return MESSAGEPORT_ERROR_IO_ERROR;
        }
 
+       if (__write_socket(sockfd, (char *)&local_trusted, sizeof(local_trusted), &nb) != MESSAGEPORT_ERROR_NONE) {
+               _LOGE("write local_trusted fail");
+               return MESSAGEPORT_ERROR_IO_ERROR;
+       }
+
        bundle_encode(kb, &kb_data, &data_len);
        if (kb_data == NULL) {
                _LOGE("bundle encode fail");
                ret = MESSAGEPORT_ERROR_IO_ERROR;
                goto out;
        }
+
        if (data_len > MAX_MESSAGE_SIZE) {
                _LOGE("bigger than max size\n");
                ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
@@ -1266,7 +1408,6 @@ static int __message_port_send_message(const char *remote_appid, const char *rem
 
        int ret = MESSAGEPORT_ERROR_NONE;
        GUnixFDList *fd_list = NULL;
-       GError *error = NULL;
 
        int len = 0;
        bundle_raw *raw = NULL;
@@ -1278,6 +1419,7 @@ static int __message_port_send_message(const char *remote_appid, const char *rem
        GDBusMessage *msg = NULL;
        GError *err = NULL;
        GVariant *body = NULL;
+       int sock_pair[2] = {0,};
 
        ret = __get_remote_port_info(remote_appid, remote_port, trusted_message, &remote_app_info, &port_info);
        if (ret != MESSAGEPORT_ERROR_NONE)
@@ -1294,9 +1436,10 @@ static int __message_port_send_message(const char *remote_appid, const char *rem
                        goto out;
                }
        }
+       __watch_remote_port_info(port_info);
 
-       if (port_info->sock_pair[0] > 0) {
-               ret = __message_port_send_async(port_info->sock_pair[0], message,
+       if (port_info->send_sock_fd > 0) {
+               ret = __message_port_send_async(port_info->send_sock_fd, message,
                                (local_port) ? local_port : "", local_trusted, bi_dir);
        } else {
 
@@ -1311,33 +1454,31 @@ static int __message_port_send_message(const char *remote_appid, const char *rem
                if (MAX_MESSAGE_SIZE < len) {
                        _LOGE("The size of message (%d) has exceeded the maximum limit.", len);
                        ret = MESSAGEPORT_ERROR_MAX_EXCEEDED;
+                       goto out;
                }
 
                body = g_variant_new("(ssbbssbus)", __app_id, (local_port) ? local_port : "", local_trusted, bi_dir,
                                remote_appid, remote_port, trusted_message, len, raw);
-
-
                if (strcmp(remote_appid, __app_id) != 0) { /* self send */
 
                        /*  if message-port fail to get socket pair, communicate using GDBus */
-                       if (aul_request_message_port_socket_pair(port_info->sock_pair) != AUL_R_OK) {
+                       if (aul_request_message_port_socket_pair(sock_pair) != AUL_R_OK) {
                                _LOGE("error create socket pair");
                        } else {
 
-                               _LOGI("sock pair : %d, %d", port_info->sock_pair[0], port_info->sock_pair[1]);
-
+                               _LOGI("sock pair : %d, %d",
+                                               sock_pair[SOCK_PAIR_SENDER], sock_pair[SOCK_PAIR_RECEIVER]);
                                fd_list = g_unix_fd_list_new();
-                               g_unix_fd_list_append(fd_list, port_info->sock_pair[1], &err);
-                               g_unix_fd_list_append(fd_list, port_info->sock_pair[0], &err);
-
+                               g_unix_fd_list_append(fd_list, sock_pair[SOCK_PAIR_RECEIVER], &err);
                                if (err != NULL) {
-                                       _LOGE("g_unix_fd_list_append [%s]", error->message);
+                                       _LOGE("g_unix_fd_list_append [%s]", err->message);
                                        ret = MESSAGEPORT_ERROR_IO_ERROR;
                                        g_error_free(err);
                                        goto out;
                                }
+                               port_info->send_sock_fd = sock_pair[SOCK_PAIR_SENDER];
+                               close(sock_pair[SOCK_PAIR_RECEIVER]);
                        }
-
                }
 
                msg = g_dbus_message_new_method_call(bus_name, MESSAGEPORT_OBJECT_PATH, interface_name, "send_message");
@@ -1349,7 +1490,6 @@ static int __message_port_send_message(const char *remote_appid, const char *rem
 
                g_dbus_message_set_unix_fd_list(msg, fd_list);
                g_dbus_message_set_body(msg, body);
-               g_dbus_message_set_flags(msg, G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED);
                g_dbus_connection_send_message(__gdbus_conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err);
                if (err != NULL) {
                        _LOGE("No reply. error = %s", err->message);
@@ -1404,6 +1544,8 @@ int messageport_unregister_local_port(int local_port_id, bool trusted_port)
        if (mi->is_trusted != trusted_port)
                return MESSAGEPORT_ERROR_INVALID_PARAMETER;
 
+       g_hash_table_remove(__callback_info_hash, GUINT_TO_POINTER(local_port_id));
+
        bus_name = __get_encoded_name(__app_id, mi->port_name, mi->is_trusted);
        if (bus_name == NULL)
                return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
@@ -1547,32 +1689,3 @@ int messageport_send_bidirectional_trusted_message(int id, const char *remote_ap
        return __message_send_bidirectional_message(id, remote_app_id, remote_port, true, message);
 }
 
-int messageport_get_local_port_name(int id, char **name)
-{
-       message_port_local_port_info_s *local_info;
-       int ret = __get_local_port_info(id, &local_info);
-
-       if (ret != MESSAGEPORT_ERROR_NONE)
-               return ret;
-
-       *name = strdup(local_info->port_name);
-
-       if (*name == NULL)
-               return MESSAGEPORT_ERROR_OUT_OF_MEMORY;
-
-       return MESSAGEPORT_ERROR_NONE;
-}
-
-int messageport_check_trusted_local_port(int id, bool *trusted)
-{
-       message_port_local_port_info_s *local_info;
-       int ret = __get_local_port_info(id, &local_info);
-
-       if (ret != MESSAGEPORT_ERROR_NONE)
-               return ret;
-
-       *trusted = local_info->is_trusted;
-
-       return MESSAGEPORT_ERROR_NONE;;
-}
-