dbus: Raise PropertiesChanged on org.freedesktop.DBus.Properties

wpa_supplicant dbus objects are currently difficult to use with
GDBusProxy. This is because they do not follow the dbus standard in
emitting the PropertiesChanged signal on the standard D-Bus properties
interface, so GDBusProxy stores stale property values.

Fix this by raising PropertiesChanged on the standard interface.
For backwards compatibility, the existing custom PropertiesChanged
signals are not removed; I anticipate them being removed in a future
major release.

See
http://lists.freedesktop.org/archives/dbus/2011-August/014593.html
for more info.

Signed-off-by: Daniel Drake <dsd@laptop.org>
This commit is contained in:
Daniel Drake 2011-10-29 19:23:42 +03:00 committed by Jouni Malinen
parent 266e2ee3cf
commit 4483f23e15
2 changed files with 83 additions and 4 deletions

View file

@ -1689,6 +1689,7 @@ static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
END_ARGS END_ARGS
} }
}, },
/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
{ "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE, { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
{ {
{ "properties", "a{sv}", ARG_OUT }, { "properties", "a{sv}", ARG_OUT },
@ -1777,6 +1778,7 @@ static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = { static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK, { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
{ {
{ "properties", "a{sv}", ARG_OUT }, { "properties", "a{sv}", ARG_OUT },
@ -1953,6 +1955,7 @@ static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = { static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS, { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS,
{ {
{ "properties", "a{sv}", ARG_OUT }, { "properties", "a{sv}", ARG_OUT },
@ -2477,6 +2480,7 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
END_ARGS END_ARGS
} }
}, },
/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE, { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
{ {
{ "properties", "a{sv}", ARG_OUT }, { "properties", "a{sv}", ARG_OUT },
@ -2497,6 +2501,7 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
END_ARGS END_ARGS
} }
}, },
/* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS, { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
{ {
{ "properties", "a{sv}", ARG_OUT }, { "properties", "a{sv}", ARG_OUT },

View file

@ -610,7 +610,7 @@ int wpa_dbus_unregister_object_per_iface(
static dbus_bool_t put_changed_properties( static dbus_bool_t put_changed_properties(
const struct wpa_dbus_object_desc *obj_dsc, const char *interface, const struct wpa_dbus_object_desc *obj_dsc, const char *interface,
DBusMessageIter *dict_iter) DBusMessageIter *dict_iter, int clear_changed)
{ {
DBusMessageIter entry_iter; DBusMessageIter entry_iter;
const struct wpa_dbus_property_desc *dsc; const struct wpa_dbus_property_desc *dsc;
@ -624,6 +624,7 @@ static dbus_bool_t put_changed_properties(
continue; continue;
if (os_strcmp(dsc->dbus_interface, interface) != 0) if (os_strcmp(dsc->dbus_interface, interface) != 0)
continue; continue;
if (clear_changed)
obj_dsc->prop_changed_flags[i] = 0; obj_dsc->prop_changed_flags[i] = 0;
if (!dbus_message_iter_open_container(dict_iter, if (!dbus_message_iter_open_container(dict_iter,
@ -660,7 +661,57 @@ static dbus_bool_t put_changed_properties(
} }
static void send_prop_changed_signal( static void do_send_prop_changed_signal(
DBusConnection *con, const char *path, const char *interface,
const struct wpa_dbus_object_desc *obj_dsc)
{
DBusMessage *msg;
DBusMessageIter signal_iter, dict_iter;
msg = dbus_message_new_signal(path, DBUS_INTERFACE_PROPERTIES,
"PropertiesChanged");
if (msg == NULL)
return;
dbus_message_iter_init_append(msg, &signal_iter);
if (!dbus_message_iter_append_basic(&signal_iter, DBUS_TYPE_STRING,
&interface))
goto err;
/* Changed properties dict */
if (!dbus_message_iter_open_container(&signal_iter, DBUS_TYPE_ARRAY,
"{sv}", &dict_iter))
goto err;
if (!put_changed_properties(obj_dsc, interface, &dict_iter, 0))
goto err;
if (!dbus_message_iter_close_container(&signal_iter, &dict_iter))
goto err;
/* Invalidated properties array (empty) */
if (!dbus_message_iter_open_container(&signal_iter, DBUS_TYPE_ARRAY,
"s", &dict_iter))
goto err;
if (!dbus_message_iter_close_container(&signal_iter, &dict_iter))
goto err;
dbus_connection_send(con, msg, NULL);
out:
dbus_message_unref(msg);
return;
err:
wpa_printf(MSG_DEBUG, "dbus: %s: Failed to construct signal",
__func__);
goto out;
}
static void do_send_deprecated_prop_changed_signal(
DBusConnection *con, const char *path, const char *interface, DBusConnection *con, const char *path, const char *interface,
const struct wpa_dbus_object_desc *obj_dsc) const struct wpa_dbus_object_desc *obj_dsc)
{ {
@ -677,7 +728,7 @@ static void send_prop_changed_signal(
"{sv}", &dict_iter)) "{sv}", &dict_iter))
goto err; goto err;
if (!put_changed_properties(obj_dsc, interface, &dict_iter)) if (!put_changed_properties(obj_dsc, interface, &dict_iter, 1))
goto err; goto err;
if (!dbus_message_iter_close_container(&signal_iter, &dict_iter)) if (!dbus_message_iter_close_container(&signal_iter, &dict_iter))
@ -696,6 +747,29 @@ err:
} }
static void send_prop_changed_signal(
DBusConnection *con, const char *path, const char *interface,
const struct wpa_dbus_object_desc *obj_dsc)
{
/*
* First, send property change notification on the standardized
* org.freedesktop.DBus.Properties interface. This call will not
* clear the property change bits, so that they are preserved for
* the call that follows.
*/
do_send_prop_changed_signal(con, path, interface, obj_dsc);
/*
* Now send PropertiesChanged on our own interface for backwards
* compatibility. This is deprecated and will be removed in a future
* release.
*/
do_send_deprecated_prop_changed_signal(con, path, interface, obj_dsc);
/* Property change bits have now been cleared. */
}
static void flush_object_timeout_handler(void *eloop_ctx, void *timeout_ctx) static void flush_object_timeout_handler(void *eloop_ctx, void *timeout_ctx)
{ {
DBusConnection *con = eloop_ctx; DBusConnection *con = eloop_ctx;