mirror of git://git.sysmocom.de/ofono
gdbus: Add support for D-Bus client properties
This commit is contained in:
parent
b30177d961
commit
8ec0dab7fa
126
gdbus/client.c
126
gdbus/client.c
|
@ -55,8 +55,61 @@ struct GDBusProxy {
|
||||||
GDBusClient *client;
|
GDBusClient *client;
|
||||||
char *obj_path;
|
char *obj_path;
|
||||||
char *interface;
|
char *interface;
|
||||||
|
GHashTable *prop_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct prop_entry {
|
||||||
|
char *name;
|
||||||
|
int type;
|
||||||
|
DBusMessage *msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct prop_entry *prop_entry_new(const char *name,
|
||||||
|
DBusMessageIter *iter)
|
||||||
|
{
|
||||||
|
struct prop_entry *prop;
|
||||||
|
|
||||||
|
prop = g_try_new0(struct prop_entry, 1);
|
||||||
|
if (prop == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
prop->name = g_strdup(name);
|
||||||
|
prop->type = dbus_message_iter_get_arg_type(iter);
|
||||||
|
|
||||||
|
if (dbus_type_is_basic(prop->type)) {
|
||||||
|
DBusMessage *msg;
|
||||||
|
DBusMessageIter append_iter;
|
||||||
|
const void *value;
|
||||||
|
|
||||||
|
msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
|
||||||
|
if (msg == NULL)
|
||||||
|
return prop;
|
||||||
|
|
||||||
|
dbus_message_iter_init_append(msg, &append_iter);
|
||||||
|
dbus_message_iter_get_basic(iter, &value);
|
||||||
|
dbus_message_iter_append_basic(&append_iter,
|
||||||
|
prop->type, &value);
|
||||||
|
|
||||||
|
prop->msg = dbus_message_copy(msg);
|
||||||
|
|
||||||
|
dbus_message_unref(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void prop_entry_free(gpointer data)
|
||||||
|
{
|
||||||
|
struct prop_entry *prop = data;
|
||||||
|
|
||||||
|
if (prop->msg != NULL)
|
||||||
|
dbus_message_unref(prop->msg);
|
||||||
|
|
||||||
|
g_free(prop->name);
|
||||||
|
|
||||||
|
g_free(prop);
|
||||||
|
}
|
||||||
|
|
||||||
static GDBusProxy *proxy_new(GDBusClient *client, const char *path,
|
static GDBusProxy *proxy_new(GDBusClient *client, const char *path,
|
||||||
const char *interface)
|
const char *interface)
|
||||||
{
|
{
|
||||||
|
@ -70,6 +123,9 @@ static GDBusProxy *proxy_new(GDBusClient *client, const char *path,
|
||||||
proxy->obj_path = g_strdup(path);
|
proxy->obj_path = g_strdup(path);
|
||||||
proxy->interface = g_strdup(interface);
|
proxy->interface = g_strdup(interface);
|
||||||
|
|
||||||
|
proxy->prop_list = g_hash_table_new_full(g_str_hash, g_str_equal,
|
||||||
|
NULL, prop_entry_free);
|
||||||
|
|
||||||
return g_dbus_proxy_ref(proxy);
|
return g_dbus_proxy_ref(proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +182,8 @@ void g_dbus_proxy_unref(GDBusProxy *proxy)
|
||||||
if (g_atomic_int_dec_and_test(&proxy->ref_count) == FALSE)
|
if (g_atomic_int_dec_and_test(&proxy->ref_count) == FALSE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
g_hash_table_destroy(proxy->prop_list);
|
||||||
|
|
||||||
g_free(proxy->obj_path);
|
g_free(proxy->obj_path);
|
||||||
g_free(proxy->interface);
|
g_free(proxy->interface);
|
||||||
|
|
||||||
|
@ -148,9 +206,49 @@ const char *g_dbus_proxy_get_interface(GDBusProxy *proxy)
|
||||||
return proxy->interface;
|
return proxy->interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean g_dbus_proxy_get_property(GDBusProxy *proxy, const char *name,
|
||||||
|
DBusMessageIter *iter)
|
||||||
|
{
|
||||||
|
struct prop_entry *prop;
|
||||||
|
|
||||||
|
if (proxy == NULL || name == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
prop = g_hash_table_lookup(proxy->prop_list, name);
|
||||||
|
if (prop == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (prop->msg == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (dbus_message_iter_init(prop->msg, iter) == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_property(GDBusProxy *proxy, const char *name,
|
||||||
|
DBusMessageIter *iter)
|
||||||
|
{
|
||||||
|
DBusMessageIter value;
|
||||||
|
struct prop_entry *prop;
|
||||||
|
|
||||||
|
if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_VARIANT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dbus_message_iter_recurse(iter, &value);
|
||||||
|
|
||||||
|
prop = prop_entry_new(name, &value);
|
||||||
|
if (prop == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_hash_table_replace(proxy->prop_list, prop->name, prop);
|
||||||
|
}
|
||||||
|
|
||||||
static void parse_properties(GDBusClient *client, const char *path,
|
static void parse_properties(GDBusClient *client, const char *path,
|
||||||
const char *interface, DBusMessageIter *iter)
|
const char *interface, DBusMessageIter *iter)
|
||||||
{
|
{
|
||||||
|
DBusMessageIter dict;
|
||||||
GDBusProxy *proxy;
|
GDBusProxy *proxy;
|
||||||
|
|
||||||
if (g_str_equal(interface, DBUS_INTERFACE_INTROSPECTABLE) == TRUE)
|
if (g_str_equal(interface, DBUS_INTERFACE_INTROSPECTABLE) == TRUE)
|
||||||
|
@ -161,6 +259,29 @@ static void parse_properties(GDBusClient *client, const char *path,
|
||||||
|
|
||||||
proxy = proxy_new(client, path, interface);
|
proxy = proxy_new(client, path, interface);
|
||||||
|
|
||||||
|
if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
dbus_message_iter_recurse(iter, &dict);
|
||||||
|
|
||||||
|
while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
|
||||||
|
DBusMessageIter entry;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
dbus_message_iter_recurse(&dict, &entry);
|
||||||
|
|
||||||
|
if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
|
||||||
|
break;
|
||||||
|
|
||||||
|
dbus_message_iter_get_basic(&entry, &name);
|
||||||
|
dbus_message_iter_next(&entry);
|
||||||
|
|
||||||
|
add_property(proxy, name, &entry);
|
||||||
|
|
||||||
|
dbus_message_iter_next(&dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
if (client->proxy_added)
|
if (client->proxy_added)
|
||||||
client->proxy_added(proxy, client->proxy_data);
|
client->proxy_added(proxy, client->proxy_data);
|
||||||
|
|
||||||
|
@ -178,7 +299,7 @@ static void parse_interfaces(GDBusClient *client, const char *path,
|
||||||
dbus_message_iter_recurse(iter, &dict);
|
dbus_message_iter_recurse(iter, &dict);
|
||||||
|
|
||||||
while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
|
while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
|
||||||
DBusMessageIter entry, value;
|
DBusMessageIter entry;
|
||||||
const char *interface;
|
const char *interface;
|
||||||
|
|
||||||
dbus_message_iter_recurse(&dict, &entry);
|
dbus_message_iter_recurse(&dict, &entry);
|
||||||
|
@ -189,8 +310,7 @@ static void parse_interfaces(GDBusClient *client, const char *path,
|
||||||
dbus_message_iter_get_basic(&entry, &interface);
|
dbus_message_iter_get_basic(&entry, &interface);
|
||||||
dbus_message_iter_next(&entry);
|
dbus_message_iter_next(&entry);
|
||||||
|
|
||||||
dbus_message_iter_recurse(&entry, &value);
|
parse_properties(client, path, interface, &entry);
|
||||||
parse_properties(client, path, interface, &value);
|
|
||||||
|
|
||||||
dbus_message_iter_next(&dict);
|
dbus_message_iter_next(&dict);
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,6 +276,9 @@ void g_dbus_proxy_unref(GDBusProxy *proxy);
|
||||||
const char *g_dbus_proxy_get_path(GDBusProxy *proxy);
|
const char *g_dbus_proxy_get_path(GDBusProxy *proxy);
|
||||||
const char *g_dbus_proxy_get_interface(GDBusProxy *proxy);
|
const char *g_dbus_proxy_get_interface(GDBusProxy *proxy);
|
||||||
|
|
||||||
|
gboolean g_dbus_proxy_get_property(GDBusProxy *proxy, const char *name,
|
||||||
|
DBusMessageIter *iter);
|
||||||
|
|
||||||
typedef struct GDBusClient GDBusClient;
|
typedef struct GDBusClient GDBusClient;
|
||||||
|
|
||||||
GDBusClient *g_dbus_client_new(DBusConnection *connection,
|
GDBusClient *g_dbus_client_new(DBusConnection *connection,
|
||||||
|
|
Loading…
Reference in New Issue