From 0645492e7c98441d230b787c5711b4e4b337655b Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 26 Feb 2016 17:16:35 +0200 Subject: [PATCH] WNM: Optimize a single BSS transition management candidate scan If the BSS Transition Management Request frame includes only a single candidate and we need to scan for the BSS to get up-to-date information, use a scan for the known BSSID instead of wildcard BSSID. In addition, set the SSID in the scan if it is known based on old scan results in the BSS table. This removes unnecessary Probe Response frames when we are interested in results from only a single BSS. Signed-off-by: Jouni Malinen --- wpa_supplicant/scan.c | 23 +++++++++++++++++++++++ wpa_supplicant/wnm_sta.c | 8 ++++++++ wpa_supplicant/wpa_supplicant_i.h | 1 + 3 files changed, 32 insertions(+) diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index c925cad11..2ce3929ed 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -1006,6 +1006,27 @@ ssid_list_set: } } + if (!is_zero_ether_addr(wpa_s->next_scan_bssid)) { + struct wpa_bss *bss; + + params.bssid = wpa_s->next_scan_bssid; + bss = wpa_bss_get_bssid_latest(wpa_s, params.bssid); + if (bss && bss->ssid_len && params.num_ssids == 1 && + params.ssids[0].ssid_len == 0) { + params.ssids[0].ssid = bss->ssid; + params.ssids[0].ssid_len = bss->ssid_len; + wpa_dbg(wpa_s, MSG_DEBUG, + "Scan a previously specified BSSID " MACSTR + " and SSID %s", + MAC2STR(params.bssid), + wpa_ssid_txt(bss->ssid, bss->ssid_len)); + } else { + wpa_dbg(wpa_s, MSG_DEBUG, + "Scan a previously specified BSSID " MACSTR, + MAC2STR(params.bssid)); + } + } + scan_params = ¶ms; scan: @@ -1066,6 +1087,8 @@ scan: #ifdef CONFIG_INTERWORKING wpa_s->interworking_fast_assoc_tried = 0; #endif /* CONFIG_INTERWORKING */ + if (params.bssid) + os_memset(wpa_s->next_scan_bssid, 0, ETH_ALEN); } } diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c index 0dc41dca2..4da912426 100644 --- a/wpa_supplicant/wnm_sta.c +++ b/wpa_supplicant/wnm_sta.c @@ -1148,6 +1148,14 @@ static void ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s, } wnm_set_scan_freqs(wpa_s); + if (wpa_s->wnm_num_neighbor_report == 1) { + os_memcpy(wpa_s->next_scan_bssid, + wpa_s->wnm_neighbor_report_elements[0].bssid, + ETH_ALEN); + wpa_printf(MSG_DEBUG, + "WNM: Scan only for a specific BSSID since there is only a single candidate " + MACSTR, MAC2STR(wpa_s->next_scan_bssid)); + } wpa_supplicant_req_scan(wpa_s, 0, 0); } else if (reply) { enum bss_trans_mgmt_status_code status; diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 0e3e42a5e..14a724589 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -640,6 +640,7 @@ struct wpa_supplicant { #define MAX_SCAN_ID 16 int scan_id[MAX_SCAN_ID]; unsigned int scan_id_count; + u8 next_scan_bssid[ETH_ALEN]; struct wpa_ssid_value *ssids_from_scan_req; unsigned int num_ssids_from_scan_req;