From d9ac0f36cd68d741102ab5cd8164787870e99cff Mon Sep 17 00:00:00 2001 From: Nedko Arnaudov Date: Sun, 9 Aug 2009 22:19:32 +0300 Subject: [PATCH] new dbus helper function: dbus_call_simple() --- daemon/common.h | 3 +- daemon/main.c | 2 - dbus/helpers.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++-- dbus/helpers.h | 5 ++ wscript | 1 + 5 files changed, 128 insertions(+), 9 deletions(-) diff --git a/daemon/common.h b/daemon/common.h index 595115c5..1f8897aa 100644 --- a/daemon/common.h +++ b/daemon/common.h @@ -40,6 +40,7 @@ #include #include "../dbus/service.h" +#include "../dbus/helpers.h" #include "../common/klist.h" #include "../common/debug.h" @@ -113,8 +114,6 @@ struct room #include "studio.h" -extern DBusConnection * g_dbus_connection; -extern DBusError g_dbus_error; extern bool g_quit; extern studio_handle g_studio; diff --git a/daemon/main.c b/daemon/main.c index e45e334c..2ee8572f 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -41,8 +41,6 @@ #include "studio.h" bool g_quit; -DBusError g_dbus_error; -DBusConnection * g_dbus_connection; const char * g_dbus_unique_name; object_path_t * g_control_object; studio_handle g_studio; diff --git a/dbus/helpers.c b/dbus/helpers.c index 8e1e41c4..2b9a0dad 100644 --- a/dbus/helpers.c +++ b/dbus/helpers.c @@ -25,6 +25,20 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include +#include +#include +#include + +#include "helpers.h" +#include "method.h" +#include "../common/debug.h" + +DBusConnection * g_dbus_connection; +DBusError g_dbus_error; + +#define DBUS_CALL_DEFAULT_TIMEOUT 1000 // in milliseconds + bool dbus_maybe_add_dict_entry_string(DBusMessageIter *dict_iter_ptr, const char * key, const char * value) { DBusMessageIter dict_entry_iter; @@ -59,11 +73,6 @@ bool dbus_add_dict_entry_uint32(DBusMessageIter * dict_iter_ptr, const char * ke { DBusMessageIter dict_entry_iter; - if (value == NULL) - { - return true; - } - if (!dbus_message_iter_open_container(dict_iter_ptr, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter)) { return false; @@ -109,3 +118,110 @@ bool dbus_add_dict_entry_bool(DBusMessageIter * dict_iter_ptr, const char * key, return true; } + +bool +dbus_call_simple( + const char * service, + const char * object, + const char * iface, + const char * method, + char * input_signature, + ...) +{ + DBusMessageIter iter; + DBusMessage * request_ptr; + DBusMessage * reply_ptr; + const char * output_signature; + const char * reply_signature; + va_list ap; + bool ret; + void * parameter_ptr; + int type; + DBusSignatureIter sig_iter; + + lash_info("dbus_call_simple('%s', '%s', '%s', '%s')", service, object, iface, method); + + ret = false; + va_start(ap, input_signature); + + if (!dbus_signature_validate(input_signature, NULL)) + { + lash_error("input signature '%s' is invalid", input_signature); + goto fail; + } + + dbus_signature_iter_init(&sig_iter, input_signature); + + request_ptr = dbus_message_new_method_call(service, object, iface, method); + if (request_ptr == NULL) + { + lash_error("dbus_message_new_method_call() failed."); + goto fail; + } + + dbus_message_iter_init_append(request_ptr, &iter); + + while (*input_signature != '\0') + { + type = dbus_signature_iter_get_current_type(&sig_iter); + if (!dbus_type_is_basic(type)) + { + lash_error("non-basic input parameter '%c' (%d)", *input_signature, type); + goto fail; + } + + parameter_ptr = va_arg(ap, void *); + + if (!dbus_message_iter_append_basic(&iter, type, parameter_ptr)) + { + lash_error("dbus_message_iter_append_basic() failed."); + goto fail; + } + + dbus_signature_iter_next(&sig_iter); + input_signature++; + } + + output_signature = va_arg(ap, const char *); + + reply_ptr = dbus_connection_send_with_reply_and_block( + g_dbus_connection, + request_ptr, + DBUS_CALL_DEFAULT_TIMEOUT, + &g_dbus_error); + + dbus_message_unref(request_ptr); + + if (reply_ptr == NULL) + { + lash_error("calling method '%s' failed, error is '%s'", method, g_dbus_error.message); + dbus_error_free(&g_dbus_error); + goto fail; + } + + reply_signature = dbus_message_get_signature(reply_ptr); + + if (strcmp(reply_signature, output_signature) != 0) + { + lash_error("reply signature is '%s' but expected signature is '%s'", reply_signature, output_signature); + } + + dbus_message_iter_init(reply_ptr, &iter); + + while (*output_signature++ != '\0') + { + assert(dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID); /* we've checked the signature, this should not happen */ + parameter_ptr = va_arg(ap, void *); + dbus_message_iter_get_basic(&iter, parameter_ptr); + dbus_message_iter_next(&iter); + } + + assert(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_INVALID); /* we've checked the signature, this should not happen */ + + ret = true; + +fail: + va_end(ap); + return ret; +} + diff --git a/dbus/helpers.h b/dbus/helpers.h index 3219efe5..0a678093 100644 --- a/dbus/helpers.h +++ b/dbus/helpers.h @@ -28,8 +28,13 @@ #ifndef HELPERS_H__6C2107A6_A5E3_4806_869B_4BE609535BA2__INCLUDED #define HELPERS_H__6C2107A6_A5E3_4806_869B_4BE609535BA2__INCLUDED +extern DBusConnection * g_dbus_connection; +extern DBusError g_dbus_error; + bool dbus_maybe_add_dict_entry_string(DBusMessageIter *dict_iter_ptr, const char * key, const char * value); bool dbus_add_dict_entry_uint32(DBusMessageIter * dict_iter_ptr, const char * key, dbus_uint32_t value); bool dbus_add_dict_entry_bool(DBusMessageIter * dict_iter_ptr, const char * key, dbus_bool_t value); +bool dbus_call_simple(const char * service, const char * object, const char * iface, const char * method, char * input_signature, ...); + #endif /* #ifndef HELPERS_H__6C2107A6_A5E3_4806_869B_4BE609535BA2__INCLUDED */ diff --git a/wscript b/wscript index 7c0eb58d..5657ad0b 100644 --- a/wscript +++ b/wscript @@ -186,6 +186,7 @@ def build(bld): 'object_path.c', 'introspection.c', 'interface.c', + 'helpers.c', ]: daemon.source.append(os.path.join("dbus", source))