mirror of git://git.sysmocom.de/ofono
gdbus/client: Use g_dbus_add_properties_watch to track properties
This make the handling much simpler and avoids duplicates of the same match rule.
This commit is contained in:
parent
607c1e088d
commit
2e5938f3bb
135
gdbus/client.c
135
gdbus/client.c
|
@ -67,7 +67,7 @@ struct GDBusProxy {
|
||||||
char *obj_path;
|
char *obj_path;
|
||||||
char *interface;
|
char *interface;
|
||||||
GHashTable *prop_list;
|
GHashTable *prop_list;
|
||||||
char *match_rule;
|
guint watch;
|
||||||
GDBusPropertyFunction prop_func;
|
GDBusPropertyFunction prop_func;
|
||||||
void *prop_data;
|
void *prop_data;
|
||||||
GDBusProxyFunction removed_func;
|
GDBusProxyFunction removed_func;
|
||||||
|
@ -358,6 +358,52 @@ static GDBusProxy *proxy_lookup(GDBusClient *client, const char *path,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean properties_changed(DBusConnection *conn, DBusMessage *msg,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
GDBusProxy *proxy = user_data;
|
||||||
|
GDBusClient *client = proxy->client;
|
||||||
|
DBusMessageIter iter, entry;
|
||||||
|
const char *interface;
|
||||||
|
|
||||||
|
if (dbus_message_iter_init(msg, &iter) == FALSE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
dbus_message_iter_get_basic(&iter, &interface);
|
||||||
|
dbus_message_iter_next(&iter);
|
||||||
|
|
||||||
|
update_properties(proxy, &iter, TRUE);
|
||||||
|
|
||||||
|
dbus_message_iter_next(&iter);
|
||||||
|
|
||||||
|
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
dbus_message_iter_recurse(&iter, &entry);
|
||||||
|
|
||||||
|
while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
dbus_message_iter_get_basic(&entry, &name);
|
||||||
|
|
||||||
|
g_hash_table_remove(proxy->prop_list, name);
|
||||||
|
|
||||||
|
if (proxy->prop_func)
|
||||||
|
proxy->prop_func(proxy, name, NULL, proxy->prop_data);
|
||||||
|
|
||||||
|
if (client->property_changed)
|
||||||
|
client->property_changed(proxy, name, NULL,
|
||||||
|
client->user_data);
|
||||||
|
|
||||||
|
dbus_message_iter_next(&entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static GDBusProxy *proxy_new(GDBusClient *client, const char *path,
|
static GDBusProxy *proxy_new(GDBusClient *client, const char *path,
|
||||||
const char *interface)
|
const char *interface)
|
||||||
{
|
{
|
||||||
|
@ -373,14 +419,12 @@ static GDBusProxy *proxy_new(GDBusClient *client, const char *path,
|
||||||
|
|
||||||
proxy->prop_list = g_hash_table_new_full(g_str_hash, g_str_equal,
|
proxy->prop_list = g_hash_table_new_full(g_str_hash, g_str_equal,
|
||||||
NULL, prop_entry_free);
|
NULL, prop_entry_free);
|
||||||
|
proxy->watch = g_dbus_add_properties_watch(client->dbus_conn,
|
||||||
proxy->match_rule = g_strdup_printf("type='signal',"
|
client->service_name,
|
||||||
"sender='%s',path='%s',interface='%s',"
|
proxy->obj_path,
|
||||||
"member='PropertiesChanged',arg0='%s'",
|
proxy->interface,
|
||||||
client->service_name, proxy->obj_path,
|
properties_changed,
|
||||||
DBUS_INTERFACE_PROPERTIES, proxy->interface);
|
proxy, NULL);
|
||||||
|
|
||||||
modify_match(client->dbus_conn, "AddMatch", proxy->match_rule);
|
|
||||||
|
|
||||||
return g_dbus_proxy_ref(proxy);
|
return g_dbus_proxy_ref(proxy);
|
||||||
}
|
}
|
||||||
|
@ -395,11 +439,7 @@ static void proxy_free(gpointer data)
|
||||||
if (client->proxy_removed)
|
if (client->proxy_removed)
|
||||||
client->proxy_removed(proxy, client->user_data);
|
client->proxy_removed(proxy, client->user_data);
|
||||||
|
|
||||||
modify_match(client->dbus_conn, "RemoveMatch",
|
g_dbus_remove_watch(client->dbus_conn, proxy->watch);
|
||||||
proxy->match_rule);
|
|
||||||
|
|
||||||
g_free(proxy->match_rule);
|
|
||||||
proxy->match_rule = NULL;
|
|
||||||
|
|
||||||
g_hash_table_remove_all(proxy->prop_list);
|
g_hash_table_remove_all(proxy->prop_list);
|
||||||
|
|
||||||
|
@ -800,64 +840,6 @@ static void refresh_properties(GDBusClient *client)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void properties_changed(GDBusClient *client, const char *path,
|
|
||||||
DBusMessage *msg)
|
|
||||||
{
|
|
||||||
GDBusProxy *proxy = NULL;
|
|
||||||
DBusMessageIter iter, entry;
|
|
||||||
const char *interface;
|
|
||||||
GList *list;
|
|
||||||
|
|
||||||
if (dbus_message_iter_init(msg, &iter) == FALSE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dbus_message_iter_get_basic(&iter, &interface);
|
|
||||||
dbus_message_iter_next(&iter);
|
|
||||||
|
|
||||||
for (list = g_list_first(client->proxy_list); list;
|
|
||||||
list = g_list_next(list)) {
|
|
||||||
GDBusProxy *data = list->data;
|
|
||||||
|
|
||||||
if (g_str_equal(data->interface, interface) == TRUE &&
|
|
||||||
g_str_equal(data->obj_path, path) == TRUE) {
|
|
||||||
proxy = data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (proxy == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
update_properties(proxy, &iter, TRUE);
|
|
||||||
|
|
||||||
dbus_message_iter_next(&iter);
|
|
||||||
|
|
||||||
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dbus_message_iter_recurse(&iter, &entry);
|
|
||||||
|
|
||||||
while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
dbus_message_iter_get_basic(&entry, &name);
|
|
||||||
|
|
||||||
g_hash_table_remove(proxy->prop_list, name);
|
|
||||||
|
|
||||||
if (proxy->prop_func)
|
|
||||||
proxy->prop_func(proxy, name, NULL, proxy->prop_data);
|
|
||||||
|
|
||||||
if (client->property_changed)
|
|
||||||
client->property_changed(proxy, name, NULL,
|
|
||||||
client->user_data);
|
|
||||||
|
|
||||||
dbus_message_iter_next(&entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
@ -1095,7 +1077,7 @@ static DBusHandlerResult message_filter(DBusConnection *connection,
|
||||||
DBusMessage *message, void *user_data)
|
DBusMessage *message, void *user_data)
|
||||||
{
|
{
|
||||||
GDBusClient *client = user_data;
|
GDBusClient *client = user_data;
|
||||||
const char *sender, *path, *interface, *member;
|
const char *sender, *path, *interface;
|
||||||
|
|
||||||
if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL)
|
if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL)
|
||||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
|
@ -1106,17 +1088,12 @@ static DBusHandlerResult message_filter(DBusConnection *connection,
|
||||||
|
|
||||||
path = dbus_message_get_path(message);
|
path = dbus_message_get_path(message);
|
||||||
interface = dbus_message_get_interface(message);
|
interface = dbus_message_get_interface(message);
|
||||||
member = dbus_message_get_member(message);
|
|
||||||
|
|
||||||
if (g_str_has_prefix(path, client->base_path) == FALSE)
|
if (g_str_has_prefix(path, client->base_path) == FALSE)
|
||||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
|
|
||||||
if (g_str_equal(interface, DBUS_INTERFACE_PROPERTIES) == TRUE) {
|
if (g_str_equal(interface, DBUS_INTERFACE_PROPERTIES) == TRUE)
|
||||||
if (g_str_equal(member, "PropertiesChanged") == TRUE)
|
|
||||||
properties_changed(client, path, message);
|
|
||||||
|
|
||||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
}
|
|
||||||
|
|
||||||
if (client->signal_func)
|
if (client->signal_func)
|
||||||
client->signal_func(connection, message, client->signal_data);
|
client->signal_func(connection, message, client->signal_data);
|
||||||
|
|
Loading…
Reference in New Issue