Merge "optimize p2p scan time in finding auto GO" into sc-dev am: d96f16d889 am: 349e972f0f

Original change: https://googleplex-android-review.googlesource.com/c/platform/external/wpa_supplicant_8/+/14157914

Change-Id: I74894478a07458d0eb4ce3ca03cbdb6d09303997
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 0d4c2bc..dffcd1b 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -816,6 +816,8 @@
 			wpa_s->sae_commit_override = wpabuf_parse_bin(value);
 	} else if (os_strcasecmp(cmd, "driver_signal_override") == 0) {
 		ret = wpas_ctrl_iface_set_dso(wpa_s, value);
+	} else if (os_strcasecmp(cmd, "force_hunting_and_pecking_pwe") == 0) {
+		wpa_s->force_hunting_and_pecking_pwe = (atoi(value) != 0) ? 1 : 0;
 #ifdef CONFIG_DPP
 	} else if (os_strcasecmp(cmd, "dpp_config_obj_override") == 0) {
 		os_free(wpa_s->dpp_config_obj_override);
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index f821709..9c4f9f5 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1063,7 +1063,7 @@
 }
 
 
-static int disabled_freq(struct wpa_supplicant *wpa_s, int freq)
+int disabled_freq(struct wpa_supplicant *wpa_s, int freq)
 {
 	int i, j;
 
diff --git a/wpa_supplicant/hidl/1.4/p2p_iface.cpp b/wpa_supplicant/hidl/1.4/p2p_iface.cpp
index 630ec68..1350c06 100644
--- a/wpa_supplicant/hidl/1.4/p2p_iface.cpp
+++ b/wpa_supplicant/hidl/1.4/p2p_iface.cpp
@@ -25,7 +25,8 @@
 #include "driver_i.h"
 }
 
-#define P2P_MAX_JOIN_SCAN_ATTEMPTS 10
+#define P2P_MAX_JOIN_SCAN_ATTEMPTS 3
+#define P2P_JOIN_SCAN_INTERVAL_USECS 1000000
 
 namespace {
 const char kConfigMethodStrPbc[] = "pbc";
@@ -92,33 +93,93 @@
 	return 1;
 }
 
