@@ -2490,6 +2490,7 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
int ap = 0;
bool trigger_6ghz_scan;
bool short_ssid_match_found = false;
+ size_t idx;
#ifndef CONFIG_NO_RANDOM_POOL
size_t i, num;
#endif /* CONFIG_NO_RANDOM_POOL */
@@ -2555,7 +2556,23 @@ 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 (data) {
+ wpa_s->last_scan_external = data->scan_info.external_scan;
+ wpa_s->last_scan_num_ssids = data->scan_info.num_ssids;
+ for (idx = 0; idx < wpa_s->last_scan_num_ssids; idx++) {
+ /* Copy the SSID and its length */
+ if (data->scan_info.ssids[idx].ssid_len > SSID_MAX_LEN)
+ continue;
+
+ os_memcpy(wpa_s->last_scan_ssids[idx].ssid,
+ data->scan_info.ssids[idx].ssid,
+ data->scan_info.ssids[idx].ssid_len);
+ wpa_s->last_scan_ssids[idx].ssid[data->scan_info.ssids[idx].ssid_len] =
+ '\0';
+ wpa_s->last_scan_ssids[idx].ssid_len =
+ data->scan_info.ssids[idx].ssid_len;
+ }
+ }
if (update_only) {
ret = 1;
@@ -5116,7 +5116,12 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
struct wpa_ssid *other_ssid;
int disconnected = 0;
+ int i;
bool request_new_scan = false;
+ bool ssid_scanned = false;
+ const char *current_ssid_name;
+ const char *prev_ssid_name;
+
if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
@@ -5162,11 +5167,36 @@ 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;
+ if (ssid->scan_ssid) {
+ /* Check if the previous scan included the selected network */
+ if (wpa_s->last_scan_num_ssids > 1) {
+ current_ssid_name = wpa_ssid_txt(ssid->ssid, ssid->ssid_len);
+ ssid_scanned = false;
+ /* Iterate through the previous scan SSIDs */
+ for (i = 0; i < wpa_s->last_scan_num_ssids; i++) {
+ prev_ssid_name = wpa_ssid_txt(
+ wpa_s->last_scan_ssids[i].ssid,
+ wpa_s->last_scan_ssids[i].ssid_len);
+ if (os_strcmp(current_ssid_name, prev_ssid_name) == 0) {
+ ssid_scanned = true;
+ break;
+ }
+ }
+ if (!ssid_scanned) {
+ /* SSID not found in previous scan, request a new scan */
+ request_new_scan = true;
+ }
+ } else {
+ /* No previous scan or wildcard scan, request a new scan */
+ request_new_scan = true;
+ }
+
+ if (request_new_scan) {
+ wpa_printf(MSG_DEBUG, "Request a new scan for hidden network");
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "Hidden network was scanned for in last scan");
+ }
} else if ((ssid->key_mgmt & WPA_KEY_MGMT_OWE) &&
!ssid->owe_only) {
wpa_printf(MSG_DEBUG,
@@ -668,6 +668,11 @@ struct ml_sta_link_info {
u16 status;
};
+struct last_scan_ssid {
+ u8 ssid[SSID_MAX_LEN + 1];
+ size_t ssid_len;
+};
+
/**
* struct wpa_supplicant - Internal data for wpa_supplicant interface
@@ -806,6 +811,9 @@ struct wpa_supplicant {
size_t last_scan_res_size;
struct os_reltime last_scan;
bool last_scan_external;
+ struct last_scan_ssid last_scan_ssids[WPAS_MAX_SCAN_SSIDS];
+ size_t last_scan_num_ssids;
+
const struct wpa_driver_ops *driver;
int interface_removed; /* whether the network interface has been
This recent patch [1] introduced a redundant scan when selecting a hidden network that was previously scanned and found. This occurs because the code only checks for the condition `(wpa_s->no_suitable_network || wpa_s->last_scan_external)`, which doesn't cover the case where the last scan successfully found the hidden SSID. This patch saves the scanned SSIDs from the last scan and updates the condition to check if the hidden SSID was included. If the hidden SSID is not found in `last_scan_ssids`, it triggers a new scan (`request_new_scan = true`). [1] https://w1.fi/cgit/hostap/commit/?id=92374d59d4efea5c8b61ed2ceef141c26bcd7f99 Signed-off-by: Arowa Suliman <arowa@chromium.org> --- wpa_supplicant/events.c | 19 ++++++++++++++- wpa_supplicant/wpa_supplicant.c | 40 +++++++++++++++++++++++++++---- wpa_supplicant/wpa_supplicant_i.h | 8 +++++++ 3 files changed, 61 insertions(+), 6 deletions(-)