diff mbox

[2/3] wpa_supplicant: Delay AP selection if all networks are temporarily disabled

Message ID 1426483203-7325-2-git-send-email-ilan.peer@intel.com
State Accepted
Headers show

Commit Message

Peer, Ilan March 16, 2015, 5:20 a.m. UTC
From: Avraham Stern <avraham.stern@intel.com>

If all networks are temporarily disabled, delay AP selection until
at least one network is enabled.
Running AP selection when all networks are disabled is useless as
wpa_supplicant will not try to connect. In addition, it will result in
needless scan iterations that may delay the connection when it is
needed.

Signed-off-by: Avraham Stern <avraham.stern@intel.com>
---
 wpa_supplicant/events.c           | 48 +++++++++++++++++++++++++++++++++++++++
 wpa_supplicant/wpa_supplicant.c   |  2 ++
 wpa_supplicant/wpa_supplicant_i.h |  1 +
 3 files changed, 51 insertions(+)

Comments

Jouni Malinen March 22, 2015, 8:15 p.m. UTC | #1
On Mon, Mar 16, 2015 at 01:20:02AM -0400, Ilan Peer wrote:
> If all networks are temporarily disabled, delay AP selection until
> at least one network is enabled.
> Running AP selection when all networks are disabled is useless as
> wpa_supplicant will not try to connect. In addition, it will result in
> needless scan iterations that may delay the connection when it is
> needed.

Thanks, applied with number of changes. I added a call to cancel the
timeout in number of places to avoid getting unexpected connection
attempts if something external were to move wpa_supplicant into
disconnected (or connected, for that matter) state. In addition, this
mechanism needs to be skipped if there are any enabled credential blocks
for Interworking network connection and auto_interworking=1
diff mbox

Patch

diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index d275ca4..bc3f201 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -71,6 +71,46 @@  static int wpas_temp_disabled(struct wpa_supplicant *wpa_s,
 }
 
 
+/**
+ * wpas_reenabled_network_time - time until first network is re-enabled
+ * @wpa_s: Pointer to wpa_supplicant data
+ * Returns: If all enabled networks are temporarily disabled, returns the time
+ *	(in sec) until the first network is re-enabled. Otherwise returns 0.
+ *
+ * This function is used in case all enabled networks are temporarily disabled,
+ * in which case it returns the time (in sec) that the first network will be
+ * re-enabled. The function assumes that at least one network is enabled.
+ */
+static int wpas_reenabled_network_time(struct wpa_supplicant *wpa_s)
+{
+	struct wpa_ssid *ssid;
+	int disabled_for, res = 0;
+
+	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
+		if (ssid->disabled)
+			continue;
+
+		disabled_for = wpas_temp_disabled(wpa_s, ssid);
+		if (!disabled_for)
+			return 0;
+
+		res = (!res || disabled_for < res) ? disabled_for : res;
+	}
+
+	return res;
+}
+
+void wpas_network_reenabled(void *eloop_ctx, void *timeout_ctx)
+{
+	struct wpa_supplicant *wpa_s = eloop_ctx;
+
+	if (wpa_supplicant_fast_associate(wpa_s) != 1) {
+		wpa_supplicant_cancel_sched_scan(wpa_s);
+		wpa_supplicant_req_scan(wpa_s, 0, 0);
+	}
+}
+
+
 static struct wpa_bss * wpa_supplicant_get_new_bss(
 	struct wpa_supplicant *wpa_s, const u8 *bssid)
 {
@@ -1421,6 +1461,14 @@  static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
 {
 	struct wpa_bss *selected;
 	struct wpa_ssid *ssid = NULL;
+	int time_to_reenable = wpas_reenabled_network_time(wpa_s);
+
+	if (time_to_reenable > 0) {
+		eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
+		eloop_register_timeout(time_to_reenable, 0,
+				       wpas_network_reenabled, wpa_s, NULL);
+		return 0;
+	}
 
 	if (wpa_s->p2p_mgmt)
 		return 0; /* no normal connection on p2p_mgmt interface */
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 6e3b907..6f5fbad 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -456,6 +456,8 @@  static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
 			     wpa_s, NULL);
 #endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
 
+	eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
+
 	wpas_wps_deinit(wpa_s);
 
 	wpabuf_free(wpa_s->pending_eapol_rx);
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 26ff216..0ec102f 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1140,4 +1140,5 @@  int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s,
 int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
 			   int *freq_array, unsigned int len);
 
+void wpas_network_reenabled(void *eloop_ctx, void *timeout_ctx);
 #endif /* WPA_SUPPLICANT_I_H */