-void setP2pCliBandScanFreqsList(
+static int setBandScanFreqsList(
     struct wpa_supplicant *wpa_s,
-    enum wpa_radio_work_band band,
+    enum hostapd_hw_mode hw_mode,
+    bool exclude_dfs,
     struct wpa_driver_scan_params *params)
 {
-	int num_channels, count, i;
-	int freq_list[P2P_MAX_CHANNELS];
-	struct p2p_data *p2p = wpa_s->global->p2p;
-	struct p2p_channels all_channels;
+	struct hostapd_hw_modes *mode;
+	int count, i;
 
-	// Add p2p client only channels also to allow client to discover and connect to devices
-	// which are operating on channels marked as NO_IR (not allow initiation of radiation)
-	p2p_channels_union(&p2p->cfg->channels, &p2p->cfg->cli_channels,
-			   &all_channels);
-	num_channels = p2p_channels_to_freqs(&all_channels, freq_list, P2P_MAX_CHANNELS);
-	params->freqs = (int *) os_calloc(num_channels + 1, sizeof(int));
-	if (params->freqs == NULL) {
+	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, hw_mode, 0);
+	if (mode == NULL || !mode->num_channels) {
 		wpa_printf(MSG_ERROR,
-		    "P2P: Cannot allocate memory for scan params freq list");
-		return;
+		    "P2P: No channels supported in this hw_mode: %d", hw_mode);
+		return -1;
 	}
-	for (count = 0, i = 0; i < num_channels; i++) {
-		if (wpas_freq_to_band(freq_list[i]) == band) {
-			params->freqs[count++] = freq_list[i];
+
+	/*
+	 * Allocate memory for frequency array, allocate one extra
+	 * slot for the zero-terminator.
+	 */
+	params->freqs = (int *) os_calloc(mode->num_channels + 1, sizeof(int));
+	if (params->freqs == NULL) {
+		return -ENOMEM;
+	}
+	for (count = 0, i = 0; i < mode->num_channels; i++) {
+		if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED) {
+			continue;
+		}
+		if (exclude_dfs && (mode->channels[i].flag & HOSTAPD_CHAN_RADAR)) {
+			continue;
+		}
+		params->freqs[count++] = mode->channels[i].freq;
+	}
+	if (!count && params->freqs) {
+		wpa_printf(MSG_ERROR,
+		    "P2P: All channels(exclude_dfs: %d) are disabled in this hw_mode: %d",
+		    exclude_dfs, hw_mode);
+		os_free(params->freqs);
+		return -1;
+	}
+	return 0;
+}
+
+static int setP2pCliOptimizedScanFreqsList(struct wpa_supplicant *wpa_s,
+    struct wpa_driver_scan_params *params, int freq)
+{
+	if (freq == 2 || freq == 5) {
+		enum hostapd_hw_mode mode;
+		int ret;
+		if (wpa_s->hw.modes == NULL) {
+			wpa_printf(MSG_DEBUG,
+				   "P2P: Unknown what %dG channels the driver supports.", freq);
+			return 0;
+		}
+		mode = freq == 5 ? HOSTAPD_MODE_IEEE80211A : HOSTAPD_MODE_IEEE80211G;
+		if (wpa_s->p2p_join_scan_count < 2) {
+			// scan all non DFS channels in the first two attempts
+			ret = setBandScanFreqsList(wpa_s, mode, true, params);
+			if (ret < 0 && (-ENOMEM != ret)) {
+				// try to scan all channels before returning error
+				ret = setBandScanFreqsList(wpa_s, mode, false, params);
+			}
+		} else {
+			// scan all channels
+			ret = setBandScanFreqsList(wpa_s, mode, false, params);
+		}
+		return ret;
+	} else {
+		if (disabled_freq(wpa_s, freq)) {
+			wpa_printf(MSG_ERROR,
+				   "P2P: freq %d is not supported for a client.", freq);
+			return -1;
+		}
+		/*
+		 * Allocate memory for frequency array, allocate one extra
+		 * slot for the zero-terminator.
+		 */
+		params->freqs = (int *) os_calloc(2, sizeof(int));
+		if (params->freqs) {
+			params->freqs[0] = freq;
+		} else {
+			return -ENOMEM;
 		}
 	}
+	return 0;
 }
+
 /*
  * isAnyEtherAddr - match any ether address
  *
@@ -252,47 +313,13 @@
 	wpa_printf(MSG_DEBUG, "Scan SSID %s for join with frequency %d (reinvoke)",
 	    wpa_ssid_txt(params.ssids[0].ssid, params.ssids[0].ssid_len), freq);
 
+	/* Construct an optimized p2p scan channel list */
 	if (freq > 0) {
-		if (freq == 2 || freq == 5) {
-			if (wpa_s->hw.modes != NULL) {
-				switch (freq) {
-				case 2:
-					setP2pCliBandScanFreqsList(wpa_s,
-					    BAND_2_4_GHZ, &params);
-				break;
-				case 5:
-					setP2pCliBandScanFreqsList(wpa_s,
-					    BAND_5_GHZ, &params);
-				break;
-				}
-				if (!params.freqs) {
-					wpa_printf(MSG_ERROR,
-					    "P2P: No supported channels in %dG band.", freq);
-					return -1;
-				}
-			} else {
-				wpa_printf(MSG_DEBUG,
-				    "P2P: Unknown what %dG channels the driver supports.", freq);
-			}
-		} else {
-			if (0 == p2p_supported_freq_cli(wpa_s->global->p2p, freq)) {
-				wpa_printf(MSG_ERROR,
-				    "P2P: freq %d is not supported for a client.", freq);
-				return -1;
-			}
-
-			/*
-			 * Allocate memory for frequency array, allocate one extra
-			 * slot for the zero-terminator.
-			 */
-			params.freqs = (int *) os_calloc(2, sizeof(int));
-			if (params.freqs) {
-				params.freqs[0] = freq;
-			} else {
-				wpa_printf(MSG_ERROR,
-				    "P2P: Cannot allocate memory for scan params.");
-				return -1;
-			}
+		ret = setP2pCliOptimizedScanFreqsList(wpa_s, &params, freq);
+		if (ret < 0) {
+			wpa_printf(MSG_ERROR,
+				   "Failed to set frequency in p2p scan params, error = %d", ret);
+			return -1;
 		}
 	}
 
@@ -323,6 +350,7 @@
 		if (wpa_s->scan_res_handler) {
 			wpa_printf(MSG_DEBUG, "Replace current running scan result handler");
 		}
+		wpa_s->p2p_join_scan_count++;
 		wpa_s->scan_res_handler = scanResJoinWrapper;
 		wpa_s->own_scan_requested = 1;
 		wpa_s->clear_driver_scan_cache = 0;
@@ -1758,7 +1786,6 @@
 		if (-EBUSY == ret) {
 			// re-schedule this join scan and don't consume retry count.
 			if (pending_scan_res_join_callback) {
-				wpa_s->p2p_join_scan_count--;
 				pending_scan_res_join_callback();
 			}
 		} else if (0 != ret) {
@@ -1786,13 +1813,12 @@
 			pending_scan_res_join_callback = NULL;
 			return;
 		}
-
-		wpa_s->p2p_join_scan_count++;
-		wpa_printf(MSG_DEBUG, "P2P: Join scan attempt %d.", wpa_s->p2p_join_scan_count);
+		wpa_printf(MSG_DEBUG, "P2P: Join scan count %d.", wpa_s->p2p_join_scan_count);
 		eloop_cancel_timeout(joinScanWrapper, wpa_s, NULL);
-		if (wpa_s->p2p_join_scan_count <= P2P_MAX_JOIN_SCAN_ATTEMPTS) {
+		if (wpa_s->p2p_join_scan_count < P2P_MAX_JOIN_SCAN_ATTEMPTS) {
 			wpa_printf(MSG_DEBUG, "P2P: Try join again later.");
-			eloop_register_timeout(1, 0, joinScanWrapper, wpa_s, this);
+			eloop_register_timeout(0, P2P_JOIN_SCAN_INTERVAL_USECS,
+			    joinScanWrapper, wpa_s, this);
 			return;
 		}
 
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 224fb10..ff3a964 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1667,6 +1667,16 @@
 	sae_pwe = wpa_s->conf->sae_pwe;
 	if (ssid->sae_password_id && sae_pwe != 3)
 		sae_pwe = 1;
+	if (bss && is_6ghz_freq(bss->freq)) {
+		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: force hash-to-element mode for 6GHz BSS.");
+		sae_pwe = 1;
+	}
+#ifdef CONFIG_TESTING_OPTIONS
+	if (wpa_s->force_hunting_and_pecking_pwe) {
+		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: force hunting and pecking mode.");
+		sae_pwe = 0;
+	}
+#endif
 	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SAE_PWE, sae_pwe);
 #ifdef CONFIG_SAE_PK
 	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SAE_PK,
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 56adf89..99dd5b0 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1239,6 +1239,7 @@
 	unsigned int oci_freq_override_ft_assoc;
 	unsigned int oci_freq_override_fils_assoc;
 	unsigned int oci_freq_override_wnm_sleep;
+	int force_hunting_and_pecking_pwe;
 #endif /* CONFIG_TESTING_OPTIONS */
 
 	struct wmm_ac_assoc_data *wmm_ac_assoc_info;
@@ -1748,5 +1749,6 @@
 			     const u8 *data, size_t data_len, u8 acked);
 int wpas_pasn_auth_rx(struct wpa_supplicant *wpa_s,
 		      const struct ieee80211_mgmt *mgmt, size_t len);
+int disabled_freq(struct wpa_supplicant *wpa_s, int freq);
 
 #endif /* WPA_SUPPLICANT_I_H */