aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant/events.c
diff options
context:
space:
mode:
authorAvraham Stern <avraham.stern@intel.com>2015-03-16 05:20:02 (GMT)
committerJouni Malinen <j@w1.fi>2015-03-22 18:53:58 (GMT)
commit9bd566a33a024675e8918ab5c77e7fc03067bc44 (patch)
tree0acad26fb6521ebb88ba44bec7ba66af1872169c /wpa_supplicant/events.c
parent701f3961e3781960ec2dff168a44e167e1dae292 (diff)
downloadhostap-9bd566a33a024675e8918ab5c77e7fc03067bc44.zip
hostap-9bd566a33a024675e8918ab5c77e7fc03067bc44.tar.gz
hostap-9bd566a33a024675e8918ab5c77e7fc03067bc44.tar.bz2
Delay AP selection if all networks are temporarily disabled
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>
Diffstat (limited to 'wpa_supplicant/events.c')
-rw-r--r--wpa_supplicant/events.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 45edec6..3adb954 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -71,6 +71,59 @@ 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;
+
+#ifdef CONFIG_INTERWORKING
+ if (wpa_s->conf->auto_interworking && wpa_s->conf->interworking &&
+ wpa_s->conf->cred)
+ return 0;
+#endif /* CONFIG_INTERWORKING */
+
+ 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;
+
+ if (!res || disabled_for < res)
+ res = disabled_for;
+ }
+
+ return res;
+}
+
+
+void wpas_network_reenabled(void *eloop_ctx, void *timeout_ctx)
+{
+ struct wpa_supplicant *wpa_s = eloop_ctx;
+
+ if (wpa_s->disconnected || wpa_s->wpa_state != WPA_SCANNING)
+ return;
+
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "Try to associate due to network getting re-enabled");
+ 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 +1474,17 @@ 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) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "Postpone network selection by %d seconds since all networks are disabled",
+ time_to_reenable);
+ 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 */
@@ -1946,6 +2010,8 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
}
#endif /* CONFIG_AP */
+ eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
+
ft_completed = wpa_ft_is_completed(wpa_s->wpa);
if (data && wpa_supplicant_event_associnfo(wpa_s, data) < 0)
return;