From 67bf89f554425b600c2ca744920cc09b43a2311a Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Thu, 27 Jul 2023 09:02:11 -0700 Subject: [PATCH] WNM: Choose the best available BSS, not just the first one This should allow STA to make better choice about which BSS to roam to. Use estimated throughput as comparison value. Can improve the estimated throughput calculation to improve this selection criteria if wanted in the future. Signed-off-by: Ben Greear --- wpa_supplicant/wnm_sta.c | 76 +++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c index 5b3de30d5..89b7ae0bd 100644 --- a/wpa_supplicant/wnm_sta.c +++ b/wpa_supplicant/wnm_sta.c @@ -614,22 +614,6 @@ static void wnm_clear_acceptable(struct wpa_supplicant *wpa_s) wpa_s->wnm_neighbor_report_elements[i].acceptable = 0; } - -static struct wpa_bss * get_first_acceptable(struct wpa_supplicant *wpa_s) -{ - unsigned int i; - struct neighbor_report *nei; - - for (i = 0; i < wpa_s->wnm_num_neighbor_report; i++) { - nei = &wpa_s->wnm_neighbor_report_elements[i]; - if (nei->acceptable) - return wpa_bss_get_bssid(wpa_s, nei->bssid); - } - - return NULL; -} - - #ifdef CONFIG_MBO static struct wpa_bss * get_mbo_transition_candidate(struct wpa_supplicant *wpa_s, @@ -724,6 +708,29 @@ end: #endif /* CONFIG_MBO */ +static struct wpa_bss * find_better_target(struct wpa_bss *a, + struct wpa_bss *b) +{ + if (!a) + return b; + if (!b) + return a; + + if (a->est_throughput > b->est_throughput) { + wpa_printf(MSG_DEBUG, "WNM: A is better: " MACSTR + " est-tput: %d B: " MACSTR " est-tput: %d", + MAC2STR(a->bssid), a->est_throughput, + MAC2STR(b->bssid), b->est_throughput); + return a; + } + + wpa_printf(MSG_DEBUG, "WNM: B is better, A: " MACSTR + " est-tput: %d B: " MACSTR " est-tput: %d", + MAC2STR(a->bssid), a->est_throughput, + MAC2STR(b->bssid), b->est_throughput); + return b; +} + static struct wpa_bss * compare_scan_neighbor_results(struct wpa_supplicant *wpa_s, os_time_t age_secs, enum mbo_transition_reject_reason *reason) @@ -731,6 +738,8 @@ compare_scan_neighbor_results(struct wpa_supplicant *wpa_s, os_time_t age_secs, u8 i; struct wpa_bss *bss = wpa_s->current_bss; struct wpa_bss *target; + struct wpa_bss *best_target = NULL; + struct wpa_bss *bss_in_list = NULL; if (!bss) return NULL; @@ -817,25 +826,44 @@ compare_scan_neighbor_results(struct wpa_supplicant *wpa_s, os_time_t age_secs, } nei->acceptable = 1; + + best_target = find_better_target(target, best_target); + if (target == bss) + bss_in_list = bss; } #ifdef CONFIG_MBO if (wpa_s->wnm_mbo_trans_reason_present) target = get_mbo_transition_candidate(wpa_s, reason); else - target = get_first_acceptable(wpa_s); + target = best_target; #else /* CONFIG_MBO */ - target = get_first_acceptable(wpa_s); + target = best_target; #endif /* CONFIG_MBO */ - if (target) { - wpa_printf(MSG_DEBUG, - "WNM: Found an acceptable preferred transition candidate BSS " - MACSTR " (RSSI %d)", - MAC2STR(target->bssid), target->level); + if (!target) + return NULL; + + wpa_printf(MSG_DEBUG, + "WNM: Found an acceptable preferred transition candidate BSS " + MACSTR " (RSSI %d, tput: %d bss-tput: %d)", + MAC2STR(target->bssid), target->level, + target->est_throughput, bss->est_throughput); + + if (!bss_in_list) + return target; + + if ((!target->est_throughput && !bss_in_list->est_throughput) || + (target->est_throughput > bss_in_list->est_throughput && + target->est_throughput - bss_in_list->est_throughput > + bss_in_list->est_throughput >> 4)) { + /* It is more than 100/16 percent better, so switch. */ + return target; } - return target; + wpa_printf(MSG_DEBUG, + "WNM: Stay with our current BSS, not enough change in estimated throughput to switch"); + return bss_in_list; } -- 2.39.2