diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index f1efe6ba8..076d31301 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1694,14 +1694,38 @@ void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s, { u8 *addr = NULL; union wpa_event_data event; + int zero_addr = 0; - if (!is_zero_ether_addr(wpa_s->bssid)) { - wpa_drv_disassociate(wpa_s, wpa_s->bssid, reason_code); + wpa_dbg(wpa_s, MSG_DEBUG, "Request to disassociate - bssid=" MACSTR + " pending_bssid=" MACSTR " reason=%d state=%s", + MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid), + reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state)); + + if (!is_zero_ether_addr(wpa_s->bssid)) addr = wpa_s->bssid; + else if (!is_zero_ether_addr(wpa_s->pending_bssid) && + (wpa_s->wpa_state == WPA_AUTHENTICATING || + wpa_s->wpa_state == WPA_ASSOCIATING)) + addr = wpa_s->pending_bssid; + else if (wpa_s->wpa_state == WPA_ASSOCIATING) { + /* + * When using driver-based BSS selection, we may not know the + * BSSID with which we are currently trying to associate. We + * need to notify the driver of this disconnection even in such + * a case, so use the all zeros address here. + */ + addr = wpa_s->bssid; + zero_addr = 1; + } + + if (addr) { + wpa_drv_disassociate(wpa_s, addr, reason_code); os_memset(&event, 0, sizeof(event)); event.disassoc_info.reason_code = (u16) reason_code; event.disassoc_info.locally_generated = 1; wpa_supplicant_event(wpa_s, EVENT_DISASSOC, &event); + if (zero_addr) + addr = NULL; } wpa_supplicant_clear_connection(wpa_s, addr); @@ -1721,14 +1745,38 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s, { u8 *addr = NULL; union wpa_event_data event; + int zero_addr = 0; - if (!is_zero_ether_addr(wpa_s->bssid)) { - wpa_drv_deauthenticate(wpa_s, wpa_s->bssid, reason_code); + wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR + " pending_bssid=" MACSTR " reason=%d state=%s", + MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid), + reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state)); + + if (!is_zero_ether_addr(wpa_s->bssid)) addr = wpa_s->bssid; + else if (!is_zero_ether_addr(wpa_s->pending_bssid) && + (wpa_s->wpa_state == WPA_AUTHENTICATING || + wpa_s->wpa_state == WPA_ASSOCIATING)) + addr = wpa_s->pending_bssid; + else if (wpa_s->wpa_state == WPA_ASSOCIATING) { + /* + * When using driver-based BSS selection, we may not know the + * BSSID with which we are currently trying to associate. We + * need to notify the driver of this disconnection even in such + * a case, so use the all zeros address here. + */ + addr = wpa_s->bssid; + zero_addr = 1; + } + + if (addr) { + wpa_drv_deauthenticate(wpa_s, addr, reason_code); os_memset(&event, 0, sizeof(event)); event.deauth_info.reason_code = (u16) reason_code; event.deauth_info.locally_generated = 1; wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event); + if (zero_addr) + addr = NULL; } wpa_supplicant_clear_connection(wpa_s, addr);