From 22628eca3440976bf51846da0554099f7429b206 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 26 Sep 2011 14:57:23 +0300 Subject: [PATCH] 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. --- wpa_supplicant/events.c | 6 +++++- wpa_supplicant/wpa_supplicant.c | 15 ++++++++++++--- wpa_supplicant/wpa_supplicant_i.h | 1 + 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index a307edac3..e60a25e1f 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -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; } diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 646a92606..ae65e4cb6 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1114,7 +1114,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, os_memset(¶ms, 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); +} diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 89b0982d9..f0e218cb2 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -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);