[PATCH 10/16] WNM: Use standard BSS selection and enable abridged bit handling

benjamin at sipsolutions.net benjamin at sipsolutions.net
Mon Apr 29 04:51:51 PDT 2024


From: Benjamin Berg <benjamin.berg at intel.com>

Most of the logic to reject BSSs during transition has been moved into
wnm_is_bss_excluded. In addition to this, since commit 67bf89f55442
("WNM: Choose the best available BSS, not just the first one") we will
simply choose the BSS with the best throughput.

Overall, this matches the behaviour that the supplicant will use anyway
in wpa_supplicant_select_bss. The only bigger difference is that using
this will check all known BSSs instead of only the ones in the candidate
list. This means that with this change the abridged bit is handled
according to spec.

Another slight change is that this drops the logic to reject candidates
with a very low signal level. This does not seem to very relevant
anymore as we prefere stronger BSSs to begin with.

Signed-off-by: Benjamin Berg <benjamin.berg at intel.com>
---
 wpa_supplicant/events.c           |   2 +-
 wpa_supplicant/wnm_sta.c          | 129 +++---------------------------
 wpa_supplicant/wpa_supplicant_i.h |   5 ++
 3 files changed, 18 insertions(+), 118 deletions(-)

diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 4505d9e15..31c807879 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1709,7 +1709,7 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
 }
 
 
-static struct wpa_bss *
+struct wpa_bss *
 wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s,
 			  struct wpa_ssid *group,
 			  struct wpa_ssid **selected_ssid,
diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
index 64124348f..8c51b3ddb 100644
--- a/wpa_supplicant/wnm_sta.c
+++ b/wpa_supplicant/wnm_sta.c
@@ -693,117 +693,6 @@ fetch_drv_mbo_transition_candidate_info(struct wpa_supplicant *wpa_s)
 #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,
-			      enum mbo_transition_reject_reason *reason)
-{
-	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;
-
-	wpa_printf(MSG_DEBUG, "WNM: Current BSS " MACSTR " RSSI %d",
-		   MAC2STR(wpa_s->bssid), bss->level);
-
-	for (i = 0; i < wpa_s->wnm_num_neighbor_report; i++) {
-		struct neighbor_report *nei;
-
-		nei = &wpa_s->wnm_neighbor_report_elements[i];
-
-		target = wpa_bss_get_bssid(wpa_s, nei->bssid);
-		if (!target) {
-			wpa_printf(MSG_DEBUG, "Candidate BSS " MACSTR
-				   " (pref %d) not found in scan results",
-				   MAC2STR(nei->bssid),
-				   nei->preference_present ? nei->preference :
-				   -1);
-			continue;
-		}
-
-		/*
-		 * TODO: Could consider allowing transition to another ESS if
-		 * PMF was enabled for the association.
-		 */
-		if (!wpa_scan_res_match(wpa_s, 0, target, wpa_s->current_ssid,
-					1, 0)) {
-			wpa_printf(MSG_DEBUG, "Candidate BSS " MACSTR
-				   " (pref %d) does not match the current network profile",
-				   MAC2STR(nei->bssid),
-				   nei->preference_present ? nei->preference :
-				   -1);
-			continue;
-		}
-
-		if (target->level < bss->level && target->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,
-				   target->level);
-			continue;
-		}
-
-		best_target = find_better_target(target, best_target);
-		if (target == bss)
-			bss_in_list = bss;
-	}
-
-	target = best_target;
-
-	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;
-	}
-
-	wpa_printf(MSG_DEBUG,
-		   "WNM: Stay with our current BSS, not enough change in estimated throughput to switch");
-	return bss_in_list;
-}
-
-
 static int wpa_bss_ies_eq(struct wpa_bss *a, struct wpa_bss *b, u8 eid)
 {
 	const u8 *ie_a, *ie_b;
@@ -1121,11 +1010,12 @@ static void wnm_bss_tm_connect(struct wpa_supplicant *wpa_s,
 
 int wnm_scan_process(struct wpa_supplicant *wpa_s, bool pre_scan_check)
 {
-	struct wpa_bss *bss;
+	struct wpa_bss *bss, *current_bss = wpa_s->current_bss;
 	struct wpa_ssid *ssid = wpa_s->current_ssid;
 	enum bss_trans_mgmt_status_code status = WNM_BSS_TM_REJECT_UNSPECIFIED;
 	enum mbo_transition_reject_reason reason =
 		MBO_TRANSITION_REJECT_REASON_UNSPECIFIED;
+	struct wpa_ssid *selected_ssid = NULL;
 
 	if (!wpa_s->wnm_dialog_token)
 		return 0;
@@ -1149,7 +1039,7 @@ int wnm_scan_process(struct wpa_supplicant *wpa_s, bool pre_scan_check)
 	fetch_drv_mbo_candidate_info(wpa_s, &reason);
 
 	/* Compare the Neighbor Report and scan results */
-	bss = compare_scan_neighbor_results(wpa_s, &reason);
+	bss = wpa_supplicant_select_bss(wpa_s, ssid, &selected_ssid, 1);
 #ifdef CONFIG_MBO
 	if (!bss && wpa_s->wnm_mbo_trans_reason_present &&
 	    wpa_s->wnm_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT) {
@@ -1175,7 +1065,7 @@ int wnm_scan_process(struct wpa_supplicant *wpa_s, bool pre_scan_check)
 				nei->drv_mbo_reject = 0;
 		}
 
-		bss = compare_scan_neighbor_results(wpa_s, &reason);
+		bss = wpa_supplicant_select_bss(wpa_s, ssid, &selected_ssid, 1);
 	}
 #endif /* CONFIG_MBO */
 
@@ -1200,9 +1090,8 @@ int wnm_scan_process(struct wpa_supplicant *wpa_s, bool pre_scan_check)
 			return 0;
 
 #ifndef CONFIG_NO_ROAMING
-		if (wpa_s->current_bss && bss != wpa_s->current_bss &&
-		    wpa_supplicant_need_to_roam_within_ess(wpa_s,
-							   wpa_s->current_bss,
+		if (current_bss && bss != current_bss &&
+		    wpa_supplicant_need_to_roam_within_ess(wpa_s, current_bss,
 							   bss))
 			return 0;
 #endif /* CONFIG_NO_ROAMING */
@@ -1214,6 +1103,12 @@ int wnm_scan_process(struct wpa_supplicant *wpa_s, bool pre_scan_check)
 		goto send_bss_resp_fail;
 	}
 
+	wpa_printf(MSG_DEBUG,
+		   "WNM: Found an acceptable preferred transition candidate BSS "
+		   MACSTR " (RSSI %d, tput: %d  bss-tput: %d)",
+		   MAC2STR(bss->bssid), bss->level, bss->est_throughput,
+		   current_bss ? current_bss->est_throughput : -1);
+
 	/* Associate to the network */
 	wnm_bss_tm_connect(wpa_s, bss, ssid, 1);
 	return 1;
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index d4a1284c3..64177546f 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1950,6 +1950,11 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
 				     struct wpa_ssid *group,
 				     int only_first_ssid, int debug_print);
 
+struct wpa_bss * wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s,
+					   struct wpa_ssid *group,
+					   struct wpa_ssid **selected_ssid,
+					   int only_first_ssid);
+
 int wpas_ctrl_iface_get_pref_freq_list_override(struct wpa_supplicant *wpa_s,
 						enum wpa_driver_if_type if_type,
 						unsigned int *num,
-- 
2.44.0




More information about the Hostap mailing list