dbus: change dbus library from dbus to gdbus 59/169259/6
authorsanghyeok.oh <sanghyeok.oh@samsung.com>
Mon, 5 Feb 2018 08:17:50 +0000 (17:17 +0900)
committersanghyeok.oh <sanghyeok.oh@samsung.com>
Mon, 5 Feb 2018 08:57:05 +0000 (17:57 +0900)
Change-Id: I87f7fb5d88cba95f08b1927012f9b65cadc538a0
Signed-off-by: sanghyeok.oh <sanghyeok.oh@samsung.com>
13 files changed:
CMakeLists.txt
apps/extended-sd/src/dbus-call.c
packaging/storaged.spec
src/block/CMakeLists.txt
src/block/block.c
src/block/vfat.c
src/core/main.c
src/shared/apps.c
src/shared/dbus.c
src/shared/dbus.h
src/shared/udev.c
src/storage/CMakeLists.txt
src/storage/storage.c [changed mode: 0755->0644]

index d9c2e2c..8b3f953 100755 (executable)
@@ -5,9 +5,9 @@ SET(CMAKE_VERBOSE_MAKEFILE OFF)
 SET(STORAGED_APPS ${CMAKE_SOURCE_DIR}/apps)
 
 SET(SRCS
-       src/core/dbus_main.c
        src/core/main.c
        src/core/modules.c
+       src/shared/dbus.c
 )
 
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src)
@@ -17,10 +17,10 @@ SET(PKG_MODULES
        argos_watchdog
        capi-base-common
        capi-system-info
-       dbus-1
        dlog
-       gio-2.0
        glib-2.0
+       gio-2.0
+       gio-unix-2.0
        libsystemd
        libtzplatform-config
        libudev
index 01360d7..8921955 100644 (file)
@@ -407,4 +407,4 @@ int dbus_method_async_with_reply(const char *dest, const char *path,
        pthread_mutex_unlock(&dmutex);
 
        return 0;
-}
\ No newline at end of file
+}
index 41f7b93..c7e3d0c 100644 (file)
@@ -15,7 +15,6 @@ BuildRequires:  libattr-devel
 BuildRequires:  pkgconfig(vconf)
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(capi-base-common)
-BuildRequires:  pkgconfig(dbus-1)
 BuildRequires:  pkgconfig(libudev)
 BuildRequires:  pkgconfig(gio-2.0)
 BuildRequires:  pkgconfig(glib-2.0)
index 4445a6c..925e54d 100644 (file)
@@ -7,7 +7,9 @@ pkg_check_modules(${PROJECT_NAME}_pkgs REQUIRED
                capi-system-info
                blkid
                dlog
-               dbus-1
+               glib-2.0
+               gio-2.0
+               gio-unix-2.0
                libudev
                mount
                storage
index 9f843d3..d5739fd 100644 (file)
@@ -134,7 +134,7 @@ enum private_operation_state {
 
 struct operation_queue {
        enum block_dev_operation op;
-       dbus_method_reply_handle_h reply_handle;
+       GDBusMethodInvocation *invocation;
        void *data;
        bool done;
 };
@@ -197,12 +197,18 @@ static int block_stop(void *data);
 
 static int add_operation(struct block_device *bdev,
                enum block_dev_operation operation,
-               dbus_method_reply_handle_h reply_handle, void *data);
+               GDBusMethodInvocation *invocation, void *data);
 static void remove_operation(struct block_device *bdev);
 static void check_removed(struct block_device *bdev, dd_list **queue, struct operation_queue **op);
 static bool check_unmount(struct block_device *bdev, dd_list **queue, struct operation_queue **op);
 static int change_mount_point(struct block_device *bdev, const char *mount_point);
 
+#define nullstr(x) (x ? x : "")
+static GVariant *block_data_to_gvariant(struct block_data *data, int flags);
+static GVariant *block_data_to_gvariant2(struct block_data *data, int flags);
+
+#define block_send_dbus_reply(invocation, result) if (invocation) {g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", result)); }
+
 static void uevent_block_handler(struct udev_device *dev);
 static struct uevent_handler uh = {
        .subsystem = BLOCK_SUBSYSTEM,
@@ -365,65 +371,23 @@ static void create_file(int id, char *mount_point, bool extendedsd)
 static void signal_device_blocked(struct block_device *bdev)
 {
        struct block_data *data;
-       char *arr[13];
-       char str_block_type[32];
-       char str_readonly[32];
-       char str_state[32];
-       char str_primary[32];
-       char str_flags[32];
-       char str_id[32];
-       char *str_null = "";
-       int flags;
 
        if (!bdev || !bdev->data)
                return;
 
        data = bdev->data;
-       flags = 0;
 
-       /* Broadcast outside with BlockManager iface */
-       snprintf(str_block_type, sizeof(str_block_type),
-                       "%d", data->block_type);
-       arr[0] = str_block_type;
-       arr[1] = (data->devnode ? data->devnode : str_null);
-       arr[2] = (data->syspath ? data->syspath : str_null);
-       arr[3] = (data->fs_usage ? data->fs_usage : str_null);
-       arr[4] = (data->fs_type ? data->fs_type : str_null);
-       arr[5] = (data->fs_version ? data->fs_version : str_null);
-       arr[6] = (data->fs_uuid_enc ? data->fs_uuid_enc : str_null);
-       snprintf(str_readonly, sizeof(str_readonly),
-                       "%d", data->readonly);
-       arr[7] = str_readonly;
-       arr[8] = (data->mount_point ? data->mount_point : str_null);
-       snprintf(str_state, sizeof(str_state),
-                       "%d", data->state);
-       arr[9] = str_state;
-       snprintf(str_primary, sizeof(str_primary),
-                       "%d", data->primary);
-       arr[10] = str_primary;
-       snprintf(str_flags, sizeof(str_flags), "%d", flags);
-       arr[11] = str_flags;
-       snprintf(str_id, sizeof(str_id), "%d", data->id);
-       arr[12] = str_id;
-
-       broadcast_dbus_signal(STORAGED_PATH_BLOCK_MANAGER,
+       dbus_handle_broadcast_dbus_signal_var(STORAGED_PATH_BLOCK_MANAGER,
                        STORAGED_INTERFACE_BLOCK_MANAGER,
                        BLOCK_DEVICE_BLOCKED,
-                       "issssssisibii", arr);
+                       block_data_to_gvariant(data, 0));
 }
 
 static void signal_device_changed(struct block_device *bdev,
                enum block_dev_operation op)
 {
        struct block_data *data;
-       char *arr[13];
-       char str_block_type[32];
-       char str_readonly[32];
-       char str_state[32];
-       char str_primary[32];
-       char str_flags[32];
-       char str_id[32];
-       char *str_null = "";
+       GVariant *var = NULL;
        int flags;
 
        if (!bdev || !bdev->data)
@@ -447,49 +411,27 @@ static void signal_device_changed(struct block_device *bdev,
        }
 
        /* Broadcast outside with BlockManager iface */
-       snprintf(str_block_type, sizeof(str_block_type),
-                       "%d", data->block_type);
-       arr[0] = str_block_type;
-       arr[1] = (data->devnode ? data->devnode : str_null);
-       arr[2] = (data->syspath ? data->syspath : str_null);
-       arr[3] = (data->fs_usage ? data->fs_usage : str_null);
-       arr[4] = (data->fs_type ? data->fs_type : str_null);
-       arr[5] = (data->fs_version ? data->fs_version : str_null);
-       arr[6] = (data->fs_uuid_enc ? data->fs_uuid_enc : str_null);
-       snprintf(str_readonly, sizeof(str_readonly),
-                       "%d", data->readonly);
-       arr[7] = str_readonly;
-       arr[8] = (data->mount_point ? data->mount_point : str_null);
-       snprintf(str_state, sizeof(str_state),
-                       "%d", data->state);
-       arr[9] = str_state;
-       snprintf(str_primary, sizeof(str_primary),
-                       "%d", data->primary);
-       arr[10] = str_primary;
-       snprintf(str_flags, sizeof(str_flags), "%d", flags);
-       arr[11] = str_flags;
-       snprintf(str_id, sizeof(str_id), "%d", data->id);
-       arr[12] = str_id;
+       var = block_data_to_gvariant(data, flags);
 
        if (op == BLOCK_DEV_INSERT)
-               broadcast_dbus_signal(STORAGED_PATH_BLOCK_MANAGER,
+               dbus_handle_broadcast_dbus_signal_var(STORAGED_PATH_BLOCK_MANAGER,
                                STORAGED_INTERFACE_BLOCK_MANAGER,
                                BLOCK_DEVICE_ADDED,
-                               "issssssisibii", arr);
+                               var);
        else if (op == BLOCK_DEV_REMOVE)
-               broadcast_dbus_signal(STORAGED_PATH_BLOCK_MANAGER,
+               dbus_handle_broadcast_dbus_signal_var(STORAGED_PATH_BLOCK_MANAGER,
                                STORAGED_INTERFACE_BLOCK_MANAGER,
                                BLOCK_DEVICE_REMOVED,
-                               "issssssisibii", arr);
+                               var);
        else {
-               broadcast_dbus_signal(STORAGED_PATH_BLOCK_MANAGER,
+               dbus_handle_broadcast_dbus_signal_var(STORAGED_PATH_BLOCK_MANAGER,
                                STORAGED_INTERFACE_BLOCK_MANAGER,
                                BLOCK_DEVICE_CHANGED,
-                               "issssssisibii", arr);
-               broadcast_dbus_signal(STORAGED_PATH_BLOCK_MANAGER,
+                               var);
+               dbus_handle_broadcast_dbus_signal_var(STORAGED_PATH_BLOCK_MANAGER,
                                STORAGED_INTERFACE_BLOCK_MANAGER,
                                BLOCK_DEVICE_CHANGED_2,
-                               "issssssisibi", arr);
+                               block_data_to_gvariant2(data, flags));
        }
 }
 
@@ -938,9 +880,8 @@ static void create_external_apps_directory(void)
 {
        int ret;
 
-       ret = call_dbus_method_async(PKGDIR_BUS_NAME, PKGDIR_PATH,
-                       PKGDIR_INTERFACE, "CreateExternalDirsForAllPkgs",
-                       NULL, NULL, NULL, DBUS_TIMEOUT_USE_DEFAULT, NULL);
+       ret = dbus_method_async(PKGDIR_BUS_NAME, PKGDIR_PATH,
+               PKGDIR_INTERFACE, "CreateExternalDirsForAllPkgs", NULL, NULL);
        if (ret)
                _E("Fail to create external directory");
 }
@@ -1670,17 +1611,6 @@ static void remove_operation(struct block_device *bdev)
        }
 }
 
-static void block_send_dbus_reply(dbus_method_reply_handle_h reply_handle, int result)
-{
-       DBusMessage *rep;
-
-       if (!reply_handle)
-               return;
-
-       rep = make_dbus_reply_message_simple(reply_handle, result);
-       reply_dbus_method_result(reply_handle, rep);
-}
-
 // Called by BlockThread
 static void check_removed(struct block_device *bdev, dd_list **queue, struct operation_queue **op)
 {
@@ -1710,7 +1640,7 @@ static void check_removed(struct block_device *bdev, dd_list **queue, struct ope
                }
                temp->done = true;
                th_manager[thread_id].op_len--;
-               block_send_dbus_reply((*op)->reply_handle, 0);
+               block_send_dbus_reply((*op)->invocation, 0);
        }
 
        remove_operation(bdev);
@@ -1760,7 +1690,7 @@ static bool check_unmount(struct block_device *bdev, dd_list **queue, struct ope
                }
                temp->done = true;
                th_manager[thread_id].op_len--;
-               block_send_dbus_reply((*op)->reply_handle, 0);
+               block_send_dbus_reply((*op)->invocation, 0);
        }
 
        remove_operation(bdev);
