diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 9548cf58b..9f6097ef2 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1383,8 +1383,10 @@ void wpa_supplicant_event(void *ctx, wpa_event_type event, case EVENT_ASSOC: wpa_supplicant_event_assoc(wpa_s, data); break; - case EVENT_DEAUTH: case EVENT_DISASSOC: + sme_event_disassoc(wpa_s, data); + /* fall through */ + case EVENT_DEAUTH: wpa_supplicant_event_disassoc(wpa_s); break; case EVENT_MICHAEL_MIC_FAILURE: diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 734b2e980..5bb45738b 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -427,3 +427,23 @@ void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s, wpa_supplicant_mark_disassoc(wpa_s); wpa_supplicant_req_scan(wpa_s, 5, 0); } + + +void sme_event_disassoc(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) +{ + wpa_printf(MSG_DEBUG, "SME: Disassociation event received"); + if (!is_zero_ether_addr(wpa_s->bssid) && + !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)) { + /* + * cfg80211/mac80211 can get into somewhat confused state if + * the AP only disassociates us and leaves us in authenticated + * state. For now, force the state to be cleared to avoid + * confusing errors if we try to associate with the AP again. + */ + wpa_printf(MSG_DEBUG, "SME: Deauthenticate to clear driver " + "state"); + wpa_drv_deauthenticate(wpa_s, wpa_s->bssid, + WLAN_REASON_DEAUTH_LEAVING); + } +} diff --git a/wpa_supplicant/sme.h b/wpa_supplicant/sme.h index 278004185..5e8a8f45a 100644 --- a/wpa_supplicant/sme.h +++ b/wpa_supplicant/sme.h @@ -28,6 +28,8 @@ void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s, union wpa_event_data *data); void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s, union wpa_event_data *data); +void sme_event_disassoc(struct wpa_supplicant *wpa_s, + union wpa_event_data *data); #else /* CONFIG_SME */ @@ -64,6 +66,11 @@ static inline void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s, { } +static inline void sme_event_disassoc(struct wpa_supplicant *wpa_s, + union wpa_event_data *data) +{ +} + #endif /* CONFIG_SME */ #endif /* SME_H */