]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Enhance select_network() to trigger new scans in some cases
authorHu Wang <quic_huw@quicinc.com>
Wed, 26 Jun 2024 03:05:12 +0000 (20:05 -0700)
committerJouni Malinen <j@w1.fi>
Mon, 22 Jul 2024 19:01:18 +0000 (19:01 +0000)
wpa_supplicant select_network() relies on fast_associate to reuse old
scan results. However, this approach does not apply in some cases in
Android:

1 - If the selected network is hidden, and the SSID is in Chinese,
Android switches between fallback SSIDs, necessitating a new scan for
switching between different hidden SSIDs.

2 - Similarly, if the selected SSID is OWE (Opportunistic Wireless
Encryption), and the OWE SSID bands have been changed, select_network()
requires a fresh scan to discover hidden OWE SSIDs.

To address these, enhance select_network() to trigger new scans instead
of relying on fast_associate. This improves network selection behavior
in Android.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
wpa_supplicant/events.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index 48a226a5f3ed981a83f1317d2aa9f514fb013f37..698fb57ef66ed8891a9a89e720df04ab375734ae 100644 (file)
@@ -2483,6 +2483,8 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
        }
 #endif /* CONFIG_NO_RANDOM_POOL */
 
+       wpa_s->last_scan_external = data && data->scan_info.external_scan;
+
        if (update_only) {
                ret = 1;
                goto scan_work_done;
index 3203446f1ddb8f742fb0dd5f3bd4f4abc54e6a31..b04fcb9875ec61e90e3213925491dea0abe81887 100644 (file)
@@ -4218,6 +4218,7 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
 #ifdef CONFIG_WNM
        wpa_s->bss_trans_mgmt_in_progress = false;
 #endif /* CONFIG_WNM */
+       wpa_s->no_suitable_network = 0;
 
        if (deinit) {
                if (work->started) {
@@ -5085,6 +5086,7 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
 
        struct wpa_ssid *other_ssid;
        int disconnected = 0;
+       bool request_new_scan = false;
 
        if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
                if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
@@ -5130,6 +5132,18 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
                        (ssid->mode == WPAS_MODE_MESH ||
                         ssid->mode == WPAS_MODE_AP) ? ssid : NULL;
 
+               if (ssid->scan_ssid &&
+                   (wpa_s->no_suitable_network || wpa_s->last_scan_external)) {
+                       wpa_printf(MSG_DEBUG,
+                                  "Request a new scan for hidden network");
+                       request_new_scan = true;
+               } else if ((ssid->key_mgmt & WPA_KEY_MGMT_OWE) &&
+                          !ssid->owe_only) {
+                       wpa_printf(MSG_DEBUG,
+                                  "Request a new scan for OWE transition SSID");
+                       request_new_scan = true;
+               }
+
                /*
                 * Don't optimize next scan freqs since a new ESS has been
                 * selected.
@@ -5149,7 +5163,7 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
                wpa_s_setup_sae_pt(wpa_s->conf, ssid, false);
        }
 
-       if (wpa_s->connect_without_scan ||
+       if (wpa_s->connect_without_scan || request_new_scan ||
            wpa_supplicant_fast_associate(wpa_s) != 1) {
                wpa_s->scan_req = NORMAL_SCAN_REQ;
                wpas_scan_reset_sched_scan(wpa_s);
index 3043bc6543064dc04ce9eba43324e78301df74ad..48ec95fa5f49bb8b1e241796299193cf2484a2c9 100644 (file)
@@ -805,6 +805,7 @@ struct wpa_supplicant {
        size_t last_scan_res_used;
        size_t last_scan_res_size;
        struct os_reltime last_scan;
+       bool last_scan_external;
 
        const struct wpa_driver_ops *driver;
        int interface_removed; /* whether the network interface has been