WNM: Allow BSS transition request in same ESS even if RSSI is worse
This allows an AP to steer us to another BSS within the ESS even if that results in reduced signal strength as long as the signal strength with the target BSS is expected to provide some connectivity. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
6900b6d96f
commit
027454d2e9
1 changed files with 60 additions and 21 deletions
|
@ -452,34 +452,73 @@ static int compare_scan_neighbor_results(struct wpa_supplicant *wpa_s,
|
||||||
{
|
{
|
||||||
|
|
||||||
u8 i, j;
|
u8 i, j;
|
||||||
|
const u8 *ssid;
|
||||||
|
struct wpa_bss *bss = wpa_s->current_bss;
|
||||||
|
|
||||||
if (scan_res == NULL || num_neigh_rep == 0 || !wpa_s->current_bss)
|
if (scan_res == NULL || num_neigh_rep == 0 || !bss)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "WNM: Current BSS " MACSTR " RSSI %d",
|
wpa_printf(MSG_DEBUG, "WNM: Current BSS " MACSTR " RSSI %d",
|
||||||
MAC2STR(wpa_s->bssid), wpa_s->current_bss->level);
|
MAC2STR(wpa_s->bssid), bss->level);
|
||||||
|
|
||||||
for (i = 0; i < num_neigh_rep; i++) {
|
for (i = 0; i < num_neigh_rep; i++) {
|
||||||
for (j = 0; j < scan_res->num; j++) {
|
struct neighbor_report *nei = &neigh_rep[i];
|
||||||
/* Check for a better RSSI AP */
|
struct wpa_scan_res *res = NULL;
|
||||||
if (os_memcmp(scan_res->res[j]->bssid,
|
|
||||||
neigh_rep[i].bssid, ETH_ALEN) == 0 &&
|
if (nei->preference_present && nei->preference == 0) {
|
||||||
scan_res->res[j]->level >
|
wpa_printf(MSG_DEBUG, "Skip excluded BSS " MACSTR,
|
||||||
wpa_s->current_bss->level) {
|
MAC2STR(nei->bssid));
|
||||||
/* Got a BSSID with better RSSI value */
|
continue;
|
||||||
os_memcpy(bssid_to_connect, neigh_rep[i].bssid,
|
|
||||||
ETH_ALEN);
|
|
||||||
wpa_printf(MSG_DEBUG, "Found a BSS " MACSTR
|
|
||||||
" with better scan RSSI %d",
|
|
||||||
MAC2STR(scan_res->res[j]->bssid),
|
|
||||||
scan_res->res[j]->level);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
wpa_printf(MSG_DEBUG, "scan_res[%d] " MACSTR
|
|
||||||
" RSSI %d", j,
|
|
||||||
MAC2STR(scan_res->res[j]->bssid),
|
|
||||||
scan_res->res[j]->level);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < scan_res->num; j++) {
|
||||||
|
if (os_memcmp(scan_res->res[j]->bssid,
|
||||||
|
neigh_rep[i].bssid, ETH_ALEN) == 0) {
|
||||||
|
res = scan_res->res[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
wpa_printf(MSG_DEBUG, "Candidate BSS " MACSTR
|
||||||
|
" (pref %d) not found in scan results",
|
||||||
|
MAC2STR(nei->bssid),
|
||||||
|
nei->preference_present ? nei->preference :
|
||||||
|
-1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssid = wpa_scan_get_ie(res, WLAN_EID_SSID);
|
||||||
|
if (ssid == NULL || bss->ssid_len != ssid[1] ||
|
||||||
|
os_memcmp(bss->ssid, ssid + 2, ssid[1]) != 0) {
|
||||||
|
/*
|
||||||
|
* TODO: Could consider allowing transition to another
|
||||||
|
* ESS if PMF was enabled for the association.
|
||||||
|
*/
|
||||||
|
wpa_printf(MSG_DEBUG, "Candidate BSS " MACSTR
|
||||||
|
" (pref %d) in different ESS",
|
||||||
|
MAC2STR(nei->bssid),
|
||||||
|
nei->preference_present ? nei->preference :
|
||||||
|
-1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res->level < bss->level && res->level < -80) {
|
||||||
|
wpa_printf(MSG_DEBUG, "Candidate BSS " MACSTR
|
||||||
|
" (pref %d) does not have sufficient signal level (%d)",
|
||||||
|
MAC2STR(nei->bssid),
|
||||||
|
nei->preference_present ? nei->preference :
|
||||||
|
-1,
|
||||||
|
res->level);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"WNM: Found an acceptable prefed transition candidate BSS "
|
||||||
|
MACSTR " (RSSI %d)",
|
||||||
|
MAC2STR(nei->bssid), res->level);
|
||||||
|
os_memcpy(bssid_to_connect, nei->bssid, ETH_ALEN);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue