<div class="gmail_quote">[corrected the sender address]</div><div class="gmail_quote">On Fri, Apr 20, 2012 at 7:42 AM, Dan Williams <span dir="ltr"><<a href="mailto:dcbw@redhat.com">dcbw@redhat.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Wed, 2012-04-18 at 12:16 -0700, Gary Morain wrote:<br>
> In the properties changed signal, added a new propery "DisconnectReason",<br>
> which carries the IEEE 802.11 reason code of the most recent<br>
> disassociation or deauthentication event. The reason code is negative<br>
> if it is locally generated. The property is sent to the DBUS<br>
> immediately so as to prevent it from being coalesced with other<br>
> disconnect events.<br>
<br>
</div>I guess I was hoping this could be pushed out with the state so we<br>
wouldn't have this sort of disconnect; ie a new property that contained<br>
both the new state and the reason for that state change in the same<br>
property to ensure they were atomic. But that got bogged down in a<br>
discussion with Jouni where he didn't want the internal supplicant<br>
states being exposed at all (like they currently are). I'm not sure if<br>
he's changed his mind on that or not.<br></blockquote><div><br></div><div><span style>I'm aware of that effort and that it did not succeed. I'm hoping that this more modest approach will have a better fate.</span></div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
One caveat with this approach is that the internal disconnect reason is<br>
now public API; we depend on that being either standard 802.11 reason<br>
codes or having a standard enum somewhere. If that's not comfortable to<br>
Jouni, then perhaps we should define a public API enum for reasons and<br>
map the internal reason to the public enum one. It looks like some of<br>
the locally generated reason codes come directly from the kernel via<br>
nl80211. Other times it looks like they come directly from the 802.11<br>
frame but are only marked locally generated based on BSSID comparisons<br>
(ie, driver_nl80211.c mlme_event_deauth_disassoc()).<br></blockquote><div><br></div><div><span style>I thought all the disconnect reason codes were standard 802.11, as defined in src/common/ieee802_11_defs.h in the WLAN_REASON_* macros. Are there exceptions? I don't want to be exposing internal (non-standard) reason codes.</span></div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class="HOEnZb"><font color="#888888"><br>
Dan<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
> wpa_supplicant/dbus/dbus_new.c | 14 ++++++++++++++<br>
> wpa_supplicant/dbus/dbus_new.h | 1 +<br>
> wpa_supplicant/dbus/dbus_new_handlers.c | 20 ++++++++++++++++++++<br>
> wpa_supplicant/dbus/dbus_new_handlers.h | 4 ++++<br>
> wpa_supplicant/events.c | 5 +++++<br>
> wpa_supplicant/notify.c | 6 ++++++<br>
> wpa_supplicant/notify.h | 1 +<br>
> wpa_supplicant/wpa_supplicant_i.h | 3 +++<br>
> 8 files changed, 54 insertions(+), 0 deletions(-)<br>
><br>
> diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c<br>
> index 0c89d14..34282fa 100644<br>
> --- a/wpa_supplicant/dbus/dbus_new.c<br>
> +++ b/wpa_supplicant/dbus/dbus_new.c<br>
> @@ -1700,10 +1700,12 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,<br>
> enum wpas_dbus_prop property)<br>
> {<br>
> char *prop;<br>
> + dbus_bool_t flush;<br>
><br>
> if (wpa_s->dbus_new_path == NULL)<br>
> return; /* Skip signal since D-Bus setup is not yet ready */<br>
><br>
> + flush = FALSE;<br>
> switch (property) {<br>
> case WPAS_DBUS_PROP_AP_SCAN:<br>
> prop = "ApScan";<br>
> @@ -1726,6 +1728,10 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,<br>
> case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:<br>
> prop = "CurrentAuthMode";<br>
> break;<br>
> + case WPAS_DBUS_PROP_DISCONNECT_REASON:<br>
> + prop = "DisconnectReason";<br>
> + flush = TRUE;<br>
> + break;<br>
> default:<br>
> wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",<br>
> __func__, property);<br>
> @@ -1735,6 +1741,10 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,<br>
> wpa_dbus_mark_property_changed(wpa_s->global->dbus,<br>
> wpa_s->dbus_new_path,<br>
> WPAS_DBUS_NEW_IFACE_INTERFACE, prop);<br>
> + if (flush)<br>
> + wpa_dbus_flush_object_changed_properties(wpa_s->global->dbus->con,<br>
> + wpa_s->dbus_new_path);<br>
> +<br>
> }<br>
><br>
><br>
> @@ -2702,6 +2712,10 @@ static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {<br>
> NULL<br>
> },<br>
> #endif /* CONFIG_P2P */<br>
> + { "DisconnectReason", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",<br>
> + wpas_dbus_getter_disconnect_reason,<br>
> + NULL<br>
> + },<br>
> { NULL, NULL, NULL, NULL, NULL }<br>
> };<br>
><br>
> diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h<br>
> index a2d7011..f4a4d2c 100644<br>
> --- a/wpa_supplicant/dbus/dbus_new.h<br>
> +++ b/wpa_supplicant/dbus/dbus_new.h<br>
> @@ -34,6 +34,7 @@ enum wpas_dbus_prop {<br>
> WPAS_DBUS_PROP_CURRENT_NETWORK,<br>
> WPAS_DBUS_PROP_CURRENT_AUTH_MODE,<br>
> WPAS_DBUS_PROP_BSSS,<br>
> + WPAS_DBUS_PROP_DISCONNECT_REASON,<br>
> };<br>
><br>
> enum wpas_dbus_bss_prop {<br>
> diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c<br>
> index 3a5bcab..74ea804 100644<br>
> --- a/wpa_supplicant/dbus/dbus_new_handlers.c<br>
> +++ b/wpa_supplicant/dbus/dbus_new_handlers.c<br>
> @@ -2298,6 +2298,26 @@ dbus_bool_t wpas_dbus_setter_fast_reauth(DBusMessageIter *iter,<br>
> return TRUE;<br>
> }<br>
><br>
> +/**<br>
> + * wpas_dbus_getter_disconenct_reason - Get most recent reason for disconect<br>
> + * @iter: Pointer to incoming dbus message iter<br>
> + * @error: Location to store error on failure<br>
> + * @user_data: Function specific data<br>
> + * Returns: TRUE on success, FALSE on failure<br>
> + *<br>
> + * Getter for "DisconnectReason" property. The reason is negative if it is<br>
> + * locally generated.<br>
> + */<br>
> +dbus_bool_t wpas_dbus_getter_disconnect_reason(DBusMessageIter *iter,<br>
> + DBusError *error,<br>
> + void *user_data)<br>
> +{<br>
> + struct wpa_supplicant *const wpa_s = user_data;<br>
> + dbus_int32_t reason = wpa_s->disconnect_reason;<br>
> + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32,<br>
> + &reason, error);<br>
> +}<br>
> +<br>
><br>
> /**<br>
> * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age<br>
> diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h<br>
> index d78aa20..ff49c80 100644<br>
> --- a/wpa_supplicant/dbus/dbus_new_handlers.h<br>
> +++ b/wpa_supplicant/dbus/dbus_new_handlers.h<br>
> @@ -147,6 +147,10 @@ dbus_bool_t wpas_dbus_setter_fast_reauth(DBusMessageIter *iter,<br>
> DBusError *error,<br>
> void *user_data);<br>
><br>
> +dbus_bool_t wpas_dbus_getter_disconnect_reason(DBusMessageIter *iter,<br>
> + DBusError *error,<br>
> + void *user_data);<br>
> +<br>
> dbus_bool_t wpas_dbus_getter_bss_expire_age(DBusMessageIter *iter,<br>
> DBusError *error, void *user_data);<br>
><br>
> diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c<br>
> index 8fdc544..8174513 100644<br>
> --- a/wpa_supplicant/events.c<br>
> +++ b/wpa_supplicant/events.c<br>
> @@ -1659,6 +1659,11 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,<br>
> if (wpa_s->wpa_state >= WPA_AUTHENTICATING)<br>
> wpas_connection_failed(wpa_s, bssid);<br>
> wpa_sm_notify_disassoc(wpa_s->wpa);<br>
> + wpa_s->disconnect_reason = reason_code;<br>
> + if (locally_generated) {<br>
> + wpa_s->disconnect_reason = -wpa_s->disconnect_reason;<br>
> + }<br>
> + wpas_notify_disconnect_reason(wpa_s);<br>
> if (!is_zero_ether_addr(bssid) ||<br>
> wpa_s->wpa_state >= WPA_AUTHENTICATING) {<br>
> wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR<br>
> diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c<br>
> index d471dfb..bb9b0db 100644<br>
> --- a/wpa_supplicant/notify.c<br>
> +++ b/wpa_supplicant/notify.c<br>
> @@ -97,6 +97,12 @@ void wpas_notify_state_changed(struct wpa_supplicant *wpa_s,<br>
> }<br>
><br>
><br>
> +void wpas_notify_disconnect_reason(struct wpa_supplicant *wpa_s)<br>
> +{<br>
> + wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_DISCONNECT_REASON);<br>
> +}<br>
> +<br>
> +<br>
> void wpas_notify_network_changed(struct wpa_supplicant *wpa_s)<br>
> {<br>
> wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_CURRENT_NETWORK);<br>
> diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h<br>
> index 0c483bc..9cfdd4f 100644<br>
> --- a/wpa_supplicant/notify.h<br>
> +++ b/wpa_supplicant/notify.h<br>
> @@ -22,6 +22,7 @@ void wpas_notify_iface_removed(struct wpa_supplicant *wpa_s);<br>
> void wpas_notify_state_changed(struct wpa_supplicant *wpa_s,<br>
> enum wpa_states new_state,<br>
> enum wpa_states old_state);<br>
> +void wpas_notify_disconnect_reason(struct wpa_supplicant *wpa_s);<br>
> void wpas_notify_network_changed(struct wpa_supplicant *wpa_s);<br>
> void wpas_notify_ap_scan_changed(struct wpa_supplicant *wpa_s);<br>
> void wpas_notify_bssid_changed(struct wpa_supplicant *wpa_s);<br>
> diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h<br>
> index b25116e..52c4dd9 100644<br>
> --- a/wpa_supplicant/wpa_supplicant_i.h<br>
> +++ b/wpa_supplicant/wpa_supplicant_i.h<br>
> @@ -548,6 +548,9 @@ struct wpa_supplicant {<br>
> } hw;<br>
><br>
> int pno;<br>
> +<br>
> + // WLAN_REASON_* reason codes. Negative if locally generated.<br>
> + int disconnect_reason;<br>
> };<br>
><br>
><br>
<br>
<br>
</div></div></blockquote></div><br>