SME: Add processing for rejected associations

This commit is contained in:
Jouni Malinen 2009-04-01 17:10:36 +03:00 committed by Jouni Malinen
parent c0a6190815
commit efa4607800
5 changed files with 79 additions and 6 deletions

View file

@ -1299,7 +1299,16 @@ typedef enum wpa_event_type {
* to receiving deauthenticate frame from the AP or when sending that * to receiving deauthenticate frame from the AP or when sending that
* frame to the current AP. * 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; } wpa_event_type;
@ -1448,6 +1457,34 @@ union wpa_event_data {
const u8 *ies; const u8 *ies;
size_t ies_len; size_t ies_len;
} auth; } 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;
}; };
/** /**

View 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); status = le_to_host16(mgmt->u.assoc_resp.status_code);
if (status != WLAN_STATUS_SUCCESS) { if (status != WLAN_STATUS_SUCCESS) {
wpa_printf(MSG_DEBUG, "nl80211: Association failed: status " os_memset(&event, 0, sizeof(event));
"code %d", status); if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
/* TODO: notify SME so that things like SA Query and comeback event.assoc_reject.resp_ies =
* time can be implemented */ (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; return;
} }
@ -600,7 +606,7 @@ static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
if (len > 24 + sizeof(mgmt->u.assoc_resp)) { if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable; event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable;
event.assoc_info.resp_ies_len = 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(drv->ctx, EVENT_ASSOC, &event);

View file

@ -1226,6 +1226,9 @@ void wpa_supplicant_event(void *ctx, wpa_event_type event,
wpa_supplicant_event_ibss_rsn_start(wpa_s, data); wpa_supplicant_event_ibss_rsn_start(wpa_s, data);
break; break;
#endif /* CONFIG_IBSS_RSN */ #endif /* CONFIG_IBSS_RSN */
case EVENT_ASSOC_REJECT:
sme_event_assoc_reject(wpa_s, data);
break;
default: default:
wpa_printf(MSG_INFO, "Unknown event %d", event); wpa_printf(MSG_INFO, "Unknown event %d", event);
break; break;

View 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; wpa_s->sme.ft_ies_len = ies_len;
return 0; 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);
}

View 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); 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, int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
const u8 *ies, size_t ies_len); 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 */ #else /* CONFIG_SME */
@ -41,6 +43,13 @@ static inline int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
{ {
return -1; return -1;
} }
static inline void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
union wpa_event_data *data)
{
}
#endif /* CONFIG_SME */ #endif /* CONFIG_SME */
#endif /* SME_H */ #endif /* SME_H */