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; }