[PATCH 2/4] wpa_supplicant: try the next AP from scan results if connection failed

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Avraham Stern <avraham.stern@xxxxxxxxx>

If connection to a selected AP failed and there are other candidates
in the BSS table and scan results are not too old, try to fast
associate to the next available candidate without triggering another
full scan.

Signed-off-by: Avraham Stern <avraham.stern@xxxxxxxxx>
Reviewed-by: Peer, Ilan <ilan.peer@xxxxxxxxx>
Reviewed-by: Otcheretianski, Andrei <andrei.otcheretianski@xxxxxxxxx>
Signed-off-by: Benjamin Berg <benjamin.berg@xxxxxxxxx>
---
 wpa_supplicant/events.c           |  7 ++--
 wpa_supplicant/interworking.c     |  2 +-
 wpa_supplicant/wpa_supplicant.c   | 70 ++++---------------------------
 wpa_supplicant/wpa_supplicant_i.h |  3 +-
 wpa_supplicant/wps_supplicant.c   |  2 +-
 5 files changed, 17 insertions(+), 67 deletions(-)

diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index d388f31ff5..c786efefcc 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1771,7 +1771,8 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s,
 
 
 struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
-					     struct wpa_ssid **selected_ssid)
+					     struct wpa_ssid **selected_ssid,
+					     bool clear_ignorelist)
 {
 	struct wpa_bss *selected = NULL;
 	size_t prio;
@@ -1810,7 +1811,7 @@ struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
 
 		if (!selected &&
 		    (wpa_s->bssid_ignore || wnm_active_bss_trans_mgmt(wpa_s)) &&
-		    !wpa_s->countermeasures) {
+		    !wpa_s->countermeasures && clear_ignorelist) {
 			wpa_dbg(wpa_s, MSG_DEBUG,
 				"No APs found - clear BSSID ignore list and try again");
 			wnm_btm_reset(wpa_s);
@@ -2728,7 +2729,7 @@ static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
 	os_free(wpa_s->owe_trans_scan_freq);
 	wpa_s->owe_trans_scan_freq = NULL;
 #endif /* CONFIG_OWE */
-	selected = wpa_supplicant_pick_network(wpa_s, &ssid);
+	selected = wpa_supplicant_pick_network(wpa_s, &ssid, new_scan);
 
 #ifdef CONFIG_MESH
 	if (wpa_s->ifmsh) {
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
index faefb66995..f77880409a 100644
--- a/wpa_supplicant/interworking.c
+++ b/wpa_supplicant/interworking.c
@@ -899,7 +899,7 @@ static int already_connected(struct wpa_supplicant *wpa_s,
 		return 0;
 
 	sel_ssid = NULL;
-	selected = wpa_supplicant_pick_network(wpa_s, &sel_ssid);
+	selected = wpa_supplicant_pick_network(wpa_s, &sel_ssid, true);
 	if (selected && sel_ssid && sel_ssid->priority > ssid->priority)
 		return 0; /* higher priority network in scan results */
 
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 0586c371ae..baadc44c0c 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -8778,46 +8778,11 @@ void add_freq(int *freqs, int *num_freqs, int freq)
 }
 
 
-static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
-{
-	struct wpa_bss *bss, *cbss;
-	const int max_freqs = 10;
-	int *freqs;
-	int num_freqs = 0;
-
-	freqs = os_calloc(max_freqs + 1, sizeof(int));
-	if (freqs == NULL)
-		return NULL;
-
-	cbss = wpa_s->current_bss;
-
-	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
-		if (bss == cbss)
-			continue;
-		if (bss->ssid_len == cbss->ssid_len &&
-		    os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
-		    !wpa_bssid_ignore_is_listed(wpa_s, bss->bssid)) {
-			add_freq(freqs, &num_freqs, bss->freq);
-			if (num_freqs == max_freqs)
-				break;
-		}
-	}
-
-	if (num_freqs == 0) {
-		os_free(freqs);
-		freqs = NULL;
-	}
-
-	return freqs;
-}
-
-
 void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid,
 			    const u8 **link_bssids)
 {
 	int timeout;
 	int count;
-	int *freqs = NULL;
 
 	wpas_connect_work_done(wpa_s);
 
@@ -8854,27 +8819,15 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid,
 	 * attempt if there could be other APs that could accept association.
 	 */
 	count = wpa_bssid_ignore_add(wpa_s, bssid);
-	if (count == 1 && wpa_s->current_bss) {
-		/*
-		 * This BSS was not in the ignore list before. If there is
-		 * another BSS available for the same ESS, we should try that
-		 * next. Otherwise, we may as well try this one once more
-		 * before allowing other, likely worse, ESSes to be considered.
-		 */
-		freqs = get_bss_freqs_in_ess(wpa_s);
-		if (freqs) {
-			wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
-				"has been seen; try it next");
-			wpa_bssid_ignore_add(wpa_s, bssid);
-			/*
-			 * On the next scan, go through only the known channels
-			 * used in this ESS based on previous scans to speed up
-			 * common load balancing use case.
-			 */
-			os_free(wpa_s->next_scan_freqs);
-			wpa_s->next_scan_freqs = freqs;
-		}
-	}
+
+	/*
+	 * This BSS was not in the ignore list before. If there is
+	 * another BSS available for the same ESS, we should try that
+	 * next. Otherwise, we may as well try this one once more
+	 * before allowing other, likely worse, ESSes to be considered.
+	 */
+	if (count == 1 && wpa_supplicant_fast_associate(wpa_s) == 1)
+		return;
 
 	wpa_s->consecutive_conn_failures++;
 
@@ -8910,11 +8863,6 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid,
 		"Consecutive connection failures: %d --> request scan in %d ms",
 		wpa_s->consecutive_conn_failures, timeout);
 
-	/*
-	 * TODO: if more than one possible AP is available in scan results,
-	 * could try the other ones before requesting a new scan.
-	 */
-
 	/* speed up the connection attempt with normal scan */
 	wpa_s->normal_scans = 0;
 	wpa_supplicant_req_scan(wpa_s, timeout / 1000,
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 2f77413d57..d8bfcfede9 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1873,7 +1873,8 @@ void wnm_bss_keep_alive_deinit(struct wpa_supplicant *wpa_s);
 int wpa_supplicant_fast_associate(struct wpa_supplicant *wpa_s);
 int wpa_wps_supplicant_fast_associate(struct wpa_supplicant *wpa_s);
 struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
-					     struct wpa_ssid **selected_ssid);
+					     struct wpa_ssid **selected_ssid,
+					     bool clear_ignorelist);
 int wpas_temp_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
 void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s,
 					struct channel_list_changed *info);
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index 405c5d6051..25a5598ce7 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -148,7 +148,7 @@ int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
 
 		wpa_printf(MSG_DEBUG, "WPS: Checking whether fast association "
 			   "without a new scan can be used");
-		bss = wpa_supplicant_pick_network(wpa_s, &ssid);
+		bss = wpa_supplicant_pick_network(wpa_s, &ssid, true);
 		if (bss) {
 			struct wpabuf *wps;
 			struct wps_parse_attr attr;
-- 
2.50.1


_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap



[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux