[PATCH] wnm: Choose best available bss, not just first one.

greearb at candelatech.com greearb at candelatech.com
Thu Jul 27 09:02:11 PDT 2023


From: Ben Greear <greearb at candelatech.com>

This should allow STA to make better choice about which
BSS to roam to.

Use estimated-throughput as comparison value.  Can improve
the est-tput measurement to improve this selection criteria
if wanted in the future.

Signed-off-by: Ben Greear <greearb at candelatech.com>
---
 wpa_supplicant/wnm_sta.c | 55 +++++++++++++++++++++++++---------------
 1 file changed, 34 insertions(+), 21 deletions(-)

diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
index 8acc8fc88..de485b510 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,
@@ -723,6 +707,19 @@ end:
 }
 #endif /* CONFIG_MBO */
 
+struct wpa_bss* find_best_target(struct wpa_bss* a, struct wpa_bss* b)
+{
+	if (a->est_throughput > b->est_throughput) {
+		wpa_printf(MSG_DEBUG, "WNM: A is best: " 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 best, 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,
@@ -731,6 +728,9 @@ 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 = bss;
+	struct wpa_bss *bss_in_list = NULL;
+	long diff;
 
 	if (!bss)
 		return NULL;
@@ -817,25 +817,38 @@ compare_scan_neighbor_results(struct wpa_supplicant *wpa_s, os_time_t age_secs,
 		}
 
 		nei->acceptable = 1;
+
+		best_target = find_best_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);
+			   MACSTR " (RSSI %d, tput: %d  bss-tput: %d)",
+			   MAC2STR(target->bssid), target->level, target->est_throughput,
+			   bss->est_throughput);
 	}
 
-	return target;
+	if (!bss_in_list)
+		return target;
+
+	diff = target->est_throughput - bss_in_list->est_throughput;
+	if (diff > bss_in_list->est_throughput >> 4) {
+		/* It is more than 100/16 percent better, so switch. */
+		return target;
+	}
+	return bss_in_list; /* stay with our existing bss, not enough change in est rate to switch. */
 }
 
 
-- 
2.40.0




More information about the Hostap mailing list