Browse Source

SME: Add processing for rejected associations

Jouni Malinen 16 years ago
parent
commit
efa4607800
5 changed files with 79 additions and 6 deletions
  1. 38 1
      src/drivers/driver.h
  2. 11 5
      src/drivers/driver_nl80211.c
  3. 3 0
      wpa_supplicant/events.c
  4. 18 0
      wpa_supplicant/sme.c
  5. 9 0
      wpa_supplicant/sme.h

+ 38 - 1
src/drivers/driver.h

@@ -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;
 };
 
 /**

+ 11 - 5
src/drivers/driver_nl80211.c

@@ -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);

+ 3 - 0
wpa_supplicant/events.c

@@ -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;

+ 18 - 0
wpa_supplicant/sme.c

@@ -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);
+}

+ 9 - 0
wpa_supplicant/sme.h

@@ -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 */