[PATCH 2/2] 0.7.x: dbus: Do Not Coalesce Supplicant State Changes
Grant Erickson
marathon96
Fri Oct 21 17:22:15 PDT 2011
To ensure that higher-level network managers receive all state changes, do not coalesce
supplicant state changes. Rather, make state change signals synchronous.
Signed-off-by: Grant Erickson <marathon96 at gmail.com>
---
wpa_supplicant/dbus/dbus_new.c | 61 +++++++++++++++++++-------
wpa_supplicant/dbus/dbus_new.h | 3 +-
wpa_supplicant/dbus/dbus_new_handlers_wps.c | 8 ++--
wpa_supplicant/dbus/dbus_new_helpers.c | 61 ++++++++++++++++++++------
wpa_supplicant/dbus/dbus_new_helpers.h | 10 +++-
wpa_supplicant/notify.c | 2 +-
6 files changed, 105 insertions(+), 40 deletions(-)
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 9798e74..acb51f5 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -410,8 +410,8 @@ void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
"%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
wpa_s->dbus_new_path, ssid->id);
- wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
- WPAS_DBUS_NEW_IFACE_NETWORK, "Enabled");
+ wpa_dbus_queue_property_changed(wpa_s->global->dbus, path,
+ WPAS_DBUS_NEW_IFACE_NETWORK, "Enabled");
}
@@ -650,6 +650,33 @@ nomem:
#endif /* CONFIG_WPS */
+/**
+ * wpas_dbus_signal_state_changed - Signals change of state property
+ * @wpa_s: %wpa_supplicant network interface data
+ *
+ * Sends ProertyChanged signals immediately with path, interface and
+ * arguments for the supplicant state property. This is sent
+ * immediately so that supplicant state changes are NOT coaslesced
+ * which can lead to problems in higher-level network managers which
+ * depend on seeing all, specific state changes for correct operation.
+ */
+void wpas_dbus_signal_state_changed(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_dbus_object_desc *obj_desc = NULL;
+
+ if (wpa_s->dbus_new_path == NULL)
+ return; /* Skip signal since D-Bus setup is not yet ready */
+
+ obj_desc = wpa_dbus_mark_property_changed(wpa_s->global->dbus,
+ wpa_s->dbus_new_path,
+ WPAS_DBUS_NEW_IFACE_INTERFACE,
+ "State");
+ if (!obj_desc)
+ return;
+
+ wpa_dbus_flush_object_changed_properties(wpa_s->global->dbus->con,
+ obj_desc->path);
+}
/**
* wpas_dbus_signal_prop_changed - Signals change of property
@@ -662,7 +689,7 @@ nomem:
void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
enum wpas_dbus_prop property)
{
- char *prop;
+ const char *prop;
if (wpa_s->dbus_new_path == NULL)
return; /* Skip signal since D-Bus setup is not yet ready */
@@ -692,9 +719,9 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
return;
}
- wpa_dbus_mark_property_changed(wpa_s->global->dbus,
- wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
+ wpa_dbus_queue_property_changed(wpa_s->global->dbus,
+ wpa_s->dbus_new_path,
+ WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
}
@@ -749,8 +776,8 @@ void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
"%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
wpa_s->dbus_new_path, id);
- wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
- WPAS_DBUS_NEW_IFACE_BSS, prop);
+ wpa_dbus_queue_property_changed(wpa_s->global->dbus, path,
+ WPAS_DBUS_NEW_IFACE_BSS, prop);
}
@@ -762,9 +789,9 @@ void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
*/
void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
{
- wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
- WPAS_DBUS_NEW_INTERFACE,
- "DebugLevel");
+ wpa_dbus_queue_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
+ WPAS_DBUS_NEW_INTERFACE,
+ "DebugLevel");
}
@@ -776,9 +803,9 @@ void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
*/
void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
{
- wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
- WPAS_DBUS_NEW_INTERFACE,
- "DebugTimestamp");
+ wpa_dbus_queue_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
+ WPAS_DBUS_NEW_INTERFACE,
+ "DebugTimestamp");
}
@@ -790,9 +817,9 @@ void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
*/
void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
{
- wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
- WPAS_DBUS_NEW_INTERFACE,
- "DebugShowKeys");
+ wpa_dbus_queue_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
+ WPAS_DBUS_NEW_INTERFACE,
+ "DebugShowKeys");
}
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index 9cdefcb..10f2352 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -90,6 +90,7 @@ void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface);
int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s);
int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s);
+void wpas_dbus_signal_state_changed(struct wpa_supplicant *wpa_s);
void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
enum wpas_dbus_prop property);
void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
@@ -133,7 +134,7 @@ static inline int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
return 0;
}
-#define wpas_dbus_signal_state_changed(w, n, o) do { } while (0)
+#define wpas_dbus_signal_state_changed(w) do { } while (0)
static inline void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
enum wpas_dbus_prop property)
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_wps.c b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
index dc44a59..26189c5 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_wps.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
@@ -322,10 +322,10 @@ DBusMessage * wpas_dbus_setter_process_credentials(
wpa_s->conf->wps_cred_processing = (process_credentials ? 2 : 1);
if ((wpa_s->conf->wps_cred_processing != 1) != old_pc)
- wpa_dbus_mark_property_changed(wpa_s->global->dbus,
- wpa_s->dbus_new_path,
- WPAS_DBUS_NEW_IFACE_WPS,
- "ProcessCredentials");
+ wpa_dbus_queue_property_changed(wpa_s->global->dbus,
+ wpa_s->dbus_new_path,
+ WPAS_DBUS_NEW_IFACE_WPS,
+ "ProcessCredentials");
return NULL;
}
diff --git a/wpa_supplicant/dbus/dbus_new_helpers.c b/wpa_supplicant/dbus/dbus_new_helpers.c
index 06749db..28c5d1b 100644
--- a/wpa_supplicant/dbus/dbus_new_helpers.c
+++ b/wpa_supplicant/dbus/dbus_new_helpers.c
@@ -754,13 +754,17 @@ void wpa_dbus_flush_all_changed_properties(DBusConnection *con)
* containing properties marked as changed, sends a PropertiesChanged signal
* containing names and new values of properties that have changed.
*
- * You need to call this function after wpa_dbus_mark_property_changed()
- * if you want to send PropertiesChanged signal immediately (i.e., without
- * waiting timeout to expire). PropertiesChanged signal for an object is sent
- * automatically short time after first marking property as changed. All
- * PropertiesChanged signals are sent automatically after responding on DBus
- * message, so if you marked a property changed as a result of DBus call
- * (e.g., param setter), you usually do not need to call this function.
+ * You need to call this function after
+ * wpa_dbus_mark_property_changed() to send the PropertyChanged signal
+ * or after wpa_dbus_queue_property_changed() if you want to send
+ * PropertiesChanged signal immediately (i.e., without waiting timeout
+ * to expire).
+ *
+ * PropertiesChanged signal for an object is sent automatically short
+ * time after first marking property as changed. All PropertiesChanged
+ * signals are sent automatically after responding on DBus message, so
+ * if you marked a property changed as a result of DBus call (e.g.,
+ * param setter), you usually do not need to call this function.
*/
void wpa_dbus_flush_object_changed_properties(DBusConnection *con,
const char *path)
@@ -790,11 +794,12 @@ void wpa_dbus_flush_object_changed_properties(DBusConnection *con,
/**
- * wpa_dbus_mark_property_changed - Mark a property as changed and
+ * wpa_dbus_mark_property_changed - Mark a property as changed
* @iface: dbus priv struct
* @path: path to DBus object which property has changed
* @interface: interface containing changed property
* @property: property name which has changed
+ * Returns: A pointer to the private data for the object on success.
*
* Iterates over all properties registered with an object and marks the one
* given in parameters as changed. All parameters registered for an object
@@ -802,23 +807,24 @@ void wpa_dbus_flush_object_changed_properties(DBusConnection *con,
* PropertiesChanged signal when function
* wpa_dbus_flush_object_changed_properties() is called.
*/
-void wpa_dbus_mark_property_changed(struct wpas_dbus_priv *iface,
- const char *path, const char *interface,
- const char *property)
+struct wpa_dbus_object_desc *
+wpa_dbus_mark_property_changed(struct wpas_dbus_priv *iface,
+ const char *path, const char *interface,
+ const char *property)
{
struct wpa_dbus_object_desc *obj_desc = NULL;
const struct wpa_dbus_property_desc *dsc;
int i = 0;
if (iface == NULL)
- return;
+ return NULL;
dbus_connection_get_object_path_data(iface->con, path,
(void **) &obj_desc);
if (!obj_desc) {
wpa_printf(MSG_ERROR, "dbus: wpa_dbus_property_changed: "
"could not obtain object's private data: %s", path);
- return;
+ return NULL;
}
for (dsc = obj_desc->properties; dsc && dsc->dbus_property; dsc++, i++)
@@ -832,9 +838,36 @@ void wpa_dbus_mark_property_changed(struct wpas_dbus_priv *iface,
if (!dsc || !dsc->dbus_property) {
wpa_printf(MSG_ERROR, "dbus: wpa_dbus_property_changed: "
"no property %s in object %s", property, path);
- return;
+ return NULL;
}
+ return obj_desc;
+}
+
+/**
+ * wpa_dbus_queue_property_changed - Mark a property as changed and send it
+ * @iface: dbus priv struct
+ * @path: path to DBus object which property has changed
+ * @interface: interface containing changed property
+ * @property: property name which has changed
+ *
+ * Iterates over all properties registered with an object and marks the one
+ * given in parameters as changed. All parameters registered for an object
+ * within a single interface will be aggregated together and sent in one
+ * PropertiesChanged signal when function
+ * wpa_dbus_flush_object_changed_properties() is called.
+ */
+void wpa_dbus_queue_property_changed(struct wpas_dbus_priv *iface,
+ const char *path, const char *interface,
+ const char *property)
+{
+ struct wpa_dbus_object_desc *obj_desc;
+
+ obj_desc = wpa_dbus_mark_property_changed(iface, path, interface,
+ property);
+ if (!obj_desc)
+ return;
+
if (!eloop_is_timeout_registered(flush_object_timeout_handler,
iface->con, obj_desc->path)) {
eloop_register_timeout(0, WPA_DBUS_SEND_PROP_CHANGED_TIMEOUT,
diff --git a/wpa_supplicant/dbus/dbus_new_helpers.h b/wpa_supplicant/dbus/dbus_new_helpers.h
index 8db7a37..b90fca8 100644
--- a/wpa_supplicant/dbus/dbus_new_helpers.h
+++ b/wpa_supplicant/dbus/dbus_new_helpers.h
@@ -137,9 +137,13 @@ void wpa_dbus_flush_all_changed_properties(DBusConnection *con);
void wpa_dbus_flush_object_changed_properties(DBusConnection *con,
const char *path);
-void wpa_dbus_mark_property_changed(struct wpas_dbus_priv *iface,
- const char *path, const char *interface,
- const char *property);
+struct wpa_dbus_object_desc * wpa_dbus_mark_property_changed(
+ struct wpas_dbus_priv *iface,
+ const char *path, const char *interface,
+ const char *property);
+void wpa_dbus_queue_property_changed(struct wpas_dbus_priv *iface,
+ const char *path, const char *interface,
+ const char *property);
DBusMessage * wpa_dbus_introspect(DBusMessage *message,
struct wpa_dbus_object_desc *obj_dsc);
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index ac65b4f..ea5d5e6 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -80,7 +80,7 @@ void wpas_notify_state_changed(struct wpa_supplicant *wpa_s,
old_state);
/* notify the new DBus API */
- wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATE);
+ wpas_dbus_signal_state_changed(wpa_s);
}
--
1.7.6.4
More information about the Hostap
mailing list