Add handling of SME auth/assoc timeout events
authorJouni Malinen <jouni.malinen@atheros.com>
Thu, 23 Apr 2009 21:08:24 +0000 (00:08 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 23 Apr 2009 21:08:24 +0000 (00:08 +0300)
This allows wpa_supplicant to start searching for other APs (or re-try)
if the MLME times out.

src/common/nl80211_copy.h
src/drivers/driver.h
src/drivers/driver_nl80211.c
wpa_supplicant/events.c
wpa_supplicant/sme.c
wpa_supplicant/sme.h

index dc9d9ec..7ae6e12 100644 (file)
  *     frame, i.e., it was for the local STA and was received in correct
  *     state. This is similar to MLME-AUTHENTICATE.confirm primitive in the
  *     MLME SAP interface (kernel providing MLME, userspace SME). The
- *     included NL80211_ATTR_FRAME attribute contains the management frame
- *     (including both the header and frame body, but not FCS).
+ *     included %NL80211_ATTR_FRAME attribute contains the management frame
+ *     (including both the header and frame body, but not FCS). This event is
+ *     also used to indicate if the authentication attempt timed out. In that
+ *     case the %NL80211_ATTR_FRAME attribute is replaced with a
+ *     %NL80211_ATTR_TIMED_OUT flag (and %NL80211_ATTR_MAC to indicate which
+ *     pending authentication timed out).
  * @NL80211_CMD_ASSOCIATE: association request and notification; like
  *     NL80211_CMD_AUTHENTICATE but for Association and Reassociation
  *     (similar to MLME-ASSOCIATE.request, MLME-REASSOCIATE.request,
@@ -485,6 +489,9 @@ enum nl80211_commands {
  * @NL80211_ATTR_FREQ_FIXED: a flag indicating the IBSS should not try to look
  *     for other networks on different channels
  *
+ * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this
+ *     is used, e.g., with %NL80211_CMD_AUTHENTICATE event
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -585,6 +592,8 @@ enum nl80211_attrs {
        NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
        NL80211_ATTR_WIPHY_RTS_THRESHOLD,
 
+       NL80211_ATTR_TIMED_OUT,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
index 930e464..943d61c 100644 (file)
@@ -1497,7 +1497,17 @@ typedef enum wpa_event_type {
         * rejected by the AP. Information about authentication result is
         * included in union wpa_event_data::assoc_reject.
         */
-       EVENT_ASSOC_REJECT
+       EVENT_ASSOC_REJECT,
+
+       /**
+        * EVENT_AUTH_TIMED_OUT - Authentication timed out
+        */
+       EVENT_AUTH_TIMED_OUT,
+
+       /**
+        * EVENT_ASSOC_TIMED_OUT - Association timed out
+        */
+       EVENT_ASSOC_TIMED_OUT
 } wpa_event_type;
 
 
@@ -1675,6 +1685,10 @@ union wpa_event_data {
                 */
                u16 status_code;
        } assoc_reject;
+
+       struct timeout_event {
+               u8 addr[ETH_ALEN];
+       } timeout_event;
 };
 
 /**
index d2855e2..51e0346 100644 (file)
@@ -740,9 +740,40 @@ static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
 }
 
 
+static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv,
+                              enum nl80211_commands cmd, struct nlattr *addr)
+{
+       union wpa_event_data event;
+       enum wpa_event_type ev;
+
+       if (nla_len(addr) != ETH_ALEN)
+               return;
+
+       wpa_printf(MSG_DEBUG, "nl80211: MLME event %d; timeout with " MACSTR,
+                  cmd, MAC2STR((u8 *) nla_data(addr)));
+
+       if (cmd == NL80211_CMD_AUTHENTICATE)
+               ev = EVENT_AUTH_TIMED_OUT;
+       else if (cmd == NL80211_CMD_ASSOCIATE)
+               ev = EVENT_ASSOC_TIMED_OUT;
+       else
+               return;
+
+       os_memset(&event, 0, sizeof(event));
+       os_memcpy(event.timeout_event.addr, nla_data(addr), ETH_ALEN);
+       wpa_supplicant_event(drv->ctx, ev, &event);
+}
+
+
 static void mlme_event(struct wpa_driver_nl80211_data *drv,
-                      enum nl80211_commands cmd, struct nlattr *frame)
+                      enum nl80211_commands cmd, struct nlattr *frame,
+                      struct nlattr *addr, struct nlattr *timed_out)
 {
+       if (timed_out && addr) {
+               mlme_timeout_event(drv, cmd, addr);
+               return;
+       }
+
        if (frame == NULL) {
                wpa_printf(MSG_DEBUG, "nl80211: MLME event %d without frame "
                           "data", cmd);
@@ -861,7 +892,8 @@ static int process_event(struct nl_msg *msg, void *arg)
        case NL80211_CMD_ASSOCIATE:
        case NL80211_CMD_DEAUTHENTICATE:
        case NL80211_CMD_DISASSOCIATE:
-               mlme_event(drv, gnlh->cmd, tb[NL80211_ATTR_FRAME]);
+               mlme_event(drv, gnlh->cmd, tb[NL80211_ATTR_FRAME],
+                          tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT]);
                break;
 #endif /* HOSTAPD */
        case NL80211_CMD_MICHAEL_MIC_FAILURE:
index 1fb1d2d..56c57fb 100644 (file)
@@ -1229,6 +1229,12 @@ void wpa_supplicant_event(void *ctx, wpa_event_type event,
        case EVENT_ASSOC_REJECT:
                sme_event_assoc_reject(wpa_s, data);
                break;
+       case EVENT_AUTH_TIMED_OUT:
+               sme_event_auth_timed_out(wpa_s, data);
+               break;
+       case EVENT_ASSOC_TIMED_OUT:
+               sme_event_assoc_timed_out(wpa_s, data);
+               break;
        default:
                wpa_printf(MSG_INFO, "Unknown event %d", event);
                break;
index 87b6b95..0d729ef 100644 (file)
@@ -361,3 +361,20 @@ void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
         */
        wpa_supplicant_req_scan(wpa_s, 5, 0);
 }
+
+
+void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s,
+                             union wpa_event_data *data)
+{
+       wpa_printf(MSG_DEBUG, "SME: Authentication timed out");
+       wpa_supplicant_req_scan(wpa_s, 5, 0);
+}
+
+
+void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s,
+                              union wpa_event_data *data)
+{
+       wpa_printf(MSG_DEBUG, "SME: Association timed out");
+       wpa_supplicant_mark_disassoc(wpa_s);
+       wpa_supplicant_req_scan(wpa_s, 5, 0);
+}
index 566e417..2780041 100644 (file)
@@ -24,6 +24,10 @@ int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
                      const u8 *ies, size_t ies_len);
 void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
                            union wpa_event_data *data);
+void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s,
+                             union wpa_event_data *data);
+void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s,
+                              union wpa_event_data *data);
 
 #else /* CONFIG_SME */
 
@@ -50,6 +54,16 @@ static inline void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
 {
 }
 
+static inline void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s,
+                                           union wpa_event_data *data)
+{
+}
+
+static inline void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s,
+                                            union wpa_event_data *data)
+{
+}
+
 #endif /* CONFIG_SME */
 
 #endif /* SME_H */