* 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;
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;
};
/**
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;
}
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);
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;
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);
+}
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 */
{
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 */