SME: Add processing for rejected associations
authorJouni Malinen <jouni.malinen@atheros.com>
Wed, 1 Apr 2009 14:10:36 +0000 (17:10 +0300)
committerJouni Malinen <j@w1.fi>
Wed, 1 Apr 2009 14:10:36 +0000 (17:10 +0300)
src/drivers/driver.h
src/drivers/driver_nl80211.c
wpa_supplicant/events.c
wpa_supplicant/sme.c
wpa_supplicant/sme.h

index 80205a4..8ce74c4 100644 (file)
@@ -1299,7 +1299,16 @@ typedef enum wpa_event_type {
         * to receiving deauthenticate frame from the AP or when sending that
         * frame to the current AP.
         */
-       EVENT_DEAUTH
+       EVENT_DEAUTH,
+
+       /**
+        * EVENT_ASSOC_REJECT - Association rejected
+        *
+        * This event should be called when (re)association attempt has been
+        * rejected by the AP. Information about authentication result is
+        * included in union wpa_event_data::assoc_reject.
+        */
+       EVENT_ASSOC_REJECT
 } wpa_event_type;
 
 
@@ -1448,6 +1457,34 @@ union wpa_event_data {
                const u8 *ies;
                size_t ies_len;
        } auth;
+
+       /**
+        * struct assoc_reject - Data for EVENT_ASSOC_REJECT events
+        */
+       struct assoc_reject {
+               /**
+                * resp_ies - (Re)Association Response IEs
+                *
+                * Optional association data from the driver. This data is not
+                * required WPA, but may be useful for some protocols and as
+                * such, should be reported if this is available to the driver
+                * interface.
+                *
+                * This should start with the first IE (fixed fields before IEs
+                * are not included).
+                */
+               u8 *resp_ies;
+
+               /**
+                * resp_ies_len - Length of resp_ies in bytes
+                */
+               size_t resp_ies_len;
+
+               /**
+                * status_code - Status Code from (Re)association Response
+                */
+               u16 status_code;
+       } assoc_reject;
 };
 
 /**
index 3e71159..b0f9308 100644 (file)
@@ -586,10 +586,16 @@ static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
 
        status = le_to_host16(mgmt->u.assoc_resp.status_code);
        if (status != WLAN_STATUS_SUCCESS) {
-               wpa_printf(MSG_DEBUG, "nl80211: Association failed: status "
-                          "code %d", status);
-               /* TODO: notify SME so that things like SA Query and comeback
-                * time can be implemented */
+               os_memset(&event, 0, sizeof(event));
+               if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
+                       event.assoc_reject.resp_ies =
+                               (u8 *) mgmt->u.assoc_resp.variable;
+                       event.assoc_reject.resp_ies_len =
+                               len - 24 - sizeof(mgmt->u.assoc_resp);
+               }
+               event.assoc_reject.status_code = status;
+
+               wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
                return;
        }
 
@@ -600,7 +606,7 @@ static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
        if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
                event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable;
                event.assoc_info.resp_ies_len =
-                       len - 24 - sizeof(mgmt->u.assoc_req);
+                       len - 24 - sizeof(mgmt->u.assoc_resp);
        }
 
        wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
index 5186d2a..1fb1d2d 100644 (file)
@@ -1226,6 +1226,9 @@ void wpa_supplicant_event(void *ctx, wpa_event_type event,
                wpa_supplicant_event_ibss_rsn_start(wpa_s, data);
                break;
 #endif /* CONFIG_IBSS_RSN */
+       case EVENT_ASSOC_REJECT:
+               sme_event_assoc_reject(wpa_s, data);
+               break;
        default:
                wpa_printf(MSG_INFO, "Unknown event %d", event);
                break;
index 9b8844d..97a5f80 100644 (file)
@@ -335,3 +335,21 @@ int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
        wpa_s->sme.ft_ies_len = ies_len;
        return 0;
 }
+
+
+void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
+                           union wpa_event_data *data)
+{
+       wpa_printf(MSG_DEBUG, "SME: Association failed: status code %d",
+                  data->assoc_reject.status_code);
+
+       wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
+       os_memset(wpa_s->bssid, 0, ETH_ALEN);
+       os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
+
+       /*
+        * TODO: if more than one possible AP is available in scan results,
+        * could try the other ones before requesting a new scan.
+        */
+       wpa_supplicant_req_scan(wpa_s, 5, 0);
+}
index ce1b2dc..566e417 100644 (file)
@@ -22,6 +22,8 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
 void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data);
 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);
 
 #else /* CONFIG_SME */
 
@@ -41,6 +43,13 @@ static inline int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
 {
        return -1;
 }
+
+
+static inline void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
+                                         union wpa_event_data *data)
+{
+}
+
 #endif /* CONFIG_SME */
 
 #endif /* SME_H */