Support driver-based BSS selection in ap_scan=1 mode

If the driver indicates that it supports BSS selection (including
roaming within an ESS) with WPA_DRIVER_FLAGS_BSS_SELECTION, modify
ap_scan=1 mode to behave like ap_scan=2 mode for BSS selection.

The initial scan is still done to avoid the need for strict
configuration of or security parameters (e.g., to figure out whether
TKIP or CCMP is being used as the group cipher). However, when
requesting the driver to connect, the bssid and freq parameters are
not provided to leave the driver in control of selecting which BSS
to use and to allow the driver to decide when to roam.
This commit is contained in:
Jouni Malinen 2011-09-26 14:57:23 +03:00 committed by Jouni Malinen
parent 004ba773ce
commit 22628eca34
3 changed files with 18 additions and 4 deletions

View File

@ -812,6 +812,9 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s,
if (wpa_s->current_ssid != ssid)
return 1; /* different network block */
if (wpas_driver_bss_selection(wpa_s))
return 0; /* Driver-based roaming */
for (i = 0; i < scan_res->num; i++) {
struct wpa_scan_res *res = scan_res->res[i];
const u8 *ie;
@ -951,7 +954,8 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
return 0;
}
if (bgscan_notify_scan(wpa_s, scan_res) == 1) {
if (!wpas_driver_bss_selection(wpa_s) &&
bgscan_notify_scan(wpa_s, scan_res) == 1) {
wpa_scan_results_free(scan_res);
return 0;
}

View File

@ -1114,7 +1114,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
os_memset(&params, 0, sizeof(params));
wpa_s->reassociate = 0;
if (bss) {
if (bss && !wpas_driver_bss_selection(wpa_s)) {
#ifdef CONFIG_IEEE80211R
const u8 *ie, *md = NULL;
#endif /* CONFIG_IEEE80211R */
@ -1301,10 +1301,12 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
if (bss) {
params.bssid = bss->bssid;
params.ssid = bss->ssid;
params.ssid_len = bss->ssid_len;
params.freq = bss->freq;
if (!wpas_driver_bss_selection(wpa_s)) {
params.bssid = bss->bssid;
params.freq = bss->freq;
}
} else {
params.ssid = ssid->ssid;
params.ssid_len = ssid->ssid_len;
@ -2824,3 +2826,10 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
wpa_supplicant_req_scan(wpa_s, timeout / 1000,
1000 * (timeout % 1000));
}
int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
{
return wpa_s->conf->ap_scan == 2 ||
(wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
}

View File

@ -635,6 +635,7 @@ void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s);
void ieee80211_sta_free_hw_features(struct hostapd_hw_modes *hw_features,
size_t num_hw_features);
void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid);
int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s);
/* events.c */
void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s);