diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 60d0fa9bb..e148595f1 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -26,6 +26,7 @@ #include "wpas_glue.h" #include "wps_supplicant.h" #include "notify.h" +#include "blacklist.h" #include "sme.h" void sme_authenticate(struct wpa_supplicant *wpa_s, @@ -357,12 +358,39 @@ void sme_event_assoc_reject(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { int bssid_changed; + int timeout = 5000; - wpa_printf(MSG_DEBUG, "SME: Association failed: status code %d", + wpa_printf(MSG_DEBUG, "SME: Association with " MACSTR " failed: " + "status code %d", MAC2STR(wpa_s->pending_bssid), data->assoc_reject.status_code); - wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); bssid_changed = !is_zero_ether_addr(wpa_s->bssid); + + /* + * For now, unconditionally terminate the previous authentication. In + * theory, this should not be needed, but mac80211 gets quite confused + * if the authentication is left pending.. Some roaming cases might + * benefit from using the previous authentication, so this could be + * optimized in the future. + */ + if (wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid, + WLAN_REASON_DEAUTH_LEAVING) < 0) { + wpa_msg(wpa_s, MSG_INFO, + "Deauth request to the driver failed"); + } + + if (wpa_blacklist_add(wpa_s, wpa_s->pending_bssid) == 0) { + struct wpa_blacklist *b; + b = wpa_blacklist_get(wpa_s, wpa_s->pending_bssid); + if (b && b->count < 3) { + /* + * Speed up next attempt if there could be other APs + * that could accept association. + */ + timeout = 100; + } + } + 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); if (bssid_changed) @@ -372,7 +400,8 @@ void sme_event_assoc_reject(struct wpa_supplicant *wpa_s, * 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); + wpa_supplicant_req_scan(wpa_s, timeout / 1000, + 1000 * (timeout % 1000)); }