<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">&lt;<a href="mailto:dcbw@redhat.com">dcbw@redhat.com</a>&gt;</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>
&gt; In the properties changed signal, added a new propery &quot;DisconnectReason&quot;,<br>
&gt; which carries the IEEE 802.11 reason code of the most recent<br>
&gt; disassociation or deauthentication event.  The reason code is negative<br>
&gt; if it is locally generated.  The property is sent to the DBUS<br>
&gt; immediately so as to prevent it from being coalesced with other<br>
&gt; disconnect events.<br>
<br>
</div>I guess I was hoping this could be pushed out with the state so we<br>
wouldn&#39;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&#39;t want the internal supplicant<br>
states being exposed at all (like they currently are).  I&#39;m not sure if<br>
he&#39;s changed his mind on that or not.<br></blockquote><div><br></div><div><span style>I&#39;m aware of that effort and that it did not succeed.  I&#39;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&#39;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&#39;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>
&gt;  wpa_supplicant/dbus/dbus_new.c          |   14 ++++++++++++++<br>
&gt;  wpa_supplicant/dbus/dbus_new.h          |    1 +<br>
&gt;  wpa_supplicant/dbus/dbus_new_handlers.c |   20 ++++++++++++++++++++<br>
&gt;  wpa_supplicant/dbus/dbus_new_handlers.h |    4 ++++<br>
&gt;  wpa_supplicant/events.c                 |    5 +++++<br>
&gt;  wpa_supplicant/notify.c                 |    6 ++++++<br>
&gt;  wpa_supplicant/notify.h                 |    1 +<br>
&gt;  wpa_supplicant/wpa_supplicant_i.h       |    3 +++<br>
&gt;  8 files changed, 54 insertions(+), 0 deletions(-)<br>
&gt;<br>
&gt; diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c<br>
&gt; index 0c89d14..34282fa 100644<br>
&gt; --- a/wpa_supplicant/dbus/dbus_new.c<br>
&gt; +++ b/wpa_supplicant/dbus/dbus_new.c<br>
&gt; @@ -1700,10 +1700,12 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,<br>
&gt;                                  enum wpas_dbus_prop property)<br>
&gt;  {<br>
&gt;       char *prop;<br>
&gt; +     dbus_bool_t flush;<br>
&gt;<br>
&gt;       if (wpa_s-&gt;dbus_new_path == NULL)<br>
&gt;               return; /* Skip signal since D-Bus setup is not yet ready */<br>
&gt;<br>
&gt; +     flush = FALSE;<br>
&gt;       switch (property) {<br>
&gt;       case WPAS_DBUS_PROP_AP_SCAN:<br>
&gt;               prop = &quot;ApScan&quot;;<br>
&gt; @@ -1726,6 +1728,10 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,<br>
&gt;       case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:<br>
&gt;               prop = &quot;CurrentAuthMode&quot;;<br>
&gt;               break;<br>
&gt; +     case WPAS_DBUS_PROP_DISCONNECT_REASON:<br>
&gt; +             prop = &quot;DisconnectReason&quot;;<br>
&gt; +             flush = TRUE;<br>
&gt; +             break;<br>
&gt;       default:<br>
&gt;               wpa_printf(MSG_ERROR, &quot;dbus: %s: Unknown Property value %d&quot;,<br>
&gt;                          __func__, property);<br>
&gt; @@ -1735,6 +1741,10 @@ void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,<br>
&gt;       wpa_dbus_mark_property_changed(wpa_s-&gt;global-&gt;dbus,<br>
&gt;                                      wpa_s-&gt;dbus_new_path,<br>
&gt;                                      WPAS_DBUS_NEW_IFACE_INTERFACE, prop);<br>
&gt; +     if (flush)<br>
&gt; +             wpa_dbus_flush_object_changed_properties(wpa_s-&gt;global-&gt;dbus-&gt;con,<br>
&gt; +                                                      wpa_s-&gt;dbus_new_path);<br>
&gt; +<br>
&gt;  }<br>
&gt;<br>
&gt;<br>
&gt; @@ -2702,6 +2712,10 @@ static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {<br>
&gt;         NULL<br>
&gt;       },<br>
&gt;  #endif /* CONFIG_P2P */<br>
&gt; +     { &quot;DisconnectReason&quot;, WPAS_DBUS_NEW_IFACE_INTERFACE, &quot;i&quot;,<br>
&gt; +       wpas_dbus_getter_disconnect_reason,<br>
&gt; +       NULL<br>
&gt; +     },<br>
&gt;       { NULL, NULL, NULL, NULL, NULL }<br>
&gt;  };<br>
&gt;<br>
&gt; diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h<br>
&gt; index a2d7011..f4a4d2c 100644<br>
&gt; --- a/wpa_supplicant/dbus/dbus_new.h<br>
&gt; +++ b/wpa_supplicant/dbus/dbus_new.h<br>
&gt; @@ -34,6 +34,7 @@ enum wpas_dbus_prop {<br>
&gt;       WPAS_DBUS_PROP_CURRENT_NETWORK,<br>
&gt;       WPAS_DBUS_PROP_CURRENT_AUTH_MODE,<br>
&gt;       WPAS_DBUS_PROP_BSSS,<br>
&gt; +     WPAS_DBUS_PROP_DISCONNECT_REASON,<br>
&gt;  };<br>
&gt;<br>
&gt;  enum wpas_dbus_bss_prop {<br>
&gt; diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c<br>
&gt; index 3a5bcab..74ea804 100644<br>
&gt; --- a/wpa_supplicant/dbus/dbus_new_handlers.c<br>
&gt; +++ b/wpa_supplicant/dbus/dbus_new_handlers.c<br>
&gt; @@ -2298,6 +2298,26 @@ dbus_bool_t wpas_dbus_setter_fast_reauth(DBusMessageIter *iter,<br>
&gt;       return TRUE;<br>
&gt;  }<br>
&gt;<br>
&gt; +/**<br>
&gt; + * wpas_dbus_getter_disconenct_reason - Get most recent reason for disconect<br>
&gt; + * @iter: Pointer to incoming dbus message iter<br>
&gt; + * @error: Location to store error on failure<br>
&gt; + * @user_data: Function specific data<br>
&gt; + * Returns: TRUE on success, FALSE on failure<br>
&gt; + *<br>
&gt; + * Getter for &quot;DisconnectReason&quot; property.  The reason is negative if it is<br>
&gt; + * locally generated.<br>
&gt; + */<br>
&gt; +dbus_bool_t wpas_dbus_getter_disconnect_reason(DBusMessageIter *iter,<br>
&gt; +                                               DBusError *error,<br>
&gt; +                                               void *user_data)<br>
&gt; +{<br>
&gt; +     struct wpa_supplicant *const wpa_s = user_data;<br>
&gt; +     dbus_int32_t reason = wpa_s-&gt;disconnect_reason;<br>
&gt; +     return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32,<br>
&gt; +                                             &amp;reason, error);<br>
&gt; +}<br>
&gt; +<br>
&gt;<br>
&gt;  /**<br>
&gt;   * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age<br>
&gt; diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h<br>
&gt; index d78aa20..ff49c80 100644<br>
&gt; --- a/wpa_supplicant/dbus/dbus_new_handlers.h<br>
&gt; +++ b/wpa_supplicant/dbus/dbus_new_handlers.h<br>
&gt; @@ -147,6 +147,10 @@ dbus_bool_t wpas_dbus_setter_fast_reauth(DBusMessageIter *iter,<br>
&gt;                                        DBusError *error,<br>
&gt;                                        void *user_data);<br>
&gt;<br>
&gt; +dbus_bool_t wpas_dbus_getter_disconnect_reason(DBusMessageIter *iter,<br>
&gt; +                                               DBusError *error,<br>
&gt; +                                               void *user_data);<br>
&gt; +<br>
&gt;  dbus_bool_t wpas_dbus_getter_bss_expire_age(DBusMessageIter *iter,<br>
&gt;                                           DBusError *error, void *user_data);<br>
&gt;<br>
&gt; diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c<br>
&gt; index 8fdc544..8174513 100644<br>
&gt; --- a/wpa_supplicant/events.c<br>
&gt; +++ b/wpa_supplicant/events.c<br>
&gt; @@ -1659,6 +1659,11 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,<br>
&gt;       if (wpa_s-&gt;wpa_state &gt;= WPA_AUTHENTICATING)<br>
&gt;               wpas_connection_failed(wpa_s, bssid);<br>
&gt;       wpa_sm_notify_disassoc(wpa_s-&gt;wpa);<br>
&gt; +        wpa_s-&gt;disconnect_reason = reason_code;<br>
&gt; +        if (locally_generated) {<br>
&gt; +             wpa_s-&gt;disconnect_reason = -wpa_s-&gt;disconnect_reason;<br>
&gt; +        }<br>
&gt; +        wpas_notify_disconnect_reason(wpa_s);<br>
&gt;       if (!is_zero_ether_addr(bssid) ||<br>
&gt;           wpa_s-&gt;wpa_state &gt;= WPA_AUTHENTICATING) {<br>
&gt;               wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED &quot;bssid=&quot; MACSTR<br>
&gt; diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c<br>
&gt; index d471dfb..bb9b0db 100644<br>
&gt; --- a/wpa_supplicant/notify.c<br>
&gt; +++ b/wpa_supplicant/notify.c<br>
&gt; @@ -97,6 +97,12 @@ void wpas_notify_state_changed(struct wpa_supplicant *wpa_s,<br>
&gt;  }<br>
&gt;<br>
&gt;<br>
&gt; +void wpas_notify_disconnect_reason(struct wpa_supplicant *wpa_s)<br>
&gt; +{<br>
&gt; +     wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_DISCONNECT_REASON);<br>
&gt; +}<br>
&gt; +<br>
&gt; +<br>
&gt;  void wpas_notify_network_changed(struct wpa_supplicant *wpa_s)<br>
&gt;  {<br>
&gt;       wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_CURRENT_NETWORK);<br>
&gt; diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h<br>
&gt; index 0c483bc..9cfdd4f 100644<br>
&gt; --- a/wpa_supplicant/notify.h<br>
&gt; +++ b/wpa_supplicant/notify.h<br>
&gt; @@ -22,6 +22,7 @@ void wpas_notify_iface_removed(struct wpa_supplicant *wpa_s);<br>
&gt;  void wpas_notify_state_changed(struct wpa_supplicant *wpa_s,<br>
&gt;                              enum wpa_states new_state,<br>
&gt;                              enum wpa_states old_state);<br>
&gt; +void wpas_notify_disconnect_reason(struct wpa_supplicant *wpa_s);<br>
&gt;  void wpas_notify_network_changed(struct wpa_supplicant *wpa_s);<br>
&gt;  void wpas_notify_ap_scan_changed(struct wpa_supplicant *wpa_s);<br>
&gt;  void wpas_notify_bssid_changed(struct wpa_supplicant *wpa_s);<br>
&gt; diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h<br>
&gt; index b25116e..52c4dd9 100644<br>
&gt; --- a/wpa_supplicant/wpa_supplicant_i.h<br>
&gt; +++ b/wpa_supplicant/wpa_supplicant_i.h<br>
&gt; @@ -548,6 +548,9 @@ struct wpa_supplicant {<br>
&gt;       } hw;<br>
&gt;<br>
&gt;       int pno;<br>
&gt; +<br>
&gt; +     // WLAN_REASON_* reason codes.  Negative if locally generated.<br>
&gt; +     int disconnect_reason;<br>
&gt;  };<br>
&gt;<br>
&gt;<br>
<br>
<br>
</div></div></blockquote></div><br>