Fix PNO restart flow
[mech_eap.git] / wpa_supplicant / events.c
index ba30780..abe3b47 100644 (file)
@@ -1101,6 +1101,10 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
                        continue;
                }
 #ifdef CONFIG_MBO
+#ifdef CONFIG_TESTING_OPTIONS
+               if (wpa_s->ignore_assoc_disallow)
+                       goto skip_assoc_disallow;
+#endif /* CONFIG_TESTING_OPTIONS */
                assoc_disallow = wpas_mbo_get_bss_attr(
                        bss, MBO_ATTR_ID_ASSOC_DISALLOW);
                if (assoc_disallow && assoc_disallow[1] >= 1) {
@@ -1115,6 +1119,9 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
                                "   skip - MBO retry delay has not passed yet");
                        continue;
                }
+#ifdef CONFIG_TESTING_OPTIONS
+       skip_assoc_disallow:
+#endif /* CONFIG_TESTING_OPTIONS */
 #endif /* CONFIG_MBO */
 
                /* Matching configuration found */
@@ -2511,6 +2518,7 @@ static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s,
        struct wpa_bss *fast_reconnect = NULL;
        struct wpa_ssid *fast_reconnect_ssid = NULL;
        struct wpa_ssid *last_ssid;
+       struct wpa_bss *curr = NULL;
 
        authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING;
        os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN);
@@ -2526,6 +2534,19 @@ static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s,
                return;
        }
 
+       if (!wpa_s->disconnected && wpa_s->wpa_state >= WPA_AUTHENTICATING &&
+           reason_code == WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY &&
+           locally_generated)
+               /*
+                * Remove the inactive AP (which is probably out of range) from
+                * the BSS list after marking disassociation. In particular
+                * mac80211-based drivers use the
+                * WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY reason code in
+                * locally generated disconnection events for cases where the
+                * AP does not reply anymore.
+                */
+               curr = wpa_s->current_bss;
+
        if (could_be_psk_mismatch(wpa_s, reason_code, locally_generated)) {
                wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - "
                        "pre-shared key may be incorrect");
@@ -2587,6 +2608,9 @@ static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s,
        last_ssid = wpa_s->current_ssid;
        wpa_supplicant_mark_disassoc(wpa_s);
 
+       if (curr)
+               wpa_bss_remove(wpa_s, curr, "Connection to AP lost");
+
        if (authenticating && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) {
                sme_disassoc_while_authenticating(wpa_s, prev_pending_bssid);
                wpa_s->current_ssid = last_ssid;
@@ -3212,14 +3236,16 @@ static void wpa_supplicant_update_channel_list(
                free_hw_features(ifs);
                ifs->hw.modes = wpa_drv_get_hw_feature_data(
                        ifs, &ifs->hw.num_modes, &ifs->hw.flags);
-       }
 
-       /* Restart sched_scan with updated channel list */
-       if (wpa_s->sched_scanning) {
-               wpa_dbg(wpa_s, MSG_DEBUG,
-                       "Channel list changed restart sched scan.");
-               wpa_supplicant_cancel_sched_scan(wpa_s);
-               wpa_supplicant_req_scan(wpa_s, 0, 0);
+               /* Restart PNO/sched_scan with updated channel list */
+               if (ifs->pno) {
+                       wpas_stop_pno(ifs);
+                       wpas_start_pno(ifs);
+               } else if (ifs->sched_scanning && !ifs->pno_sched_pending) {
+                       wpa_dbg(ifs, MSG_DEBUG,
+                               "Channel list changed - restart sched_scan");
+                       wpas_scan_restart_sched_scan(ifs);
+               }
        }
 
        wpas_p2p_update_channel_list(wpa_s, WPAS_P2P_CHANNEL_UPDATE_DRIVER);
@@ -3445,6 +3471,13 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                sme_event_auth(wpa_s, data);
                break;
        case EVENT_ASSOC:
+#ifdef CONFIG_TESTING_OPTIONS
+               if (wpa_s->ignore_auth_resp) {
+                       wpa_printf(MSG_INFO,
+                                  "EVENT_ASSOC - ignore_auth_resp active!");
+                       break;
+               }
+#endif /* CONFIG_TESTING_OPTIONS */
                wpa_supplicant_event_assoc(wpa_s, data);
                if (data && data->assoc_info.authorized)
                        wpa_supplicant_event_assoc_auth(wpa_s, data);
@@ -3459,6 +3492,13 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                                    data ? &data->disassoc_info : NULL);
                break;
        case EVENT_DEAUTH:
+#ifdef CONFIG_TESTING_OPTIONS
+               if (wpa_s->ignore_auth_resp) {
+                       wpa_printf(MSG_INFO,
+                                  "EVENT_DEAUTH - ignore_auth_resp active!");
+                       break;
+               }
+#endif /* CONFIG_TESTING_OPTIONS */
                wpas_event_deauth(wpa_s,
                                  data ? &data->deauth_info : NULL);
                break;
@@ -4026,6 +4066,20 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                        break;
 
                /*
+                * If the driver stopped scanning without being requested to,
+                * request a new scan to continue scanning for networks.
+                */
+               if (!wpa_s->sched_scan_stop_req &&
+                   wpa_s->wpa_state == WPA_SCANNING) {
+                       wpa_dbg(wpa_s, MSG_DEBUG,
+                               "Restart scanning after unexpected sched_scan stop event");
+                       wpa_supplicant_req_scan(wpa_s, 1, 0);
+                       break;
+               }
+
+               wpa_s->sched_scan_stop_req = 0;
+
+               /*
                 * Start a new sched scan to continue searching for more SSIDs
                 * either if timed out or PNO schedule scan is pending.
                 */