diff options
author | Lucas De Marchi <lucas.demarchi@profusion.mobi> | 2012-10-04 04:26:28 -0300 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2012-10-04 17:05:25 +0300 |
commit | c374734a864550d04f91bc745ae7480ebcbe6c29 (patch) | |
tree | 5c71d6bebe1717c002aa3dd3e039e7531b9d9aba | |
parent | a5b71bdd782de7880fe1a08eac8d1e5baceeb09b (diff) | |
download | bluez-c374734a864550d04f91bc745ae7480ebcbe6c29.tar.gz |
gdbus: Implement DBus.Properties.Get method
-rw-r--r-- | gdbus/gdbus.h | 8 | ||||
-rw-r--r-- | gdbus/object.c | 62 |
2 files changed, 69 insertions, 1 deletions
diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h index 34e3cb32b..b2e78c4ad 100644 --- a/gdbus/gdbus.h +++ b/gdbus/gdbus.h @@ -66,6 +66,12 @@ typedef void (* GDBusDestroyFunction) (void *user_data); typedef DBusMessage * (* GDBusMethodFunction) (DBusConnection *connection, DBusMessage *message, void *user_data); +typedef gboolean (*GDBusPropertyGetter)(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *data); + +typedef gboolean (*GDBusPropertyExists)(const GDBusPropertyTable *property, + void *data); + typedef guint32 GDBusPendingReply; typedef void (* GDBusSecurityFunction) (DBusConnection *connection, @@ -116,6 +122,8 @@ struct GDBusSignalTable { struct GDBusPropertyTable { const char *name; const char *type; + GDBusPropertyGetter get; + GDBusPropertyExists exists; GDBusPropertyFlags flags; }; diff --git a/gdbus/object.c b/gdbus/object.c index 6c1152815..89138f7e7 100644 --- a/gdbus/object.c +++ b/gdbus/object.c @@ -507,10 +507,70 @@ static const GDBusMethodTable introspect_methods[] = { { } }; +static inline const GDBusPropertyTable *find_property(const GDBusPropertyTable *properties, + const char *name) +{ + const GDBusPropertyTable *p; + + for (p = properties; p && p->name; p++) { + if (strcmp(name, p->name) == 0) + return p; + } + + return NULL; +} + static DBusMessage *properties_get(DBusConnection *connection, DBusMessage *message, void *user_data) { - return NULL; + struct generic_data *data = user_data; + struct interface_data *iface; + const GDBusPropertyTable *property; + const char *interface, *name; + DBusMessageIter iter, value; + DBusMessage *reply; + + if (!dbus_message_get_args(message, NULL, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return NULL; + + iface = find_interface(data->interfaces, interface); + if (iface == NULL) + return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS, + "No such interface '%s'", interface); + + property = find_property(iface->properties, name); + if (property == NULL) + return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS, + "No such property '%s'", name); + + if (property->exists != NULL && + !property->exists(property, iface->user_data)) + return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS, + "No such property '%s'", name); + + if (property->get == NULL) + return g_dbus_create_error(message, DBUS_ERROR_INVALID_ARGS, + "Property '%s' is not readable", name); + + reply = dbus_message_new_method_return(message); + if (reply == NULL) + return NULL; + + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, + property->type, &value); + + if (!property->get(property, &value, iface->user_data)) { + dbus_message_unref(reply); + return NULL; + } + + dbus_message_iter_close_container(&iter, &value); + + return reply; } static DBusMessage *properties_get_all(DBusConnection *connection, |