@@ -1852,7 +1782,7 @@ static void trigger_operation(struct block_device *bdev, dd_list *queue, struct
                op->done = true;
                th_manager[thread_id].op_len--;
 
-               block_send_dbus_reply(op->reply_handle, ret);
+               block_send_dbus_reply(op->invocation, ret);
 
                queue = bdev->op_queue;
                if (queue != NULL) {
@@ -1989,7 +1919,7 @@ static int find_thread(char *devnode)
 // Called by MainThread
 static int add_operation(struct block_device *bdev,
                enum block_dev_operation operation,
-               dbus_method_reply_handle_h reply_handle, void *data)
+               GDBusMethodInvocation *invocation, void *data)
 {
        struct operation_queue *op;
        int ret;
@@ -2018,7 +1948,7 @@ static int add_operation(struct block_device *bdev,
 
        op->op = operation;
        op->data = data;
-       op->reply_handle = reply_handle;
+       op->invocation = invocation;
 
        /* LOCK
         * during adding queue and checking the queue length */
@@ -2651,10 +2581,13 @@ static void remove_whole_block_device(void)
        }
 }
 
-static void booting_done(const char *sender_name,
-               const char *object_path, const char *interface_name,
-               const char *signal_name, DBusMessage *msg,
-               void *data)
+static void booting_done(GDBusConnection  *conn,
+                                                       const gchar *sender,
+                                                       const gchar *path,
+                                                       const gchar *iface,
+                                                       const gchar *name,
+                                                       GVariant *param,
+                                                       gpointer data)
 {
        static int done = 0;
        int ret;
@@ -2676,10 +2609,13 @@ static void booting_done(const char *sender_name,
        block_boot = true;
 }
 
-static void block_poweroff(const char *sender_name,
-               const char *object_path, const char *interface_name,
-               const char *signal_name, DBusMessage *msg,
-               void *data)
+static void block_poweroff(GDBusConnection  *conn,
+                                                       const gchar *sender,
+                                                       const gchar *path,
+                                                       const gchar *iface,
+                                                       const gchar *name,
+                                                       GVariant *param,
+                                                       gpointer data)
 {
        static int status = 0;
        if (status > 0)
@@ -2768,11 +2704,12 @@ static void uevent_block_handler(struct udev_device *dev)
        }
 }
 
-static DBusMessage *request_mount_block(dbus_method_reply_handle_h reply_handle,
-               DBusMessage *msg, bool onprivate)
+static GVariant *request_mount_block(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data, bool onprivate)
 {
        struct block_device *bdev;
-       char *mount_point;
+       char *mount_point = NULL;
        int id;
        int ret = -EBADMSG;
 
@@ -2782,15 +2719,7 @@ static DBusMessage *request_mount_block(dbus_method_reply_handle_h reply_handle,
                goto out;
        }
 
-       if (!reply_handle || !msg)
-               goto out;
-
-       ret = dbus_message_get_args(msg, NULL,
-                       DBUS_TYPE_INT32, &id,
-                       DBUS_TYPE_STRING, &mount_point,
-                       DBUS_TYPE_INVALID);
-       if (!ret)
-               goto out;
+       g_variant_get(param, "(is)", &id, &mount_point);
 
        bdev = find_block_device_by_id(id);
        if (!bdev) {
@@ -2819,7 +2748,7 @@ static DBusMessage *request_mount_block(dbus_method_reply_handle_h reply_handle,
 
        if (onprivate) {
                bdev->on_private_op = REQ_PRIVATE;
-               bdev->private_pid = get_dbus_method_sender_pid(reply_handle);
+               bdev->private_pid = dbus_handle_get_sender_pid(NULL, sender);
                _D("Private operation state: %d", bdev->on_private_op);
        } else {
                if (bdev->on_private_op != REQ_NORMAL) {
@@ -2844,32 +2773,37 @@ static DBusMessage *request_mount_block(dbus_method_reply_handle_h reply_handle,
                create_file(bdev->data->id, bdev->data->mount_point, false);
        }
 
-       ret = add_operation(bdev, BLOCK_DEV_MOUNT, reply_handle, NULL);
+       ret = add_operation(bdev, BLOCK_DEV_MOUNT, invocation, NULL);
        if (ret < 0) {
                _E("Failed to add operation (mount %s)", bdev->data->devnode);
                goto out;
        }
 
+       g_free(mount_point);
        return NULL;
 
 out:
-       return make_dbus_reply_message_simple(reply_handle, ret);
+       g_free(mount_point);
+       return g_variant_new("(i)", ret);
 }
 
-static DBusMessage *request_public_mount_block(dbus_method_reply_handle_h reply_handle,
-               DBusMessage *msg)
+static GVariant *request_public_mount_block(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
 {
-       return request_mount_block(reply_handle, msg, false);
+       return request_mount_block(conn, sender, path, iface, name, param, invocation, user_data, false);
 }
 
-static DBusMessage *request_private_mount_block(dbus_method_reply_handle_h reply_handle,
-               DBusMessage *msg)
+static GVariant *request_private_mount_block(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
 {
-       return request_mount_block(reply_handle, msg, true);
+       return request_mount_block(conn, sender, path, iface, name, param, invocation, user_data, true);
 }
 
-static DBusMessage *request_unmount_block(dbus_method_reply_handle_h reply_handle,
-               DBusMessage *msg, bool onprivate)
+static GVariant *request_unmount_block(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data, bool onprivate)
 {
        struct block_device *bdev;
        pid_t pid;
@@ -2883,15 +2817,7 @@ static DBusMessage *request_unmount_block(dbus_method_reply_handle_h reply_handl
                goto out;
        }
 
-       if (!reply_handle || !msg)
-               goto out;
-
-       ret = dbus_message_get_args(msg, NULL,
-                       DBUS_TYPE_INT32, &id,
-                       DBUS_TYPE_INT32, &option,
-                       DBUS_TYPE_INVALID);
-       if (!ret)
-               goto out;
+       g_variant_get(param, "(ii)", &id, &option);
 
        bdev = find_block_device_by_id(id);
        if (!bdev) {
@@ -2908,7 +2834,7 @@ static DBusMessage *request_unmount_block(dbus_method_reply_handle_h reply_handl
        }
 
        if (onprivate) {
-               pid = get_dbus_method_sender_pid(reply_handle);
+               pid = dbus_handle_get_sender_pid(NULL, sender);
                if (bdev->on_private_op == REQ_NORMAL || (bdev->on_private_op != REQ_NORMAL && pid != bdev->private_pid)) {
                        _E("Failed to process private unmount operation");
                        ret = -EPERM;
@@ -2922,7 +2848,7 @@ static DBusMessage *request_unmount_block(dbus_method_reply_handle_h reply_handl
                }
        }
 
-       ret = add_operation(bdev, BLOCK_DEV_UNMOUNT, reply_handle, (void *)option);
+       ret = add_operation(bdev, BLOCK_DEV_UNMOUNT, invocation, (void *)option);
        if (ret < 0) {
                _E("Failed to add operation (unmount %s)", bdev->data->devnode);
                goto out;
@@ -2937,23 +2863,26 @@ static DBusMessage *request_unmount_block(dbus_method_reply_handle_h reply_handl
        return NULL;
 
 out:
-       return make_dbus_reply_message_simple(reply_handle, ret);
+       return g_variant_new("(i)", ret);
 }
 
-static DBusMessage *request_public_unmount_block(dbus_method_reply_handle_h reply_handle,
-               DBusMessage *msg)
+static GVariant *request_public_unmount_block(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
 {
-       return request_unmount_block(reply_handle, msg, false);
+       return request_unmount_block(conn, sender, path, iface, name, param, invocation, user_data, false);
 }
 
-static DBusMessage *request_private_unmount_block(dbus_method_reply_handle_h reply_handle,
-               DBusMessage *msg)
+static GVariant *request_private_unmount_block(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
 {
-       return request_unmount_block(reply_handle, msg, true);
+       return request_unmount_block(conn, sender, path, iface, name, param, invocation, user_data, true);
 }
 
-static DBusMessage *request_format_block(dbus_method_reply_handle_h reply_handle,
-               DBusMessage *msg)
+static GVariant *request_format_block(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
 {
        struct block_device *bdev;
        struct format_data *fdata;
@@ -2969,15 +2898,7 @@ static DBusMessage *request_format_block(dbus_method_reply_handle_h reply_handle
                goto out;
        }
 
-       if (!reply_handle || !msg)
-               goto out;
-
-       ret = dbus_message_get_args(msg, NULL,
-                       DBUS_TYPE_INT32, &id,
-                       DBUS_TYPE_INT32, &option,
-                       DBUS_TYPE_INVALID);
-       if (!ret)
-               goto out;
+       g_variant_get(param, "(ii)", &id, &option);
 
        bdev = find_block_device_by_id(id);
        if (!bdev) {
@@ -2992,7 +2913,7 @@ static DBusMessage *request_format_block(dbus_method_reply_handle_h reply_handle
                goto out;
        }
 
-       pid = get_dbus_method_sender_pid(reply_handle);
+       pid = dbus_handle_get_sender_pid(NULL, sender);
        if (bdev->on_private_op != REQ_NORMAL && pid != bdev->private_pid) {
                _E("Failed to format on private state");
                ret = -EPERM;
@@ -3019,7 +2940,7 @@ static DBusMessage *request_format_block(dbus_method_reply_handle_h reply_handle
                }
        }
 
-       ret = add_operation(bdev, BLOCK_DEV_FORMAT, reply_handle, (void *)fdata);
+       ret = add_operation(bdev, BLOCK_DEV_FORMAT, invocation, (void *)fdata);
        if (ret < 0) {
                _E("Failed to add operation (format %s)", bdev->data->devnode);
                release_format_data(fdata);
@@ -3036,15 +2957,16 @@ static DBusMessage *request_format_block(dbus_method_reply_handle_h reply_handle
        return NULL;
 
 out:
-       return make_dbus_reply_message_simple(reply_handle, ret);
+       return g_variant_new("(i)", ret);
 }
 
-static DBusMessage *request_format_block_type(dbus_method_reply_handle_h reply_handle,
-               DBusMessage *msg)
+static GVariant *request_format_block_type(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
 {
        struct block_device *bdev;
        struct format_data *fdata;
-       char *type;
+       char *type = NULL;
        pid_t pid;
        int id;
        int option;
@@ -3057,16 +2979,7 @@ static DBusMessage *request_format_block_type(dbus_method_reply_handle_h reply_h
                goto out;
        }
 
-       if (!reply_handle || !msg)
-               goto out;
-
-       ret = dbus_message_get_args(msg, NULL,
-                       DBUS_TYPE_INT32, &id,
-                       DBUS_TYPE_INT32, &option,
-                       DBUS_TYPE_STRING, &type,
-                       DBUS_TYPE_INVALID);
-       if (!ret)
-               goto out;
+       g_variant_get(param, "(iis)", &id, &option, &type);
 
        bdev = find_block_device_by_id(id);
        if (!bdev) {
@@ -3081,7 +2994,7 @@ static DBusMessage *request_format_block_type(dbus_method_reply_handle_h reply_h
                goto out;
        }
 
-       pid = get_dbus_method_sender_pid(reply_handle);
+       pid = dbus_handle_get_sender_pid(NULL, sender);
        if (bdev->on_private_op != REQ_NORMAL && pid != bdev->private_pid) {
                _E("Failed to format on private state");
                ret = -EPERM;
@@ -3108,7 +3021,7 @@ static DBusMessage *request_format_block_type(dbus_method_reply_handle_h reply_h
                }
        }
 
-       ret = add_operation(bdev, BLOCK_DEV_FORMAT, reply_handle, (void *)fdata);
+       ret = add_operation(bdev, BLOCK_DEV_FORMAT, invocation, (void *)fdata);
        if (ret < 0) {
                _E("Failed to add operation (format %s)", bdev->data->devnode);
                release_format_data(fdata);
@@ -3122,123 +3035,117 @@ static DBusMessage *request_format_block_type(dbus_method_reply_handle_h reply_h
                }
        }
 
+       g_free(type);
        return NULL;
 
 out:
-       return make_dbus_reply_message_simple(reply_handle, ret);
-}
-
-static int add_device_to_iter(struct block_data *data, DBusMessageIter *piter)
-{
-       char *str_null = "";
-
-       if (!data || !piter)
-               return -EINVAL;
-
-       dbus_message_iter_append_basic(piter, DBUS_TYPE_INT32,
-                       &(data->block_type));
-       dbus_message_iter_append_basic(piter, DBUS_TYPE_STRING,
-                       data->devnode ? &(data->devnode) : &str_null);
-       dbus_message_iter_append_basic(piter, DBUS_TYPE_STRING,
-                       data->syspath ? &(data->syspath) : &str_null);
-       dbus_message_iter_append_basic(piter, DBUS_TYPE_STRING,
-                       data->fs_usage ? &(data->fs_usage) : &str_null);
-       dbus_message_iter_append_basic(piter, DBUS_TYPE_STRING,
-                       data->fs_type ? &(data->fs_type) : &str_null);
-       dbus_message_iter_append_basic(piter, DBUS_TYPE_STRING,
-                       data->fs_version ? &(data->fs_version) : &str_null);
-       dbus_message_iter_append_basic(piter, DBUS_TYPE_STRING,
-                       data->fs_uuid_enc ? &(data->fs_uuid_enc) : &str_null);
-       dbus_message_iter_append_basic(piter, DBUS_TYPE_INT32,
-                       &(data->readonly));
-       dbus_message_iter_append_basic(piter, DBUS_TYPE_STRING,
-                       data->mount_point ? &(data->mount_point) : &str_null);
-       dbus_message_iter_append_basic(piter, DBUS_TYPE_INT32,
-                       &(data->state));
-       dbus_message_iter_append_basic(piter, DBUS_TYPE_BOOLEAN,
-                       &(data->primary));
-       dbus_message_iter_append_basic(piter, DBUS_TYPE_INT32,
-                       &(data->flags));
-       dbus_message_iter_append_basic(piter, DBUS_TYPE_INT32,
-                       &(data->id));
-
-       return 0;
-}
-
-
-static int add_device_to_struct_iter(struct block_data *data, DBusMessageIter *iter)
-{
-       DBusMessageIter piter;
-
-       if (!data || !iter)
-               return -EINVAL;
-
-       dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, &piter);
-       add_device_to_iter(data, &piter);
-       dbus_message_iter_close_container(iter, &piter);
-
-       return 0;
+       g_free(type);
+       return g_variant_new("(i)", ret);
 }
 
-static int add_device_to_iter_2(struct block_data *data, DBusMessageIter *iter)
+static GVariant *block_data_to_gvariant(struct block_data *data, int flags)
 {
-       DBusMessageIter piter;
-       char *str_null = "";
-
-       if (!data || !iter)
-               return -EINVAL;
-
-       dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, &piter);
-       dbus_message_iter_append_basic(&piter, DBUS_TYPE_INT32,
-                       &(data->block_type));
-       dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING,
-                       data->devnode ? &(data->devnode) : &str_null);
-       dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING,
-                       data->syspath ? &(data->syspath) : &str_null);
-       dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING,
-                       data->fs_usage ? &(data->fs_usage) : &str_null);
-       dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING,
-                       data->fs_type ? &(data->fs_type) : &str_null);
-       dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING,
-                       data->fs_version ? &(data->fs_version) : &str_null);
-       dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING,
-                       data->fs_uuid_enc ? &(data->fs_uuid_enc) : &str_null);
-       dbus_message_iter_append_basic(&piter, DBUS_TYPE_INT32,
-                       &(data->readonly));
-       dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING,
-                       data->mount_point ? &(data->mount_point) : &str_null);
-       dbus_message_iter_append_basic(&piter, DBUS_TYPE_INT32,
-                       &(data->state));
-       dbus_message_iter_append_basic(&piter, DBUS_TYPE_BOOLEAN,
-                       &(data->primary));
-       dbus_message_iter_append_basic(&piter, DBUS_TYPE_INT32,
-                       &(data->flags));
-       dbus_message_iter_close_container(iter, &piter);
-
-       return 0;
-}
-
-static DBusMessage *request_get_device_info(dbus_method_reply_handle_h reply_handle,
-               DBusMessage *msg)
+       if (!data)
+               return dbus_handle_new_g_variant_tuple();
+
+       return g_variant_new("(issssssisibii)",
+               data->block_type,
+               nullstr(data->devnode),
+               nullstr(data->syspath),
+               nullstr(data->fs_usage),
+               nullstr(data->fs_type),
+               nullstr(data->fs_version),
+               nullstr(data->fs_uuid_enc),
+               data->readonly,
+               nullstr(data->mount_point),
+               data->state,
+               data->primary,
+               flags >= 0 ? flags : data->flags,
+               data->id);
+}
+
+static GVariant *block_data_to_gvariant2(struct block_data *data, int flags)
 {
-       DBusMessageIter iter;
-       DBusMessage *reply;
-       struct block_device *bdev;
-       struct block_data *data;
-       int ret, id;
-
-       if (!reply_handle || !msg)
-               return NULL;
-
-       reply = make_dbus_reply_message(reply_handle);
-       if (!reply)
-               goto out;
+       if (!data)
+               return dbus_handle_new_g_variant_tuple();
+
+       return g_variant_new("(issssssisibi)",
+               data->block_type,
+               nullstr(data->devnode),
+               nullstr(data->syspath),
+               nullstr(data->fs_usage),
+               nullstr(data->fs_type),
+               nullstr(data->fs_version),
+               nullstr(data->fs_uuid_enc),
+               data->readonly,
+               nullstr(data->mount_point),
+               data->state,
+               data->primary,
+               flags >= 0 ? flags : data->flags);
+}
+
+
+//static int add_device_to_struct_iter(struct block_data *data, DBusMessageIter *iter)
+//{
+//     //DBusMessageIter piter;
+//
+//     //if (!data || !iter)
+//     //      return -EINVAL;
+//
+//     //dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, &piter);
+//     //add_device_to_iter(data, &piter);
+//     //dbus_message_iter_close_container(iter, &piter);
+//
+//     return 0;
+//}
+
+//static int add_device_to_iter_2(struct block_data *data, DBusMessageIter *iter)
+//{
+//     DBusMessageIter piter;
+//     char *str_null = "";
+//
+//     if (!data || !iter)
+//             return -EINVAL;
+//
+//     //dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, &piter);
+//     //dbus_message_iter_append_basic(&piter, DBUS_TYPE_INT32,
+//     //              &(data->block_type));
+//     //dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING,
+//     //              data->devnode ? &(data->devnode) : &str_null);
+//     //dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING,
+//     //              data->syspath ? &(data->syspath) : &str_null);
+//     //dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING,
+//     //              data->fs_usage ? &(data->fs_usage) : &str_null);
+//     //dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING,
+//     //              data->fs_type ? &(data->fs_type) : &str_null);
+//     //dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING,
+//     //              data->fs_version ? &(data->fs_version) : &str_null);
+//     //dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING,
+//     //              data->fs_uuid_enc ? &(data->fs_uuid_enc) : &str_null);
+//     //dbus_message_iter_append_basic(&piter, DBUS_TYPE_INT32,
+//     //              &(data->readonly));
+//     //dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING,
+//     //              data->mount_point ? &(data->mount_point) : &str_null);
+//     //dbus_message_iter_append_basic(&piter, DBUS_TYPE_INT32,
+//     //              &(data->state));
+//     //dbus_message_iter_append_basic(&piter, DBUS_TYPE_BOOLEAN,
+//     //              &(data->primary));
+//     //dbus_message_iter_append_basic(&piter, DBUS_TYPE_INT32,
+//     //              &(data->flags));
+//     //dbus_message_iter_close_container(iter, &piter);
+//
+//     return 0;
+//}
+
+static GVariant *request_get_device_info(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       struct block_device *bdev = NULL;
+       struct block_data *data = NULL;
+       int id;
 
-       ret = dbus_message_get_args(msg, NULL,
-                       DBUS_TYPE_INT32, &id,
-                       DBUS_TYPE_INVALID);
-       if (!ret)
-               goto out;
+       g_variant_get(param, "(i)", &id);
 
        bdev = find_block_device_by_id(id);
        if (!bdev)
@@ -3247,44 +3154,32 @@ static DBusMessage *request_get_device_info(dbus_method_reply_handle_h reply_han
        if (!data)
                goto out;
 
-       dbus_message_iter_init_append(reply, &iter);
-       add_device_to_iter(data, &iter);
-
 out:
-       return reply;
+       return block_data_to_gvariant(data, -1);
 }
 
-static DBusMessage *request_show_device_list(dbus_method_reply_handle_h reply_handle,
-               DBusMessage *msg)
+static GVariant *request_show_device_list(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
 {
        show_block_device_list();
-       return make_dbus_reply_message(reply_handle);
+       return dbus_handle_new_g_variant_tuple();
 }
-
 // Called by MainThread
-static DBusMessage *request_get_device_list(dbus_method_reply_handle_h reply_handle,
-               DBusMessage *msg)
+static GVariant *request_get_device_list(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
 {
-       DBusMessageIter iter;
-       DBusMessageIter aiter;
-       DBusMessage *reply;
+       GVariant *reply = NULL;
        struct block_device *bdev;
        struct block_data *data;
        dd_list *elem;
        char *type = NULL;
-       int ret = -EBADMSG;
        int block_type;
        int i;
+       GVariantBuilder *builder = NULL;
 
-       reply = make_dbus_reply_message(reply_handle);
-
-       ret = dbus_message_get_args(msg, NULL,
-                       DBUS_TYPE_STRING, &type,
-                       DBUS_TYPE_INVALID);
-       if (!ret) {
-               _E("Failed to get args");
-               goto out;
-       }
+       g_variant_get(param, "(s)", &type);
 
        if (!type) {
                _E("Delivered type is NULL");
@@ -3304,8 +3199,7 @@ static DBusMessage *request_get_device_list(dbus_method_reply_handle_h reply_han
                goto out;
        }
 
-       dbus_message_iter_init_append(reply, &iter);
-       dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(issssssisibii)", &aiter);
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a(issssssisibii)"));
 
        for (i = 0; i < THREAD_MAX; i++) {
                pthread_mutex_lock(&(th_manager[i].mutex));
@@ -3325,40 +3219,49 @@ static DBusMessage *request_get_device_list(dbus_method_reply_handle_h reply_han
                        default:
                                break;
                        }
-                       add_device_to_struct_iter(data, &aiter);
+
+                       g_variant_builder_add(builder, "(issssssisibii)",
+                               data->block_type,
+                               nullstr(data->devnode),
+                               nullstr(data->syspath),
+                               nullstr(data->fs_usage),
+                               nullstr(data->fs_type),
+                               nullstr(data->fs_version),
+                               nullstr(data->fs_uuid_enc),
+                               data->readonly,
+                               nullstr(data->mount_point),
+                               data->state,
+                               data->primary,
+                               data->flags,
+                               data->id);
                }
                pthread_mutex_unlock(&(th_manager[i].mutex));
        }
-       dbus_message_iter_close_container(&iter, &aiter);
+       reply = g_variant_new("(a(issssssisibii))", builder);
+       g_variant_builder_unref(builder);
 
 out:
+       g_free(type);
+       if (!reply)
+               reply = dbus_handle_new_g_variant_tuple();
        return reply;
 }
 
 // Called by MainThread
-static DBusMessage *request_get_device_list_2(dbus_method_reply_handle_h reply_handle,
-               DBusMessage *msg)
+static GVariant *request_get_device_list_2(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
 {
-       DBusMessageIter iter;
-       DBusMessageIter aiter;
-       DBusMessage *reply;
+       GVariant *reply = NULL;
        struct block_device *bdev;
        struct block_data *data;
        dd_list *elem;
        char *type = NULL;
-       int ret = -EBADMSG;
        int block_type;
        int i;
+       GVariantBuilder *builder = NULL;
 
-       reply = make_dbus_reply_message(reply_handle);
-
-       ret = dbus_message_get_args(msg, NULL,
-                       DBUS_TYPE_STRING, &type,
-                       DBUS_TYPE_INVALID);
-       if (!ret) {
-               _E("Failed to get args");
-               goto out;
-       }
+       g_variant_get(param, "(s)", &type);
 
        if (!type) {
                _E("Delivered type is NULL");
@@ -3378,8 +3281,7 @@ static DBusMessage *request_get_device_list_2(dbus_method_reply_handle_h reply_h
                goto out;
        }
 
-       dbus_message_iter_init_append(reply, &iter);
-       dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(issssssisibi)", &aiter);
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a(issssssisibi)"));
 
        for (i = 0; i < THREAD_MAX; i++) {
                pthread_mutex_lock(&(th_manager[i].mutex));
@@ -3400,35 +3302,40 @@ static DBusMessage *request_get_device_list_2(dbus_method_reply_handle_h reply_h
                                break;
                        }
 
-                       add_device_to_iter_2(data, &aiter);
+                       g_variant_builder_add(builder, "(issssssisibi)",
+                               data->block_type,
+                               nullstr(data->devnode),
+                               nullstr(data->syspath),
+                               nullstr(data->fs_usage),
+                               nullstr(data->fs_type),
+                               nullstr(data->fs_version),
+                               nullstr(data->fs_uuid_enc),
+                               data->readonly,
+                               nullstr(data->mount_point),
+                               data->state,
+                               data->primary,
+                               data->flags);
                }
                pthread_mutex_unlock(&(th_manager[i].mutex));
        }
-       dbus_message_iter_close_container(&iter, &aiter);
+       reply = g_variant_new("(a(issssssisibi))", builder);
+       g_variant_builder_unref(builder);
 
 out:
+       g_free(type);
        return reply;
 }
 
-static DBusMessage *request_get_mmc_primary(dbus_method_reply_handle_h reply_handle,
-               DBusMessage *msg)
+static GVariant *request_get_mmc_primary(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
 {
-       DBusMessageIter iter;
-       DBusMessage *reply;
        struct block_device *bdev;
        struct block_data *data, nodata = {0,};
        dd_list *elem;
-       bool found;
+       bool found = false;
        int i;
 
-       if (!reply_handle || !msg)
-               return NULL;
-
-       reply = make_dbus_reply_message(reply_handle);
-       if (!reply)
-               goto out;
-
-       found = false;
        for (i = 0; i < THREAD_MAX; i++) {
                pthread_mutex_lock(&(th_manager[i].mutex));
                DD_LIST_FOREACH(th_manager[i].block_dev_list, elem, bdev) {
@@ -3453,24 +3360,19 @@ static DBusMessage *request_get_mmc_primary(dbus_method_reply_handle_h reply_han
                        break;
        }
 
-       dbus_message_iter_init_append(reply, &iter);
-       if (found)
-               add_device_to_iter(data, &iter);
-       else {
+       if (!found) {
                nodata.id = -ENODEV;
-               add_device_to_iter(&nodata, &iter);
+               data = &nodata;
        }
 
-out:
-       return reply;
+       return block_data_to_gvariant(data, -1);
 }
 
-static DBusMessage *request_check_speed(dbus_method_reply_handle_h reply_handle,
-               DBusMessage *msg)
+static GVariant *request_check_speed(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
 {
        struct timespec start_time, end_time;
-       DBusMessageIter iter;
-       DBusMessage *reply;
        struct block_device *bdev;
        struct block_data *data;
        char *buf;
@@ -3480,16 +3382,7 @@ static DBusMessage *request_check_speed(dbus_method_reply_handle_h reply_handle,
        int fd;
        int time_diff;
 
-       if (!reply_handle || !msg)
-               return NULL;
-
-       ret = dbus_message_get_args(msg, NULL,
-                       DBUS_TYPE_INT32, &id,
-                       DBUS_TYPE_INVALID);
-       if (!ret) {
-               result = -1;
-               goto out;
-       }
+       g_variant_get(param, "(i)", &id);
 
        bdev = find_block_device_by_id(id);
        if (!bdev) {
@@ -3535,29 +3428,18 @@ static DBusMessage *request_check_speed(dbus_method_reply_handle_h reply_handle,
 
        close(fd);
 out:
-       reply = dbus_message_new_method_return(msg);
-       dbus_message_iter_init_append(reply, &iter);
-       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &result);
-       return reply;
+       return g_variant_new("(i)", result);
 }
 
 
-static DBusMessage *request_control_block(dbus_method_reply_handle_h reply_handle,
-               DBusMessage *msg)
+static GVariant *request_control_block(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
 {
-       int ret;
        int enable;
        int result;
-       DBusMessage *reply;
-       DBusMessageIter iter;
 
-       ret = dbus_message_get_args(msg, NULL,
-                       DBUS_TYPE_INT32, &enable,
-                       DBUS_TYPE_INVALID);
-       if (!ret) {
-               result = -1;
-               goto out;
-       }
+       g_variant_get(param, "(i)", &enable);
 
        switch (enable) {
        case 0:
@@ -3576,30 +3458,20 @@ static DBusMessage *request_control_block(dbus_method_reply_handle_h reply_handl
                break;
        }
 
-out:
-       reply = dbus_message_new_method_return(msg);
-       dbus_message_iter_init_append(reply, &iter);
-       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &result);
-
-       return reply;
+       return g_variant_new("(i)", result);
 }
 
-static DBusMessage *request_getcontrol_block(dbus_method_reply_handle_h reply_handle,
-               DBusMessage *msg)
+static GVariant *request_getcontrol_block(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
 {
        int result;
-       DBusMessage *reply;
-       DBusMessageIter iter;
 
        _I("getcontrol block");
 
        result = block_control;
 
-       reply = dbus_message_new_method_return(msg);
-       dbus_message_iter_init_append(reply, &iter);
-       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &result);
-
-       return reply;
+       return g_variant_new("(i)", result);
 }
 
 /*
@@ -3617,23 +3489,23 @@ static DBusMessage *request_getcontrol_block(dbus_method_reply_handle_h reply_ha
 */
 
 static const dbus_method_s manager_methods[] = {
-       { "ShowDeviceList",         NULL, request_show_device_list },
-       { "GetDeviceList" ,         "s", request_get_device_list },
-       { "GetDeviceList2",         "s", request_get_device_list_2 },
-       { "Mount",                  "is", request_public_mount_block },
-       { "Unmount",                "ii", request_public_unmount_block },
-       { "Format",                 "ii", request_format_block },
-       { "FormatwithType",        "iis", request_format_block_type },
-       { "GetDeviceInfo",          "i", request_get_device_info },
-       { "GetMmcPrimary" ,         NULL, request_get_mmc_primary },
-       { "PrivateMount",           "is", request_private_mount_block },
-       { "PrivateUnmount",         "ii", request_private_unmount_block },
-       { "CheckSpeed",              "i", request_check_speed },
-       { "Control",                 "i", request_control_block },
-       { "GetControl",              "i", request_getcontrol_block },
+       { "ShowDeviceList", NULL, NULL, request_show_device_list },
+       { "GetDeviceList" , "s", "a(issssssisibii)", request_get_device_list },
+       { "GetDeviceList2", "s", "a(issssssisibi)", request_get_device_list_2 },
+       { "Mount", "is", "i", request_public_mount_block },
+       { "Unmount", "ii", "i", request_public_unmount_block },
+       { "Format", "ii", "i", request_format_block },
+       { "FormatwithType", "iis", "i", request_format_block_type },
+       { "GetDeviceInfo", "i", "issssssisibii", request_get_device_info },
+       { "GetMmcPrimary", NULL, "issssssisibii", request_get_mmc_primary },
+       { "PrivateMount", "is", "i", request_private_mount_block },
+       { "PrivateUnmount", "ii", "i", request_private_unmount_block },
+       { "CheckSpeed", "i", "i", request_check_speed },
+       { "Control", "i", "i", request_control_block },
+       { "GetControl", "i", "i", request_getcontrol_block },
 };
 
-static dbus_interface_s block_interface = {
+static const dbus_interface_u block_interface = {
        .name = STORAGED_INTERFACE_BLOCK_MANAGER,
        .methods = manager_methods,
        .nr_methods = ARRAY_SIZE(manager_methods),
@@ -3694,12 +3566,14 @@ static int mount_root_path_tmpfs(void)
 #define mount_root_path_tmpfs() 0
 #endif
 
+static guint id_booting_done;
+static guint id_block_poweroff;
+
 static void block_init(void *data)
 {
        struct stat buf;
        int ret;
        int i;
-       dbus_handle_h handle;
 
        udev_init(NULL);
 
@@ -3712,14 +3586,8 @@ static void block_init(void *data)
        if (ret < 0)
                _E("Failed to mount tmpfs to root mount path (%d)", ret);
 
-       ret = dbus_get_connection(&handle);
-       if (ret < 0)
-               _E("Failed to get dbus connection(%d)", ret);
-
        /* register block manager object and interface */
-       ret = register_dbus_methods(handle,
-                       STORAGED_PATH_BLOCK_MANAGER, &block_interface,
-                       NULL, NULL);
+       ret = dbus_handle_register_dbus_object(NULL, STORAGED_PATH_BLOCK_MANAGER, &block_interface);
        if (ret < 0)
                _E("Failed to register block interface and methods (%d)", ret);
 
@@ -3729,12 +3597,12 @@ static void block_init(void *data)
                _E("fail to init pipe");
 
        /* System Session is loaded completely */
-       register_dbus_signal(SYSTEMD_DBUS_PATH,
+       id_booting_done = subscribe_dbus_signal(NULL, SYSTEMD_DBUS_PATH,
                    SYSTEMD_DBUS_IFACE_MANAGER,
                    SYSTEMD_DBUS_SIGNAL_SYSTEM_STARTUP_FINISHED,
                    booting_done, NULL, NULL);
 
-       register_dbus_signal(DEVICED_PATH_POWEROFF,
+       id_block_poweroff = subscribe_dbus_signal(NULL, DEVICED_PATH_POWEROFF,
                        DEVICED_INTERFACE_POWEROFF,
                        SIGNAL_POWEROFF_STATE,
                        block_poweroff, NULL, NULL);
@@ -3798,14 +3666,8 @@ static void block_exit(void *data)
        udev_exit(NULL);
 
        /* unregister notifier for below each event */
-       unregister_dbus_signal(SYSTEMD_DBUS_PATH,
-                   SYSTEMD_DBUS_IFACE_MANAGER,
-                   SYSTEMD_DBUS_SIGNAL_SYSTEM_STARTUP_FINISHED,
-                   booting_done);
-
-       unregister_dbus_signal(DEVICED_PATH_POWEROFF,
-                       DEVICED_INTERFACE_POWEROFF,
-                       SIGNAL_POWEROFF_STATE, block_poweroff);
+       unsubscribe_dbus_signal(NULL, id_booting_done);
+       unsubscribe_dbus_signal(NULL, id_block_poweroff);
 
        /* unregister mmc uevent control routine */
        ret = unregister_udev_uevent_control(&uh);
index d66ef0f..19ddf39 100644 (file)
@@ -137,12 +137,11 @@ static int vfat_format(const char *devpath)
 {
        int argc;
 
-       if(!is_emulator()) {
+       if (!is_emulator()) {
                argc = ARRAY_SIZE(vfat_arg);
                vfat_arg[argc - 2] = devpath;
                return run_child(argc, vfat_arg);
-       }
-       else {
+       } else {
                argc = ARRAY_SIZE(emul_vfat_arg);
                emul_vfat_arg[argc - 2] = devpath;
                return run_child(argc, emul_vfat_arg);
index db63353..fee7ee9 100644 (file)
@@ -24,9 +24,9 @@
 #include <systemd/sd-daemon.h>
 #include <glib.h>
 
-#include "dbus_main.h"
 #include "log.h"
 #include "modules.h"
+#include "dbus.h"
 
 #define WATCHDOG_TIMEOUT       15 /* Seconds */
 
@@ -76,10 +76,9 @@ int main(int argc, char **argv)
                return -ENOMEM;
        }
 
-       ret = set_dbus_connection(STORAGED_BUS_NAME);
-       if (ret < 0) {
-               _E("Failed to set dbus connection (%s, %d)", STORAGED_BUS_NAME, ret);
-               return ret;
+       if (!dbus_handle_init(G_BUS_TYPE_SYSTEM, STORAGED_BUS_NAME)) {
+               _E("Failed to set dbus connection (%s)", STORAGED_BUS_NAME);
+               return 0;
        }
 
        modules_init(NULL);
index 3d4200b..246b592 100755 (executable)
@@ -58,7 +58,7 @@ int launch_system_app(char *type, int num, ...)
 
        va_start(args, num);
 
-       ret = call_dbus_method_async_pairs(app_match[match].bus,
+       ret = dbus_method_async_pairs(app_match[match].bus,
                        app_match[match].path,
                        app_match[match].iface,
                        app_match[match].method,
index 59fafde..2778d25 100644 (file)
  * limitations under the License.
 */
 
+
 #include <stdio.h>
 #include <stdlib.h>
-#include <errno.h>
-#include <dbus/dbus.h>
 #include <stdbool.h>
-#include <limits.h>
-#include "fd_handler.h"
-#include "dbus.h"
+#include <stdint.h>
+#include <errno.h>
+
+#include "common.h"
 #include "log.h"
+#include "dbus.h"
 
-/* -1 is a default timeout value, it's converted to 25*1000 internally. */
-#define DBUS_REPLY_TIMEOUT  (-1)
+/* 10 seconds */
+#define DBUS_REPLY_TIMEOUT     (10000)
 
-struct dbus_handle_s {
-       DBusConnection *conn;
-       char *name;
-       GList *method_handle_list;
-};
+int check_systemd_active(void)
+{
+       int ret = FALSE;
+       GVariant *msg = NULL;
+       GVariant *var = NULL;
+       char *state;
+
+       _I("%s %s", "org.freedesktop.systemd1.Unit", "ActiveState");
+
+       msg = dbus_method_sync_with_reply_var("org.freedesktop.systemd1",
+                       "/org/freedesktop/systemd1/unit/default_2etarget",
+                       "org.freedesktop.DBus.Properties",
+                       "Get", g_variant_new("(ss)", "org.freedesktop.systemd1.Unit", "ActiveState"));
+       if (!msg)
+               return -EBADMSG;
 
-struct dbus_method_reply_handle_s {
-       struct dbus_handle_s *handle;
-       DBusMessage *msg;
-};
+       if (!dh_get_param_from_var(msg, "(v)", &var)) {
+               _E("reply is not variant type");
+               ret = -EBADMSG;
+               goto out;
+       }
+       if (!dh_get_param_from_var(var, "(s)", &state)) {
+               _E("variant doesn't have string (%s)", g_variant_get_type_string(var));
+               ret = -EBADMSG;
+               goto out;
+       }
 
-struct dbus_method_handle_s {
-       struct dbus_handle_s *handle;
-       const char *path;
-       const dbus_interface_s *iface;
-       void (*method_handle_received)(void *method_handle, void *data);
-       void *data;
-};
+       if (strncmp(state, "active", 6) == 0)
+               ret = TRUE;
 
-struct signal_info {
-       const char *path;
-       const char *iface;
-       const char *name;
-       dbus_signal_received cb;
-       destroy_notified free_func;
-       void *data;
-       guint handler;
-};
+       g_free(state);
+out:
+       if (var)
+               g_variant_unref(var);
+       if (msg)
+               g_variant_unref(msg);
 
-struct pending_call_data {
-       dbus_pending_cb func;
-       void *data;
-};
+       return ret;
+}
 
-static GList *connection_handle_list;
-static GList *signal_handler_list;
+static GBusType g_default_bus_type = G_BUS_TYPE_SYSTEM;
+pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
 
-static DBusConnection *get_dbus_connection(void)
+void dbus_handle_set_default_bus_type(GBusType bus_type)
 {
-       static DBusConnection *conn;
-       DBusError err;
+       if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION)
+               return ;
 
-       if (conn)
-               return conn;
+       pthread_mutex_lock(&g_mutex);
+       g_default_bus_type = bus_type;
+       pthread_mutex_unlock(&g_mutex);
+}
 
-       dbus_error_init(&err);
+GBusType dbus_handle_get_default_bus_type(void)
+{
+       GBusType type;
 
-       conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
-       if (!conn) {
-               if (dbus_error_is_set(&err)) {
-                       _E("dbus_bus_get error(%s, %s)", err.name, err.message);
-                       dbus_error_free(&err);
-               } else
-                       _E("dbus_bus_get error");
-       }
+       pthread_mutex_lock(&g_mutex);
+       type = g_default_bus_type;
+       pthread_mutex_unlock(&g_mutex);
 
-       return conn;
+       return type;
 }
 
-int dbus_get_connection(dbus_handle_h *handle)
-{
-       static DBusConnection *conn;
-       struct dbus_handle_s *h;
-       int ret;
+typedef struct {
+       const char *bus_name;
+       guint id;
+} dbus_name;
+
+/* basic information */
+typedef struct {
+       GDBusConnection *conn;
+       GBusType bus_type;
+       gboolean priv;
+       GList *list_names; // dbus_name
+       GList *list_object; /* dbus_object_handle_s */
+       pthread_mutex_t mutex;// = PTHREAD_MUTEX_INITIALIZER;
+} dbus_handle_s;
+
+/* path + interfaces */
+typedef struct {
+       dbus_handle_s *dh;                              /* dbus handle */
+       const char *path;
+       GList *list_ifaces;                                     /* dbus_interface_s */
+} dbus_object_handle_s;
+
+typedef struct {
+       dbus_object_handle_s *oh;
+       const char *name;
+       GList *list_methods; // const dbus_method_s;
+       guint reg_id;
+       int modified;
+} dbus_interface_s;
+
+#define get_dh_from_oh(oh) ((dbus_object_handle_s*)oh)->dh
 
-       if (!handle)
-               return -EINVAL;
+static dbus_handle_s g_dh[2];
+
+static dbus_handle_s *_dbus_handle_get_connection(GBusType bus_type);
+
+dbus_handle_s * _dbus_handle_get_default_connection(void)
+{
+       return _dbus_handle_get_connection(dbus_handle_get_default_bus_type());
+}
 
-       h = calloc(1, sizeof(struct dbus_handle_s));
-       if (!h) {
-               _E("calloc() failed");
-               return -ENOMEM;
+#define dbus_handle_lock(handle) do {\
+       assert(handle);\
+       pthread_mutex_lock(&((handle)->mutex));\
+} while (0);
+
+#define dbus_handle_unlock(handle) do {\
+       assert(handle);\
+       pthread_mutex_unlock(&(handle)->mutex);\
+} while (0);
+
+#define dcl_dbus_handle() dbus_handle_s *dh = (dbus_handle_s *)handle;
+#define dcl_dbus_handle_null_check() dbus_handle_s *dh = (dbus_handle_s *)handle;\
+       if (!dh) {\
+       _E("dbus handle is null\n");\
+       return 0;\
        }
 
-       conn = get_dbus_connection();
-       if (!conn) {
-               _E("Failed to get dbus connection");
-               ret = -ECOMM;
-               goto out;
+dbus_object_handle_s * _dbus_handle_lookup_object(GList *list_obj, const char *obj_path);
+dbus_interface_s * _dbus_handle_lookup_interface(GList *list_iface, const char *iface_name);
+dbus_method_s * _dbus_handle_lookup_method(GList *list_methods, const char *method_name);
+static GVariant* _append_variant(const char *signature, const char *param[]);
+
+dbus_interface_s *_iface_u_to_s(const dbus_interface_u *iface_u)
+{
+       dbus_interface_s *iface = NULL;
+
+       if (!iface_u || !iface_u->methods) {
+               _E("param is null");
+               return NULL;
        }
 
-       h->conn = conn;
-       *handle = h;
+       iface = (dbus_interface_s *)calloc(1, sizeof(dbus_interface_s));
+       if (!iface) {
+               _E("failed to calloc");
+               return NULL;
+       }
 
-       connection_handle_list = g_list_append(connection_handle_list, h);
+       iface->name = iface_u->name;
+       iface->modified = TRUE;
 
-       return 0;
+       for (int i = 0 ; i < iface_u->nr_methods; ++i) {
+               //_D("attached %s:%p", iface_u->methods[i].member, iface_u->methods[i].func);
+               iface->list_methods = g_list_prepend(iface->list_methods, (void*)(iface_u->methods + i));
+       }
 
-out:
-       free(h);
-       return ret;
+       return iface;
 }
 
-int get_dbus_method_sender_name(dbus_method_reply_handle_h reply_handle,
-               char *name, size_t len)
+static GDBusConnection * _get_bus(GBusType bus_type)
 {
-       struct dbus_method_reply_handle_s *reply = reply_handle;
-       const char *sender;
+       GDBusConnection *conn = NULL;
+       GError *err = NULL;
 
-       if (!reply || !reply->msg || !name)
-               return -EINVAL;
+       if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
+               _E("Wrong bus_type %d", bus_type);
+               return NULL;
+       }
 
-       sender = dbus_message_get_sender(reply->msg);
-       snprintf(name, len, "%s", sender);
+       conn = g_bus_get_sync(bus_type, NULL, &err);
+       if (!conn || err) {
+               _E("failed to get bus:type:%d, %s\n", bus_type, err->message);
+               g_error_free(err);
+               return NULL;
+       }
 
-       return 0;
+       return conn;
 }
 
-int get_dbus_method_sender_pid(dbus_method_reply_handle_h reply_handle)
+static GDBusConnection * _get_bus_private(GBusType bus_type)
 {
-       char *param[1];
-       pid_t pid;
-       char name[NAME_MAX];
-       DBusMessage *msg;
-       DBusError err;
-       int ret;
+       GError *err = NULL;
+       GDBusConnection *conn = NULL;
+       const char * address;
 
-       ret = get_dbus_method_sender_name(reply_handle, name, sizeof(name));
-       if (ret < 0)
-               return ret;
-
-       param[0] = name;
-       ret = call_dbus_method_sync(DBUS_SERVICE_DBUS,
-                       DBUS_PATH_DBUS,
-                       DBUS_INTERFACE_DBUS,
-                       "GetConnectionUnixProcessID",
-                       "s", param, DBUS_REPLY_TIMEOUT,
-                       &msg);
-       if (ret < 0) {
-               _E("Faild to get pid of sender(%s)", name);
-               return ret;
+       if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
+               _E("Wrong bus_type %d", bus_type);
+               return NULL;
        }
 
-       dbus_error_init(&err);
-
-       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_UINT32, &pid, DBUS_TYPE_INVALID);
-       dbus_message_unref(msg);
-       if (dbus_error_is_set(&err)) {
-               _E("no message : [%s:%s]", err.name, err.message);
-               dbus_error_free(&err);
-               return -ENOMSG;
+       address = g_dbus_address_get_for_bus_sync(bus_type, NULL, &err);
+       if (!address || err) {
+               _E("failed to get bus address\n");
+               g_error_free(err);
+               return NULL;
        }
-       if (!ret) {
-               _E("no message");
-               return -ENOMSG;
+
+       conn = g_dbus_connection_new_for_address_sync(address,
+                                                                               (GDBusConnectionFlags) (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
+                                                                               G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION),
+                                                                               NULL, /* GDBusAuthObserver */
+                                                                               NULL,
+                                                                               &err);
+       if (!conn || err) {
+               _E("failed to get private bus\n");
+               g_error_free(err);
+               return NULL;
        }
 
-       return pid;
+       return conn;
 }
 
-DBusMessage *make_dbus_reply_message(dbus_method_reply_handle_h reply_handle)
+/* ref cout is 1 */
+static dbus_handle_s *_dbus_handle_get_connection(GBusType bus_type)
 {
-       struct dbus_method_reply_handle_s *reply = reply_handle;
+       int ibus = bus_type - 1;
+       dbus_handle_s *dh = NULL;
 
-       if (!reply || !(reply->msg)) {
-               _E("Invalid parameter");
+       if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
+               _E("Unknown bus type %d", bus_type);
                return NULL;
        }
+       dh = &g_dh[ibus];
 
-       return dbus_message_new_method_return(reply->msg);
-}
-
-DBusMessage *make_dbus_reply_message_simple(dbus_method_reply_handle_h reply_handle, int result)
-{
-       DBusMessage *rep;
-       DBusMessageIter iter;
-       rep = make_dbus_reply_message(reply_handle);
-       dbus_message_iter_init_append(rep, &iter);
-       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &result);
-       return rep;
-}
+       dbus_handle_lock(dh);
 
-void reply_dbus_method_result(dbus_method_reply_handle_h reply_handle, DBusMessage *reply_msg)
-{
-       struct dbus_method_reply_handle_s *reply = reply_handle;
+       if (!dh->conn) {
+               dh->conn = _get_bus(bus_type);
+               dh->priv = FALSE;
+               dh->bus_type = bus_type;
+               if (!dh->conn)
+                       dh = NULL;
+       }
 
-       if (!reply || !reply_msg)
-               return;
+       dbus_handle_unlock(dh);
 
-       dbus_connection_send(reply->handle->conn, reply_msg, NULL);
-       if (reply->msg)
-               dbus_message_unref(reply->msg);
-       dbus_message_unref(reply_msg);
-       if (reply)
-               free(reply);
+       return dh;
 }
 
-static DBusHandlerResult method_call_handler(DBusConnection *connection,
-               DBusMessage *msg, void *user_data)
+/* ref cout is 1 */
+static dbus_handle_s *_dbus_handle_get_connection_private(GBusType bus_type)
 {
-       int i;
-       struct dbus_method_handle_s *mh = user_data;
-       struct dbus_method_reply_handle_s *reply;
-       const dbus_interface_s *iface;
-       const dbus_method_s *methods;
-       DBusMessage *result = NULL;
-       bool method_is_implemented = false;
+       dbus_handle_s * dh;
 
-       _D("Method call handler");
-
-       if (!msg || !mh)
-               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; // No message to handle
-
-       iface = mh->iface;
-       methods = iface->methods;
+       if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
+               _E("Unknown bus type %d", bus_type);
+               return NULL;
+       }
 
-       for (i = 0 ; i < iface->nr_methods ; i++) {
-               if (dbus_message_is_method_call(msg, iface->name, methods[i].member) != TRUE)
-                       continue;
+       dh = (dbus_handle_s *)calloc(1, sizeof(dbus_handle_s));
+       if (!dh) {
+               _E("failed to allocate memory for dbus handle");
+               return NULL;
+       }
 
-               method_is_implemented = true;
-               reply = calloc(1, sizeof(struct dbus_method_reply_handle_s));
-               if (!reply) {
-                       _E("calloc() failed");
-                       return DBUS_HANDLER_RESULT_NEED_MEMORY; // Failed to create reply, try again later
-               }
+       dbus_handle_lock(dh);
 
-               reply->handle = mh->handle;
-               reply->msg = dbus_message_ref(msg);
-               result = methods[i].func(reply, msg);
-               if (!result)
-                       _E("result == NULL");
-               break;
+       if (!dh->conn) {
+               dh->conn = _get_bus_private(bus_type);
+               dh->bus_type = bus_type;
+               if (!dh->conn)
+                       goto err;
        }
 
-       if (!method_is_implemented)
-               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; // Missing method, no reply
-       /* If result is null, reply will be sent by worker thread */
-       if (result)
-               reply_dbus_method_result(reply, result); // Method handled, reply sent
+       dbus_handle_unlock(dh);
 
-       return DBUS_HANDLER_RESULT_HANDLED;
+       return dh;
+err:
+       if (dh) {
+               dbus_handle_unlock(dh);
+               free(dh);
+       }
+       return NULL;
 }
 
-static const DBusObjectPathVTable path_vtable = {
-       NULL,
-       method_call_handler,
-       NULL, NULL, NULL, NULL,
-};
-
-static gboolean register_methods(gpointer data)
+dbus_handle_h dbus_handle_get_connection(GBusType bus_type, gboolean priv)
 {
-       dbus_bool_t ret;
-       struct dbus_method_handle_s *mh = data;
-
-       if (!mh)
-               return FALSE;
+       dbus_handle_s *dh = NULL;
 
-       ret = dbus_connection_register_object_path(mh->handle->conn,
-                       mh->path, &path_vtable, mh);
-       if (ret == FALSE) {
-               _E("Failed to register methods (%s)", mh->path);
-               return FALSE;
+       if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
+               _E("Wrong bus_type %d\n", bus_type);
+               return dh;
        }
 
-       if (mh->method_handle_received)
-               mh->method_handle_received(mh, mh->data);
+       /* private */
+       if (priv)
+               dh = _dbus_handle_get_connection_private(bus_type);
+       /* shared */
+       else
+               dh = _dbus_handle_get_connection(bus_type);
 
-       _I("object path(%s)", mh->path);
-
-       return FALSE;
+       return dh;
 }
 
-struct watch_info {
-       DBusWatch *watch;
-       void *data;
-};
+static void _dbus_handle_add_bus_name(dbus_handle_s *handle, const char *name, guint id)
+{
+       dbus_name *dn = NULL;
+       int locked = 0;
 
-static fd_handler_h watch_handler;
+       if (!handle || !name || !id)
+               return ;
 
-static bool watch_changed_cb(int fd, void *data)
-{
-       struct watch_info *winfo = data;
+       dn = (dbus_name*)calloc(1, sizeof(dbus_name));
+       if (!dn) {
+               _E("failed to calloc");
+               assert(0);
+       }
+       dn->bus_name = name;
+       dn->id = id;
+
+       // todo : delete lock ?
+       locked = pthread_mutex_trylock(&handle->mutex);
+       if (locked != 0 && locked != EBUSY) {
+               _E("failed to lock %d\n", locked);
+               assert(0);
+       }
 
-       dbus_watch_handle(winfo->watch, DBUS_WATCH_READABLE | DBUS_WATCH_ERROR);
+       handle->list_names = g_list_prepend(handle->list_names, dn);
 
-       return true;
+       // todo : delete lock ?
+       if (locked != EBUSY)
+               dbus_handle_unlock(handle);
 }
 
-static void free_watch_info(void *data)
+static gint _compare_dbus_name(gconstpointer a, gconstpointer b)
 {
-       if (data)
-               free(data);
+       const char *bus_name = ((dbus_name *)a)->bus_name;
+       if (!bus_name || !b)
+               return -1;
+       return strcmp(bus_name, (const char *)b);
 }
 
-static dbus_bool_t add_watch_cb(DBusWatch *watch, void *data)
+dbus_name * _dbus_handle_lookup_dbus_name(GList *list_name, const char *bus_name)
 {
-       int fd;
-       int ret;
-       struct watch_info *winfo;
-       dbus_bool_t enabled;
-
-       _I("add_watch_cb %s", (dbus_watch_get_enabled(watch) == 0 ? "disabled" : "enabled"));
+       if (!list_name || !bus_name)
+               return NULL;
 
-       enabled = dbus_watch_get_enabled(watch);
+       GList *item = g_list_find_custom(list_name, bus_name, _compare_dbus_name);
+       if (!item)
+               return NULL;
 
-       if (watch_handler || !enabled)
-               return TRUE;
+       return (dbus_name *)item->data;
+}
 
-       winfo = calloc(1, sizeof(struct watch_info));
-       if (!winfo) {
-               _E("calloc() failed");
-               return TRUE;
-       }
+#define dh_to_ds(x) ((dbus_handle_s*)x)
 
-       winfo->watch = watch;
-       winfo->data = NULL;
+/* remove dbus_name from dbus handle */
+static void _dbus_handle_remove_bus_name(dbus_handle_s *handle, const char *bus_name)
+{
+       dcl_dbus_handle();
+       dbus_name *dn = NULL;
 
-       fd = dbus_watch_get_unix_fd(watch);
-       ret = add_fd_read_handler(fd, watch_changed_cb, winfo, free_watch_info, &watch_handler);
-       if (ret < 0)
-               _E("Failed to add fd handler (%d)", ret);
+       if (!bus_name) {
+               _E("wrong bus_name %s", bus_name);
+               return ;
+       }
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return ;
+               }
+       }
 
-       return TRUE;
+       dbus_handle_lock(dh);
+       dn = _dbus_handle_lookup_dbus_name(dh->list_names, bus_name);
+       if (!dn) {
+               _E("failed to find dbus name %s", bus_name);
+               goto out;
+       }
+       dh->list_names = g_list_remove(dh->list_names, dn);
+       free(dn);
+out:
+       dbus_handle_unlock(dh);
 }
 
-static void remove_watch_cb(DBusWatch *watch, void *data)
+static void _name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
 {
-       int ret;
+       dbus_handle_s *dh = (dbus_handle_s *)user_data;
 
-       if (!watch_handler)
-               return;
+       _D("name %s", name);
 
-       ret = remove_fd_read_handler(&watch_handler);
-       if (ret < 0)
-               _E("Failed to remove fd handler (%d)", ret);
-       watch_handler = NULL;
+       if (!dh) {
+               _E("%s:%d:dbus handle is null\n", __func__, __LINE__);
+               return ;
+       }
+       // todo: add bus name?
+       //dh->bus_name = name;
 }
 
-static void toggle_watch_cb(DBusWatch *watch, void *data)
+static void _name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data)
 {
-       return;
+       _E("%s:%d:%s\n", __func__, __LINE__, name);
+       dbus_handle_s *dh = (dbus_handle_s *)user_data;
+       if (!dh) {
+               _E("%s:%d:dbus handle is null\n", __func__, __LINE__);
+               return ;
+       }
+       _dbus_handle_remove_bus_name(dh, name);
 }
 
-static dbus_bool_t add_timeout_cb(DBusTimeout *timeout, void *data)
+int dbus_handle_request_bus_name(dbus_handle_h handle, const char *bus_name)
 {
-       return TRUE;
-}
+       dcl_dbus_handle();
+       int id = -1;
+       GList *item = NULL;
 
-static void remove_timeout_cb(DBusTimeout *timeout, void *data)
-{
-       return;
-}
+       if (!bus_name) {
+               _E("bus_name is NULL");
+               return -1;
+       }
 
-static void toggle_timeout_cb(DBusTimeout *timeout, void *data)
-{
-       return;
+       /* get shared connection */
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return -1;
+               }
+       }
+
+       dbus_handle_lock(dh);
+       if (!dh->conn) {
+               _E("failed to register name: connection is null\n");
+               goto out;
+       }
+
+       /* todo : search name on connection */
+       item = g_list_find_custom(dh->list_names, bus_name, _compare_dbus_name);
+       if (item) {
+               id = ((dbus_name*)(item->data))->id;
+               _E("name already exist:%u", id);
+               goto out;
+       }
+
+       id = g_bus_own_name_on_connection(dh->conn, bus_name, G_BUS_NAME_OWNER_FLAGS_NONE, _name_acquired, _name_lost, dh, NULL);
+       if (!id) {
+               _E("failed to own name:%s\n", bus_name);
+               goto out;
+       }
+
+       _dbus_handle_add_bus_name(dh, bus_name, id);
+
+out:
+       dbus_handle_unlock(dh);
+       return id;
 }
 
-static gboolean dispatch_idler_cb(gpointer data)
+int dbus_handle_release_bus_name(dbus_handle_h handle, const char *bus_name)
 {
-       DBusConnection *conn = data;
+       dcl_dbus_handle();
+       dbus_name *dn = NULL;
 
-       if (!conn) {
-               _E("conn == NULL");
-               return FALSE;
+       if (!bus_name) {
+               _E("Wrong bus name");
+               return -1;
        }
 
-       dbus_connection_ref(conn);
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return -1;
+               }
+       }
 
-       while (dbus_connection_get_dispatch_status(conn) == DBUS_DISPATCH_DATA_REMAINS)
-               dbus_connection_dispatch(conn);
+       dn = _dbus_handle_lookup_dbus_name(dh->list_names, bus_name);
+       if (!dn) {
+               _E("failed to find bus_name %s on dbus handle", bus_name);
+               return -1;
+       }
 
-       dbus_connection_unref(conn);
+       _E("unown name %d", dn->id);
+       /* _name_lost handler is disabled by g_bus_unown_name : ubuntu */
+       g_bus_unown_name(dn->id);
 
-       return FALSE;
-}
+       dbus_handle_lock(dh);
+       dh->list_names = g_list_remove(dh->list_names, dn);
+       free(dn);
+       dbus_handle_unlock(dh);
 
-static void dispatch_status_cb(DBusConnection *conn, DBusDispatchStatus new_status, void *data)
-{
-       if (new_status == DBUS_DISPATCH_DATA_REMAINS)
-               g_idle_add(dispatch_idler_cb, conn);
+       return 0;
 }
 
-int register_dbus_methods(dbus_handle_h handle,
-               const char *object_path, const dbus_interface_s *interface,
-               void (*method_handle_received)(dbus_method_handle_h method_handle, void *data),
-               void *data)
+int dbus_handle_free_connection(dbus_handle_h handle)
 {
-       struct dbus_method_handle_s *mh;
-       struct dbus_handle_s *h = handle;
-       static bool set_dispatch = false;
-
-       if (!h || !(h->conn) || !object_path || !interface)
-               return -EINVAL;
+       dcl_dbus_handle();
+       dbus_handle_s *pdh = NULL;
+       GError *err = NULL;
+       GList *item = NULL;
+
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return -1;
+               }
+       }
 
-       mh = calloc(1, sizeof(struct dbus_method_handle_s));
-       if (!mh) {
-               _E("calloc() failed");
-               return -ENOMEM;
+       if (!dh->conn) {
+               _E("connection is NULL");
+               return 0;
        }
 
-       mh->handle = h;
-       mh->path = object_path;
-       mh->iface = interface;
-       mh->method_handle_received = method_handle_received;
-       mh->data = data;
+       pdh = dh;
 
-       h->method_handle_list = g_list_append(h->method_handle_list, mh);
+       /* disable dbus handler */
+       dbus_handle_lock(dh);
+       if (!pdh->conn) {
+               _E("conn is null");
+               free(pdh);
+               return 0;
+       }
 
-       if (!set_dispatch) {
-               set_dispatch = true;
+       /* flush everything */
+       if (!g_dbus_connection_flush_sync(pdh->conn, NULL, &err)) {
+               _E("failed to flush %s\n", err->message);
+               g_error_free(err);
+               err = NULL;
+       }
 
-               dbus_connection_set_watch_functions(h->conn,
-                               add_watch_cb, remove_watch_cb, toggle_watch_cb,
-                               NULL, NULL);
+       _D("list_names %u", g_list_length(pdh->list_names));
 
-               dbus_connection_set_timeout_functions(h->conn,
-                               add_timeout_cb, remove_timeout_cb, toggle_timeout_cb,
-                               NULL, NULL);
+       /* unown every well-knwon name */
+       if (pdh->list_names) {
+               dbus_name *dn = NULL;
+               for (item = g_list_first(pdh->list_names); item != NULL; item = g_list_next(item)) {
+                       dn = (dbus_name *)item->data;
+                       if (!dn)
+                               continue;
 
-               dbus_connection_set_dispatch_status_function(h->conn,
-                               dispatch_status_cb, NULL, NULL);
+                       /* _name_lost handler is disabled by g_bus_unown_name : ubuntu */
+                       _D("unown name id : %u", dn->id);
+                       g_bus_unown_name(dn->id);
+                       free(dn);
+               }
+               g_list_free(pdh->list_names);
+               pdh->list_names = NULL;
        }
 
-       dispatch_status_cb(h->conn, dbus_connection_get_dispatch_status(h->conn), NULL);
+       _D("list_object %u", g_list_length(pdh->list_object));
 
-       register_methods(mh);
+       /* unregister every object */
+       if (pdh->list_object) {
+               dbus_object_handle_s * oh = NULL;
+               //g_list_foreach(pdh->list_object, [] (gpointer data, gpointer user_data) {}, NULL);
+               for (item = g_list_first(pdh->list_object); item != NULL; item = g_list_next(item)) {
+                       oh = (dbus_object_handle_s *)item->data;
+                       if (!oh || !oh->list_ifaces)
+                               continue;
 
-       return 0;
-}
+                       _D("delete object path %s", oh->path);
 
-void unregister_dbus_methods(dbus_handle_h handle, dbus_method_handle_h method_handle)
-{
-       GList *l;
-       struct dbus_method_handle_s *item;
-       struct dbus_handle_s *h = handle;
-       struct dbus_method_handle_s *mh = method_handle;
-       bool found = false;
+                       /* unregister every interface, method handles */
+                       for (GList *iface = g_list_first(oh->list_ifaces); iface != NULL; iface = g_list_next(iface)) {
+                               dbus_interface_s *ih = (dbus_interface_s *)iface->data;
+                               if (!ih)
+                                       continue;
 
-       if (!h || !h->conn)
-               return;
-       if (!mh)
-               return;
+                               _D("delete object iface %s", ih->name);
 
-       for (l = h->method_handle_list ; l && (item = l->data) ;
-                       l = g_list_next(l), item = NULL) {
-               if (item == mh) {
-                       h->method_handle_list = g_list_remove(h->method_handle_list, item);
-                       found = true;
-                       break;
+                               if (ih->reg_id)
+                                       g_dbus_connection_unregister_object(pdh->conn, ih->reg_id);
+                       }
                }
        }
 
-       if (!found)
-               return;
+       /* close connection */
+       if (pdh->priv) {
+               _E("close private connection\n");
+
+               if (!g_dbus_connection_close_sync(pdh->conn, NULL, &err)) {
+                       _E("Error closing connection %s\n", err->message);
+                       g_error_free(err);
+                       err = NULL;
+               }
+       }
+
+       /* _free_func_object callback free the data */
+       //assert(g_list_length(pdh->list_names) == 0);
+       //assert(g_list_length(pdh->list_object) == 0);
+
+       g_object_unref(pdh->conn);
+
+       dbus_handle_unlock(dh);
+
+       if (dh->priv)
+               free(dh);
 
-       dbus_connection_unregister_object_path(h->conn, item->path);
-       free(item);
+       return 0;
+
+       // todo: signal ?
 }
 
-static int append_variant(DBusMessageIter *iter, const char *sig, char *param[])
+#define buf_cal_free_space(size, nwrite) ((size - nwrite - 1) > 0 ? (size - nwrite - 1) : 0)
+#define buf_block_size 8192
+
+#define buf_check_space_realloc(buf, nwrite, buf_len) do {\
+       if ((nwrite >= buf_len - 1024)) {\
+               if (buf_len >= buf_block_size * 10) {\
+                       _E("buf is too big to allocate. %d", buf_len);\
+               } else {\
+                       _E("buf_check_space_realloc");\
+                       char *tmp = NULL;\
+                       buf_len += buf_block_size;\
+                       tmp = (char *)realloc(buf, buf_len);\
+                       if (!tmp) {\
+                               _E("failed to realloc");\
+                       } else\
+                               buf = tmp;\
+               } \
+       } \
+} while (0);
+
+static int _check_brace(const char * expr)
 {
-       char *ch;
-       int i;
-       int int_type;
-       dbus_bool_t bool_type;
-       unsigned long long int64_type;
-       DBusMessageIter arr;
-       struct dbus_byte *byte;
+       int len = 0;
+       char qu[128];
+       int qucnt = 0;
 
-       if (!sig || !param)
-               return 0;
+       if (!expr)
+               return -1;
 
-       for (ch = (char *)sig, i = 0; *ch != '\0'; ++i, ++ch) {
-               switch (*ch) {
-               case 'b':
-                       bool_type = (atoi(param[i]) == 0 ? FALSE : TRUE);
-                       dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &bool_type);
-                       break;
-               case 'i':
-                       int_type = atoi(param[i]);
-                       dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &int_type);
-                       break;
-               case 'u':
-                       int_type = strtoul(param[i], NULL, 10);
-                       dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &int_type);
-                       break;
-               case 't':
-                       int64_type = atoll(param[i]);
-                       dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &int64_type);
-                       break;
-               case 's':
-                       dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &param[i]);
-                       break;
-               case 'a':
-                       ++ch;
-                       switch (*ch) {
-                       case 'y':
-                               ++i;
-                               dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &arr);
-                               byte = (struct dbus_byte *)param[i];
-                               dbus_message_iter_append_fixed_array(&arr, DBUS_TYPE_BYTE, &(byte->data), byte->size);
-                               dbus_message_iter_close_container(iter, &arr);
-                               break;
-                       default:
-                               break;
+       len = strlen(expr);
+
+       if (expr[0] != '(' && expr[0] != '{')
+               return -1;
+
+       for (int i = 0 ; i < len; ++i) {
+
+               if (expr[i] == '(' || expr[i] == '{') {
+                       qu[qucnt++] = expr[i];
+                       if (qucnt >= sizeof(qu)) {
+                               _E("queue is too large. %s", expr);
+                               return -1;
+                       }
+                       continue;
+               }
+
+               if (expr[i] == ')' || expr[i] == '}') {
+                       char ch;
+
+                       if (qucnt > 0)
+                               ch = qu[qucnt-1];
+                       else
+                               return -1;
+
+                       if (expr[i] == ')') {
+                               if (ch == '(') {
+                                       --qucnt;
+                               } else
+                                       return -1;
+                       } else if (expr[i] == '}') {
+                               if (ch == '{') {
+                                       --qucnt;
+                               } else
+                                       return -1;
+                       } else
+                               return -1;
+
+                       if (qucnt == 0) {
+                               return i + 1;
                        }
-                       break;
-               default:
-                       return -EINVAL;
                }
        }
 
-       return 0;
+       return -1;
 }
 
-int broadcast_dbus_signal(const char *path, const char *iface,
-               const char *name, const char *sig, char *param[])
+static int _get_xml_from_interfaces(char **xml, const dbus_interface_s *interfaces)
 {
-       DBusConnection *conn;
-       DBusMessage *msg;
-       DBusMessageIter iter;
-       int ret;
-
-       conn = get_dbus_connection();
-       if (!conn) {
-               _E("Failed to get dbus connection");
-               return -ECOMM;
+       int nwrite = 0;
+       int len_args;
+       char *buf = NULL;
+       const dbus_method_s *pmethod;
+       int buf_len = buf_block_size;
+
+       if (!interfaces) {
+               _E("interfaces is null");
+               return -1;
        }
 
-       msg = dbus_message_new_signal(path, iface, name);
-       if (!msg) {
-               _E("fail to allocate new %s.%s signal", iface, name);
-               return -EPERM;
+       // todo : check dbus naming rule for interface name. ?
+       if (!interfaces->name) {
+               _E("wrong interface name");
+               return -1;
+       }
+       if (!interfaces->list_methods) {
+               _E("no methods");
+               return -1;
        }
 
-       dbus_message_iter_init_append(msg, &iter);
-       ret = append_variant(&iter, sig, param);
-       if (ret < 0) {
-               _E("append_variant error(%d)", ret);
-               return -EPERM;
+       buf = (char *)malloc(buf_len);
+       if (!buf) {
+               _E("buf is null. not enough memory\n");
+               return -1;
        }
 
-       ret = dbus_connection_send(conn, msg, NULL);
-       dbus_message_unref(msg);
-       if (ret != TRUE) {
-               _E("dbus_connection_send error(%s:%s-%s)", path, iface, name);
-               return -ECOMM;
+       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "<node>""\n""\t""<interface name='%s'>""\n", interfaces->name);
+
+       /* members */
+       for (GList *item = g_list_first(interfaces->list_methods); item != NULL; item = g_list_next(item)) {
+               pmethod = (const dbus_method_s *)item->data;
+               if (!pmethod)
+                       continue;
+
+               /* check free space of buf */
+               buf_check_space_realloc(buf, nwrite, buf_len);
+
+               if (pmethod->signature_in == NULL && pmethod->signature_out == NULL) {
+                       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""<method name='%s'/>""\n", pmethod->member);
+                       continue;
+               }
+
+               /* <method name='###'> */
+               nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""<method name='%s'>""\n", pmethod->member);
+
+               /* in args */
+               len_args = pmethod->signature_in ? strlen(pmethod->signature_in) : 0;
+               for (int m = 0; m < len_args; ++m) {
+                       // todo
+                       // array a(), as, ay ?
+                       if (pmethod->signature_in[m] == 'a') {
+                               int ei; //end index
+                               ei = _check_brace(pmethod->signature_in + m + 1);
+                               if (ei > 0) {
+                                       char tmp[128] = {0,};
+                                       strncpy(tmp, pmethod->signature_in + m, ei + 1);
+                                       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%s' name='arg%d' direction='in'/>""\n", tmp, m);
+                                       m += ei;
+                                       continue;
+                               } else {
+                                       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c%c' name='arg%d' direction='in'/>""\n", pmethod->signature_in[m], pmethod->signature_in[m+1], m);
+                                       m += 1;
+                                       continue;
+                               }
+                       }
+                       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c' name='arg%d' direction='in'/>""\n", pmethod->signature_in[m], m);
+               }
+
+               /* out args */
+               len_args = pmethod->signature_out ? strlen(pmethod->signature_out) : 0;
+               for (int m = 0; m < len_args; ++m) {
+                       // array
+                       // todo: container type
+                       if (pmethod->signature_out[m] == 'a') {
+                               int ei; //end index
+                               ei = _check_brace(pmethod->signature_out + m + 1);
+                               if (ei > 0) {
+                                       char tmp[128] = {0,};
+                                       strncpy(tmp, pmethod->signature_out + m, ei + 1);
+                                       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%s' name='arg%d' direction='out'/>""\n", tmp, m);
+                                       m += ei;
+                                       continue;
+                               } else {
+                                       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c%c' name='arg%d' direction='out'/>""\n", pmethod->signature_out[m], pmethod->signature_out[m+1], m);
+                                       m += 1;
+                                       continue;
+                               }
+                       }
+                       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c' name='arg%d' direction='out'/>""\n", pmethod->signature_out[m], m);
+               }
+
+               /* </method> */
+               nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""</method>""\n");
        }
 
+       nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t""</interface>""\n""</node>""");
+
+       *xml = buf;
+
+       /* todo: delete log */
+#if 0
+       if (nwrite <= 512)
+               _E("%s", buf);
+       else
+               _E("%s", buf + nwrite - 512);
+#endif
        return 0;
 }
 
-static void release_signal_info(struct signal_info *info)
+static gint _compare_dbus_object(gconstpointer a, gconstpointer b)
 {
-       if (info) {
-               if (info->free_func)
-                       info->free_func(info->data);
-               free(info);
-       }
+       dbus_object_handle_s * pa = (dbus_object_handle_s *)a;
+       if (!pa->path || !((const char*)b))
+               return -1;
+       return strcmp(pa->path, (const char*)b);
 }
 
-static struct signal_info *find_signal_info(const char *path,
-               const char *iface, const char *name, dbus_signal_received cb)
+static gint _compare_dbus_interface(gconstpointer a, gconstpointer b)
 {
-       GList *l;
-       size_t path_len, iface_len, name_len;
-       struct signal_info *info;
-
-       path_len = strlen(path) + 1;
-       iface_len = strlen(iface) + 1;
-       name_len = strlen(name) + 1;
+       dbus_interface_s * pa = (dbus_interface_s *)a;
+       if (!pa->name || !((const char*)b))
+               return -1;
+       return strcmp(pa->name, (const char*)b);
+}
 
-       for (l = signal_handler_list ; l && (info = l->data) ; l = g_list_next(l), info = NULL) {
-               if (strncmp(info->path, path, path_len))
-                       continue;
-               if (strncmp(info->iface, iface, iface_len))
-                       continue;
-               if (strncmp(info->name, name, name_len))
-                       continue;
-               if (cb && info->cb != cb)
-                       continue;
-               return info;
-       }
+static gint _compare_dbus_interface_by_id(gconstpointer a, gconstpointer b)
+{
+       dbus_interface_s * pa = (dbus_interface_s *)a;
+       if (!pa->reg_id || !((guint*)b))
+               return -1;
+       return !(pa->reg_id == *((guint*)b));
+}
 
-       return NULL;
+static gint _compare_dbus_method(gconstpointer a, gconstpointer b)
+{
+       dbus_method_s *pa = (dbus_method_s*)a;
+       if (!pa->member || !((const char*)b))
+               return -1;
+       return strcmp(pa->member, (const char*)b);
 }
 
-static void call_signal_callbacks(const char *path,
-               const char *iface, const char *name, DBusMessage *msg)
+dbus_object_handle_s * _dbus_handle_lookup_object(GList *list_obj, const char *obj_path)
 {
-       GList *l;
-       size_t path_len, iface_len, name_len;
-       struct signal_info *info;
+       if (!list_obj || !obj_path)
+               return NULL;
 
-       path_len = strlen(path) + 1;
-       iface_len = strlen(iface) + 1;
-       name_len = strlen(name) + 1;
+       GList *item = g_list_find_custom(list_obj, obj_path, _compare_dbus_object);
+       if (!item)
+               return NULL;
 
-       for (l = signal_handler_list ; l && (info = l->data) ; l = g_list_next(l), info = NULL) {
-               _I("path(%s), info(%s), name(%s)", info->path, info->iface, info->name);
-               if (strncmp(info->path, path, path_len))
-                       continue;
-               if (strncmp(info->iface, iface, iface_len))
-                       continue;
-               if (strncmp(info->name, name, name_len))
-                       continue;
-               if (info->cb)
-                       info->cb(NULL, path, iface, name, msg, info->data);
-       }
+       return (dbus_object_handle_s *)item->data;
 }
 
-static int make_match(const char *path, const char *iface,
-               const char *name, char *buf, size_t len)
+dbus_interface_s * _dbus_handle_lookup_interface(GList *list_iface, const char *iface_name)
 {
-       if (!path || !iface || ! name || !buf)
-               return -EINVAL;
+       if (!list_iface || !iface_name)
+               return NULL;
 
-       snprintf(buf, len,
-                       "type='signal',path=%s,interface=%s,member=%s",
-                       path, iface, name);
+       GList *item = g_list_find_custom(list_iface, iface_name, _compare_dbus_interface);
+       if (!item)
+               return NULL;
 
-       return 0;
+       return (dbus_interface_s *)item->data;
 }
 
-void unregister_dbus_signal_all(void)
+dbus_interface_s * _dbus_handle_lookup_interface_by_id(GList *list_iface, guint id)
 {
-       GList *l, *l_next;
-       struct signal_info *info;
-       char match[256];
-       int ret;
-       DBusConnection *conn;
-
-       for (l = signal_handler_list, l_next = g_list_next(l) ;
-                       l && (info = l->data) ;
-                       l = l_next, l_next = g_list_next(l), info = NULL) {
-               signal_handler_list = g_list_remove(signal_handler_list, info);
+       if (!list_iface || !id)
+               return NULL;
 
-               ret = make_match(info->path, info->iface, info->name,
-                               match, sizeof(match));
-               if (ret == 0) {
-                       conn = get_dbus_connection();
-                       if (conn)
-                               dbus_bus_remove_match(conn, match, NULL);
-               }
+       GList *item = g_list_find_custom(list_iface, &id, _compare_dbus_interface_by_id);
+       if (!item)
+               return NULL;
 
-               release_signal_info(info);
-       }
+       return (dbus_interface_s *)item->data;
 }
 
-static DBusHandlerResult signal_filter(DBusConnection *conn, DBusMessage *msg, void *data)
+dbus_method_s * _dbus_handle_lookup_method(GList *list_methods, const char *method_name)
 {
-       const char *path, *iface, *name;
-
-       if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
-               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-       path = dbus_message_get_path(msg);
-       iface = dbus_message_get_interface(msg);
-       name = dbus_message_get_member(msg);
+       if (!list_methods || !method_name)
+               return NULL;
 
-       call_signal_callbacks(path, iface, name, msg);
+       GList *item = g_list_find_custom(list_methods, method_name, _compare_dbus_method);
+       if (!item)
+               return NULL;
 
-       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+       return (dbus_method_s *)item->data;
 }
 
-int register_dbus_signal(const char *path,
-               const char *interface, const char *name,
-               dbus_signal_received cb, void *data,
-               destroy_notified free_func)
+static void _free_func_object(gpointer data)
 {
-       struct signal_info *info;
-       DBusConnection *conn;
-       static int add_filter = 0;
-       char match[256];
-       int ret;
+       dbus_interface_s *ih = (dbus_interface_s *)data;
+       dbus_object_handle_s *oh = NULL;
 
-       conn = get_dbus_connection();
-       if (!conn) {
-               _E("Failed to get dbus connection");
-               return -ECOMM;
+       if (!ih) {
+               _E("interface handle is null");
+               assert(0); // something wrong
+               return ;
        }
 
-       info = find_signal_info(path, interface, name, cb);
-       if (info)
-               return -EEXIST;
+       _E("unregister interface %s", ih->name);
+
+       /* just free list, not data(static dbus_method_s) */
+       g_list_free(ih->list_methods);
 
-       info = calloc(1, sizeof(struct signal_info));
-       if (!info) {
-               _E("calloc failed");
-               return -ENOMEM;
+       oh = ih->oh;
+       if (!oh) {
+               _E("object handle is null");
+               assert(0); // something wrong
+               return ;
        }
 
-       info->path = path;
-       info->iface = interface;
-       info->name = name;
-       info->cb = cb;
-       info->free_func = free_func;
-       info->data = data;
+       /* remove ih from list_ifaces */
+       oh->list_ifaces = g_list_remove(oh->list_ifaces, ih);
 
-       if (add_filter == 0) {
-               add_filter = 1;
-               dbus_connection_add_filter(conn, signal_filter, NULL, NULL);
-       }
+       /* interface_s is copy of interface_u */
+       free(ih);
 
-       ret = make_match(path, interface, name, match, sizeof(match));
-       if (ret < 0) {
-               _E("Failed to make match (%d)", ret);
-               free(info);
-               return ret;
+       /* remove oh from list_object */
+       if (!oh->list_ifaces) {
+               oh->dh->list_object = g_list_remove(oh->dh->list_object, oh);
+               free(oh);
        }
-       dbus_bus_add_match(conn, match, NULL);
+}
 
-       signal_handler_list = g_list_append(signal_handler_list, info);
+static int _dbus_handle_attach_object(dbus_handle_s *dh, const char *obj_path, dbus_interface_s *iface)
+{
+       dbus_object_handle_s *oh = NULL;
 
+       if (!dh || !obj_path || !iface) {
+               _E("failed to attache object. wrong parameter");
+               return -1;
+       }
+
+       /* find object handle */
+       if (dh->list_object)
+               oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
+
+       if (!oh) {
+               oh = (dbus_object_handle_s*)calloc(1, sizeof(dbus_object_handle_s));
+               if (!oh) {
+                       _E("failed to calloc");
+                       return -1;
+               }
+               oh->dh = dh;
+               oh->path = obj_path;
+
+               /* attach object */
+               dh->list_object = g_list_prepend(dh->list_object, oh);
+       }
+
+       iface->oh = oh;
+       /* attach interface */
+       oh->list_ifaces = g_list_prepend(oh->list_ifaces, iface);
+
+       return 0;
+}
+
+/* libgio verify path and interface */
+static void _method_call_handler(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       dbus_interface_s *iface_s = (dbus_interface_s *)user_data;
+       const dbus_method_s *methods;
+       GVariant *result = NULL;
+
+       /* todo: ghash ? */
+       methods = _dbus_handle_lookup_method(iface_s->list_methods, name);
+       if (methods) {
+               result = methods->func(conn, sender, path, iface, name, param, invocation, get_dh_from_oh(iface_s->oh));
+
+               /* async, maybe they will reply...maybe.. */
+               if (!result) {
+                       _E("finish method handle : NULL");
+                       return ;
+               }
+       } else {
+               _E("no methods");
+       }
+
+       g_dbus_method_invocation_return_value(invocation, result);
+       //if (g_variant_is_of_type(result, G_VARIANT_TYPE_TUPLE)) {
+       //      //_E("TUPLE %s", g_variant_get_type_string(result));
+       //      g_dbus_method_invocation_return_value(invocation, result);
+       //}
+       //else if (g_variant_is_container(result)) {
+       //      /* todo: we don't have any plan to using variant type for reply */
+       //      _E("CONTAINER %s", g_variant_get_type_string(result));
+       //      g_dbus_method_invocation_return_value(invocation, result);
+       //      //g_dbus_method_invocation_return_value(invocation, g_variant_new("(v)", result));
+       //} else {
+       //      _E("Type is not Container : %s", g_variant_get_type_string(result));
+       //}
+}
+
+static GDBusInterfaceVTable path_vtable = {_method_call_handler};
+
+
+/*
+before register object, attach object into dbus handle
+_dbus_handle_attach_object()
+*/
+static int _dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, dbus_interface_s *iface)
+{
+       dcl_dbus_handle();
+       int ret = 0;
+       char *buf = NULL;
+       GError *err = NULL;
+       GDBusNodeInfo * nodeinfo = NULL;
+       GDBusInterfaceInfo *ifaceinfo = NULL;
+
+       if (!obj_path || !iface) {
+               _E("wrong parameter\n");
+               return -1;
+       }
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return -1;
+               }
+       }
+       if (!dh->conn) {
+               _E("connection is null\n");
+               return -1;
+       }
+
+       ret = _get_xml_from_interfaces(&buf, iface);
+       if (ret < 0) {
+               _E("failed to make xml format");
+               goto err;
+       }
+
+       /* todo: delete this */
+#if 0
+       if (strlen(buf) <= 512) {
+               _E("%s", buf);
+       } else {
+               _E("%s", buf + strlen(buf) - 512);
+       }
+#endif
+
+       nodeinfo = g_dbus_node_info_new_for_xml(buf, &err);
+       if (!nodeinfo || err) {
+               _E("failed to make introspection data:err:%s:xml:%s\n", err->message, buf);
+               ret = -1;
+               goto err;
+       }
+
+       ifaceinfo = g_dbus_node_info_lookup_interface(nodeinfo, iface->name);
+       if (!ifaceinfo) {
+               _E("failed to g_dbus_node_info_lookup_interface");
+               ret = -1;
+               goto err;
+       }
+
+       /*
+               path own single interface
+               if interface is already registered, then failed.
+               g_dbus_connection_register_object ref(ifaceinfo) now, unref if object is unregistered
+       */
+       ret = g_dbus_connection_register_object(dh->conn, obj_path, ifaceinfo/*ref 2*/, &path_vtable, (void*)iface,
+               _free_func_object,
+               &err);
+       if (err) {
+               _E("failed to register object:err:%s:\n", err->message);
+               ret = -1;
+               goto err;
+       }
+
+       iface->reg_id = ret;
+       iface->modified = FALSE;
+
+err:
+       /* todo: detach object */
+       //_dbus_handle_detach_object(dh, obj_path, iface);
+       /* attach interface before register object */
+       /*ret = _dbus_handle_detach_object(dh, obj_path, iface);
+       if (ret < 0) {
+               _E("failed to attach object");
+               goto err;
+       }*/
+
+       if (nodeinfo)
+               g_dbus_node_info_unref(nodeinfo);
+       if (buf)
+               free(buf);
+       if (err)
+               g_error_free(err);
+
+       return ret;
+}
+
+/*
+register same interface at once
+
+if interface is constructed by multiple methods,
+also it is not possible to make methods struct at once,
+
+use dbus_handle_add_dbus_object(), dbus_handle_register_dbus_object_all().
+
+return reg_id
+*/
+int dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u)
+{
+       dcl_dbus_handle();
+       int ret = 0;
+       dbus_interface_s *iface = NULL;
+
+       if (!obj_path || !iface_u) {
+               _E("wrong parameter\n");
+               return -1;
+       }
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return -1;
+               }
+       }
+       if (!dh->conn) {
+               _E("connection is null\n");
+               return -1;
+       }
+
+       /* check registered interface */
+       if (dh->list_object) {
+               dbus_object_handle_s *oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
+               if (oh) {
+                       dbus_interface_s *ih = _dbus_handle_lookup_interface(oh->list_ifaces, iface_u->name);
+                       if (ih) {
+                               _E("path %s, interface %s already registered", obj_path, iface_u->name);
+                               return -1;
+                       }
+               }
+       }
+
+       iface = _iface_u_to_s(iface_u);
+       if (!iface) {
+               _E("failed to _iface_u_to_s");
+               return -1;
+       }
+
+       /* attach interface before register object */
+       ret = _dbus_handle_attach_object(dh, obj_path, iface);
+       if (ret < 0) {
+               _E("failed to attach object");
+               goto err;
+       }
+
+       ret = _dbus_handle_register_dbus_object(dh, obj_path, iface);
+       if (ret <= 0) {
+               _E("failed to register dbus object%d", ret);
+               goto err;
+       }
+err:
+       return ret;
+}
+
+int dbus_handle_unregister_dbus_object(dbus_handle_h handle, const char *obj_path)
+{
+       dcl_dbus_handle();
+       dbus_object_handle_s *oh = NULL;
+       int ret = 0;
+
+       if (!obj_path) {
+               return -1;
+       }
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return -1;
+               }
+       }
+       if (!dh->list_object) {
+               _E("list_object is empty");
+               return 0;
+       }
+
+       oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
+       if (!oh) {
+               _E("no object with name %s", obj_path);
+               return -1;
+       }
+
+       /* unregister every interface of object*/
+       for (GList *item = g_list_first(oh->list_ifaces); item != NULL; item = g_list_next(item)) {
+               dbus_interface_s *ih = item->data;
+               if (!ih) {
+                       _E("this is error");
+                       assert(0);
+               }
+
+               /* remove ih from list_ifaces */
+               if (!ih->reg_id) {
+                       item = g_list_previous(item);
+
+                       /* remove and free link */
+                       oh->list_ifaces = g_list_remove(oh->list_ifaces, ih);
+
+                       /* free list_methods */
+                       g_list_free(ih->list_methods);
+
+                       /* free data */
+                       free(ih);
+                       continue;
+               }
+
+               /* unregister object by id */
+               ret = g_dbus_connection_unregister_object(dh->conn, ih->reg_id);
+               if (!ret)
+                       _E("failed to unregister object %s, interface %s, regid %d", oh->path, ih->name, ih->reg_id);
+       }
+
+       return 0;
+}
+
+/*
+add object temporarily.
+dbus_handle_register_dbus_object_all will register every objects on connection.
+
+return registered method count
+*/
+int dbus_handle_add_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u)
+{
+       dcl_dbus_handle();
+       dbus_object_handle_s *oh = NULL;
+       dbus_interface_s *ih = NULL;
+       int cnt;
+
+       if (!obj_path || !iface_u) {
+               _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u);
+               return -1;
+       }
+       if (iface_u && (!iface_u->name || !iface_u->methods)) {
+               _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u);
+               return -1;
+       }
+
+       cnt = iface_u->nr_methods;
+
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return -1;
+               }
+       }
+
+       if (!dh->conn) {
+               _E("failed to register method. connection is null\n");
+               return -1;
+       }
+
+       /* if there are no object list, just add */
+       if (!dh->list_object) {
+               if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
+                       _E("failed to attach object");
+                       return -1;
+               }
+               goto out;
+       }
+
+       oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
+       /* if there are no matched object, just add */
+       if (!oh) {
+               if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
+                       _E("failed to attach object");
+                       return -1;
+               }
+               goto out;
+       }
+
+       /* this is an error, interface must have one or more item ? */
+       if (!oh->list_ifaces) {
+               _E("error. list_ifaces is null\n");
+               assert(0);
+               goto out;
+       }
+
+       ih = _dbus_handle_lookup_interface(oh->list_ifaces, iface_u->name);
+       /* if there are no matched interface, just add */
+       if (!ih) {
+               if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
+                       _E("failed to attach object");
+                       return -1;
+               }
+               goto out;
+       }
+
+       /*  todo:
+               1. unregister interface
+               2. update interface and methods
+               3. register interface
+       */
+       if (ih->reg_id) {
+               _E("interface already registered, ignore new interface");
+               return -1;
+       }
+
+       /* attach new methods */
+       cnt = 0;
+       for (int i = 0; i < iface_u->nr_methods; ++i) {
+               GList *item = g_list_find_custom(g_list_first(ih->list_methods), iface_u->methods[i].member, _compare_dbus_method);
+               if (!item) {
+                       //_D("attached %s", iface_u->methods[i].member);
+                       ih->list_methods = g_list_prepend(ih->list_methods, (void*)(iface_u->methods + i));
+                       ++cnt;
+               }
+       }
+
+       if (cnt)
+               ih->modified = TRUE;
+
+out:
+       /*todo: delete debugging log */
+       //if (dh && dh->list_object)
+       //      _D("obj list len %d", g_list_length(dh->list_object));
+       //if (oh && oh->list_ifaces)
+       //      _D("iface list len %d", g_list_length(oh->list_ifaces));
+       //if (ih && ih->list_methods)
+       //      _D("method list len %d", g_list_length(ih->list_methods));
+
+       return cnt;
+}
+
+int dbus_handle_register_dbus_object_all(dbus_handle_h handle)
+{
+       dcl_dbus_handle();
+       dbus_object_handle_s *oh = NULL;
+       dbus_interface_s *ih = NULL;
+       int ret = 0;
+
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return -1;
+               }
+       }
+       if (!dh->conn) {
+               _E("connection is null\n");
+               return -1;
+       }
+
+       if (!dh->list_object) {
+               _E("obj list is empty");
+               return -1;
+       }
+
+       /*if (dh && dh->list_object)
+               _D("obj list len %d", g_list_length(dh->list_object));*/
+
+       for (GList *item = g_list_first(dh->list_object); item != NULL; item = g_list_next(item)) {
+               oh = (dbus_object_handle_s *)item->data;
+
+               if (!oh) {
+                       _E("something wrong");
+                       assert(0);
+               }
+               if (!oh->list_ifaces) {
+                       _E("path %s: list_ifaces are null", oh->path);
+                       goto err;
+               }
+
+               //_D("iface list len %d", g_list_length(oh->list_ifaces));
+
+               for (GList *li = g_list_first(oh->list_ifaces); li != NULL; li = g_list_next(li)) {
+                       ih = (dbus_interface_s *)li->data;
+
+                       /* if there are no modification, goto next */
+                       if (!ih->modified)
+                               continue;
+
+                       /* todo: if already registered interface, unregister first */
+
+                       /*_E("interface %s:", ih->name);
+                       if (ih && ih->list_methods)
+                               _D("method list len %d", g_list_length(ih->list_methods));*/
+
+                       ret = _dbus_handle_register_dbus_object(dh, oh->path, ih);
+                       if (ret <= 0)
+                               _E("failed to register dbus object%d", ret);
+
+               }
+       }
        return 0;
+err:
+
+       // todo: delete all updates
+
+       return -1;
+}
+
+static void _free_func_signal(gpointer data)
+{
+       //_D("free signal subscribe");
+}
+
+guint subscribe_dbus_signal(dbus_handle_h handle, const char *path,
+                                                       const char *iface, const char *name,
+                                                       GDBusSignalCallback cb, void *data,
+                                                       destroy_notified free_func)
+{
+       dcl_dbus_handle();
+
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return 0;
+               }
+       }
+
+       if (!dh->conn) {
+               _E("connection is null. check bus status");
+               return 0;
+       }
+       return g_dbus_connection_signal_subscribe(dh->conn, NULL, iface, name, path, NULL, G_DBUS_SIGNAL_FLAGS_NONE, cb, data, _free_func_signal);
+}
+
+void unsubscribe_dbus_signal(dbus_handle_h handle, guint id)
+{
+       dcl_dbus_handle();
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return ;
+               }
+       }
+
+       if (!dh->conn) {
+               _E("connection is null. check bus status");
+               return ;
+       }
+
+       g_dbus_connection_signal_unsubscribe(dh->conn, id);
+}
+
+int _check_type_string_is_container(const char *signature)
+{
+       if (!signature)
+               return FALSE;
+
+       switch (signature[0]) {
+       case 'a':
+       case 'm':
+       case 'r':
+       case '(':
+       case '{':
+       case 'v':
+               return TRUE;
+       default:
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+GVariant *dbus_handle_make_simple_array(const char *sig, int *param)
+{
+       GVariantBuilder *builder = NULL;
+       GVariant *var = NULL;
+       char format[256];
+       int i = 0;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE(sig));
+       if (!builder) {
+               _E("failed to g_variant_builder_new");
+               return NULL;
+       }
+
+       while (param[i])
+               g_variant_builder_add(builder, "i", param[i++]);
+
+       snprintf(format, sizeof(format) - 1, "(%s)", sig);
+       var = g_variant_new(format, builder);
+       g_variant_builder_unref(builder);
+       return var;
+}
+
+/* todo: looks like garbage... */
+static GVariant* _append_variant(const char *signature, const char *param[])
+{
+       char *ch;
+       int i;
+       int pi;
+       int int_type;
+       gboolean bool_type;
+       unsigned long long int64_type;
+       GVariant *ret;
+       int len;
+       char container[255];// The maximum length of a signature is 255.
+       const char *sig = signature;
+       GVariantBuilder *builder = NULL;
+
+       if (!signature || !param)
+               return 0;
+
+       /* workaround for user fault "(i) != i" but we treat this as same signature */
+       /* G_VARIANT_TYPE("si") return NULL */
+       /* todo: actually user have to use correct signature */
+       if (!_check_type_string_is_container(signature)) {
+               snprintf(container, sizeof(container) - 1, "(%s)", signature);
+               sig = container;
+       }
+       if (!g_variant_type_is_container(G_VARIANT_TYPE(sig))) {
+               _E("signature (%s) is not container type", signature);
+       }
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE(sig));
+       len = strlen(sig);
+       pi = 0;
+       for (ch = (char *)sig, i = 0; i < len; ++i, ++ch) {
+               switch (*ch) {
+               case '(':
+               case ')':
+                       continue;
+               case 'b':
+                       bool_type = (atoi(param[pi++]) == 0 ? FALSE : TRUE);
+                       g_variant_builder_add(builder, "b", bool_type);
+                       break;
+               case 'i':
+                       int_type = atoi(param[pi++]);
+                       g_variant_builder_add(builder, "i", int_type);
+                       break;
+               case 'u':
+                       int_type = strtoul(param[pi++], NULL, 10);
+                       g_variant_builder_add(builder, "u", int_type);
+                       break;
+               case 't':
+                       int64_type = atoll(param[pi++]);
+                       g_variant_builder_add(builder, "t", int64_type);
+                       break;
+               case 's':
+                       g_variant_builder_add(builder, "s", param[pi++]);
+                       break;
+               case 'a':
+                       ++ch;
+                       switch (*ch) {
+                       case 'y':
+                               g_variant_builder_add(builder, "^ay", param[pi++]);
+                               ++i;
+                               break;
+                       default:
+                               break;
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+       ret = g_variant_builder_end(builder);
+       g_variant_builder_clear(builder);
+       g_variant_builder_unref(builder);
+
+       return ret;
+}
+
+int dbus_handle_broadcast_dbus_signal(const char *path,
+                                                               const char *iface, const char *name,
+                                                               const char *signature, const char *param[])
+{
+       dbus_handle_s *dh = NULL;
+       GError *err = NULL;
+       gboolean ret = 0;
+       GVariant *var = NULL;
+
+       dh = _dbus_handle_get_default_connection();
+       if (!dh) {
+               _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+               return -1;
+       }
+
+       if (signature && param)
+               var = _append_variant(signature, param);
+       ret = g_dbus_connection_emit_signal(dh->conn, NULL, path, iface, name, var, &err);
+       if (err) {
+               _E("%d %s\n", ret, err ? err->message : NULL);
+               g_error_free(err);
+       }
+
+       return ret;
+}
+
+int dbus_handle_broadcast_dbus_signal_var(const char *path,
+                                                                                       const char *iface, const char *name,
+                                                                                       GVariant *param)
+{
+       dbus_handle_s *dh = NULL;
+       GError *err = NULL;
+       gboolean ret = 0;
+
+       dh = _dbus_handle_get_default_connection();
+       if (!dh) {
+               _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+               return -1;
+       }
+
+       ret = g_dbus_connection_emit_signal(dh->conn, NULL, path, iface, name, param, &err);
+       if (err) {
+               _E("%d %s\n", ret, err ? err->message : NULL);
+               g_error_free(err);
+       }
+
+       return ret;
+}
+
+GVariant *dbus_method_sync_with_reply(const char *dest, const char *path,
+                                                                               const char *iface, const char *method,
+                                                                               const char *signature, const char *param[])
+{
+       GError *err = NULL;
+       GVariant * var = NULL;
+       GVariant * ret = NULL;
+       dbus_handle_s *dh = NULL;
+
+       if (!dest || !path || !iface || !method) {
+               _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
+               return NULL;
+       }
+
+       dh = _dbus_handle_get_default_connection();
+       if (!dh) {
+               _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+               return NULL;
+       }
+
+       if (signature && param)
+               var = _append_variant(signature, param);
+
+       ret = g_dbus_connection_call_sync(dh->conn,
+               dest, path, iface, method,
+               var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err);
+       if (!ret || err) {
+               if (err) {
+                       _E("failed to g_dbus_connection_call_sync:%s", err->message);
+                       g_error_free(err);
+               } else {
+                       _E("failed to g_dbus_connection_call_sync");
+                       g_variant_unref(var);
+               }
+               return NULL;
+       }
+
+       return ret;
+}
+
+GVariant *dbus_method_sync_with_reply_var(const char *dest, const char *path,
+       const char *iface, const char *method, GVariant *var)
+{
+       GError *err = NULL;
+       GVariant * ret = NULL;
+       dbus_handle_s *dh = NULL;
+
+       if (!dest || !path || !iface || !method) {
+               _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
+               if (var)
+                       g_variant_unref(var);
+               return NULL;
+       }
+
+       dh = _dbus_handle_get_default_connection();
+       if (!dh) {
+               _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+               if (var)
+                       g_variant_unref(var);
+               return NULL;
+       }
+
+       ret = g_dbus_connection_call_sync(dh->conn,
+                                                                               dest, path, iface, method,
+                                                                               var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err);
+       if (!ret || err) {
+               if (err) {
+                       _E("failed to g_dbus_connection_call_sync:%s", err->message);
+                       g_error_free(err);
+               } else {
+                       _E("failed to g_dbus_connection_call_sync");
+               }
+               return NULL;
+       }
+
+       return ret;
 }
 
-int unregister_dbus_signal(const char *path,
-               const char *interface, const char *name,
-               dbus_signal_received cb)
+gint* dbus_handle_get_unix_fd_list(GDBusMethodInvocation *invocation, int *size)
 {
-       struct signal_info *info;
-       DBusConnection *conn;
-       char match[256];
-       int ret;
+       GUnixFDList *fd_list = NULL;
+       int length = 0;
 
-       conn = get_dbus_connection();
-       if (!conn) {
-               _E("Failed to get dbus connection");
-               return -ECOMM;
+       fd_list = g_dbus_message_get_unix_fd_list(g_dbus_method_invocation_get_message(invocation));
+
+       if (!fd_list) {
+               _E("failed to g_unix_fd_list_get_length: fd_list is null");
+               return NULL;
        }
 
-       info = find_signal_info(path, interface, name, cb);
-       if (!info)
-               return -ENOENT;
+       length = g_unix_fd_list_get_length(fd_list);
+       if (length == 0) {
+               _E("failed to g_unix_fd_list_get_length: list size is 0");
+               return NULL;
+       }
+       if (size)
+               *size = length;
 
-       signal_handler_list = g_list_remove(signal_handler_list, info);
-       release_signal_info(info);
+       return g_unix_fd_list_steal_fds(fd_list, NULL);
+}
 
-       ret = make_match(path, interface, name, match, sizeof(match));
-       if (ret < 0) {
-               _E("Failed to make match (%d)", ret);
-               return ret;
+GVariant *dbus_method_with_unix_fd_list_sync_with_reply(const char *dest, const char *path,
+                                                                                                               const char *iface, const char *method,
+                                                                                                               const char *signature, const char *param[],
+                                                                                                               int *in_fdlist, int in_size,
+                                                                                                               int **out_fdlist, int *out_size)
+{
+       GError *err = NULL;
+       GVariant * var = NULL;
+       GVariant * ret = NULL;
+       dbus_handle_s *dh = NULL;
+       GDBusProxy *proxy = NULL;
+       GUnixFDList *g_infdlist = NULL;
+       GUnixFDList *g_outfdlist = NULL;
+
+       if (!dest || !path || !iface || !method) {
+               _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
+               return NULL;
+       }
+       if (in_fdlist && in_size == 0) {
+               _E("wrong in_fdlist is not null but in_size is 0");
+               return NULL;
+       }
+
+       dh = _dbus_handle_get_default_connection();
+       if (!dh) {
+               _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+               return NULL;
        }
 
-       dbus_bus_remove_match(conn, match, NULL);
+       if (signature && param)
+               var = _append_variant(signature, param);
+
+       proxy = g_dbus_proxy_new_sync(dh->conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dest, path, iface, NULL, &err);
+       if (!proxy) {
+               if (err) {
+                       _E("failed to proxy_new_sync(%s)\n", err->message);
+                       g_error_free(err);
+               } else {
+                       _E("failed to proxy_new_sync\n");
+                       if (var)
+                               g_variant_unref(var);
+               }
+       }
 
-       return 0;
+       /* append fd */
+       if (in_fdlist) {
+               g_infdlist = g_unix_fd_list_new_from_array(in_fdlist, in_size);
+               if (!g_infdlist) {
+                       _E("failed to g_unix_fd_list_new_from_array\n");
+                       goto out;
+               }
+               //g_infdlist = g_unix_fd_list_new();
+               //if (g_unix_fd_list_append(g_infdlist, in_fdlist[0], &err) < 0) {
+       }
+
+       ret = g_dbus_proxy_call_with_unix_fd_list_sync(proxy, method, var, G_DBUS_CALL_FLAGS_NONE, -1,
+               g_infdlist, &g_outfdlist, NULL, &err);
+       if (!ret || err) {
+               if (err) {
+                       _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:%s", err->message);
+                       g_error_free(err);
+               } else {
+                       _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:");
+                       if (var)
+                               g_variant_unref(var);
+                       if (g_infdlist)
+                               g_object_unref(g_infdlist);
+               }
+               goto out;
+       }
+
+       /* fds to out array */
+       if (g_outfdlist) {
+               *out_size = g_unix_fd_list_get_length(g_outfdlist);
+               if (*out_size == 0)
+                       goto out;
+
+               *out_fdlist = g_unix_fd_list_steal_fds(g_outfdlist, NULL);
+       }
+
+out:
+       if (g_outfdlist)
+               g_object_unref(g_outfdlist);
+       if (proxy)
+               g_object_unref(proxy);
+
+       return ret;
 }
 
-int call_dbus_method_sync(const char *dest, const char *path,
-               const char *interface, const char *method,
-               const char *sig, char *param[], int timeout,
-               DBusMessage **reply)
+GVariant *dbus_method_with_unix_fd_list_sync_with_reply_var(const char *dest, const char *path,
+                                                                                                                       const char *iface, const char *method,
+                                                                                                                       GVariant *param,
+                                                                                                                       int *in_fdlist, int in_size,
+                                                                                                                       int **out_fdlist, int *out_size)
 {
-       DBusConnection *conn;
-       DBusMessage *msg;
-       DBusMessageIter iter;
-       DBusMessage *rep;
-       DBusError err;
-       int r;
+       GError *err = NULL;
+       GVariant * ret = NULL;
+       dbus_handle_s *dh = NULL;
+       GDBusProxy *proxy = NULL;
+       GUnixFDList *g_infdlist = NULL;
+       GUnixFDList *g_outfdlist = NULL;
+
+       if (!dest || !path || !iface || !method) {
+               _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
+               return NULL;
+       }
+       if (in_fdlist && in_size == 0) {
+               _E("wrong in_fdlist is not null but in_size is 0");
+               return NULL;
+       }
 
-       if (!dest || !path || !interface || !method || !reply)
-               return -EINVAL;
+       dh = _dbus_handle_get_default_connection();
+       if (!dh) {
+               _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+               return NULL;
+       }
 
-       conn = get_dbus_connection();
-       if (!conn) {
-               _E("Failed to get dbus connection");
-               return -ECOMM;
+       proxy = g_dbus_proxy_new_sync(dh->conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dest, path, iface, NULL, &err);
+       if (!proxy) {
+               if (err) {
+                       _E("failed to proxy_new_sync(%s)\n", err->message);
+                       g_error_free(err);
+               } else {
+                       _E("failed to proxy_new_sync\n");
+                       if (param)
+                               g_variant_unref(param);
+               }
+               goto out;
        }
 
-       msg = dbus_message_new_method_call(dest, path, interface, method);
-       if (!msg) {
-               _E("dbus_message_new_method_call(%s:%s-%s)",
-                               path, interface, method);
-               return -EPERM;
+       /* append fd */
+       if (in_fdlist) {
+               g_infdlist = g_unix_fd_list_new_from_array(in_fdlist, in_size);
+               if (!g_infdlist) {
+                       _E("failed to g_unix_fd_list_new_from_array\n");
+                       goto out;
+               }
+               //g_infdlist = g_unix_fd_list_new();
+               //if (g_unix_fd_list_append(g_infdlist, in_fdlist[0], &err) < 0) {
        }
 
-       dbus_message_iter_init_append(msg, &iter);
-       r = append_variant(&iter, sig, param);
-       if (r < 0) {
-               _E("append_variant error(%d) %s %s:%s-%s",
-                               r, dest, path, interface, method);
-               dbus_message_unref(msg);
-               return r;
+       /* send message */
+       ret = g_dbus_proxy_call_with_unix_fd_list_sync(proxy, method, param, G_DBUS_CALL_FLAGS_NONE, -1,
+               g_infdlist, &g_outfdlist, NULL, &err);
+       if (!ret || err) {
+               if (err) {
+                       _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:%s", err->message);
+                       g_error_free(err);
+               } else {
+                       _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:");
+                       if (param)
+                               g_variant_unref(param);
+                       if (g_infdlist)
+                               g_object_unref(g_infdlist);
+               }
+               goto out;
        }
 
-       dbus_error_init(&err);
+       /* copy fds to out array */
+       if (g_outfdlist) {
+               *out_size = g_unix_fd_list_get_length(g_outfdlist);
+               if (*out_size == 0)
+                       goto out;
+               *out_fdlist = g_unix_fd_list_steal_fds(g_outfdlist, NULL);
+       }
+out:
+       if (g_outfdlist)
+               g_object_unref(g_outfdlist);
+       if (proxy)
+               g_object_unref(proxy);
+       return ret;
+}
 
-       rep = dbus_connection_send_with_reply_and_block(conn, msg, timeout, &err);
-       dbus_message_unref(msg);
-       if (dbus_error_is_set(&err)) {
-               _E("dbus_connection_send error(%s:%s) %s %s:%s-%s",
-                               err.name, err.message, dest, path, interface, method);
-               dbus_error_free(&err);
-               return -EPERM;
+int dbus_method_sync(const char *dest, const char *path,
+                                               const char *iface, const char *method,
+                                               const char *signature, const char *param[])
+{
+       int result;
+       gboolean result_bool;
+       GVariant *reply = NULL;
+
+       if (!dest || !path || !iface || !method) {
+               _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
+               return -1;
        }
-       if (!rep) {
-               _E("dbus_connection_send error(No reply) %s %s:%s-%s",
-                               dest, path, interface, method);
-               return -EPERM;
+
+       reply = dbus_method_sync_with_reply(dest, path, iface, method, signature, param);
+       if (!reply)
+               return -ECOMM;
+
+       if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) {
+               g_variant_get(reply, "(i)", &result);
+       } else if (g_strcmp0("(b)", g_variant_get_type_string(reply)) == 0) {
+               g_variant_get(reply, "(b)", &result_bool);
+               result = (int)result_bool;
+       } else {
+               result = -ENOMSG;
        }
 
-       *reply = rep;
+       g_variant_unref(reply);
 
-       return 0;
+       return result;
 }
 
-int call_dbus_method_sync_pairs(const char *dest,
-               const char *path, const char *interface, const char *method,
-               int num, va_list args)
+int dbus_method_sync_var(const char *dest, const char *path,
+       const char *iface, const char *method, GVariant *param)
 {
-       DBusConnection *conn;
-       DBusMessage *msg;
-       DBusMessageIter iter;
-       DBusMessageIter aiter, piter;
-       DBusMessage *reply;
-       DBusError err;
-       char *key, *value;
-       int ret, result;
-       int i;
+       int result;
+       gboolean result_bool;
+       GVariant *reply = NULL;
 
-       if (!dest || !path || !interface || !method)
-               return -EINVAL;
+       if (!dest || !path || !iface || !method) {
+               _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
+               return -1;
+       }
 
-       conn = get_dbus_connection();
-       if (!conn) {
-               _E("Failed to get dbus connection");
+       reply = dbus_method_sync_with_reply_var(dest, path, iface, method, param);
+       if (!reply)
                return -ECOMM;
+
+       if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) {
+               g_variant_get(reply, "(i)", &result);
+       } else if (g_strcmp0("(b)", g_variant_get_type_string(reply)) == 0) {
+               g_variant_get(reply, "(b)", &result_bool);
+               result = (int)result_bool;
+       } else {
+               result = -ENOMSG;
+       }
+
+       g_variant_unref(reply);
+
+       return result;
+}
+
+int dbus_method_sync_timeout(const char *dest, const char *path,
+                                                               const char *iface, const char *method,
+                                                               const char *signature, const char *param[], int timeout)
+{
+       dbus_handle_s *dh = NULL;
+       GError *err = NULL;
+       GVariant * var = NULL;
+       GVariant * reply = NULL;
+       int result = 0;
+
+       if (!dest || !path || !iface || !method) {
+               _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
+               return -1;
        }
 
-       msg = dbus_message_new_method_call(dest, path, interface, method);
-       if (!msg) {
-               _E("dbus_message_new_method_call(%s:%s-%s)",
-                               path, interface, method);
+       dh = _dbus_handle_get_default_connection();
+       if (!dh) {
+               _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
                return -EPERM;
        }
 
-       dbus_message_iter_init_append(msg, &iter);
-       dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{ss}", &aiter);
+       if (signature && param)
+               var = _append_variant(signature, param);
 
-       for (i = 0 ; i < num ; i = i + 2) {
-               key = va_arg(args, char *);
-               value = va_arg(args, char *);
-               _I("key(%s), value(%s)", key, value);
-               dbus_message_iter_open_container(&aiter, DBUS_TYPE_DICT_ENTRY, NULL, &piter);
-               dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING, &key);
-               dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING, &value);
-               dbus_message_iter_close_container(&aiter, &piter);
+       reply = g_dbus_connection_call_sync(dh->conn,
+                                                                               dest, path, iface, method,
+                                                                               var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout, NULL, &err);
+       if (!reply || err) {
+               _E("failed to g_dbus_connection_call_sync:%s", err->message);
+               g_error_free(err);
+               return -1;
        }
 
-       dbus_message_iter_close_container(&iter, &aiter);
+       if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0)
+               g_variant_get(reply, "(i)", &result);
+       else
+               result = -ENOMSG;
+
+       g_variant_unref(reply);
 
-       dbus_error_init(&err);
+       return result;
+}
 
-       reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_REPLY_TIMEOUT, &err);
-       if (!reply) {
-               _E("dbus_connection_send error(No reply) %s %s:%s-%s",
-                               dest, path, interface, method);
+int dbus_method_sync_pairs(const char *dest, const char *path,
+                                                       const char *iface, const char *method,
+                                                       int num, va_list args)
+{
+       GError *err = NULL;
+       GVariant * reply = NULL;
+       char *key, *value;
+       int ret = 0;
+       GVariant *var;
+       GVariantBuilder *builder;
+       dbus_handle_s *dh = NULL;
+
+       if (!dest || !path || !iface || !method) {
+               _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
+               return -1;
        }
 
-       if (dbus_error_is_set(&err)) {
-               _E("dbus_connection_send error(%s:%s) %s %s:%s-%s",
-                               err.name, err.message, dest, path, interface, method);
-               dbus_error_free(&err);
-               reply = NULL;
+       dh = _dbus_handle_get_default_connection();
+       if (!dh) {
+               _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+               return -1;
        }
-       dbus_message_unref(msg);
 
-       if (!reply)
-               return -EPERM;
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}"));
 
-       ret = dbus_message_get_args(reply, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
-       dbus_message_unref(reply);
-       if (!ret) {
-               _E("no message : [%s:%s] %s %s:%s-%s",
-                               err.name, err.message, dest, path, interface, method);
-               dbus_error_free(&err);
-               return -ENOMSG;
+       for (int i = 0 ; i < num ; i = i + 2) {
+               key = va_arg(args, char *);
+               value = va_arg(args, char *);
+               _I("key(%s), value(%s)", key, value);
+               g_variant_builder_add(builder, "{ss}", key, value);
        }
 
-       return result;
+       var = g_variant_new("(a{ss})", builder);
+       g_variant_builder_unref(builder);
+
+       reply = g_dbus_connection_call_sync(dh->conn,
+               dest, path, iface, method,
+               var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err);
+       if (!reply || err) {
+               _E("failed to g_dbus_connection_call_sync");
+               return -1;
+       }
+
+       if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0)
+               g_variant_get(reply, "(i)", &ret);
+       else
+               ret = -ENOMSG;
+
+       g_variant_unref(reply);
+
+       return ret;
 }
 
-int call_dbus_method_async_pairs(const char *dest,
-               const char *path, const char *interface, const char *method,
-               int num, va_list args)
+int dbus_method_async_pairs(const char *dest, const char *path,
+       const char *iface, const char *method,
+       int num, va_list args)
 {
-       DBusConnection *conn;
-       DBusMessage *msg;
-       DBusMessageIter iter;
-       DBusMessageIter aiter, piter;
        char *key, *value;
-       int ret, i;
+       GVariant *var;
+       GVariantBuilder *builder;
+       dbus_handle_s *dh = NULL;
 
-       if (!dest || !path || !interface || !method)
-               return -EINVAL;
-
-       conn = get_dbus_connection();
-       if (!conn) {
-               _E("Failed to get dbus connection");
-               return -ECOMM;
+       if (!dest || !path || !iface || !method) {
+               _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
+               return -1;
        }
 
-       msg = dbus_message_new_method_call(dest, path, interface, method);
-       if (!msg) {
-               _E("dbus_message_new_method_call(%s:%s-%s)",
-                               path, interface, method);
-               return -EPERM;
+       dh = _dbus_handle_get_default_connection();
+       if (!dh) {
+               _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+               return -1;
        }
 
-       dbus_message_iter_init_append(msg, &iter);
-       dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{ss}", &aiter);
+       // dict
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}"));
 
-       for (i = 0 ; i < num ; i = i + 2) {
+       for (int i = 0 ; i < num ; i = i + 2) {
                key = va_arg(args, char *);
                value = va_arg(args, char *);
                _I("key(%s), value(%s)", key, value);
-               dbus_message_iter_open_container(&aiter, DBUS_TYPE_DICT_ENTRY, NULL, &piter);
-               dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING, &key);
-               dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING, &value);
-               dbus_message_iter_close_container(&aiter, &piter);
+               g_variant_builder_add(builder, "{ss}", key, value);
        }
 
-       dbus_message_iter_close_container(&iter, &aiter);
+       var = g_variant_new("(a{ss})", builder);
+       g_variant_builder_unref(builder);
 
-       ret = dbus_connection_send(conn, msg, NULL);
-       dbus_message_unref(msg);
-       if (ret != TRUE) {
-               _E("dbus_connection_send error(%s %s:%s-%s)",
-                               dest, path, interface, method);
-               return -ECOMM;
+       g_dbus_connection_call(dh->conn, dest, path, iface, method,
+               var, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+               NULL,
+               NULL);
+
+       return 0;
+}
+
+int dbus_method_async(const char *dest, const char *path,
+       const char *iface, const char *method,
+       const char *signature, const char *param[])
+{
+       GVariant * var = NULL;
+       dbus_handle_s *dh = NULL;
+
+       if (!dest || !path || !iface || !method) {
+               _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
+               return -1;
+       }
+
+       dh = _dbus_handle_get_default_connection();
+       if (!dh) {
+               _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+               return -1;
        }
 
+       if (signature && param)
+               var = _append_variant(signature, param);
+
+       g_dbus_connection_call(dh->conn, dest, path, iface, method,
+                                                       var, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+                                                       NULL,
+                                                       NULL);
+
        return 0;
 }
 
-static void cb_pending(DBusPendingCall *pending, void *user_data)
+int dbus_method_async_var(const char *dest, const char *path,
+       const char *iface, const char *method, GVariant *param)
 {
-       DBusMessage *msg;
-       struct pending_call_data *data = user_data;
-       int ret;
+       dbus_handle_s *dh = NULL;
 
-       ret = dbus_pending_call_get_completed(pending);
-       if (!ret) {
-               _I("dbus_pending_call_get_completed() fail");
-               dbus_pending_call_unref(pending);
-               return;
+       if (!dest || !path || !iface || !method) {
+               _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
+               return -1;
        }
 
-       msg = dbus_pending_call_steal_reply(pending);
-       if (!msg) {
-               _E("message is NULL");
-               if (data->func)
-                       data->func(data->data, NULL, -ECOMM);
-               return;
+       dh = _dbus_handle_get_default_connection();
+       if (!dh) {
+               _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+               return -1;
        }
 
-       if (data->func)
-               data->func(data->data, msg, 0);
+       g_dbus_connection_call(dh->conn, dest, path, iface, method,
+               param, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+               NULL,
+               NULL);
 
-       dbus_message_unref(msg);
-       dbus_pending_call_unref(pending);
+       return 0;
 }
 
-int call_dbus_method_async(const char *dest, const char *path,
-               const char *interface, const char *method,
-               const char *sig, char *param[],
-               dbus_pending_cb cb, int timeout, void *data)
+/* callback should free gvariant */
+static void _cb_pending(GDBusConnection *conn,
+                                               GAsyncResult    *res,
+                                               gpointer         user_data)
 {
-       DBusConnection *conn;
-       DBusMessage *msg;
-       DBusMessageIter iter;
-       DBusPendingCall *pending = NULL;
-       struct pending_call_data *pdata;
-       int ret;
+       GVariant *reply = NULL;
+       GError *err = NULL;
+       pending_call_data *data = (pending_call_data *)user_data;
+
+       reply = g_dbus_connection_call_finish(conn, res, &err);
+       if (!reply || err) {
+               if (err) {
+                       _E("no message : [%s]", err->message);
+                       g_error_free(err);
+               } else {
+                       _E("no message");
+               }
 
-       conn = get_dbus_connection();
-       if (!conn) {
-               _E("Failed to get dbus connection");
-               return -ECOMM;
+               if (data && data->func)
+                       data->func(NULL, data->data, err);
+               goto out;
        }
 
-       msg = dbus_message_new_method_call(dest, path, interface, method);
-       if (!msg) {
-               _E("dbus_message_new_method_call(%s:%s-%s)",
-                               path, interface, method);
-               return -EBADMSG;
+       if (data && data->func)
+               data->func(reply, data->data, err);
+out:
+       if (data)
+               free(data);
+}
+
+int dbus_method_async_with_reply(const char *dest,
+                                                                       const char *path,
+                                                                       const char *iface,
+                                                                       const char *method,
+                                                                       const char *signature,
+                                                                       const char *param[],
+                                                                       dbus_pending_cb cb,
+                                                                       int timeout_msec,
+                                                                       void *data)
+{
+       dbus_handle_s *dh = NULL;
+       pending_call_data *pdata = NULL;
+       GVariant * var = NULL;
+       int ret = 0;
+
+       if (!dest || !path || !iface || !method) {
+               _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
+               return -1;
        }
 
-       dbus_message_iter_init_append(msg, &iter);
-       ret = append_variant(&iter, sig, param);
-       if (ret < 0) {
-               _E("append_variant error(%d)%s %s:%s-%s",
-                               ret, dest, path, interface, method);
-               dbus_message_unref(msg);
-               return ret;
+       if (timeout_msec < -1) {
+               _E("wrong timeout %d", timeout_msec);
+               return -1;
        }
 
-       ret = dbus_connection_send_with_reply(conn, msg, &pending, timeout);
-       if (!ret) {
-               dbus_message_unref(msg);
-               _E("dbus_connection_send error(%s %s:%s-%s)",
-                               dest, path, interface, method);
-               return -ECOMM;
+       dh = _dbus_handle_get_default_connection();
+       if (!dh) {
+               _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+               return -EPERM;
+       }
+
+       if (signature && param)
+               var = _append_variant(signature, param);
+
+       if (cb) {
+               pdata = (pending_call_data*)malloc(sizeof(pending_call_data));
+               if (!pdata) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
+
+               pdata->func = cb;
+               pdata->data = data;
+       }
+       g_dbus_connection_call(dh->conn, dest, path, iface, method,
+                                                       var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL,
+                                                       (GAsyncReadyCallback)_cb_pending,
+                                                       pdata);
+
+       return ret;
+err:
+       if (var)
+               g_variant_unref(var);
+       return ret;
+}
+
+int dbus_method_async_with_reply_var(const char *dest,
+                                                                               const char *path,
+                                                                               const char *iface,
+                                                                               const char *method,
+                                                                               GVariant *param,
+                                                                               dbus_pending_cb cb,
+                                                                               int timeout_msec,
+                                                                               void *data)
+{
+       dbus_handle_s *dh = NULL;
+       pending_call_data *pdata = NULL;
+       int ret = 0;
+
+       if (!dest || !path || !iface || !method) {
+               _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
+               return -1;
+       }
+
+       if (timeout_msec < -1) {
+               _E("wrong timeout %d", timeout_msec);
+               return -1;
        }
 
-       dbus_message_unref(msg);
+       dh = _dbus_handle_get_default_connection();
+       if (!dh) {
+               _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+               return -EPERM;
+       }
 
-       if (cb && pending) {
-               pdata = calloc(1, sizeof(struct pending_call_data));
+       if (cb) {
+               pdata = (pending_call_data*)malloc(sizeof(pending_call_data));
                if (!pdata) {
-                       _E("malloc error : %s-%s", interface, method);
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto err;
                }
 
                pdata->func = cb;
                pdata->data = data;
+       }
+       g_dbus_connection_call(dh->conn, dest, path, iface, method,
+               param, NULL, G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL,
+               (GAsyncReadyCallback)_cb_pending,
+               pdata);
+
+       return ret;
+err:
+       if (param)
+               g_variant_unref(param);
+       return ret;
+}
+
+int dbus_connection_get_sender_pid(GDBusConnection *conn, const char * sender)
+{
+       GError *err = NULL;
+       GVariant *vret = NULL;
+       pid_t pid = 0;
+
+       if (!conn) {
+               _E("connection is null");
+               return -1;
+       }
+       if (!sender) {
+               _E("sender is null");
+               return -1;
+       }
+
+       vret = g_dbus_connection_call_sync(conn,
+               "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "GetConnectionUnixProcessID",
+               g_variant_new("(s)", sender),
+               NULL,
+               G_DBUS_CALL_FLAGS_NONE,
+               DBUS_REPLY_TIMEOUT,
+               NULL,
+               &err);
+       if (!vret || err) {
+               _E("failed to g_dbus_connection_call_sync:%s", err->message);
+               g_error_free(err);
+               return -1;
+       }
+
+       g_variant_get(vret, "(u)", &pid);
+       g_variant_unref(vret);
+
+       return pid;
+}
+
+int dbus_handle_get_sender_pid(dbus_handle_h handle, const char * sender)
+{
+       dcl_dbus_handle();
+
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return -1;
+               }
+       }
+       if (!dh->conn) {
+               _E("wrong dbus handle. connection is null");
+               assert(0);
+               return -1;
+       }
+
+       return dbus_connection_get_sender_pid(dh->conn, sender);
+}
+
+int dbus_handle_get_sender_credentials(dbus_handle_h handle, const char *name, GDBusCredentials *creds)
+{
+       dcl_dbus_handle();
+       GVariant *vret = NULL;
+       GError *err = NULL;
+       GVariantIter *iter = NULL;
+       char * item;
+       GVariant *sub;
+
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return -1;
+               }
+       }
+       vret = g_dbus_connection_call_sync(dh->conn, DBUS_BUS_NAME, DBUS_OBJECT_PATH, DBUS_INTERFACE_NAME,
+               "GetConnectionCredentials", g_variant_new("(s)", name), NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err);
+       if (!vret || err) {
+               _E("failed to g_dbus_connection_call_sync:%s", err->message);
+               return -1;
+       }
 
-               ret = dbus_pending_call_set_notify(pending, cb_pending, pdata, free);
-               if (!ret) {
-                       free(pdata);
-                       dbus_pending_call_cancel(pending);
-                       return -ECOMM;
+       g_variant_get(vret, "(a{sv})", &iter);
+
+       while (g_variant_iter_loop(iter, "{sv}", &item, &sub)) {
+               if (!g_strcmp0(item, "UnixUserID")) {
+                       g_variant_get(sub, "u", &creds->uid);
+                       _D("UnixUserID %u", creds->uid);
+               } else if (!g_strcmp0(item, "ProcessID")) {
+                       g_variant_get(sub, "u", &creds->pid);
+                       _D("ProcessID %u", creds->pid);
+               } else if (!g_strcmp0(item, "LinuxSecurityLabel")) {
+                       g_variant_get(sub, "^ay", &creds->sec_label);
+                       _D("%s", creds->sec_label);
                }
        }
 
+       if (iter)
+               g_variant_iter_free(iter);
+       if (vret)
+               g_variant_unref(vret);
+
+       return 0;
+}
+
+void _destroy_notify_watch_name(gpointer data)
+{
+       if (data)
+               free(data);
+}
+
+int dbus_handle_watch_name(const char *name,
+                                                       GBusNameAppearedCallback  name_appeared_handler,
+                                                       GBusNameVanishedCallback  name_vanished_handler,
+                                                       void *user_data)
+{
+       guint id = 0;
+
+       if (!name) {
+               _E("wrong name name %s", name);
+               return -1;
+       }
+       if (!name_appeared_handler && !name_vanished_handler) {
+               _E("both function pointers are null");
+               return -1;
+       }
+
+       id = g_bus_watch_name(dbus_handle_get_default_bus_type(), name, G_BUS_NAME_WATCHER_FLAGS_NONE, name_appeared_handler, name_vanished_handler, user_data, _destroy_notify_watch_name);
+       if (!id) {
+               _E("failed to g_bus_watch_name");
+               return -1;
+       }
+
+       return id;
+}
+
+void dbus_handle_unwatch_name(guint id)
+{
+       if (id == 0) {
+               _E("wrong id %d", id);
+               return;
+       }
+       g_bus_unwatch_name(id);
+}
+
+int _get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size)
+{
+       int fd, ret;
+       char buf[PATH_MAX + 1];
+       char *filename;
+
+       snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
+       fd = open(buf, O_RDONLY);
+       if (fd < 0) {
+               errno = ESRCH;
+               return -1;
+       }
+
+       ret = read(fd, buf, PATH_MAX);
+       close(fd);
+       if (ret < 0)
+               return -1;
+
+       buf[PATH_MAX] = '\0';
+
+       filename = strrchr(buf, '/');
+       if (filename == NULL)
+               filename = buf;
+       else
+               filename = filename + 1;
+
+       if (cmdline_size < strlen(filename) + 1) {
+               errno = EOVERFLOW;
+               return -1;
+       }
+
+       strncpy(cmdline, filename, cmdline_size - 1);
+       cmdline[cmdline_size - 1] = '\0';
        return 0;
 }
+
+// g_strfreev(strv)
+char **dbus_handle_get_owner_list(dbus_handle_h handle, const char *bus_name)
+{
+       dcl_dbus_handle();
+       GError *err = NULL;
+       GVariant *vret = NULL;
+       GVariantIter *iter = NULL;
+       gchar **strv = NULL;
+       gchar *str = NULL;
+       int i = 0;
+
+       if (!bus_name) {
+               _E("wrong parameter bus_name(%s)", bus_name);
+               return NULL;
+       }
+
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return NULL;
+               }
+       }
+
+       vret = g_dbus_connection_call_sync(dh->conn,
+               "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "ListQueuedOwners",
+               g_variant_new("(s)", bus_name),
+               NULL,
+               G_DBUS_CALL_FLAGS_NONE,
+               DBUS_REPLY_TIMEOUT,
+               NULL,
+               &err);
+       if (!vret || err) {
+               _E("failed to g_dbus_connection_call_sync:%s", err->message);
+               g_error_free(err);
+               return NULL;
+       }
+
+       g_variant_get(vret, "(as)", &iter);
+       strv = g_new(gchar *, g_variant_iter_n_children(iter) + 1);
+
+       i = 0;
+       while (g_variant_iter_loop(iter, "s", &str))
+               strv[i++] = g_strdup(str);
+       strv[i] = NULL;
+
+       g_variant_iter_free(iter);
+       g_variant_unref(vret);
+
+       return strv;
+}
+
+void dbush_handle_check_owner_name(dbus_handle_h handle, const char *owner_name)
+{
+       dcl_dbus_handle();
+       char exe_name[PATH_MAX];
+       int pid;
+       char **strv = NULL;
+       int i;
+
+       if (!dh) {
+               dh = _dbus_handle_get_default_connection();
+               if (!dh) {
+                       _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
+                       return ;
+               }
+       }
+
+       strv = dbus_handle_get_owner_list(dh, owner_name);
+       if (!strv) {
+               _E("failed to get owner list of %s", owner_name);
+               return ;
+       }
+
+       for (i = 0; strv[i] != NULL; ++i) {
+               pid = dbus_handle_get_sender_pid(dh, strv[i]);
+               if (_get_cmdline_name(pid, exe_name, PATH_MAX) != 0)
+                       break;
+               _I("%s(%d)", exe_name, pid);
+       }
+
+       g_strfreev(strv);
+}
+
+dbus_handle_h dbus_handle_init(GBusType type, const char* bus_name)
+{
+       dbus_handle_h handle = NULL;
+       int i, ret = 0;
+
+       if (!bus_name) {
+               _E("Wrong bus name, %s", bus_name);
+               return NULL;
+       }
+
+       // todo: do we need retry ? - booting time
+       for (i = 0 ; i < 3; ++i) {
+               handle = dbus_handle_get_connection(type, FALSE);
+               if (handle)
+                       break;
+               usleep(5000);
+       }
+       ret = dbus_handle_request_bus_name(handle, bus_name);
+       if (ret <= 0)
+               goto out;
+
+       dbush_handle_check_owner_name(NULL, bus_name);
+
+       return handle;
+
+out:
+       return NULL;
+}
+
index 10bc475..7225546 100644 (file)
 #ifndef __STORAGED_DBUS_H__
 #define __STORAGED_DBUS_H__
 
-#include <glib.h>
-#include <dbus/dbus.h>
+#include <gio/gio.h>
+#include <glib-unix.h>
+#include <gio/gunixfdlist.h>
+#include <stdarg.h>
+#include <assert.h>
+
 #include "dbus_macro.h"
 
+
+/*
+ * DBus daemon
+ */
+#define DBUS_BUS_NAME                       "org.freedesktop.DBus"
+#define DBUS_OBJECT_PATH                    "/org/freedesktop/DBus"
+#define DBUS_INTERFACE_NAME                 DBUS_BUS_NAME
 /**
  * @brief   Structure for byte array
  * @since_tizen 4.0
  */
-struct dbus_byte {
+typedef struct {
        const unsigned char *data;
        int size;
-};
+} dbus_byte;
+
+GVariant *dbus_method_sync_with_reply(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, const char *param[]);
+
+GVariant *dbus_method_sync_with_reply_var(const char *dest, const char *path, const char *iface, const char *method, GVariant *var);
+
+/* fd */
+gint* dbus_handle_get_unix_fd_list(GDBusMethodInvocation *invocation, int *size);
+
+GVariant *dbus_method_with_unix_fd_list_sync_with_reply(const char *dest, const char *path,
+                                                                                                               const char *iface, const char *method,
+                                                                                                               const char *signature, const char *param[],
+                                                                                                               int *in_fdlist, int in_size,
+                                                                                                               int **out_fdlist, int *out_size);
+GVariant *dbus_method_with_unix_fd_list_sync_with_reply_var(const char *dest, const char *path,
+                                                                                                                       const char *iface, const char *method,
+                                                                                                                       GVariant *param,
+                                                                                                                       int *in_fdlist, int in_size,
+                                                                                                                       int **out_fdlist, int *out_size);
+
+int dbus_method_sync(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, const char *param[]);
+
+int dbus_method_sync_var(const char *dest, const char *path, const char *iface, const char *method, GVariant *param);
+
+int dbus_method_sync_timeout(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, const char *param[], int timeout);
+
+int dbus_method_sync_pairs(const char *dest, const char *path,
+               const char *interface, const char *method,
+               int num, va_list args);
+int dbus_method_async_pairs(const char *dest, const char *path,
+               const char *interface, const char *method,
+               int num, va_list args);
+int dbus_method_async(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, const char *param[]);
+
+int dbus_method_async_var(const char *dest, const char *path, const char *iface, const char *method, GVariant *param);
+
+typedef void (*dbus_pending_cb)(GVariant *var, void *user_data, GError *err);
+
+int dbus_method_async_with_reply(const char *dest,
+                                                                       const char *path,
+                                                                       const char *iface,
+                                                                       const char *method,
+                                                                       const char *signature,
+                                                                       const char *param[],
+                                                                       dbus_pending_cb cb,
+                                                                       int timeout_msec,
+                                                                       void *data);
 
-/**
- * @brief   Structure for integer array
- * @since_tizen 4.0
- */
-struct dbus_int {
-       int *list;
-       int size;
-};
+
+int dbus_method_async_with_reply_var(const char *dest,
+                                                                       const char *path,
+                                                                       const char *iface,
+                                                                       const char *method,
+                                                                       GVariant *param,
+                                                                       dbus_pending_cb cb,
+                                                                       int timeout_msec,
+                                                                       void *data);
+
+int check_systemd_active(void);
 
 /**
  * @brief   Dbus handler which is used to register and call methods
@@ -52,225 +120,79 @@ typedef void *dbus_handle_h;
  * @brief   Dbus method handler which is used to unregister dbus methods
  * @since_tizen 4.0
  */
-typedef void *dbus_method_handle_h;
-
-/**
- * @brief   Dbus reply handler which is used to reply for dbus methods
- * @since_tizen 4.0
- */
-typedef void *dbus_method_reply_handle_h;
+typedef void *dbus_object_handle_h;
 
 /**
  * @brief   Structure which contains the dbus method name and callback function.
  * @since_tizen 4.0
  */
-typedef struct dbus_method {
+typedef struct {
        const char *member;
-       const char *sig;
-       DBusMessage *(*func)(dbus_method_reply_handle_h reply, DBusMessage *msg);
+       const char *signature_in;
+       const char *signature_out;
+       GVariant *(*func)(GDBusConnection *conn,
+               const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+               GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data);
 } dbus_method_s;
 
 /**
- * @brief   Callback function which is called when the specified signal is delivered.
- * @since_tizen 4.0
- */
-typedef void (*dbus_signal_received)(const char *sender_name,
-               const char *object_path, const char *interface_name,
-               const char *signal_name, DBusMessage *msg,
-               void *data);
-
-/**
- * @brief   Type for the callback function of the Async dbus method calls
- * @since_tizen 4.0
- */
-typedef void (*dbus_pending_cb)(void *data, DBusMessage *msg, int err);
-
-/**
- * @brief   Callback function which is called when the user data needs to be released.
- * @since_tizen 4.0
- */
-typedef void (*destroy_notified)(void *data);
-
-/**
  * @brief   Structure which contains the dbus interface information and its methods.i
  * @since_tizen 4.0
  */
-typedef struct dbus_interface {
+typedef struct {
        const char *name;
        const dbus_method_s *methods;
        int nr_methods;
-} dbus_interface_s;
+} dbus_interface_u;
 
-/**
- * @brief   Get dbus handle for dbus connection
- * @since_tizen 4.0
- * @param[in]  bus     The dbus bus name
- * @param[out] handle  The dbus handle
- * @return  @c 0 on success,
- *          otherwise a negative error value
- */
-int dbus_get_connection(dbus_handle_h *handle);
+#define dh_get_param_from_var(gvar, signature, ...) ((g_strcmp0(signature, g_variant_get_type_string(gvar)) == 0) ? g_variant_get(gvar, signature, __VA_ARGS__), TRUE : FALSE)
 
-/**
- * @brief   Register dbus methods.
- * @since_tizen 4.0
- * @param[in]  handle    The dbus handle obtained by syscommon_get_dbus_connection().
- * @param[in]  object_path The dbus object path.
- * @param[in]  interface  The dbus interface object.
- * @param[in]  interface_handle_received The callback function called if the interface is registered.
- * @param[in]  data The user data which is delivered to the interface_handle_received function.
- * @return  @c 0 on success,
- *          otherwise a negative error value
- */
-int register_dbus_methods(dbus_handle_h handle,
-               const char *object_path, const dbus_interface_s *interface,
-               void (*method_handle_received)(dbus_method_handle_h method_handle, void *data),
-               void *data);
+#define dbus_handle_new_g_variant_tuple() g_variant_new_tuple(NULL, 0)
 
 /**
- * @brief   Deliver the return value of the dbus methods
+ * @brief   Callback function which is called when the user data needs to be released.
  * @since_tizen 4.0
- * @param[in]  invocation The invocation information which is delivered to the callback function registered by syscommon_register_dbus_methods().
- * @param[in] result The gvariant value which contains the result.
  */
-void reply_dbus_method_result(dbus_method_reply_handle_h reply_handle, DBusMessage *reply_msg);
+typedef void (*destroy_notified)(void *data);
 
-DBusMessage *make_dbus_reply_message(dbus_method_reply_handle_h reply_handle);
+typedef struct {
+       dbus_pending_cb func;
+       void *data;
+} pending_call_data;
 
-DBusMessage *make_dbus_reply_message_simple(dbus_method_reply_handle_h reply_handle, int result);
+int dbus_handle_request_bus_name(dbus_handle_h handle, const char *bus_name);
 
-int get_dbus_method_sender_name(dbus_method_reply_handle_h reply_handle, char *name, size_t len);
+dbus_handle_h dbus_handle_get_connection(GBusType bus_type, gboolean priv);
 
-int get_dbus_method_sender_pid(dbus_method_reply_handle_h reply_handle);
+int dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface);
+int dbus_handle_unregister_dbus_object(dbus_handle_h handle, const char *obj_path);
 
-/**
- * @brief   Unregister dbus methods
- * @since_tizen 4.0
- * @param[in]  handle  The dbus handle obtained by syscommon_get_dbus_connection().
- * @param[in]  id      The method regist ID which is obtained by the id_received callback of the syscommon_register_dbus_methods().
- */
-void unregister_dbus_methods(dbus_handle_h handle, dbus_method_handle_h method_handle);
+int dbus_handle_add_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u);
+int dbus_handle_register_dbus_object_all(dbus_handle_h handle);
 
-/**
- * @brief   Register dbus signal
- * @since_tizen 4.0
- * @param[in]  path The dbus object path.
- * @param[in]  interface The dbus interface name.
- * @param[in]  name The dbus signal name.
- * @param[in]  cb The callback function which will called when the signal is delivered.
- * @param[in]  data The user data which is delivered to the callback function.
- * @param[in]  free_func The function which is called when the signal handler is removed
- * @return  @c 0 on success,
- *          otherwise a negative error value
- */
-int register_dbus_signal(const char *path,
-               const char *interface, const char *name,
-               dbus_signal_received cb, void *data,
-               destroy_notified free_func);
+guint subscribe_dbus_signal(dbus_handle_h handle, const char *path, const char *iface, const char *name, GDBusSignalCallback cb, void *data, destroy_notified free_func);
+void unsubscribe_dbus_signal(dbus_handle_h handle, guint id);
 
-/**
- * @brief   Unregister dbus signal
- * @since_tizen 4.0
- * @param[in]  path The dbus object path.
- * @param[in]  interface The dbus interface name.
- * @param[in]  name The dbus signal name.
- * @return  @c 0 on success,
- *          otherwise a negative error value
- */
-int unregister_dbus_signal(const char *path,
-               const char *interface, const char *name,
-               dbus_signal_received cb);
+GVariant *dbus_handle_make_simple_array(const char *sig, int *param);
 
-/**
- * @brief   Unregister all dbus signals
- * @since_tizen 4.0
- */
-void unregister_dbus_signal_all(void);
+int dbus_handle_broadcast_dbus_signal(const char *path, const char *iface, const char *name, const char *signature, const char *param[]);
+int dbus_handle_broadcast_dbus_signal_var(const char *path, const char *iface, const char *name, GVariant *param);
 
-/**
- * @brief   Broadcast dbus signal
- * @since_tizen 4.0
- * @param[in]  path The dbus object path.
- * @param[in]  iface The dbus interface name.
- * @param[in]  name The dbus signal name.
- * @param[in]  sig The format string of parameter.
- * @param[in]  param The parameter array.
- * @return  @c 0 on success,
- *          otherwise a negative error value
- */
-int broadcast_dbus_signal(const char *path,
-               const char *iface, const char *name,
-               const char *sig, char *param[]);
-
-
-/**
- * @brief   Call dbus method synchronously.
- * @remarks The function expects that the return value is just single integer.
- * @since_tizen 4.0
- * @param[in]  dest The dbus bus name.
- * @param[in]  path The dbus object path.
- * @param[in]  iface The dbus interface name.
- * @param[in]  method The dbus method name.
- * @param[in]  sig The format string of parameter.
- * @param[in]  param The parameter array.
- * @return  return value of the method
- */
-int call_dbus_method_sync(const char *dest,
-               const char *path, const char *iface,
-               const char *method, const char *sig, char *param[],
-               int timeout, DBusMessage **info);
-
-/**
- * @brief   Call dbus method Asynchronously and get return value from the callback function.
- * @remarks The return value with the DBusMessage type is delivered to the callback function.
- * @since_tizen 4.0
- * @param[in]  dest The dbus bus name.
- * @param[in]  path The dbus object path.
- * @param[in]  iface The dbus interface name.
- * @param[in]  method The dbus method name.
- * @param[in]  sig The format string of parameter.
- * @param[in]  param The parameter array.
- * @param[in]  cb The callback function which is called when the dbus method returns.
- * @param[in]  timeout The timeout for calling the callback function.
- * @param[in]  data The user data which is delivered to the callback function.
- * @return  @c 0 on success,
- *          otherwise a negative error value
- */
-int call_dbus_method_async(const char *dest,
-               const char *path, const char *iface, const char *method,
-               const char *sig, char *param[],
-               dbus_pending_cb cb, int timeout, void *data);
+typedef struct
+{
+       guint   pid;
+       guint   uid;
+       gchar  *unique_name;
+       gchar  *sec_label;
+} GDBusCredentials;
 
-/**
- * @brief   Call dbus method for lauching apps synchronously
- * @since_tizen 4.0
- * @param[in]  dest The dbus bus name.
- * @param[in]  path The dbus object path.
- * @param[in]  iface The dbus interface name.
- * @param[in]  method The dbus method name.
- * @param[in]  num The number of parameters constained in args
- * @param[in]  args The va_list variable which contains the parameters
- * @return  return value of the method
- */
-int call_dbus_method_sync_pairs(const char *dest,
-               const char *path, const char *iface, const char *method,
-               int num, va_list args);
-
-/**
- * @brief   Call dbus method for lauching apps Asynchronously
- * @since_tizen 4.0
- * @param[in]  dest The dbus bus name.
- * @param[in]  path The dbus object path.
- * @param[in]  iface The dbus interface name.
- * @param[in]  method The dbus method name.
- * @param[in]  num The number of parameters constained in args
- * @param[in]  args The va_list variable which contains the parameters
- * @return  @c 0 on success,
- *          otherwise a negative error value
- */
-
-int call_dbus_method_async_pairs(const char *dest,
-               const char *path, const char *iface, const char *method,
-               int num, va_list args);
+int dbus_connection_get_sender_pid(GDBusConnection *conn, const char * sender);
+int dbus_handle_get_sender_pid(dbus_handle_h handle, const char * sender);
+int dbus_handle_get_sender_credentials(dbus_handle_h handle, const char *name, GDBusCredentials *creds);
+int dbus_handle_watch_name(const char *name, GBusNameAppearedCallback name_appeared_handler, GBusNameVanishedCallback name_vanished_handler, void *user_data);
+void dbus_handle_unwatch_name(guint id);
+dbus_handle_h dbus_handle_init(GBusType type, const char* bus_name);
+char** dbus_handle_get_owner_list(dbus_handle_h handle, const char *bus_name);
+void dbush_handle_check_owner_name(dbus_handle_h handle, const char *owner_name);
 
-#endif /* __STORAGED_BUS_H__ */
+#endif
index c4a60b6..2bdecfa 100644 (file)
@@ -46,6 +46,8 @@ static struct udev *udev;
 static struct uevent_info kevent; /* kernel */
 static struct uevent_info uevent; /* udev */
 
+static guint id_device_change_poweroff; /* signal subscription id */
+
 static bool uevent_control_cb(int fd, void *data)
 {
        struct uevent_info *info = data;
@@ -262,10 +264,13 @@ int unregister_udev_uevent_control(const struct uevent_handler *uh)
        return unregister_uevent_control(&uevent, uh);
 }
 
-static void device_change_poweroff(const char *sender_name,
-               const char *object_path, const char *interface_name,
-               const char *signal_name, DBusMessage *msg,
-               void *data)
+static void device_change_poweroff(GDBusConnection  *conn,
+                                                                       const gchar *sender,
+                                                                       const gchar *path,
+                                                                       const gchar *iface,
+                                                                       const gchar *name,
+                                                                       GVariant *param,
+                                                                       gpointer data)
 {
        static int status = 0;
        if (status > 0)
@@ -278,7 +283,7 @@ static void device_change_poweroff(const char *sender_name,
 
 void udev_init(void *data)
 {
-       register_dbus_signal(DEVICED_PATH_POWEROFF,
+       id_device_change_poweroff = subscribe_dbus_signal(NULL, DEVICED_PATH_POWEROFF,
                        DEVICED_INTERFACE_POWEROFF,
                        SIGNAL_POWEROFF_STATE,
                        device_change_poweroff,
@@ -293,8 +298,5 @@ void udev_init(void *data)
 
 void udev_exit(void *data)
 {
-       unregister_dbus_signal(DEVICED_PATH_POWEROFF,
-                       DEVICED_INTERFACE_POWEROFF,
-                       SIGNAL_POWEROFF_STATE,
-                       device_change_poweroff);
+       unsubscribe_dbus_signal(NULL, id_device_change_poweroff);
 }
index f3bac89..422b91d 100644 (file)
@@ -4,9 +4,9 @@ PROJECT(module_storage C)
 INCLUDE(FindPkgConfig)
 pkg_check_modules(${PROJECT_NAME}_pkgs REQUIRED
                dlog
-               dbus-1
                gio-2.0
                glib-2.0
+               gio-unix-2.0
                storage
                vconf
 )
old mode 100755 (executable)
new mode 100644 (file)
index 79c1c1f..fb26935
@@ -76,6 +76,9 @@ struct storage_config_info {
 
 static guint memnoti_timer;
 
+static guint id_booting_done;
+static guint id_storage_poweroff;
+
 static struct storage_config_info storage_internal_info = {
        .current_noti_level = MEMNOTI_LEVEL_NORMAL,
        .warning_level      = MEMNOTI_WARNING_VALUE,
@@ -92,14 +95,9 @@ static struct storage_config_info storage_tmp_info = {
 
 static void memnoti_send_broadcast(char *signal, int status)
 {
-       char *arr[1];
-       char str_status[32];
-
        _I("signal %s status %d", signal, status);
-       snprintf(str_status, sizeof(str_status), "%d", status);
-       arr[0] = str_status;
-       broadcast_dbus_signal(STORAGED_PATH_LOWMEM, STORAGED_INTERFACE_LOWMEM,
-                       signal, "i", arr);
+       dbus_handle_broadcast_dbus_signal_var(STORAGED_PATH_LOWMEM, STORAGED_INTERFACE_LOWMEM,
+                       signal, g_variant_new("(i)", status));
 }
 
 static int launch_memory_popup(int num, ...)
@@ -109,7 +107,7 @@ static int launch_memory_popup(int num, ...)
 
        va_start(args, num);
 
-       ret = call_dbus_method_async_pairs(POPUP_BUS_NAME,
+       ret = dbus_method_async_pairs(POPUP_BUS_NAME,
                        POPUP_PATH_SYSTEM,
                        POPUP_INTERFACE_SYSTEM,
                        "PopupLaunch",
@@ -279,10 +277,10 @@ static int init_storage_config_info_all(void)
        return 0;
 }
 
-static DBusMessage *dbus_getstatus(dbus_method_reply_handle_h reply_handle, DBusMessage *msg)
+static GVariant *dbus_getstatus(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
 {
-       DBusMessageIter iter;
-       DBusMessage *reply;
        struct statvfs s;
        unsigned long long dAvail = 0.0;
        unsigned long long dTotal = 0.0;
@@ -291,69 +289,56 @@ static DBusMessage *dbus_getstatus(dbus_method_reply_handle_h reply_handle, DBus
        dTotal = (unsigned long long)s.f_frsize * s.f_blocks;
        dAvail = (unsigned long long)s.f_bsize * s.f_bavail;
 
-       reply = make_dbus_reply_message(reply_handle);
-       dbus_message_iter_init_append(reply, &iter);
-       dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT64, &dTotal);
-       dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT64, &dAvail);
-       return reply;
+       return g_variant_new("(tt)", dTotal, dAvail);
 }
 
-static DBusMessage *dbus_get_storage_status(dbus_method_reply_handle_h reply_handle, DBusMessage *msg)
+static GVariant *dbus_get_storage_status(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
 {
-       DBusMessageIter iter;
-       DBusMessage *reply;
-       DBusError err;
-       char *path;
+       char *str_path;
        struct statvfs s;
        pid_t pid;
        unsigned long long dAvail = 0.0;
        unsigned long long dTotal = 0.0;
 
-       dbus_error_init(&err);
-       if (!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) {
-               _E("Bad message: [%s:%s]", err.name, err.message);
-               dbus_error_free(&err);
-               goto out;
-       }
+       g_variant_get(param, "(s)", &str_path);
 
-       if (!strcmp(path, tzplatform_getenv(TZ_SYS_HOME)))
+       if (!strcmp(str_path, tzplatform_getenv(TZ_SYS_HOME)))
                storage_get_internal_memory_size(&s);
        else
-               storage_get_memory_size(path, &s);
+               storage_get_memory_size(str_path, &s);
 
        dTotal = (unsigned long long)s.f_frsize * s.f_blocks;
        dAvail = (unsigned long long)s.f_bsize * s.f_bavail;
 
-       pid = get_dbus_method_sender_pid(reply_handle);
+       pid = dbus_handle_get_sender_pid(NULL, sender);
 
-       _D("[request %d] path %s total %4.0llu avail %4.0llu", pid, path, dTotal, dAvail);
+       _D("[request %d] path %s total %4.0llu avail %4.0llu", pid, str_path, dTotal, dAvail);
 
-out:
-       reply = make_dbus_reply_message(reply_handle);
-       dbus_message_iter_init_append(reply, &iter);
-       dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT64, &dTotal);
-       dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT64, &dAvail);
-       return reply;
+       g_free(str_path);
+       return g_variant_new("(tt)", dTotal, dAvail);
 }
 
 static const dbus_method_s storage_methods[] = {
-       { "getstorage", NULL, dbus_getstatus },
-       { "GetStatus",   "s", dbus_get_storage_status},
+       { "getstorage", NULL, "tt", dbus_getstatus },
+       { "GetStatus",   "s", "tt", dbus_get_storage_status},
        /* Add methods here */
 };
 
-static dbus_interface_s storage_interface = {
+static dbus_interface_u storage_interface = {
        .name = STORAGED_INTERFACE_STORAGE,
        .methods = storage_methods,
        .nr_methods = ARRAY_SIZE(storage_methods),
 };
 
-static void booting_done(const char *sender_name,
-               const char *object_path,
-               const char *interface_name,
-               const char *signal_name,
-               DBusMessage *msg,
-               void *data)
+static void booting_done(GDBusConnection  *conn,
+                                                       const gchar *sender,
+                                                       const gchar *path,
+                                                       const gchar *iface,
+                                                       const gchar *name,
+                                                       GVariant *param,
+                                                       gpointer data)
 {
        static int done;
 
@@ -366,12 +351,13 @@ static void booting_done(const char *sender_name,
                _E("fail remain mem noti control fd init");
 }
 
-static void storage_poweroff(const char *sender_name,
-               const char *object_path,
-               const char *interface_name,
-               const char *signal_name,
-               DBusMessage *msg,
-               void *data)
+static void storage_poweroff(GDBusConnection  *conn,
+                                                               const gchar *sender,
+                                                               const gchar *path,
+                                                               const gchar *iface,
+                                                               const gchar *name,
+                                                               GVariant *param,
+                                                               gpointer data)
 {
        if (memnoti_timer) {
                g_source_remove(memnoti_timer);
@@ -418,28 +404,22 @@ static void storage_config_load(struct storage_config_info *info)
 static void storage_init(void *data)
 {
        int ret;
-       dbus_handle_h handle;
-
-       ret = dbus_get_connection(&handle);
-       if (ret < 0) {
-               _E("Failed to get dbus connection(%d)", ret);
-               return;
-       }
 
        storage_config_load(&storage_internal_info);
+
        /* System Session is loaded completely */
-       register_dbus_signal(SYSTEMD_DBUS_PATH,
+       id_booting_done = subscribe_dbus_signal(NULL, SYSTEMD_DBUS_PATH,
                    SYSTEMD_DBUS_IFACE_MANAGER,
                    SYSTEMD_DBUS_SIGNAL_SYSTEM_STARTUP_FINISHED,
                    booting_done, NULL, NULL);
 
-       register_dbus_signal(DEVICED_PATH_POWEROFF,
+       id_storage_poweroff = subscribe_dbus_signal(NULL, DEVICED_PATH_POWEROFF,
                        DEVICED_INTERFACE_POWEROFF,
                        SIGNAL_POWEROFF_STATE,
                        storage_poweroff, NULL, NULL);
 
-       ret = register_dbus_methods(handle, STORAGED_PATH_STORAGE,
-                       &storage_interface, NULL, NULL);
+       ret = dbus_handle_register_dbus_object(NULL, STORAGED_PATH_STORAGE,
+                       &storage_interface);
        if (ret < 0)
                _E("Failed to register dbus interface and methods(%d)", ret);
 }
@@ -447,14 +427,8 @@ static void storage_init(void *data)
 static void storage_exit(void *data)
 {
        /* unregister notifier for below each event */
-       unregister_dbus_signal(SYSTEMD_DBUS_PATH,
-                   SYSTEMD_DBUS_IFACE_MANAGER,
-                   SYSTEMD_DBUS_SIGNAL_SYSTEM_STARTUP_FINISHED,
-                   booting_done);
-
-       unregister_dbus_signal(DEVICED_PATH_POWEROFF,
-                       DEVICED_INTERFACE_POWEROFF,
-                       SIGNAL_POWEROFF_STATE, storage_poweroff);
+       unsubscribe_dbus_signal(NULL, id_booting_done);
+       unsubscribe_dbus_signal(NULL, id_storage_poweroff);
 }
 
 static storaged_module_interface storage_module = {