diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 09f72af78..53d2d0155 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -6702,6 +6702,8 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s) MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid)); } + + eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL); } @@ -8262,6 +8264,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, wpa_supplicant_cancel_scan(wpa_s); wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); + eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL); } else if (os_strcmp(buf, "SCAN") == 0) { wpas_ctrl_scan(wpa_s, NULL, reply, reply_size, &reply_len); } else if (os_strncmp(buf, "SCAN ", 5) == 0) { diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 45edec6e1..3adb95427 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; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 6e3b907d9..6f5fbadaa 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 26ff216b0..0ec102f1c 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 */