From b5c310e675794fb6736a49a7c3ad0faef6a9d6b4 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Tue, 1 Aug 2017 15:50:22 +0900 Subject: [PATCH 01/16] dbus: clean up dbus policy Change-Id: I2dd9e43cbfc9a5353fcf91035a684d355a50dbe2 Signed-off-by: sanghyeok.oh --- scripts/storaged.conf | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/scripts/storaged.conf b/scripts/storaged.conf index ecd3199..b6f7967 100644 --- a/scripts/storaged.conf +++ b/scripts/storaged.conf @@ -1,17 +1,9 @@ - - - - - - - - - + + -- 2.7.4 From b69e936ca63fce2ff6ad779b319176f622f3bd41 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Mon, 5 Feb 2018 17:17:50 +0900 Subject: [PATCH 02/16] dbus: change dbus library from dbus to gdbus Change-Id: I87f7fb5d88cba95f08b1927012f9b65cadc538a0 Signed-off-by: sanghyeok.oh --- CMakeLists.txt | 6 +- apps/extended-sd/src/dbus-call.c | 2 +- packaging/storaged.spec | 1 - src/block/CMakeLists.txt | 4 +- src/block/block.c | 718 ++++----- src/block/vfat.c | 5 +- src/core/main.c | 9 +- src/shared/apps.c | 2 +- src/shared/dbus.c | 2979 ++++++++++++++++++++++++++++---------- src/shared/dbus.h | 326 ++--- src/shared/udev.c | 20 +- src/storage/CMakeLists.txt | 2 +- src/storage/storage.c | 116 +- 13 files changed, 2729 insertions(+), 1461 deletions(-) mode change 100755 => 100644 src/storage/storage.c diff --git a/CMakeLists.txt b/CMakeLists.txt index d9c2e2c..8b3f953 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/apps/extended-sd/src/dbus-call.c b/apps/extended-sd/src/dbus-call.c index 01360d7..8921955 100644 --- a/apps/extended-sd/src/dbus-call.c +++ b/apps/extended-sd/src/dbus-call.c @@ -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 +} diff --git a/packaging/storaged.spec b/packaging/storaged.spec index 41f7b93..c7e3d0c 100644 --- a/packaging/storaged.spec +++ b/packaging/storaged.spec @@ -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) diff --git a/src/block/CMakeLists.txt b/src/block/CMakeLists.txt index 4445a6c..925e54d 100644 --- a/src/block/CMakeLists.txt +++ b/src/block/CMakeLists.txt @@ -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 diff --git a/src/block/block.c b/src/block/block.c index 9f843d3..d5739fd 100644 --- a/src/block/block.c +++ b/src/block/block.c @@ -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); diff --git a/src/block/vfat.c b/src/block/vfat.c index d66ef0f..19ddf39 100644 --- a/src/block/vfat.c +++ b/src/block/vfat.c @@ -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); diff --git a/src/core/main.c b/src/core/main.c index db63353..fee7ee9 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -24,9 +24,9 @@ #include #include -#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); diff --git a/src/shared/apps.c b/src/shared/apps.c index 3d4200b..246b592 100755 --- a/src/shared/apps.c +++ b/src/shared/apps.c @@ -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, diff --git a/src/shared/dbus.c b/src/shared/dbus.c index 59fafde..2778d25 100644 --- a/src/shared/dbus.c +++ b/src/shared/dbus.c @@ -15,1037 +15,2546 @@ * limitations under the License. */ + #include #include -#include -#include #include -#include -#include "fd_handler.h" -#include "dbus.h" +#include +#include + +#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, ¶m[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), """\n""\t""""\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""""\n", pmethod->member); + continue; + } + + /* */ + nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""""\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""""\n", tmp, m); + m += ei; + continue; + } else { + nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""""\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""""\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""""\n", tmp, m); + m += ei; + continue; + } else { + nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""""\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""""\n", pmethod->signature_out[m], m); + } + + /* */ + nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""""\n"); } + nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t""""\n"""""); + + *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; +} + diff --git a/src/shared/dbus.h b/src/shared/dbus.h index 10bc475..7225546 100644 --- a/src/shared/dbus.h +++ b/src/shared/dbus.h @@ -19,27 +19,95 @@ #ifndef __STORAGED_DBUS_H__ #define __STORAGED_DBUS_H__ -#include -#include +#include +#include +#include +#include +#include + #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 diff --git a/src/shared/udev.c b/src/shared/udev.c index c4a60b6..2bdecfa 100644 --- a/src/shared/udev.c +++ b/src/shared/udev.c @@ -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); } diff --git a/src/storage/CMakeLists.txt b/src/storage/CMakeLists.txt index f3bac89..422b91d 100644 --- a/src/storage/CMakeLists.txt +++ b/src/storage/CMakeLists.txt @@ -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 ) diff --git a/src/storage/storage.c b/src/storage/storage.c old mode 100755 new mode 100644 index 79c1c1f..fb26935 --- a/src/storage/storage.c +++ b/src/storage/storage.c @@ -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 = { -- 2.7.4 From 26852340c0e4fe61c7d63b20aaa0a878f3d92552 Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Tue, 6 Feb 2018 20:17:26 +0900 Subject: [PATCH 03/16] Straighten up the code Change-Id: I8804cdf9385afcc74eda7939650bb4fff8be2973 Signed-off-by: pr.jung --- src/block/block.c | 220 +++++++++++++++++++++++++------------------------- src/shared/udev.c | 12 +-- src/storage/storage.c | 38 ++++----- 3 files changed, 135 insertions(+), 135 deletions(-) diff --git a/src/block/block.c b/src/block/block.c index d5739fd..601ef4e 100644 --- a/src/block/block.c +++ b/src/block/block.c @@ -881,7 +881,7 @@ static void create_external_apps_directory(void) int ret; ret = dbus_method_async(PKGDIR_BUS_NAME, PKGDIR_PATH, - PKGDIR_INTERFACE, "CreateExternalDirsForAllPkgs", NULL, NULL); + PKGDIR_INTERFACE, "CreateExternalDirsForAllPkgs", NULL, NULL); if (ret) _E("Fail to create external directory"); } @@ -2582,12 +2582,12 @@ static void remove_whole_block_device(void) } static void booting_done(GDBusConnection *conn, - const gchar *sender, - const gchar *path, - const gchar *iface, - const gchar *name, - GVariant *param, - gpointer data) + const gchar *sender, + const gchar *path, + const gchar *iface, + const gchar *name, + GVariant *param, + gpointer data) { static int done = 0; int ret; @@ -2610,12 +2610,12 @@ static void booting_done(GDBusConnection *conn, } static void block_poweroff(GDBusConnection *conn, - const gchar *sender, - const gchar *path, - const gchar *iface, - const gchar *name, - GVariant *param, - gpointer data) + const gchar *sender, + const gchar *path, + const gchar *iface, + const gchar *name, + GVariant *param, + gpointer data) { static int status = 0; if (status > 0) @@ -2705,8 +2705,8 @@ static void uevent_block_handler(struct udev_device *dev) } 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) + 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 = NULL; @@ -2749,7 +2749,7 @@ static GVariant *request_mount_block(GDBusConnection *conn, if (onprivate) { bdev->on_private_op = REQ_PRIVATE; bdev->private_pid = dbus_handle_get_sender_pid(NULL, sender); - _D("Private operation state: %d", bdev->on_private_op); + _D("Private operation state: %d pid: %d", bdev->on_private_op, bdev->private_pid); } else { if (bdev->on_private_op != REQ_NORMAL) { _E("Failed to process mount operation"); @@ -2788,22 +2788,22 @@ out: } 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) + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { return request_mount_block(conn, sender, path, iface, name, param, invocation, user_data, false); } 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) + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { return request_mount_block(conn, sender, path, iface, name, param, invocation, user_data, true); } 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) + 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; @@ -2836,7 +2836,7 @@ static GVariant *request_unmount_block(GDBusConnection *conn, if (onprivate) { 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"); + _E("Failed to process private unmount operation pid: %d private_pid: %d", pid, bdev->private_pid); ret = -EPERM; goto out; } @@ -2867,22 +2867,22 @@ out: } 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) + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { return request_unmount_block(conn, sender, path, iface, name, param, invocation, user_data, false); } 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) + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { return request_unmount_block(conn, sender, path, iface, name, param, invocation, user_data, true); } 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) + 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; @@ -2961,8 +2961,8 @@ out: } 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) + 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; @@ -3049,19 +3049,19 @@ static GVariant *block_data_to_gvariant(struct block_data *data, int flags) 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); + 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) @@ -3070,18 +3070,18 @@ static GVariant *block_data_to_gvariant2(struct block_data *data, int flags) 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); + 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); } @@ -3138,7 +3138,7 @@ static GVariant *block_data_to_gvariant2(struct block_data *data, int flags) //} static GVariant *request_get_device_info(GDBusConnection *conn, - const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { struct block_device *bdev = NULL; @@ -3159,16 +3159,16 @@ out: } 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) + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { show_block_device_list(); return dbus_handle_new_g_variant_tuple(); } // Called by MainThread 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) + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { GVariant *reply = NULL; struct block_device *bdev; @@ -3221,19 +3221,19 @@ static GVariant *request_get_device_list(GDBusConnection *conn, } 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); + 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)); } @@ -3249,8 +3249,8 @@ out: // Called by MainThread 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) + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { GVariant *reply = NULL; struct block_device *bdev; @@ -3303,18 +3303,18 @@ static GVariant *request_get_device_list_2(GDBusConnection *conn, } 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); + 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)); } @@ -3327,8 +3327,8 @@ out: } 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) + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { struct block_device *bdev; struct block_data *data, nodata = {0,}; @@ -3369,8 +3369,8 @@ static GVariant *request_get_mmc_primary(GDBusConnection *conn, } 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) + 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; struct block_device *bdev; @@ -3433,8 +3433,8 @@ out: 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) + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { int enable; int result; @@ -3462,8 +3462,8 @@ static GVariant *request_control_block(GDBusConnection *conn, } 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) + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { int result; @@ -3489,20 +3489,20 @@ static GVariant *request_getcontrol_block(GDBusConnection *conn, */ static const dbus_method_s manager_methods[] = { - { "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 }, + { "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 const dbus_interface_u block_interface = { diff --git a/src/shared/udev.c b/src/shared/udev.c index 2bdecfa..4ce94ea 100644 --- a/src/shared/udev.c +++ b/src/shared/udev.c @@ -265,12 +265,12 @@ int unregister_udev_uevent_control(const struct uevent_handler *uh) } static void device_change_poweroff(GDBusConnection *conn, - const gchar *sender, - const gchar *path, - const gchar *iface, - const gchar *name, - GVariant *param, - gpointer data) + const gchar *sender, + const gchar *path, + const gchar *iface, + const gchar *name, + GVariant *param, + gpointer data) { static int status = 0; if (status > 0) diff --git a/src/storage/storage.c b/src/storage/storage.c index fb26935..b18f6db 100644 --- a/src/storage/storage.c +++ b/src/storage/storage.c @@ -278,8 +278,8 @@ static int init_storage_config_info_all(void) } 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) + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { struct statvfs s; unsigned long long dAvail = 0.0; @@ -293,8 +293,8 @@ static GVariant *dbus_getstatus(GDBusConnection *conn, } 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) + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { char *str_path; struct statvfs s; @@ -333,12 +333,12 @@ static dbus_interface_u storage_interface = { }; static void booting_done(GDBusConnection *conn, - const gchar *sender, - const gchar *path, - const gchar *iface, - const gchar *name, - GVariant *param, - gpointer data) + const gchar *sender, + const gchar *path, + const gchar *iface, + const gchar *name, + GVariant *param, + gpointer data) { static int done; @@ -352,12 +352,12 @@ static void booting_done(GDBusConnection *conn, } static void storage_poweroff(GDBusConnection *conn, - const gchar *sender, - const gchar *path, - const gchar *iface, - const gchar *name, - GVariant *param, - gpointer data) + const gchar *sender, + const gchar *path, + const gchar *iface, + const gchar *name, + GVariant *param, + gpointer data) { if (memnoti_timer) { g_source_remove(memnoti_timer); @@ -409,9 +409,9 @@ static void storage_init(void *data) /* System Session is loaded completely */ id_booting_done = subscribe_dbus_signal(NULL, SYSTEMD_DBUS_PATH, - SYSTEMD_DBUS_IFACE_MANAGER, - SYSTEMD_DBUS_SIGNAL_SYSTEM_STARTUP_FINISHED, - booting_done, NULL, NULL); + SYSTEMD_DBUS_IFACE_MANAGER, + SYSTEMD_DBUS_SIGNAL_SYSTEM_STARTUP_FINISHED, + booting_done, NULL, NULL); id_storage_poweroff = subscribe_dbus_signal(NULL, DEVICED_PATH_POWEROFF, DEVICED_INTERFACE_POWEROFF, -- 2.7.4 From 9efd90a5495d50680f209403ca5a2f300f4c1c58 Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Fri, 9 Feb 2018 15:05:28 +0900 Subject: [PATCH 04/16] block: Fix dbus method string format for GetControl Change-Id: Iff6538b88827af03d9622d62dcfa650d78ce2a1c Signed-off-by: pr.jung --- src/block/block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/block.c b/src/block/block.c index 601ef4e..8c69605 100644 --- a/src/block/block.c +++ b/src/block/block.c @@ -3502,7 +3502,7 @@ static const dbus_method_s manager_methods[] = { { "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 }, + { "GetControl", NULL, "i", request_getcontrol_block }, }; static const dbus_interface_u block_interface = { -- 2.7.4 From f1bd86bd98923166a4d52d0fb06993f3b44c9c5b Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Mon, 26 Feb 2018 20:05:44 +0900 Subject: [PATCH 05/16] Change speedcheck methods by using O_DIRECT read operations to prevent corruption in existing filesystem on MicroSD card. Further work might be required to consider optimized zero-page reads in several MicroSD cards. Change-Id: Ic26f9c3c5396bbad7b21683d1b08a72c6a8404a3 Signed-off-by: Hyotaek Shim --- src/block/block.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/block/block.c b/src/block/block.c index 8c69605..a6267af 100644 --- a/src/block/block.c +++ b/src/block/block.c @@ -102,20 +102,21 @@ #define EXTENDEDSD_NAME "extendedsd" /* Minimum value of block id */ -#define BLOCK_ID_MIN 10 +#define BLOCK_ID_MIN 10 /* For 2.4 Backward Compatibility */ #define EXT_PRIMARY_SD_FIXID 1 /* Maximum number of thread */ -#define THREAD_MAX 5 +#define THREAD_MAX 5 -#define SPEEDCHECK 16 +#define SPEEDCHECK_SIZE 16 +#define SPEEDCHECK_CRITERION 4 /* MB/s */ #define PKGDIR_BUS_NAME "org.tizen.pkgdir_tool" #define PKGDIR_PATH "/org/tizen/pkgdir_tool" #define PKGDIR_INTERFACE "org.tizen.pkgdir_tool" -#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0])) +#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0])) enum block_dev_operation { BLOCK_DEV_MOUNT, @@ -3375,7 +3376,7 @@ static GVariant *request_check_speed(GDBusConnection *conn, struct timespec start_time, end_time; struct block_device *bdev; struct block_data *data; - char *buf; + char *buf = NULL; int ret; int result = 0; int id; @@ -3396,36 +3397,35 @@ static GVariant *request_check_speed(GDBusConnection *conn, } _D("speed check: %s", data->devnode); - fd = open(data->devnode, O_RDWR | O_SYNC); - buf = calloc(1, SPEEDCHECK << 20); - if (!buf) { - _E("calloc() failed"); + fd = open(data->devnode, O_RDONLY | O_DIRECT); + ret = posix_memalign((void**)&buf, 4096, SPEEDCHECK_SIZE << 20); + if (ret) { + _E("posix_memalign() failed"); result = -1; - close(fd); - goto out; + goto out_close; } + clock_gettime(CLOCK_REALTIME, &start_time); _I("start time: %lu.%lu", start_time.tv_sec, start_time.tv_nsec); - ret = write(fd, buf, SPEEDCHECK << 20); + ret = read(fd, buf, SPEEDCHECK_SIZE << 20); clock_gettime(CLOCK_REALTIME, &end_time); _I("end time %lu.%lu", end_time.tv_sec, end_time.tv_nsec); free(buf); - time_diff = end_time.tv_sec - start_time.tv_sec; - if (time_diff > 0 && (SPEEDCHECK / time_diff < 4)) { + if (ret < 0) { + _E("read() failed %d", errno); result = -1; - close(fd); - goto out; + goto out_close; } - if (ret < 0) { - _E("write() failed %d", errno); + time_diff = end_time.tv_sec - start_time.tv_sec; + if (time_diff > 0 && (SPEEDCHECK_SIZE / time_diff < SPEEDCHECK_CRITERION)) { result = -1; - close(fd); - goto out; + goto out_close; } +out_close: close(fd); out: return g_variant_new("(i)", result); -- 2.7.4 From e7f997efe23ba02d3dce6c61360b8435a862a89b Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Tue, 20 Feb 2018 14:50:02 +0900 Subject: [PATCH 06/16] auto-test: Add auto-test for storaged Change-Id: I272e1c869628569663da76aa377892a58a5042ba Signed-off-by: pr.jung Signed-off-by: Hyotaek Shim --- CMakeLists.txt | 2 + packaging/storaged.spec | 12 ++ scripts/storaged.conf | 12 +- src/auto-test/CMakeLists.txt | 37 ++++ src/auto-test/block.c | 420 +++++++++++++++++++++++++++++++++++++++++++ src/auto-test/main.c | 81 +++++++++ src/auto-test/result.c | 35 ++++ src/auto-test/storage.c | 125 +++++++++++++ src/auto-test/test.c | 71 ++++++++ src/auto-test/test.h | 97 ++++++++++ src/block/utils.h | 2 +- src/shared/dbus.c | 40 ++++- src/shared/dbus.h | 2 + 13 files changed, 932 insertions(+), 4 deletions(-) create mode 100644 src/auto-test/CMakeLists.txt create mode 100755 src/auto-test/block.c create mode 100644 src/auto-test/main.c create mode 100644 src/auto-test/result.c create mode 100755 src/auto-test/storage.c create mode 100644 src/auto-test/test.c create mode 100644 src/auto-test/test.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b3f953..cd7094b 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,3 +58,5 @@ ENDIF() IF(STORAGE_MODULE STREQUAL on) ADD_SUBDIRECTORY(src/storage) ENDIF() + +ADD_SUBDIRECTORY(src/auto-test) diff --git a/packaging/storaged.spec b/packaging/storaged.spec index c7e3d0c..1b2122c 100644 --- a/packaging/storaged.spec +++ b/packaging/storaged.spec @@ -66,6 +66,13 @@ Requires: %{name} = %{version}-%{release} %description org.tizen.extended-sd App to setup sdcard +%package auto-test +Summary: Storaged auto test tool +Group: System/Utilities +%description auto-test +Storaged helper programs. +This package can be installed optional for auto dbus test. + %prep %setup -q %if %{with emulator} @@ -151,3 +158,8 @@ systemctl daemon-reload %{TZ_SYS_RO_APP}/org.tizen.extended-sd/res/* %{TZ_SYS_RO_PACKAGES}/org.tizen.extended-sd.xml %{TZ_SYS_RO_APP}/org.tizen.extended-sd/res/edje/extended-sd.edj + +%files auto-test +%license LICENSE.Apache-2.0 +%manifest %{name}.manifest +%{_bindir}/storaged-auto-test diff --git a/scripts/storaged.conf b/scripts/storaged.conf index b6f7967..ecd3199 100644 --- a/scripts/storaged.conf +++ b/scripts/storaged.conf @@ -1,9 +1,17 @@ + + + + + - - + + + + diff --git a/src/auto-test/CMakeLists.txt b/src/auto-test/CMakeLists.txt new file mode 100644 index 0000000..e61607b --- /dev/null +++ b/src/auto-test/CMakeLists.txt @@ -0,0 +1,37 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(storaged-auto-test C) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src) + +SET(SRCS + test.c + main.c + result.c + ../shared/dbus.c + block.c + storage.c +) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src/shared) + +SET(PKG_MODULES + dlog + glib-2.0 +) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkgs REQUIRED ${PKG_MODULES}) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Werror") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -lrt -fPIE") +SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") + +ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} "-ldl" "-lm") + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin) diff --git a/src/auto-test/block.c b/src/auto-test/block.c new file mode 100755 index 0000000..bc2a7b2 --- /dev/null +++ b/src/auto-test/block.c @@ -0,0 +1,420 @@ +/* + * storaged auto-test + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless requblocked by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "test.h" + +#define METHOD_BLOCK_SHOWDEVICELIST "ShowDeviceList" +#define METHOD_BLOCK_GETDEVICELIST "GetDeviceList" +#define METHOD_BLOCK_GETDEVICELIST2 "GetDeviceList2" +#define METHOD_BLOCK_MOUNT "Mount" +#define METHOD_BLOCK_UNMOUNT "Unmount" +#define METHOD_BLOCK_FORMAT "Format" +#define METHOD_BLOCK_FORMATWITHTYPE "FormatwithType" +#define METHOD_BLOCK_GETDEVICEINFO "GetDeviceInfo" +#define METHOD_BLOCK_GETMMCPRIMARY "GetMmcPrimary" +#define METHOD_BLOCK_PRIVATEMOUNT "PrivateMount" +#define METHOD_BLOCK_PRIVATEUNMOUNT "PrivateUnmount" +#define METHOD_BLOCK_CHECKSPEED "CheckSpeed" +#define METHOD_BLOCK_CONTROL "Control" +#define METHOD_BLOCK_GETCONTROL "GetControl" + +#define DBUS_DEFAULT_TIMEOUT (-1) + +static bool request_block_method(const char *method, GVariant *param, int timeout) +{ + GVariant *msg; + int val; + bool ret = FALSE; + + msg = dbus_method_sync_with_reply_var_timeout(STORAGED_BUS_NAME, + STORAGED_PATH_BLOCK_MANAGER, + STORAGED_INTERFACE_BLOCK_MANAGER, + method, param, timeout); + + if (!msg) { + _E("fail (%s): no reply", method); + return ret; + } + + if (!dh_get_param_from_var(msg, "(i)", &val)) + _E("fail (%s): no message", method); + else { + if ((val == -ENOTSUP) || (val == -ENOSYS)) { + _I("Not supported feature! (%s): %d", method, val); + ret = TRUE; + } else if (val == -ENODEV) { + _E("fail (%s): device open fail (%d)", method, val); + } else if (val < 0) { + _E("fail (%s): returned fail (%d)", method, val); + } else { + _I("success (%s): %d", method, val); + ret = TRUE; + } + } + + g_variant_unref(msg); + return ret; +} + +static int get_id() +{ + GVariant *msg; + int val; + int ret = -1; + + msg = dbus_method_sync_with_reply_var(STORAGED_BUS_NAME, + STORAGED_PATH_BLOCK_MANAGER, + STORAGED_INTERFACE_BLOCK_MANAGER, + METHOD_BLOCK_GETMMCPRIMARY, + NULL); + + if (!msg) { + _E("fail (%s): no reply", METHOD_BLOCK_GETMMCPRIMARY); + return ret; + } + + if (!dh_get_param_from_var(msg, "(issssssisibii)", + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, &val)) + _E("fail (%s): no message", METHOD_BLOCK_GETMMCPRIMARY); + else + ret = val; + + _D("id: %d", ret); + g_variant_unref(msg); + return ret; +} + +static bool block_showdevicelist() +{ + GVariant *msg; + int ret = FALSE; + + _D("----------------------------------------------------------------------------------"); + + msg = dbus_method_sync_with_reply_var(STORAGED_BUS_NAME, + STORAGED_PATH_BLOCK_MANAGER, + STORAGED_INTERFACE_BLOCK_MANAGER, + METHOD_BLOCK_SHOWDEVICELIST, + NULL); + + if (!msg) { + _E("fail (%s): no reply", METHOD_BLOCK_SHOWDEVICELIST); + return ret; + } + + _I("success (%s)", METHOD_BLOCK_SHOWDEVICELIST); + g_variant_unref(msg); + return TRUE; +} + +static bool block_getdevicelist(char *type) +{ + GVariant *msg; + GVariantIter *iter; + int val; + int ret = FALSE; + + _D("----------------------------------------------------------------------------------"); + msg = dbus_method_sync_with_reply_var(STORAGED_BUS_NAME, + STORAGED_PATH_BLOCK_MANAGER, + STORAGED_INTERFACE_BLOCK_MANAGER, + METHOD_BLOCK_GETDEVICELIST, + g_variant_new("(s)", type)); + + if (!msg) { + _E("fail (%s): no reply", METHOD_BLOCK_GETMMCPRIMARY); + return ret; + } + + g_variant_get(msg, "(a(issssssisibii))", &iter); + while (g_variant_iter_loop(iter, "(issssssisibii)", + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, &val)) { + _D("id: %d", val); + ret = TRUE; + } + + _I("success (%s): %d", METHOD_BLOCK_GETDEVICELIST, ret); + return ret; +} + +static bool block_getdevicelist2(char *type) +{ + GVariant *msg; + GVariantIter *iter; + char *val; + int ret = FALSE; + + _D("----------------------------------------------------------------------------------"); + msg = dbus_method_sync_with_reply_var(STORAGED_BUS_NAME, + STORAGED_PATH_BLOCK_MANAGER, + STORAGED_INTERFACE_BLOCK_MANAGER, + METHOD_BLOCK_GETDEVICELIST2, + g_variant_new("(s)", type)); + + if (!msg) { + _E("fail (%s): no reply", METHOD_BLOCK_GETMMCPRIMARY); + return ret; + } + + g_variant_get(msg, "(a(issssssisibi))", &iter); + while (g_variant_iter_loop(iter, "(issssssisibi)", + NULL, &val, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL)) { + _D("devnode: %s", val); + ret = TRUE; + } + + _I("success (%s): %d", METHOD_BLOCK_GETDEVICELIST2, ret); + return ret; +} + +static bool block_mount(int id, char *mount_point) +{ + _D("----------------------------------------------------------------------------------"); + return request_block_method(METHOD_BLOCK_MOUNT, g_variant_new("(is)", id, mount_point), DBUS_DEFAULT_TIMEOUT); +} + +static bool block_unmount(int id, int option) +{ + _D("----------------------------------------------------------------------------------"); + return request_block_method(METHOD_BLOCK_UNMOUNT, g_variant_new("(ii)", id, option), DBUS_DEFAULT_TIMEOUT); +} + +static bool block_format(int id, int option) +{ + _D("----------------------------------------------------------------------------------"); + return request_block_method(METHOD_BLOCK_FORMAT, g_variant_new("(ii)", id, option), G_MAXINT); +} + +static bool block_formatwithtype(int id, int option, char *type) +{ + _D("----------------------------------------------------------------------------------"); + return request_block_method(METHOD_BLOCK_FORMATWITHTYPE, g_variant_new("(iis)", id, option, type), G_MAXINT); +} + +static bool block_getdeviceinfo(int id) +{ + GVariant *msg; + int val = -1; + int ret = FALSE; + + _D("----------------------------------------------------------------------------------"); + msg = dbus_method_sync_with_reply_var(STORAGED_BUS_NAME, + STORAGED_PATH_BLOCK_MANAGER, + STORAGED_INTERFACE_BLOCK_MANAGER, + METHOD_BLOCK_GETDEVICEINFO, + g_variant_new("(i)", id)); + + if (!msg) { + _E("fail (%s): no reply", METHOD_BLOCK_GETMMCPRIMARY); + return ret; + } + + if (!dh_get_param_from_var(msg, "(issssssisibii)", + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, &val)) + _E("fail (%s): no message", METHOD_BLOCK_GETMMCPRIMARY); + else + ret = TRUE; + + if (val != id) { + ret = FALSE; + _E("fail (%s)", METHOD_BLOCK_GETMMCPRIMARY); + } + + _I("success (%s): %d", METHOD_BLOCK_GETDEVICEINFO, ret); + return ret; +} + +static bool block_getmmcprimary() +{ + GVariant *msg; + int val = -1; + int ret = FALSE; + + _D("----------------------------------------------------------------------------------"); + msg = dbus_method_sync_with_reply_var(STORAGED_BUS_NAME, + STORAGED_PATH_BLOCK_MANAGER, + STORAGED_INTERFACE_BLOCK_MANAGER, + METHOD_BLOCK_GETMMCPRIMARY, + NULL); + + if (!msg) { + _E("fail (%s): no reply", METHOD_BLOCK_GETMMCPRIMARY); + return ret; + } + + if (!dh_get_param_from_var(msg, "(issssssisibii)", + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, &val)) + _E("fail (%s): no message", METHOD_BLOCK_GETMMCPRIMARY); + else + ret = TRUE; + + _D("id: %d", val); + _I("success (%s): %d", METHOD_BLOCK_GETMMCPRIMARY, ret); + return ret; +} + +static bool block_privatemount(int id, char *mount_point) +{ + _D("----------------------------------------------------------------------------------"); + return request_block_method(METHOD_BLOCK_PRIVATEMOUNT, g_variant_new("(is)", id, mount_point), DBUS_DEFAULT_TIMEOUT); +} + +static bool block_privateunmount(int id, int option) +{ + _D("----------------------------------------------------------------------------------"); + return request_block_method(METHOD_BLOCK_PRIVATEUNMOUNT, g_variant_new("(ii)", id, option), DBUS_DEFAULT_TIMEOUT); +} + +static bool block_checkspeed(int id) +{ + _D("----------------------------------------------------------------------------------"); + return request_block_method(METHOD_BLOCK_CHECKSPEED, g_variant_new("(i)", id), G_MAXINT); +} + +static bool block_control(int enable) +{ + _D("----------------------------------------------------------------------------------"); + return request_block_method(METHOD_BLOCK_CONTROL, g_variant_new("(i)", enable), DBUS_DEFAULT_TIMEOUT); +} + +static bool block_getcontrol() +{ + _D("----------------------------------------------------------------------------------"); + return request_block_method(METHOD_BLOCK_GETCONTROL, NULL, DBUS_DEFAULT_TIMEOUT); +} + +void block_test_all(int *success, int *fail) +{ + int s = 0; + int f = 0; + int id = 0; + + id = get_id(); + + _D("------------------- Precondition start --------------------"); + block_unmount(id, 1); + _D("------------------- Precondition end ----------------------"); + (block_checkspeed(id)) ? s++ : f++; + (block_format(id, 1)) ? s++ : f++; + (block_formatwithtype(id, 1, "vfat")) ? s++ : f++; + (block_showdevicelist()) ? s++ : f++; + (block_getdevicelist("all")) ? s++ : f++; + (block_getdevicelist2("all")) ? s++ : f++; + (block_mount(id, "")) ? s++ : f++; + (block_unmount(id, 1)) ? s++ : f++; + (block_getdeviceinfo(id)) ? s++ : f++; + (block_getmmcprimary()) ? s++ : f++; + (block_privatemount(id, "")) ? s++ : f++; + (block_privateunmount(id, 1)) ? s++ : f++; + block_mount(id, ""); + (block_control(0)) ? s++ : f++; + request_block_method(METHOD_BLOCK_CONTROL, g_variant_new("(i)", 1), DBUS_DEFAULT_TIMEOUT); + (block_getcontrol()) ? s++ : f++; + _D("----------------------------------------------------------------------------------"); + + if (NULL != success) *success = s; + if (NULL != fail) *fail = f; +} + +static void block_init(void *data) +{ + int success = 0; + int fail = 0; + + _I("start test"); + + block_test_all(&success, &fail); + + _I("Total: %d, Success: %d, Fail: %d", success+fail, success, fail); +} + +static void block_exit(void *data) +{ + _I("end test"); +} + +static int block_unit(int argc, char **argv) +{ + int id = 0; + + id = get_id(); + + if (argc < 3) { + int success = 0; + int fail = 0; + + _I("start test"); + block_test_all(&success, &fail); + _I("Total: %d, Success: %d, Fail: %d", success+fail, success, fail); + } else if (0 == strcasecmp(argv[2], METHOD_BLOCK_SHOWDEVICELIST)) { + block_showdevicelist(); + } else if (0 == strcasecmp(argv[2], METHOD_BLOCK_GETDEVICELIST)) { + block_getdevicelist(argv[3]); + } else if (0 == strcasecmp(argv[2], METHOD_BLOCK_GETDEVICELIST2)) { + block_getdevicelist2(argv[3]); + } else if (0 == strcasecmp(argv[2], METHOD_BLOCK_MOUNT)) { + block_mount(id, argv[3]); + } else if (0 == strcasecmp(argv[2], METHOD_BLOCK_UNMOUNT)) { + block_unmount(id, atoi(argv[3])); + } else if (0 == strcasecmp(argv[2], METHOD_BLOCK_FORMAT)) { + block_format(id, atoi(argv[3])); + } else if (0 == strcasecmp(argv[2], METHOD_BLOCK_FORMATWITHTYPE)) { + block_formatwithtype(id, atoi(argv[3]), argv[4]); + } else if (0 == strcasecmp(argv[2], METHOD_BLOCK_GETDEVICEINFO)) { + block_getdeviceinfo(id); + } else if (0 == strcasecmp(argv[2], METHOD_BLOCK_GETMMCPRIMARY)) { + block_getmmcprimary(); + } else if (0 == strcasecmp(argv[2], METHOD_BLOCK_PRIVATEMOUNT)) { + _D("------------------- Private operation test precondition start --------------------"); + block_unmount(id, 1); + _D("------------------- Private operation test precondition end--------------------"); + block_privatemount(id, argv[3]); + } else if (0 == strcasecmp(argv[2], METHOD_BLOCK_PRIVATEUNMOUNT)) { + _D("------------------- Private operation test precondition start --------------------"); + block_unmount(id, 1); + block_privatemount(id, ""); + _D("------------------- Private operation test precondition end--------------------"); + block_privateunmount(id, atoi(argv[3])); + } else if (0 == strcasecmp(argv[2], METHOD_BLOCK_CHECKSPEED)) { + block_checkspeed(id); + } else if (0 == strcasecmp(argv[2], METHOD_BLOCK_CONTROL)) { + block_control(atoi(argv[3])); + request_block_method(METHOD_BLOCK_CONTROL, g_variant_new("(i)", 1), DBUS_DEFAULT_TIMEOUT); + } else if (0 == strcasecmp(argv[2], METHOD_BLOCK_GETCONTROL)) { + block_getcontrol(); + } else { + _E("Unknown test case!!!"); + } + _D("----------------------------------------------------------------------------------"); + + return 0; +} + +static const struct test_ops block_test_ops = { + .priority = TEST_PRIORITY_NORMAL, + .name = "block", + .init = block_init, + .exit = block_exit, + .unit = block_unit, +}; + +TEST_OPS_REGISTER(&block_test_ops) diff --git a/src/auto-test/main.c b/src/auto-test/main.c new file mode 100644 index 0000000..055a556 --- /dev/null +++ b/src/auto-test/main.c @@ -0,0 +1,81 @@ +/* + * storaged auto-test + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test.h" + +static void test_main(int argc, char **argv) +{ + _I("auto test all"); + test_init((void *)NULL); + test_exit((void *)NULL); +} + +static void unit_test(int argc, char **argv) +{ + const struct test_ops *ops; + + ops = find_test(argv[1]); + if (!ops) { + _E("there is no test ops : %s", argv[1]); + return; + } + ops->unit(argc, argv); +} + +void show_usage() +{ + printf("Usage: storaged-auto-test [MODULE] [UNIT-METHOD] [OPTS]\n\n"); + printf("Optional arguments\nIf you don't give any optional arguments, all supported modules will be tested.\n"); + printf("All module list is as below.\nAs per profile, supported modules are different.\n"); + printf("[MODULE] [UNIT-METHOD] [OPTS]\n"); + printf("block ShowDeviceList N/A\n"); + printf("block GetDeviceList scsi/mmc/all\n"); + printf("block GetDeviceList2 scsi/mmc/all\n"); + printf("block Mount mount path\n"); + printf("block Unmount option: 0(normal)/1(force)\n"); + printf("block Format option: 0(normal)/1(force)\n"); + printf("block FormatwithType filesystem: vfat/ext4, option: 0/1\n"); + printf("block GetDeviceInfo N/A\n"); + printf("block GetMmcPrimary N/A\n"); + printf("block PrivateMount mount path\n"); + printf("block PrivateUnmount option: 0(normal)/1(force)\n"); + printf("block CheckSpeed N/A\n"); + printf("block Control option: 0(disable)/1(enable)\n"); + printf("block GetControl N/A\n"); + printf("storage getstorage N/A\n"); + printf("storage GetStatus path\n"); +} + +int main(int argc, char **argv) +{ + if (argc == 2) { + if (!strncmp(argv[1], "help", strlen("help") + 1)) { + show_usage(); + return 0; + } + } + + if (argc >= 2) + unit_test(argc, argv); + else + test_main(argc, argv); + + + return 0; +} + diff --git a/src/auto-test/result.c b/src/auto-test/result.c new file mode 100644 index 0000000..83bad1a --- /dev/null +++ b/src/auto-test/result.c @@ -0,0 +1,35 @@ +/* + * storaged auto-test + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "shared/log.h" + +#define BUF_MAX 256 + +void _R(const char *format, ...) +{ + va_list args; + char buf[BUF_MAX]; + + va_start(args, format); + vsnprintf(buf, BUF_MAX, format, args); + va_end(args); + + _D("%s", buf); +} diff --git a/src/auto-test/storage.c b/src/auto-test/storage.c new file mode 100755 index 0000000..e800027 --- /dev/null +++ b/src/auto-test/storage.c @@ -0,0 +1,125 @@ +/* + * storaged auto-test + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless requstorageed by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "test.h" + +#define METHOD_STORAGE_GETSTORAGE "getstorage" +#define METHOD_STORAGE_GETSTATUS "GetStatus" + +static bool request_storage_method(const char *method, GVariant *param) +{ + GVariant *msg; + unsigned long long val1, val2; + bool ret = FALSE; + + msg = dbus_method_sync_with_reply_var(STORAGED_BUS_NAME, + STORAGED_PATH_STORAGE, + STORAGED_INTERFACE_STORAGE, + method, param); + + if (!msg) { + _E("fail (%s): no reply", method); + return ret; + } + + if (!dh_get_param_from_var(msg, "(tt)", &val1, &val2)) + _E("fail (%s): no message", method); + else { + if (val1 <= 0) { + _E("fail (%s): returned total storage (%d)", method, val1); + } else { + _I("success (%s): Total: %4.0llu Avail: %4.0llu", method, val1, val2); + ret = TRUE; + } + } + + g_variant_unref(msg); + return ret; +} + +static bool storage_getstorage() +{ + _D("----------------------------------------------------------------------------------"); + return request_storage_method(METHOD_STORAGE_GETSTORAGE, NULL); +} + +static bool storage_getstatus(char *path) +{ + _D("----------------------------------------------------------------------------------"); + return request_storage_method(METHOD_STORAGE_GETSTATUS, g_variant_new("(s)", path)); +} + +void storage_test_all(int *success, int *fail) +{ + int s = 0; + int f = 0; + + (storage_getstorage()) ? s++ : f++; + (storage_getstatus("/opt/usr/home")) ? s++ : f++; + _D("----------------------------------------------------------------------------------"); + + if (NULL != success) *success = s; + if (NULL != fail) *fail = f; +} + +static void storage_init(void *data) +{ + int success = 0; + int fail = 0; + + _I("start test"); + + storage_test_all(&success, &fail); + + _I("Total: %d, Success: %d, Fail: %d", success+fail, success, fail); +} + +static void storage_exit(void *data) +{ + _I("end test"); +} + +static int storage_unit(int argc, char **argv) +{ + if (argc < 3) { + int success = 0; + int fail = 0; + + _I("start test"); + storage_test_all(&success, &fail); + _I("Total: %d, Success: %d, Fail: %d", success+fail, success, fail); + } else if (0 == strcasecmp(argv[2], METHOD_STORAGE_GETSTORAGE)) { + storage_getstorage(); + } else if (0 == strcasecmp(argv[2], METHOD_STORAGE_GETSTATUS)) { + storage_getstatus(argv[3]); + } else { + _E("Unknown test case!!!"); + } + _D("----------------------------------------------------------------------------------"); + + return 0; +} + +static const struct test_ops storage_test_ops = { + .priority = TEST_PRIORITY_NORMAL, + .name = "storage", + .init = storage_init, + .exit = storage_exit, + .unit = storage_unit, +}; + +TEST_OPS_REGISTER(&storage_test_ops) diff --git a/src/auto-test/test.c b/src/auto-test/test.c new file mode 100644 index 0000000..d59cf6f --- /dev/null +++ b/src/auto-test/test.c @@ -0,0 +1,71 @@ +/* + * storaged auto-test + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test.h" + +static dd_list *dd_head; + +void add_test(const struct test_ops *d) +{ + if (d->priority == TEST_PRIORITY_HIGH) + DD_LIST_PREPEND(dd_head, d); + else + DD_LIST_APPEND(dd_head, d); +} + +void remove_test(const struct test_ops *d) +{ + DD_LIST_REMOVE(dd_head, d); +} + +const struct test_ops *find_test(const char *name) +{ + dd_list *elem; + const struct test_ops *d; + + DD_LIST_FOREACH(dd_head, elem, d) { + if (!strcasecmp(d->name, name)) + return d; + } + return NULL; +} + +void test_init(void *data) +{ + dd_list *elem; + const struct test_ops *d; + + _D("test module count(%d)", DD_LIST_LENGTH(dd_head)); + DD_LIST_FOREACH(dd_head, elem, d) { + _D("[%s] initialize", d->name); + if (d->init) + d->init(data); + } +} + +void test_exit(void *data) +{ + dd_list *elem; + const struct test_ops *d; + + DD_LIST_FOREACH(dd_head, elem, d) { + _D("[%s] deinitialize", d->name); + if (d->exit) + d->exit(data); + } +} diff --git a/src/auto-test/test.h b/src/auto-test/test.h new file mode 100644 index 0000000..3d04127 --- /dev/null +++ b/src/auto-test/test.h @@ -0,0 +1,97 @@ +/* + * storaged auto-test + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __TEST_H__ +#define __TEST_H__ +#include +#include + +#include "list.h" +#include "log.h" +#include "dbus.h" +#include "storaged_common.h" + +#ifdef ENABLE_TEST_DLOG +#define ENABLE_DLOG +#endif + +enum test_priority { + TEST_PRIORITY_NORMAL = 0, + TEST_PRIORITY_HIGH, +}; + +struct test_ops { + enum test_priority priority; + char *name; + void (*init) (void *data); + void (*exit) (void *data); + int (*start) (void); + int (*stop) (void); + int (*status) (void); + int (*unit) (int argc, char **argv); +}; + +enum test_ops_status { + TEST_OPS_STATUS_UNINIT, + TEST_OPS_STATUS_START, + TEST_OPS_STATUS_STOP, + TEST_OPS_STATUS_MAX, +}; + +void test_init(void *data); +void test_exit(void *data); + +static inline int test_start(const struct test_ops *c) +{ + if (c && c->start) + return c->start(); + + return -EINVAL; +} + +static inline int test_stop(const struct test_ops *c) +{ + if (c && c->stop) + return c->stop(); + + return -EINVAL; +} + +static inline int test_get_status(const struct test_ops *c) +{ + if (c && c->status) + return c->status(); + + return -EINVAL; +} + +#define TEST_OPS_REGISTER(c) \ +static void __CONSTRUCTOR__ module_init(void) \ +{ \ + add_test(c); \ +} \ +static void __DESTRUCTOR__ module_exit(void) \ +{ \ + remove_test(c); \ +} +void add_test(const struct test_ops *c); +void remove_test(const struct test_ops *c); +const struct test_ops *find_test(const char *name); +void _R(const char *format, ...); +#endif diff --git a/src/block/utils.h b/src/block/utils.h index 8bf2a9b..23d058a 100644 --- a/src/block/utils.h +++ b/src/block/utils.h @@ -21,7 +21,7 @@ #include #include "log.h" -#include "common.h" +#include "storaged_common.h" int print_open_files(const char *mount_point); int terminate_process(const char *partition, bool force); diff --git a/src/shared/dbus.c b/src/shared/dbus.c index 2778d25..bf7c396 100644 --- a/src/shared/dbus.c +++ b/src/shared/dbus.c @@ -22,7 +22,7 @@ #include #include -#include "common.h" +#include "storaged_common.h" #include "log.h" #include "dbus.h" @@ -1684,6 +1684,44 @@ GVariant *dbus_method_sync_with_reply_var(const char *dest, const char *path, return ret; } +GVariant *dbus_method_sync_with_reply_var_timeout(const char *dest, const char *path, + const char *iface, const char *method, GVariant *var, int timeout) +{ + 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, 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; +} + gint* dbus_handle_get_unix_fd_list(GDBusMethodInvocation *invocation, int *size) { GUnixFDList *fd_list = NULL; diff --git a/src/shared/dbus.h b/src/shared/dbus.h index 7225546..d70ef19 100644 --- a/src/shared/dbus.h +++ b/src/shared/dbus.h @@ -49,6 +49,8 @@ GVariant *dbus_method_sync_with_reply(const char *dest, const char *path, GVariant *dbus_method_sync_with_reply_var(const char *dest, const char *path, const char *iface, const char *method, GVariant *var); +GVariant *dbus_method_sync_with_reply_var_timeout(const char *dest, const char *path, const char *iface, const char *method, GVariant *var, int timeout); + /* fd */ gint* dbus_handle_get_unix_fd_list(GDBusMethodInvocation *invocation, int *size); -- 2.7.4 From ecb04355a10bef78a3e77b584a5fd5bdc478aa72 Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Mon, 5 Mar 2018 20:45:26 +0900 Subject: [PATCH 07/16] Add compile options: -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 Change-Id: Ieb40d80c30668673177f6ccee9e580d79b62ef6e Signed-off-by: Hyotaek Shim --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index cd7094b..4fefdc7 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,7 @@ FOREACH(flag ${${PROJECT_NAME}_pkgs_CFLAGS}) ENDFOREACH(flag) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Werror -rdynamic -Wno-deprecated-declarations") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64") SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -lrt -fPIE") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") -- 2.7.4 From bc75ac30c74b14b088254042d7bcf6263fd56fed Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Tue, 27 Feb 2018 18:08:34 +0900 Subject: [PATCH 08/16] block: Add GetStatvfs dbus method Change-Id: I2d6f6fa61a8785638624e93ee02992c880da3f70 Signed-off-by: pr.jung --- src/storage/storage.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/storage/storage.c b/src/storage/storage.c index b18f6db..9e7b368 100644 --- a/src/storage/storage.c +++ b/src/storage/storage.c @@ -320,9 +320,35 @@ static GVariant *dbus_get_storage_status(GDBusConnection *conn, return g_variant_new("(tt)", dTotal, dAvail); } +static GVariant *dbus_getstatvfs(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) +{ + char *str_path; + pid_t pid; + struct statvfs s; + + g_variant_get(param, "(s)", &str_path); + + storage_get_memory_size(str_path, &s); + + pid = dbus_handle_get_sender_pid(NULL, sender); + + _D("[request %d] path %s", pid, str_path); + + g_free(str_path); + + return g_variant_new("(ttttttttttt)", (guint64)(s.f_bsize), (guint64)(s.f_frsize), + (guint64)(s.f_blocks), (guint64)(s.f_bfree), (guint64)(s.f_bavail), + (guint64)(s.f_files), (guint64)(s.f_ffree), (guint64)(s.f_favail), + (guint64)(s.f_fsid), (guint64)(s.f_flag), (guint64)(s.f_namemax)); + +} + static const dbus_method_s storage_methods[] = { { "getstorage", NULL, "tt", dbus_getstatus }, { "GetStatus", "s", "tt", dbus_get_storage_status}, + { "GetStatvfs", "s", "ttttttttttt", dbus_getstatvfs }, /* Add methods here */ }; -- 2.7.4 From a54f6748eae0a1d3ced2266ca2b1dea72228faff Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Mon, 5 Mar 2018 22:23:51 +0900 Subject: [PATCH 09/16] dbus: modify dbus policy correctly Change-Id: I3d26b9ed55aa7462e3fa4fe3ff44a1578f595a4d Signed-off-by: sanghyeok.oh --- apps/extended-sd/org.tizen.extended-sd.xml | 1 + scripts/storaged.conf | 53 +++++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 8 deletions(-) mode change 100644 => 100755 scripts/storaged.conf diff --git a/apps/extended-sd/org.tizen.extended-sd.xml b/apps/extended-sd/org.tizen.extended-sd.xml index 7b4b24f..2ddf588 100755 --- a/apps/extended-sd/org.tizen.extended-sd.xml +++ b/apps/extended-sd/org.tizen.extended-sd.xml @@ -5,6 +5,7 @@ http://tizen.org/privilege/appmanager.launch http://tizen.org/privilege/display + http://tizen.org/privilege/externalstorage diff --git a/scripts/storaged.conf b/scripts/storaged.conf old mode 100644 new mode 100755 index ecd3199..8657f26 --- a/scripts/storaged.conf +++ b/scripts/storaged.conf @@ -1,23 +1,60 @@ + - - + + + + - + + + - + + + + + + + + + + + + -- 2.7.4 From d4db6714f55810866cb4268c8db4722d66d0f16c Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Thu, 8 Mar 2018 08:50:30 +0900 Subject: [PATCH 10/16] Minor fixes: chmod files, rename dbus conf file, etc. Change-Id: Ia23bfea0d18dd65f9c3a7a504f0b7b4817980d89 Signed-off-by: Hyotaek Shim --- CMakeLists.txt | 4 ++-- apps/CMakeLists.txt | 0 apps/extended-sd/CMakeLists.txt | 0 apps/extended-sd/org.tizen.extended-sd.xml | 0 .../resource/images/extended_storage_sd_card.png | Bin scripts/storaged.conf => conf/org.tizen.system.storage.conf | 0 packaging/storaged.spec | 2 +- src/auto-test/block.c | 0 src/auto-test/storage.c | 0 src/shared/apps.c | 0 src/shared/apps.h | 0 src/shared/dbus_macro.h | 0 12 files changed, 3 insertions(+), 3 deletions(-) mode change 100755 => 100644 CMakeLists.txt mode change 100755 => 100644 apps/CMakeLists.txt mode change 100755 => 100644 apps/extended-sd/CMakeLists.txt mode change 100755 => 100644 apps/extended-sd/org.tizen.extended-sd.xml mode change 100755 => 100644 apps/extended-sd/resource/images/extended_storage_sd_card.png rename scripts/storaged.conf => conf/org.tizen.system.storage.conf (100%) mode change 100755 => 100644 mode change 100755 => 100644 src/auto-test/block.c mode change 100755 => 100644 src/auto-test/storage.c mode change 100755 => 100644 src/shared/apps.c mode change 100755 => 100644 src/shared/apps.h mode change 100755 => 100644 src/shared/dbus_macro.h diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100755 new mode 100644 index 4fefdc7..e949ab8 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,7 @@ SET(PKG_MODULES ) ADD_DEFINITIONS("-DLIBPATH=\"${LIB_INSTALL_DIR}\"") +ADD_DEFINITIONS("-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64") INCLUDE(FindPkgConfig) pkg_check_modules(${PROJECT_NAME}_pkgs REQUIRED ${PKG_MODULES}) @@ -38,7 +39,6 @@ FOREACH(flag ${${PROJECT_NAME}_pkgs_CFLAGS}) ENDFOREACH(flag) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Werror -rdynamic -Wno-deprecated-declarations") -SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64") SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -lrt -fPIE") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") @@ -47,7 +47,7 @@ ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${${PROJECT_NAME}_pkgs_LDFLAGS} "-ldl" "-lm") INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin) -INSTALL(FILES ${CMAKE_SOURCE_DIR}/scripts/storaged.conf DESTINATION /etc/dbus-1/system.d) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/conf/org.tizen.system.storage.conf DESTINATION /etc/dbus-1/system.d) INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/systemd/ DESTINATION lib/systemd/system FILES_MATCHING PATTERN "storaged.service") diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/apps/extended-sd/CMakeLists.txt b/apps/extended-sd/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/apps/extended-sd/org.tizen.extended-sd.xml b/apps/extended-sd/org.tizen.extended-sd.xml old mode 100755 new mode 100644 diff --git a/apps/extended-sd/resource/images/extended_storage_sd_card.png b/apps/extended-sd/resource/images/extended_storage_sd_card.png old mode 100755 new mode 100644 diff --git a/scripts/storaged.conf b/conf/org.tizen.system.storage.conf old mode 100755 new mode 100644 similarity index 100% rename from scripts/storaged.conf rename to conf/org.tizen.system.storage.conf diff --git a/packaging/storaged.spec b/packaging/storaged.spec index 1b2122c..15b86c9 100644 --- a/packaging/storaged.spec +++ b/packaging/storaged.spec @@ -132,7 +132,7 @@ systemctl daemon-reload %files %manifest %{name}.manifest %license LICENSE.Apache-2.0 -%config %{_sysconfdir}/dbus-1/system.d/storaged.conf +%config %{_sysconfdir}/dbus-1/system.d/org.tizen.system.storage.conf %{_unitdir}/multi-user.target.wants/storaged.service %{_unitdir}/storaged.service %{_bindir}/storaged diff --git a/src/auto-test/block.c b/src/auto-test/block.c old mode 100755 new mode 100644 diff --git a/src/auto-test/storage.c b/src/auto-test/storage.c old mode 100755 new mode 100644 diff --git a/src/shared/apps.c b/src/shared/apps.c old mode 100755 new mode 100644 diff --git a/src/shared/apps.h b/src/shared/apps.h old mode 100755 new mode 100644 diff --git a/src/shared/dbus_macro.h b/src/shared/dbus_macro.h old mode 100755 new mode 100644 -- 2.7.4 From 960470a3c710b6659f624113eee08382645a431e Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Mon, 12 Mar 2018 17:59:35 +0900 Subject: [PATCH 11/16] block: Create default directory for mmc - Create default directories (Images, Videos, Sountds, Downloads) for primary sdcard Change-Id: If3cb0d66ad41d13c05a00dfc85256f8eabafc8b3 Signed-off-by: pr.jung --- src/block/block.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/block/block.c b/src/block/block.c index a6267af..7a11e3d 100644 --- a/src/block/block.c +++ b/src/block/block.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "log.h" #include "config-parser.h" @@ -118,6 +119,8 @@ #define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0])) +#define FILE_NAME_LEN_MAX 255 + enum block_dev_operation { BLOCK_DEV_MOUNT, BLOCK_DEV_UNMOUNT, @@ -179,6 +182,15 @@ static struct manage_thread { bool start_th; } th_manager[THREAD_MAX]; +char mmc_default_path[][FILE_NAME_LEN_MAX + 1] = { + {"Images"}, + {"Videos"}, + {"Sounds"}, + {"Downloads"}, +}; + +#define DIR_NUM ((int)(sizeof(mmc_default_path)/sizeof(mmc_default_path[0]))) + static dd_list *fs_head; static dd_list *block_ops_list; static bool smack; @@ -877,6 +889,30 @@ static const char *get_operation_char(enum block_dev_operation op) return "unknown"; } +void mmc_make_default_path(const char *mount_path) +{ + int i = 0; + int ret = 0; + char mmc_path[FILE_NAME_LEN_MAX + 1] = {0, }; + + for (i = 0; i < DIR_NUM; ++i) { + memset(mmc_path, 0, sizeof(mmc_path)); + snprintf(mmc_path, sizeof(mmc_path), "%s/%s", mount_path, mmc_default_path[i]); + if (!g_file_test(mmc_path, G_FILE_TEST_IS_DIR)) { + _D("%s path did not exist", mmc_path); + ret = mkdir(mmc_path, 0770); + if (ret != 0) + _E("mkdir failed: %d", errno); + + /*this fuction for emulator*/ + /*at the first time, the directroies are made permission 755*/ + ret = chmod(mmc_path, 0770); + if (ret != 0) + _E("chmod failed: %d", errno); + } + } +} + static void create_external_apps_directory(void) { int ret; @@ -941,8 +977,10 @@ static bool pipe_cb(int fd, void *data) if (pdata.op == BLOCK_DEV_MOUNT && pdata.bdev->data->state == BLOCK_MOUNT && pdata.bdev->data->block_type == BLOCK_MMC_DEV && - pdata.bdev->data->primary) + pdata.bdev->data->primary) { create_external_apps_directory(); + mmc_make_default_path(pdata.bdev->data->mount_point); + } if (pdata.op == BLOCK_DEV_UNMOUNT) { /* Remove file for block device /run/xxxxxx/id */ remove_file(pdata.bdev->data->id, pdata.bdev->data->block_type == BLOCK_EXTENDEDSD_DEV); -- 2.7.4 From c14e76cb69a1ca760d52917df394d4ea696c165c Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Tue, 13 Mar 2018 11:24:28 +0900 Subject: [PATCH 12/16] block: Remove memset Change-Id: I758bed8d6bbd08425135ea2461ffe4717925f01b Signed-off-by: pr.jung --- src/block/block.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/block/block.c b/src/block/block.c index 7a11e3d..c30008d 100644 --- a/src/block/block.c +++ b/src/block/block.c @@ -896,7 +896,6 @@ void mmc_make_default_path(const char *mount_path) char mmc_path[FILE_NAME_LEN_MAX + 1] = {0, }; for (i = 0; i < DIR_NUM; ++i) { - memset(mmc_path, 0, sizeof(mmc_path)); snprintf(mmc_path, sizeof(mmc_path), "%s/%s", mount_path, mmc_default_path[i]); if (!g_file_test(mmc_path, G_FILE_TEST_IS_DIR)) { _D("%s path did not exist", mmc_path); -- 2.7.4 From 9f7577771a7e54375699c842a408fd854f35ec96 Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Tue, 13 Mar 2018 19:47:02 +0900 Subject: [PATCH 13/16] block: Change external storage permission to 777 - Directory permission is 777, uid is root groupid is priv_externalstorage - security-manager will handle access control for external storage - When externalstorage privilege is configured as privacy, security framework will enforce this privilege with different mechanism - per-application mount namespace. In such case mount options must be different to allow all users and groups access to mount point. If an application is not supposed to have access to externalstorage, security-manager will mount a special directory over sdcard mount point. In such case access control is no longer based on GID, so mount options must allow application access regardless of its groups. Change-Id: I1582d3afd70354cc81d7142fee4c9edf4c94ef30 Signed-off-by: pr.jung --- src/block/block.c | 8 ++++++-- src/block/mmc-smack-label | 2 +- src/block/vfat.c | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/block/block.c b/src/block/block.c index c30008d..10c3f56 100644 --- a/src/block/block.c +++ b/src/block/block.c @@ -899,15 +899,19 @@ void mmc_make_default_path(const char *mount_path) snprintf(mmc_path, sizeof(mmc_path), "%s/%s", mount_path, mmc_default_path[i]); if (!g_file_test(mmc_path, G_FILE_TEST_IS_DIR)) { _D("%s path did not exist", mmc_path); - ret = mkdir(mmc_path, 0770); + ret = mkdir(mmc_path, 0777); if (ret != 0) _E("mkdir failed: %d", errno); /*this fuction for emulator*/ /*at the first time, the directroies are made permission 755*/ - ret = chmod(mmc_path, 0770); + ret = chmod(mmc_path, 0777); if (ret != 0) _E("chmod failed: %d", errno); + + ret = chown(mmc_path, 0, 10001); + if (ret != 0) + _E("chown failed: %d", errno); } } } diff --git a/src/block/mmc-smack-label b/src/block/mmc-smack-label index c206758..70337cc 100755 --- a/src/block/mmc-smack-label +++ b/src/block/mmc-smack-label @@ -6,7 +6,7 @@ source /etc/tizen-platform.conf MOUNT_DIRECTORY=$1 find $MOUNT_DIRECTORY -type d | xargs chsmack -a '*' -t find $MOUNT_DIRECTORY -type f | xargs chsmack -a '*' -find $MOUNT_DIRECTORY -type d | xargs chmod 770 +find $MOUNT_DIRECTORY -type d | xargs chmod 777 find $MOUNT_DIRECTORY -type f | xargs chmod 660 find $MOUNT_DIRECTORY -type d | xargs chown root:priv_externalstorage find $MOUNT_DIRECTORY -type f | xargs chown root:priv_externalstorage diff --git a/src/block/vfat.c b/src/block/vfat.c index 19ddf39..6fed522 100644 --- a/src/block/vfat.c +++ b/src/block/vfat.c @@ -32,7 +32,7 @@ #define FS_VFAT_NAME "mkdosfs" /* guid 10001 - group priv_externalstorage */ -#define FS_VFAT_MOUNT_OPT "uid=0,gid=10001,dmask=0007,fmask=0117,iocharset=iso8859-1,utf8,shortname=mixed" +#define FS_VFAT_MOUNT_OPT "uid=0,gid=10001,dmask=0000,fmask=0117,iocharset=iso8859-1,utf8,shortname=mixed" static const char *vfat_arg[] = { "/usr/bin/newfs_msdos", -- 2.7.4 From f7ef75adb9e94e872ce8cd9527fb8db340ce4aab Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Tue, 13 Mar 2018 20:26:19 +0900 Subject: [PATCH 14/16] block: Fix code to be more readable Change-Id: I413ad40cb7cd633f5ad2f2af3af4343e9e497e79 Signed-off-by: pr.jung --- src/block/block.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/block/block.c b/src/block/block.c index 10c3f56..9eec602 100644 --- a/src/block/block.c +++ b/src/block/block.c @@ -2003,7 +2003,7 @@ static int add_operation(struct block_device *bdev, DD_LIST_APPEND(bdev->op_queue, op); th_manager[thread_id].op_len++; - if (th_manager[thread_id].op_len == 1 && !start_th) + if (th_manager[thread_id].op_len == 1 && start_th) pthread_cond_signal(&(th_manager[thread_id].cond)); pthread_mutex_unlock(&(th_manager[thread_id].mutex)); @@ -2018,9 +2018,9 @@ static int add_operation(struct block_device *bdev, _E("app2ext_disable_all_external_pkgs() failed"); - if (start_th) { + if (!start_th) { _D("Start New thread for block device"); - th_manager[thread_id].start_th = false; + th_manager[thread_id].start_th = true; ret = pthread_create(&(th_manager[thread_id].th), NULL, block_th_start, &th_manager[thread_id]); if (ret != 0) { _E("fail to create thread for %s", bdev->data->devnode); @@ -3651,7 +3651,7 @@ static void block_init(void *data) for (i = 0; i < THREAD_MAX; i++) { th_manager[i].num_dev = 0; th_manager[i].op_len = 0; - th_manager[i].start_th = true; + th_manager[i].start_th = false; th_manager[i].thread_id = i; pthread_mutex_init(&(th_manager[i].mutex), NULL); pthread_cond_init(&(th_manager[i].cond), NULL); @@ -3719,7 +3719,7 @@ static void block_exit(void *data) remove_whole_block_device(); for (i = 0; i < THREAD_MAX; i++) { - if (!th_manager[i].start_th) + if (th_manager[i].start_th) pthread_cancel(th_manager[i].th); DD_LIST_FOREACH_SAFE(th_manager[i].th_node_list, elem, elem_next, temp) { DD_LIST_REMOVE(th_manager[i].th_node_list, temp); -- 2.7.4 From 8f3dcbb698dc2f1048256b4da3447bf960cb7033 Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Thu, 15 Mar 2018 13:30:16 +0900 Subject: [PATCH 15/16] block: Add mmc inserted & removed popup - Launch notice popup when mmc is mounted and unexpectedly removed Change-Id: I0978c2bb8eee80129490065bac1749cf03883674 Signed-off-by: pr.jung --- src/block/block.c | 27 +++++++++++++++++++++++++++ src/shared/dbus_macro.h | 3 +++ 2 files changed, 30 insertions(+) diff --git a/src/block/block.c b/src/block/block.c index 9eec602..4779adb 100644 --- a/src/block/block.c +++ b/src/block/block.c @@ -117,6 +117,10 @@ #define PKGDIR_PATH "/org/tizen/pkgdir_tool" #define PKGDIR_INTERFACE "org.tizen.pkgdir_tool" +#define MMC_POPUP_NOTI "SDcardNoti" +#define MMC_INSERTED "inserted" +#define MMC_REMOVED "removed" + #define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0])) #define FILE_NAME_LEN_MAX 255 @@ -983,10 +987,33 @@ static bool pipe_cb(int fd, void *data) pdata.bdev->data->primary) { create_external_apps_directory(); mmc_make_default_path(pdata.bdev->data->mount_point); + + _D("prprprpr inserted"); + ret = dbus_method_sync_var(POPUP_BUS_NAME, + POPUP_PATH_NOTI, + POPUP_INTERFACE_NOTI, + MMC_POPUP_NOTI, + g_variant_new("(s)", MMC_INSERTED)); + if (ret != 0) + _E("Popup failed: %d", ret); } if (pdata.op == BLOCK_DEV_UNMOUNT) { /* Remove file for block device /run/xxxxxx/id */ remove_file(pdata.bdev->data->id, pdata.bdev->data->block_type == BLOCK_EXTENDEDSD_DEV); + + if (pdata.bdev->data->block_type == BLOCK_MMC_DEV && + pdata.bdev->data->primary && + BLOCK_IS_FLAG_SET(pdata.bdev->data, UNMOUNT_UNSAFE) ) { + _D("prprprpr unexpectedly removed"); + + ret = dbus_method_sync_var(POPUP_BUS_NAME, + POPUP_PATH_NOTI, + POPUP_INTERFACE_NOTI, + MMC_POPUP_NOTI, + g_variant_new("(s)", MMC_REMOVED)); + if (ret != 0) + _E("Popup failed: %d", ret); + } } /* Broadcast to mmc and usb storage module */ diff --git a/src/shared/dbus_macro.h b/src/shared/dbus_macro.h index af7ea0c..d6fa082 100644 --- a/src/shared/dbus_macro.h +++ b/src/shared/dbus_macro.h @@ -98,6 +98,9 @@ #define POPUP_PATH_SYSTEM POPUP_OBJECT_PATH"/System" #define POPUP_INTERFACE_SYSTEM POPUP_INTERFACE_NAME".System" +#define POPUP_PATH_NOTI POPUP_OBJECT_PATH"/Noti" +#define POPUP_INTERFACE_NOTI POPUP_INTERFACE_NAME".Noti" + /* ODE */ #define POPUP_METHOD_LAUNCH "PopupLaunch" #define POPUP_KEY_CONTENT "_SYSPOPUP_CONTENT_" -- 2.7.4 From 3ca824d46e158f40aaeb99c2809423b629396f0b Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Thu, 22 Mar 2018 14:01:21 +0900 Subject: [PATCH 16/16] libgdbus: Move common gdbus interfaces to libsystem package Change-Id: Icc59a49192a4a5a9f1392eb44a2a7551ecf6ba4d Signed-off-by: pr.jung --- CMakeLists.txt | 3 +- apps/extended-sd/include/dbus-call.h | 17 +- packaging/storaged.spec | 1 + src/auto-test/CMakeLists.txt | 8 +- src/auto-test/block.c | 14 +- src/auto-test/result.c | 1 + src/auto-test/storage.c | 2 +- src/auto-test/test.h | 6 +- src/block/CMakeLists.txt | 3 +- src/block/block.c | 20 +- src/core/dbus_main.c | 2 +- src/core/dbus_main.h | 2 +- src/core/main.c | 4 +- src/shared/apps.c | 3 +- src/shared/apps.h | 2 +- src/shared/dbus.c | 2598 ---------------------------------- src/shared/dbus.h | 200 --- src/shared/dbus_macro.h | 114 -- src/shared/udev.c | 2 +- src/storage/CMakeLists.txt | 3 +- src/storage/storage.c | 6 +- 21 files changed, 58 insertions(+), 2953 deletions(-) delete mode 100644 src/shared/dbus.c delete mode 100644 src/shared/dbus.h delete mode 100644 src/shared/dbus_macro.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e949ab8..03adf5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,6 @@ SET(STORAGED_APPS ${CMAKE_SOURCE_DIR}/apps) SET(SRCS src/core/main.c src/core/modules.c - src/shared/dbus.c ) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src) @@ -20,12 +19,12 @@ SET(PKG_MODULES dlog glib-2.0 gio-2.0 - gio-unix-2.0 libsystemd libtzplatform-config libudev vconf ode + libgdbus ) ADD_DEFINITIONS("-DLIBPATH=\"${LIB_INSTALL_DIR}\"") diff --git a/apps/extended-sd/include/dbus-call.h b/apps/extended-sd/include/dbus-call.h index fcc3659..ffc6cb1 100644 --- a/apps/extended-sd/include/dbus-call.h +++ b/apps/extended-sd/include/dbus-call.h @@ -22,11 +22,23 @@ #include #include -#include "dbus_macro.h" #include "extended-sd-main.h" #define DBUS_REPLY_TIMEOUT (-1) +#define STORAGED_BUS_NAME "org.tizen.system.storage" +#define STORAGED_OBJECT_PATH "/Org/Tizen/System/Storage" +#define STORAGED_INTERFACE_NAME STORAGED_BUS_NAME + +#define STORAGED_PATH_BLOCK STORAGED_OBJECT_PATH"/Block" +#define STORAGED_PATH_BLOCK_MANAGER STORAGED_PATH_BLOCK"/Manager" +#define STORAGED_INTERFACE_BLOCK_MANAGER STORAGED_INTERFACE_NAME".BlockManager" + +#define VIEWTYPE_KEY "viewtype" +#define DEVPATH_KEY "dev_path" +#define MAPPING_NODE_KEY "mapping_node" +#define SDCARD_SETUP_TYPE "_SDCARD_SETUP_TYPE_" + struct dbus_int { int *list; int size; @@ -46,9 +58,6 @@ int dbus_method_async_with_reply(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); -int register_signal_handler(appdata_s *); -int unregister_signal_handler(void); - /** * If result is NULL, err is set. * Do not invoke g_variant_unref() with result. diff --git a/packaging/storaged.spec b/packaging/storaged.spec index 15b86c9..57dc13d 100644 --- a/packaging/storaged.spec +++ b/packaging/storaged.spec @@ -27,6 +27,7 @@ BuildRequires: pkgconfig(storage) BuildRequires: pkgconfig(app2sd) BuildRequires: pkgconfig(blkid) BuildRequires: pkgconfig(mount) +BuildRequires: pkgconfig(libgdbus) BuildRequires: pkgconfig(capi-ui-efl-util) BuildRequires: pkgconfig(capi-appfw-application) diff --git a/src/auto-test/CMakeLists.txt b/src/auto-test/CMakeLists.txt index e61607b..c33a6df 100644 --- a/src/auto-test/CMakeLists.txt +++ b/src/auto-test/CMakeLists.txt @@ -7,7 +7,6 @@ SET(SRCS test.c main.c result.c - ../shared/dbus.c block.c storage.c ) @@ -17,12 +16,13 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src/shared) SET(PKG_MODULES dlog glib-2.0 + libgdbus ) INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED ${PKG_MODULES}) +pkg_check_modules(${PROJECT_NAME}_pkgs REQUIRED ${PKG_MODULES}) -FOREACH(flag ${pkgs_CFLAGS}) +FOREACH(flag ${${PROJECT_NAME}_pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) @@ -32,6 +32,6 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -lrt -fPIE") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} "-ldl" "-lm") +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${${PROJECT_NAME}_pkgs_LDFLAGS} "-ldl" "-lm") INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin) diff --git a/src/auto-test/block.c b/src/auto-test/block.c index bc2a7b2..265104c 100644 --- a/src/auto-test/block.c +++ b/src/auto-test/block.c @@ -40,7 +40,7 @@ static bool request_block_method(const char *method, GVariant *param, int timeou int val; bool ret = FALSE; - msg = dbus_method_sync_with_reply_var_timeout(STORAGED_BUS_NAME, + msg = dbus_handle_method_sync_with_reply_var_timeout(STORAGED_BUS_NAME, STORAGED_PATH_BLOCK_MANAGER, STORAGED_INTERFACE_BLOCK_MANAGER, method, param, timeout); @@ -76,7 +76,7 @@ static int get_id() int val; int ret = -1; - msg = dbus_method_sync_with_reply_var(STORAGED_BUS_NAME, + msg = dbus_handle_method_sync_with_reply_var(STORAGED_BUS_NAME, STORAGED_PATH_BLOCK_MANAGER, STORAGED_INTERFACE_BLOCK_MANAGER, METHOD_BLOCK_GETMMCPRIMARY, @@ -106,7 +106,7 @@ static bool block_showdevicelist() _D("----------------------------------------------------------------------------------"); - msg = dbus_method_sync_with_reply_var(STORAGED_BUS_NAME, + msg = dbus_handle_method_sync_with_reply_var(STORAGED_BUS_NAME, STORAGED_PATH_BLOCK_MANAGER, STORAGED_INTERFACE_BLOCK_MANAGER, METHOD_BLOCK_SHOWDEVICELIST, @@ -130,7 +130,7 @@ static bool block_getdevicelist(char *type) int ret = FALSE; _D("----------------------------------------------------------------------------------"); - msg = dbus_method_sync_with_reply_var(STORAGED_BUS_NAME, + msg = dbus_handle_method_sync_with_reply_var(STORAGED_BUS_NAME, STORAGED_PATH_BLOCK_MANAGER, STORAGED_INTERFACE_BLOCK_MANAGER, METHOD_BLOCK_GETDEVICELIST, @@ -161,7 +161,7 @@ static bool block_getdevicelist2(char *type) int ret = FALSE; _D("----------------------------------------------------------------------------------"); - msg = dbus_method_sync_with_reply_var(STORAGED_BUS_NAME, + msg = dbus_handle_method_sync_with_reply_var(STORAGED_BUS_NAME, STORAGED_PATH_BLOCK_MANAGER, STORAGED_INTERFACE_BLOCK_MANAGER, METHOD_BLOCK_GETDEVICELIST2, @@ -215,7 +215,7 @@ static bool block_getdeviceinfo(int id) int ret = FALSE; _D("----------------------------------------------------------------------------------"); - msg = dbus_method_sync_with_reply_var(STORAGED_BUS_NAME, + msg = dbus_handle_method_sync_with_reply_var(STORAGED_BUS_NAME, STORAGED_PATH_BLOCK_MANAGER, STORAGED_INTERFACE_BLOCK_MANAGER, METHOD_BLOCK_GETDEVICEINFO, @@ -249,7 +249,7 @@ static bool block_getmmcprimary() int ret = FALSE; _D("----------------------------------------------------------------------------------"); - msg = dbus_method_sync_with_reply_var(STORAGED_BUS_NAME, + msg = dbus_handle_method_sync_with_reply_var(STORAGED_BUS_NAME, STORAGED_PATH_BLOCK_MANAGER, STORAGED_INTERFACE_BLOCK_MANAGER, METHOD_BLOCK_GETMMCPRIMARY, diff --git a/src/auto-test/result.c b/src/auto-test/result.c index 83bad1a..3debbe9 100644 --- a/src/auto-test/result.c +++ b/src/auto-test/result.c @@ -17,6 +17,7 @@ */ #include +#include #include "shared/log.h" diff --git a/src/auto-test/storage.c b/src/auto-test/storage.c index e800027..579fa22 100644 --- a/src/auto-test/storage.c +++ b/src/auto-test/storage.c @@ -26,7 +26,7 @@ static bool request_storage_method(const char *method, GVariant *param) unsigned long long val1, val2; bool ret = FALSE; - msg = dbus_method_sync_with_reply_var(STORAGED_BUS_NAME, + msg = dbus_handle_method_sync_with_reply_var(STORAGED_BUS_NAME, STORAGED_PATH_STORAGE, STORAGED_INTERFACE_STORAGE, method, param); diff --git a/src/auto-test/test.h b/src/auto-test/test.h index 3d04127..eb45603 100644 --- a/src/auto-test/test.h +++ b/src/auto-test/test.h @@ -17,14 +17,14 @@ */ -#ifndef __TEST_H__ -#define __TEST_H__ +#ifndef STORAGED__TEST_H__ +#define STORAGED__TEST_H__ #include #include +#include #include "list.h" #include "log.h" -#include "dbus.h" #include "storaged_common.h" #ifdef ENABLE_TEST_DLOG diff --git a/src/block/CMakeLists.txt b/src/block/CMakeLists.txt index 925e54d..ac084b3 100644 --- a/src/block/CMakeLists.txt +++ b/src/block/CMakeLists.txt @@ -9,7 +9,6 @@ pkg_check_modules(${PROJECT_NAME}_pkgs REQUIRED dlog glib-2.0 gio-2.0 - gio-unix-2.0 libudev mount storage @@ -17,6 +16,7 @@ pkg_check_modules(${PROJECT_NAME}_pkgs REQUIRED vconf capi-system-device ode + libgdbus ) FOREACH(flag ${${PROJECT_NAME}_pkgs_CFLAGS}) @@ -38,7 +38,6 @@ SET(SRCS ${ALL_SRCS}) SET(SHARED_SRCS ../shared/common.c ../shared/config-parser.c - ../shared/dbus.c ../shared/apps.c ../shared/fd_handler.c ../shared/udev.c diff --git a/src/block/block.c b/src/block/block.c index 4779adb..c38632e 100644 --- a/src/block/block.c +++ b/src/block/block.c @@ -41,7 +41,10 @@ #include #include #include +#include #include +#include +#include #include "log.h" #include "config-parser.h" @@ -49,7 +52,6 @@ #include "udev.h" #include "list.h" #include "block.h" -#include "dbus.h" #include "fd_handler.h" #include "utils.h" #include "apps.h" @@ -117,6 +119,12 @@ #define PKGDIR_PATH "/org/tizen/pkgdir_tool" #define PKGDIR_INTERFACE "org.tizen.pkgdir_tool" +#define POPUP_KEY_CONTENT "_SYSPOPUP_CONTENT_" +#define VIEWTYPE_KEY "viewtype" +#define DEVPATH_KEY "dev_path" +#define MAPPING_NODE_KEY "mapping_node" +#define INSERT_SD_CARD "INSERT_SD_CARD" + #define MMC_POPUP_NOTI "SDcardNoti" #define MMC_INSERTED "inserted" #define MMC_REMOVED "removed" @@ -924,7 +932,7 @@ static void create_external_apps_directory(void) { int ret; - ret = dbus_method_async(PKGDIR_BUS_NAME, PKGDIR_PATH, + ret = dbus_handle_method_async(PKGDIR_BUS_NAME, PKGDIR_PATH, PKGDIR_INTERFACE, "CreateExternalDirsForAllPkgs", NULL, NULL); if (ret) _E("Fail to create external directory"); @@ -988,8 +996,7 @@ static bool pipe_cb(int fd, void *data) create_external_apps_directory(); mmc_make_default_path(pdata.bdev->data->mount_point); - _D("prprprpr inserted"); - ret = dbus_method_sync_var(POPUP_BUS_NAME, + ret = dbus_handle_method_sync_var(POPUP_BUS_NAME, POPUP_PATH_NOTI, POPUP_INTERFACE_NOTI, MMC_POPUP_NOTI, @@ -1003,10 +1010,9 @@ static bool pipe_cb(int fd, void *data) if (pdata.bdev->data->block_type == BLOCK_MMC_DEV && pdata.bdev->data->primary && - BLOCK_IS_FLAG_SET(pdata.bdev->data, UNMOUNT_UNSAFE) ) { - _D("prprprpr unexpectedly removed"); + BLOCK_IS_FLAG_SET(pdata.bdev->data, UNMOUNT_UNSAFE)) { - ret = dbus_method_sync_var(POPUP_BUS_NAME, + ret = dbus_handle_method_sync_var(POPUP_BUS_NAME, POPUP_PATH_NOTI, POPUP_INTERFACE_NOTI, MMC_POPUP_NOTI, diff --git a/src/core/dbus_main.c b/src/core/dbus_main.c index f7cc658..fec4350 100644 --- a/src/core/dbus_main.c +++ b/src/core/dbus_main.c @@ -21,8 +21,8 @@ #include #include #include +#include #include "fd_handler.h" -#include "dbus.h" #include "log.h" /* -1 is a default timeout value, it's converted to 25*1000 internally. */ diff --git a/src/core/dbus_main.h b/src/core/dbus_main.h index ce2a14a..65a52e8 100644 --- a/src/core/dbus_main.h +++ b/src/core/dbus_main.h @@ -19,7 +19,7 @@ #ifndef __STORAGED_DBUS_MAIN_H__ #define __STORAGED_DBUS_MAIN_H__ -#include "dbus_macro.h" +#include int set_dbus_connection(const char *bus); diff --git a/src/core/main.c b/src/core/main.c index fee7ee9..998dec2 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -23,10 +23,10 @@ #include #include #include +#include #include "log.h" #include "modules.h" -#include "dbus.h" #define WATCHDOG_TIMEOUT 15 /* Seconds */ @@ -76,7 +76,7 @@ int main(int argc, char **argv) return -ENOMEM; } - if (!dbus_handle_init(G_BUS_TYPE_SYSTEM, STORAGED_BUS_NAME)) { + if (!dbus_handle_init(G_BUS_TYPE_SYSTEM, STORAGED_BUS_NAME, NULL, NULL)) { _E("Failed to set dbus connection (%s)", STORAGED_BUS_NAME); return 0; } diff --git a/src/shared/apps.c b/src/shared/apps.c index 246b592..4d7b13b 100644 --- a/src/shared/apps.c +++ b/src/shared/apps.c @@ -22,6 +22,7 @@ #include "apps.h" #define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0])) +#define POPUP_METHOD_LAUNCH "PopupLaunch" static const struct app_dbus_match { const char *type; @@ -58,7 +59,7 @@ int launch_system_app(char *type, int num, ...) va_start(args, num); - ret = dbus_method_async_pairs(app_match[match].bus, + ret = dbus_handle_method_async_pairs(app_match[match].bus, app_match[match].path, app_match[match].iface, app_match[match].method, diff --git a/src/shared/apps.h b/src/shared/apps.h index b3d3c79..cbd51ab 100644 --- a/src/shared/apps.h +++ b/src/shared/apps.h @@ -19,7 +19,7 @@ #ifndef __APPS_H__ #define __APPS_H__ -#include "dbus.h" +#include #define POPUP_DEFAULT "system" diff --git a/src/shared/dbus.c b/src/shared/dbus.c deleted file mode 100644 index bf7c396..0000000 --- a/src/shared/dbus.c +++ /dev/null @@ -1,2598 +0,0 @@ -/* - * storaged - * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"), - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - - -#include -#include -#include -#include -#include - -#include "storaged_common.h" -#include "log.h" -#include "dbus.h" - -/* 10 seconds */ -#define DBUS_REPLY_TIMEOUT (10000) - -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; - - 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; - } - - if (strncmp(state, "active", 6) == 0) - ret = TRUE; - - g_free(state); -out: - if (var) - g_variant_unref(var); - if (msg) - g_variant_unref(msg); - - return ret; -} - -static GBusType g_default_bus_type = G_BUS_TYPE_SYSTEM; -pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; - -void dbus_handle_set_default_bus_type(GBusType bus_type) -{ - if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) - return ; - - pthread_mutex_lock(&g_mutex); - g_default_bus_type = bus_type; - pthread_mutex_unlock(&g_mutex); -} - -GBusType dbus_handle_get_default_bus_type(void) -{ - GBusType type; - - pthread_mutex_lock(&g_mutex); - type = g_default_bus_type; - pthread_mutex_unlock(&g_mutex); - - return type; -} - -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 - -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()); -} - -#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;\ - } - -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; - } - - iface = (dbus_interface_s *)calloc(1, sizeof(dbus_interface_s)); - if (!iface) { - _E("failed to calloc"); - return NULL; - } - - iface->name = iface_u->name; - iface->modified = TRUE; - - 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)); - } - - return iface; -} - -static GDBusConnection * _get_bus(GBusType bus_type) -{ - GDBusConnection *conn = NULL; - GError *err = NULL; - - if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) { - _E("Wrong bus_type %d", bus_type); - return NULL; - } - - 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 conn; -} - -static GDBusConnection * _get_bus_private(GBusType bus_type) -{ - GError *err = NULL; - GDBusConnection *conn = NULL; - const char * address; - - if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) { - _E("Wrong bus_type %d", bus_type); - return NULL; - } - - 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; - } - - 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 conn; -} - -/* ref cout is 1 */ -static dbus_handle_s *_dbus_handle_get_connection(GBusType bus_type) -{ - int ibus = bus_type - 1; - dbus_handle_s *dh = NULL; - - 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]; - - dbus_handle_lock(dh); - - if (!dh->conn) { - dh->conn = _get_bus(bus_type); - dh->priv = FALSE; - dh->bus_type = bus_type; - if (!dh->conn) - dh = NULL; - } - - dbus_handle_unlock(dh); - - return dh; -} - -/* ref cout is 1 */ -static dbus_handle_s *_dbus_handle_get_connection_private(GBusType bus_type) -{ - dbus_handle_s * dh; - - if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) { - _E("Unknown bus type %d", bus_type); - return NULL; - } - - dh = (dbus_handle_s *)calloc(1, sizeof(dbus_handle_s)); - if (!dh) { - _E("failed to allocate memory for dbus handle"); - return NULL; - } - - dbus_handle_lock(dh); - - if (!dh->conn) { - dh->conn = _get_bus_private(bus_type); - dh->bus_type = bus_type; - if (!dh->conn) - goto err; - } - - dbus_handle_unlock(dh); - - return dh; -err: - if (dh) { - dbus_handle_unlock(dh); - free(dh); - } - return NULL; -} - -dbus_handle_h dbus_handle_get_connection(GBusType bus_type, gboolean priv) -{ - dbus_handle_s *dh = NULL; - - if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) { - _E("Wrong bus_type %d\n", bus_type); - return dh; - } - - /* private */ - if (priv) - dh = _dbus_handle_get_connection_private(bus_type); - /* shared */ - else - dh = _dbus_handle_get_connection(bus_type); - - return dh; -} - -static void _dbus_handle_add_bus_name(dbus_handle_s *handle, const char *name, guint id) -{ - dbus_name *dn = NULL; - int locked = 0; - - if (!handle || !name || !id) - return ; - - 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); - } - - handle->list_names = g_list_prepend(handle->list_names, dn); - - // todo : delete lock ? - if (locked != EBUSY) - dbus_handle_unlock(handle); -} - -static gint _compare_dbus_name(gconstpointer a, gconstpointer b) -{ - const char *bus_name = ((dbus_name *)a)->bus_name; - if (!bus_name || !b) - return -1; - return strcmp(bus_name, (const char *)b); -} - -dbus_name * _dbus_handle_lookup_dbus_name(GList *list_name, const char *bus_name) -{ - if (!list_name || !bus_name) - return NULL; - - GList *item = g_list_find_custom(list_name, bus_name, _compare_dbus_name); - if (!item) - return NULL; - - return (dbus_name *)item->data; -} - -#define dh_to_ds(x) ((dbus_handle_s*)x) - -/* 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; - - 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 ; - } - } - - 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 _name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data) -{ - dbus_handle_s *dh = (dbus_handle_s *)user_data; - - _D("name %s", name); - - if (!dh) { - _E("%s:%d:dbus handle is null\n", __func__, __LINE__); - return ; - } - // todo: add bus name? - //dh->bus_name = name; -} - -static void _name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data) -{ - _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); -} - -int dbus_handle_request_bus_name(dbus_handle_h handle, const char *bus_name) -{ - dcl_dbus_handle(); - int id = -1; - GList *item = NULL; - - if (!bus_name) { - _E("bus_name is NULL"); - return -1; - } - - /* 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; -} - -int dbus_handle_release_bus_name(dbus_handle_h handle, const char *bus_name) -{ - dcl_dbus_handle(); - dbus_name *dn = NULL; - - if (!bus_name) { - _E("Wrong bus name"); - 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; - } - } - - 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; - } - - _E("unown name %d", dn->id); - /* _name_lost handler is disabled by g_bus_unown_name : ubuntu */ - g_bus_unown_name(dn->id); - - dbus_handle_lock(dh); - dh->list_names = g_list_remove(dh->list_names, dn); - free(dn); - dbus_handle_unlock(dh); - - return 0; -} - -int dbus_handle_free_connection(dbus_handle_h handle) -{ - 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; - } - } - - if (!dh->conn) { - _E("connection is NULL"); - return 0; - } - - pdh = dh; - - /* disable dbus handler */ - dbus_handle_lock(dh); - if (!pdh->conn) { - _E("conn is null"); - free(pdh); - return 0; - } - - /* 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; - } - - _D("list_names %u", g_list_length(pdh->list_names)); - - /* 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; - - /* _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; - } - - _D("list_object %u", g_list_length(pdh->list_object)); - - /* 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; - - _D("delete object path %s", oh->path); - - /* 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; - - _D("delete object iface %s", ih->name); - - if (ih->reg_id) - g_dbus_connection_unregister_object(pdh->conn, ih->reg_id); - } - } - } - - /* 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); - - return 0; - - // todo: signal ? -} - -#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) -{ - int len = 0; - char qu[128]; - int qucnt = 0; - - if (!expr) - return -1; - - 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; - } - } - } - - return -1; -} - -static int _get_xml_from_interfaces(char **xml, const dbus_interface_s *interfaces) -{ - 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; - } - - // 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; - } - - buf = (char *)malloc(buf_len); - if (!buf) { - _E("buf is null. not enough memory\n"); - return -1; - } - - nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), """\n""\t""""\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""""\n", pmethod->member); - continue; - } - - /* */ - nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""""\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""""\n", tmp, m); - m += ei; - continue; - } else { - nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""""\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""""\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""""\n", tmp, m); - m += ei; - continue; - } else { - nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""""\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""""\n", pmethod->signature_out[m], m); - } - - /* */ - nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""""\n"); - } - - nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t""""\n"""""); - - *xml = buf; - - /* todo: delete log */ -#if 0 - if (nwrite <= 512) - _E("%s", buf); - else - _E("%s", buf + nwrite - 512); -#endif - return 0; -} - -static gint _compare_dbus_object(gconstpointer a, gconstpointer b) -{ - 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 gint _compare_dbus_interface(gconstpointer a, gconstpointer b) -{ - dbus_interface_s * pa = (dbus_interface_s *)a; - if (!pa->name || !((const char*)b)) - return -1; - return strcmp(pa->name, (const char*)b); -} - -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)); -} - -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); -} - -dbus_object_handle_s * _dbus_handle_lookup_object(GList *list_obj, const char *obj_path) -{ - if (!list_obj || !obj_path) - return NULL; - - GList *item = g_list_find_custom(list_obj, obj_path, _compare_dbus_object); - if (!item) - return NULL; - - return (dbus_object_handle_s *)item->data; -} - -dbus_interface_s * _dbus_handle_lookup_interface(GList *list_iface, const char *iface_name) -{ - if (!list_iface || !iface_name) - return NULL; - - GList *item = g_list_find_custom(list_iface, iface_name, _compare_dbus_interface); - if (!item) - return NULL; - - return (dbus_interface_s *)item->data; -} - -dbus_interface_s * _dbus_handle_lookup_interface_by_id(GList *list_iface, guint id) -{ - if (!list_iface || !id) - return NULL; - - GList *item = g_list_find_custom(list_iface, &id, _compare_dbus_interface_by_id); - if (!item) - return NULL; - - return (dbus_interface_s *)item->data; -} - -dbus_method_s * _dbus_handle_lookup_method(GList *list_methods, const char *method_name) -{ - if (!list_methods || !method_name) - return NULL; - - GList *item = g_list_find_custom(list_methods, method_name, _compare_dbus_method); - if (!item) - return NULL; - - return (dbus_method_s *)item->data; -} - -static void _free_func_object(gpointer data) -{ - dbus_interface_s *ih = (dbus_interface_s *)data; - dbus_object_handle_s *oh = NULL; - - if (!ih) { - _E("interface handle is null"); - assert(0); // something wrong - return ; - } - - _E("unregister interface %s", ih->name); - - /* just free list, not data(static dbus_method_s) */ - g_list_free(ih->list_methods); - - oh = ih->oh; - if (!oh) { - _E("object handle is null"); - assert(0); // something wrong - return ; - } - - /* remove ih from list_ifaces */ - oh->list_ifaces = g_list_remove(oh->list_ifaces, ih); - - /* interface_s is copy of interface_u */ - free(ih); - - /* remove oh from list_object */ - if (!oh->list_ifaces) { - oh->dh->list_object = g_list_remove(oh->dh->list_object, oh); - free(oh); - } -} - -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; -} - -GVariant *dbus_method_sync_with_reply_var_timeout(const char *dest, const char *path, - const char *iface, const char *method, GVariant *var, int timeout) -{ - 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, 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; -} - -gint* dbus_handle_get_unix_fd_list(GDBusMethodInvocation *invocation, int *size) -{ - GUnixFDList *fd_list = NULL; - int length = 0; - - 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; - } - - 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; - - return g_unix_fd_list_steal_fds(fd_list, NULL); -} - -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; - } - - 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); - } - } - - /* 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; -} - -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) -{ - 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; - } - - 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; - } - - 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; - } - - /* 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) { - } - - /* 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; - } - - /* 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; -} - -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; - } - - 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; - } - - g_variant_unref(reply); - - return result; -} - -int dbus_method_sync_var(const char *dest, const char *path, - const char *iface, const char *method, GVariant *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; - } - - 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; - } - - 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); - - 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; - } - - if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) - g_variant_get(reply, "(i)", &result); - else - result = -ENOMSG; - - g_variant_unref(reply); - - return result; -} - -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; - } - - 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; - } - - builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}")); - - 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); - } - - 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 dbus_method_async_pairs(const char *dest, const char *path, - const char *iface, const char *method, - int num, va_list args) -{ - char *key, *value; - 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; - } - - 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; - } - - // dict - builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}")); - - 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); - } - - var = g_variant_new("(a{ss})", builder); - g_variant_builder_unref(builder); - - 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; -} - -int dbus_method_async_var(const char *dest, const char *path, - const char *iface, const char *method, GVariant *param) -{ - 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; - } - - g_dbus_connection_call(dh->conn, dest, path, iface, method, - param, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, - NULL, - NULL); - - return 0; -} - -/* callback should free gvariant */ -static void _cb_pending(GDBusConnection *conn, - GAsyncResult *res, - gpointer user_data) -{ - 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"); - } - - if (data && data->func) - data->func(NULL, data->data, err); - goto out; - } - - 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; - } - - if (timeout_msec < -1) { - _E("wrong timeout %d", timeout_msec); - 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 -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; - } - - 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) { - 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, - 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; - } - - 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; -} - diff --git a/src/shared/dbus.h b/src/shared/dbus.h deleted file mode 100644 index d70ef19..0000000 --- a/src/shared/dbus.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * storaged - * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#ifndef __STORAGED_DBUS_H__ -#define __STORAGED_DBUS_H__ - -#include -#include -#include -#include -#include - -#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 - */ -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); - -GVariant *dbus_method_sync_with_reply_var_timeout(const char *dest, const char *path, const char *iface, const char *method, GVariant *var, int timeout); - -/* 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); - - -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 - - * @since_tizen 4.0 - */ -typedef void *dbus_handle_h; - -/** - * @brief Dbus method handler which is used to unregister dbus methods - * @since_tizen 4.0 - */ -typedef void *dbus_object_handle_h; - -/** - * @brief Structure which contains the dbus method name and callback function. - * @since_tizen 4.0 - */ -typedef struct { - const char *member; - 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 Structure which contains the dbus interface information and its methods.i - * @since_tizen 4.0 - */ -typedef struct { - const char *name; - const dbus_method_s *methods; - int nr_methods; -} dbus_interface_u; - -#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) - -#define dbus_handle_new_g_variant_tuple() g_variant_new_tuple(NULL, 0) - -/** - * @brief Callback function which is called when the user data needs to be released. - * @since_tizen 4.0 - */ -typedef void (*destroy_notified)(void *data); - -typedef struct { - dbus_pending_cb func; - void *data; -} pending_call_data; - -int dbus_handle_request_bus_name(dbus_handle_h handle, const char *bus_name); - -dbus_handle_h dbus_handle_get_connection(GBusType bus_type, gboolean priv); - -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); - -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); - -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); - -GVariant *dbus_handle_make_simple_array(const char *sig, int *param); - -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); - -typedef struct -{ - guint pid; - guint uid; - gchar *unique_name; - gchar *sec_label; -} GDBusCredentials; - -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 diff --git a/src/shared/dbus_macro.h b/src/shared/dbus_macro.h deleted file mode 100644 index d6fa082..0000000 --- a/src/shared/dbus_macro.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * storaged - * - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#ifndef __STORAGED_DBUS_MACRO_H__ -#define __STORAGED_DBUS_MACRO_H__ - - -/******************************************************************************* - * - * Template - * - ******************************************************************************/ -/* -#define XXX_BUS_NAME "org.tizen.system.XXX" -#define XXX_OBJECT_PATH "/Org/Tizen/System/XXX" -#define XXX_INTERFACE_NAME XXX_BUS_NAME -#define XXX_PATH_YYY XXX_OBJECT_PATH"/YYY" -#define XXX_INTERFACE_YYY XXX_INTERFACE_NAME".YYY" -#define XXX_SIGNAL_ZZZ "ZZZ" -#define XXX_METHOD_ZZZ "ZZZ" - */ - - -/******************************************************************************* - * - * System daemon (systemd) - * - ******************************************************************************/ -#define SYSTEMD_DBUS_PATH "/org/freedesktop/systemd1" -#define SYSTEMD_DBUS_DEST "org.freedesktop.systemd1" -#define SYSTEMD_DBUS_IFACE_MANAGER SYSTEMD_DBUS_DEST ".Manager" -#define SYSTEMD_DBUS_SIGNAL_SYSTEM_STARTUP_FINISHED "StartupFinished" - - -/******************************************************************************* - * - * Device daemon (deviced) - * - ******************************************************************************/ -#define DEVICED_BUS_NAME "org.tizen.system.deviced" -#define DEVICED_OBJECT_PATH "/Org/Tizen/System/DeviceD" -#define DEVICED_INTERFACE_NAME DEVICED_BUS_NAME - -/* Poweroff service: get power off status operations about Poweroff */ -#define DEVICED_PATH_POWEROFF DEVICED_OBJECT_PATH"/PowerOff" -#define DEVICED_INTERFACE_POWEROFF DEVICED_INTERFACE_NAME".PowerOff" - - -/******************************************************************************* - * - * Storage daemon (storaged) - * - ******************************************************************************/ -#define STORAGED_BUS_NAME "org.tizen.system.storage" -#define STORAGED_OBJECT_PATH "/Org/Tizen/System/Storage" -#define STORAGED_INTERFACE_NAME STORAGED_BUS_NAME - -/* Block service */ -#define STORAGED_PATH_BLOCK STORAGED_OBJECT_PATH"/Block" -#define STORAGED_PATH_BLOCK_MANAGER STORAGED_PATH_BLOCK"/Manager" -#define STORAGED_INTERFACE_BLOCK_MANAGER STORAGED_INTERFACE_NAME".BlockManager" - -/* Storage service: get storage size operatioins about storage */ -#define STORAGED_PATH_STORAGE STORAGED_OBJECT_PATH"/Storage" -#define STORAGED_INTERFACE_STORAGE STORAGED_INTERFACE_NAME".storage" - -/* Lowmem service: get critical low status operations about Lowmem */ -#define STORAGED_PATH_LOWMEM STORAGED_OBJECT_PATH"/Lowmem" -#define STORAGED_INTERFACE_LOWMEM STORAGED_INTERFACE_NAME".lowmem" - - -/******************************************************************************* - * - * Popup launcher (system-popup) - * - ******************************************************************************/ -#define POPUP_BUS_NAME "org.tizen.system.popup" -#define POPUP_OBJECT_PATH "/Org/Tizen/System/Popup" -#define POPUP_INTERFACE_NAME POPUP_BUS_NAME - -/* System */ -#define POPUP_PATH_SYSTEM POPUP_OBJECT_PATH"/System" -#define POPUP_INTERFACE_SYSTEM POPUP_INTERFACE_NAME".System" - -#define POPUP_PATH_NOTI POPUP_OBJECT_PATH"/Noti" -#define POPUP_INTERFACE_NOTI POPUP_INTERFACE_NAME".Noti" - -/* ODE */ -#define POPUP_METHOD_LAUNCH "PopupLaunch" -#define POPUP_KEY_CONTENT "_SYSPOPUP_CONTENT_" -#define POPUP_SDCARD_ID "_SDCARD_NUM_" -#define VIEWTYPE_KEY "viewtype" -#define DEVPATH_KEY "dev_path" -#define MAPPING_NODE_KEY "mapping_node" -#define SDCARD_SETUP_TYPE "_SDCARD_SETUP_TYPE_" -#define INSERT_SD_CARD "INSERT_SD_CARD" - -#endif /* __STORAGED_DBUS_MACRO_H__ */ diff --git a/src/shared/udev.c b/src/shared/udev.c index 4ce94ea..b4b1d0c 100644 --- a/src/shared/udev.c +++ b/src/shared/udev.c @@ -20,12 +20,12 @@ #include #include #include +#include #include "log.h" #include "fd_handler.h" #include "udev.h" #include "list.h" -#include "dbus.h" #define KERNEL "kernel" #define UDEV "udev" diff --git a/src/storage/CMakeLists.txt b/src/storage/CMakeLists.txt index 422b91d..d2a97ee 100644 --- a/src/storage/CMakeLists.txt +++ b/src/storage/CMakeLists.txt @@ -6,9 +6,9 @@ pkg_check_modules(${PROJECT_NAME}_pkgs REQUIRED dlog gio-2.0 glib-2.0 - gio-unix-2.0 storage vconf + libgdbus ) FOREACH(flag ${${PROJECT_NAME}_pkgs_CFLAGS}) @@ -25,7 +25,6 @@ FILE(GLOB ALL_SRCS "*.c") SET(SRCS ${ALL_SRCS}) SET(SHARED_SRCS ../shared/config-parser.c - ../shared/dbus.c ../shared/fd_handler.c ) diff --git a/src/storage/storage.c b/src/storage/storage.c index 9e7b368..3106eae 100644 --- a/src/storage/storage.c +++ b/src/storage/storage.c @@ -17,7 +17,9 @@ */ #include +#include #include +#include #include #include #include @@ -30,10 +32,10 @@ #include #include #include +#include #include "log.h" #include "config-parser.h" -#include "dbus.h" #include "module-intf.h" #define MEMORY_STATUS_TMP_PATH "/tmp" @@ -107,7 +109,7 @@ static int launch_memory_popup(int num, ...) va_start(args, num); - ret = dbus_method_async_pairs(POPUP_BUS_NAME, + ret = dbus_handle_method_async_pairs(POPUP_BUS_NAME, POPUP_PATH_SYSTEM, POPUP_INTERFACE_SYSTEM, "PopupLaunch", -- 2.7.4