[automerger skipped] Merge Android 24Q2 Release (ab/11526283) to aosp-main-future am: 239b876d4e -s ours

am skip reason: Merged-In I1ab30ffeefcfd9e988dbf01d6ad7080798cc588e with SHA-1 8211a66b35 is already in history

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

Change-Id: I12ecd46f349c2a070d1b60171d11ee09141c71c1
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Android.bp b/Android.bp
index 35cdb4f..068630b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -34,3 +34,33 @@
         "src/drivers",
     ],
 }
+
+// Generated by building hs20-osu-client and printing LOCAL_SRC_FILES
+filegroup {
+    name: "hs20-osu-client_srcs",
+    srcs: [
+        "hs20/client/spp_client.c",
+        "hs20/client/oma_dm_client.c",
+        "hs20/client/osu_client.c",
+        "hs20/client/est.c",
+        "src/common/wpa_ctrl.c",
+        "src/common/wpa_helpers.c",
+        "src/crypto/crypto_internal.c",
+        "src/crypto/md5-internal.c",
+        "src/crypto/sha1-internal.c",
+        "src/crypto/sha256-internal.c",
+        "src/crypto/tls_openssl_ocsp.c",
+        "src/utils/base64.c",
+        "src/utils/browser-android.c",
+        "src/utils/common.c",
+        "src/utils/eloop.c",
+        "src/utils/http_curl.c",
+        "src/utils/os_unix.c",
+        "src/utils/wpa_debug.c",
+        "src/utils/wpabuf.c",
+        "src/utils/xml_libxml2.c",
+        "src/utils/xml-utils.c",
+        "src/wps/httpread.c",
+        "src/wps/http_server.c",
+    ],
+}
diff --git a/hostapd/Android.bp b/hostapd/Android.bp
index 119f66e..8a7dacf 100644
--- a/hostapd/Android.bp
+++ b/hostapd/Android.bp
@@ -39,7 +39,6 @@
     soc_specific: true,
 }
 
-
 cc_defaults {
     name: "hostapd_defaults",
     defaults: ["hostapd_cflags_defaults"],
@@ -199,7 +198,6 @@
     ],
 }
 
-
 // Generated by building hostapd and printing LOCAL_SRC_FILES.
 filegroup {
     name: "hostapd_srcs",
@@ -354,3 +352,18 @@
     name: "android.hardware.wifi.hostapd.xml",
     srcs: ["android.hardware.wifi.hostapd.xml"],
 }
+
+// Generated by building hostapd_cli and printing LOCAL_SRC_FILES
+filegroup {
+    name: "hostapd_cli_srcs",
+    srcs: [
+        "hostapd_cli.c",
+        "src/common/cli.c",
+        "src/common/wpa_ctrl.c",
+        "src/utils/common.c",
+        "src/utils/edit.c",
+        "src/utils/eloop.c",
+        "src/utils/os_unix.c",
+        "src/utils/wpa_debug.c",
+    ],
+}
diff --git a/hostapd/aidl/hostapd.cpp b/hostapd/aidl/hostapd.cpp
index ed77a82..afb4147 100644
--- a/hostapd/aidl/hostapd.cpp
+++ b/hostapd/aidl/hostapd.cpp
@@ -61,6 +61,24 @@
 int band6Ghz = (int)BandMask::BAND_6_GHZ;
 int band60Ghz = (int)BandMask::BAND_60_GHZ;
 
+int32_t aidl_client_version = 0;
+int32_t aidl_service_version = 0;
+
+/**
+ * Check that the AIDL service is running at least the expected version.
+ * Use to avoid the case where the AIDL interface version
+ * is greater than the version implemented by the service.
+ */
+inline int32_t isAidlServiceVersionAtLeast(int32_t expected_version)
+{
+	return expected_version <= aidl_service_version;
+}
+
+inline int32_t isAidlClientVersionAtLeast(int32_t expected_version)
+{
+	return expected_version <= aidl_client_version;
+}
+
 #define MAX_PORTS 1024
 bool GetInterfacesInBridge(std::string br_name,
                            std::vector<std::string>* interfaces) {
@@ -294,6 +312,33 @@
 	return true;
 }
 
+std::string getInterfaceMacAddress(const std::string& if_name)
+{
+	u8 addr[ETH_ALEN] = {};
+	struct ifreq ifr;
+	std::string mac_addr;
+
+	android::base::unique_fd sock(socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+	if (sock.get() < 0) {
+		wpa_printf(MSG_ERROR, "Failed to create sock (%s) in %s",
+			strerror(errno), __FUNCTION__);
+		return "";
+	}
+
+	memset(&ifr, 0, sizeof(ifr));
+	strlcpy(ifr.ifr_name, if_name.c_str(), IFNAMSIZ);
+	if (ioctl(sock.get(), SIOCGIFHWADDR, &ifr) < 0) {
+		wpa_printf(MSG_ERROR, "Could not get interface %s hwaddr: %s",
+			   if_name.c_str(), strerror(errno));
+		return "";
+	}
+
+	memcpy(addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
+	mac_addr = StringPrintf("" MACSTR, MAC2STR(addr));
+
+	return mac_addr;
+}
+
 std::string CreateHostapdConfig(
 	const IfaceParams& iface_params,
 	const ChannelParams& channelParams,
@@ -541,64 +586,115 @@
 	std::string eht_params_as_string;
 #ifdef CONFIG_IEEE80211BE
 	if (iface_params.hwModeParams.enable80211BE && !is_60Ghz_used) {
-		eht_params_as_string = "ieee80211be=1";
+		eht_params_as_string = "ieee80211be=1\n";
+		if (isAidlServiceVersionAtLeast(2) && isAidlClientVersionAtLeast(2)) {
+			std::string interface_mac_addr = getInterfaceMacAddress(iface_params.name);
+			if (interface_mac_addr.empty()) {
+				wpa_printf(MSG_ERROR,
+				    "Unable to set interface mac address as bssid for 11BE SAP");
+				return "";
+			}
+			eht_params_as_string += StringPrintf(
+				"bssid=%s\n"
+				"mld_ap=1",
+				interface_mac_addr.c_str());
+		}
 		/* TODO set eht_su_beamformer, eht_su_beamformee, eht_mu_beamformer */
 	} else {
 		eht_params_as_string = "ieee80211be=0";
 	}
 #endif /* CONFIG_IEEE80211BE */
 
-	std::string ht_cap_vht_oper_he_oper_chwidth_as_string;
+	std::string ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string;
 	switch (iface_params.hwModeParams.maximumChannelBandwidth) {
 	case ChannelBandwidth::BANDWIDTH_20:
-		ht_cap_vht_oper_he_oper_chwidth_as_string = StringPrintf(
+		ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string = StringPrintf(
+#ifdef CONFIG_IEEE80211BE
+			"eht_oper_chwidth=0\n"
+#endif /* CONFIG_IEEE80211BE */
 #ifdef CONFIG_IEEE80211AX
 			"he_oper_chwidth=0\n"
 #endif
-			"vht_oper_chwidth=0");
+			"vht_oper_chwidth=0\n"
+			"%s", (band & band6Ghz) ? "op_class=131" : "");
 		break;
 	case ChannelBandwidth::BANDWIDTH_40:
-		ht_cap_vht_oper_he_oper_chwidth_as_string = StringPrintf(
+		ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string = StringPrintf(
 			"ht_capab=[HT40+]\n"
+#ifdef CONFIG_IEEE80211BE
+			"eht_oper_chwidth=0\n"
+#endif /* CONFIG_IEEE80211BE */
 #ifdef CONFIG_IEEE80211AX
 			"he_oper_chwidth=0\n"
 #endif
-			"vht_oper_chwidth=0");
+			"vht_oper_chwidth=0\n"
+			"%s", (band & band6Ghz) ? "op_class=132" : "");
 		break;
 	case ChannelBandwidth::BANDWIDTH_80:
-		ht_cap_vht_oper_he_oper_chwidth_as_string = StringPrintf(
+		ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string = StringPrintf(
 			"ht_capab=[HT40+]\n"
+#ifdef CONFIG_IEEE80211BE
+			"eht_oper_chwidth=%d\n"
+#endif /* CONFIG_IEEE80211BE */
 #ifdef CONFIG_IEEE80211AX
 			"he_oper_chwidth=%d\n"
 #endif
-			"vht_oper_chwidth=%d",
+			"vht_oper_chwidth=%d\n"
+			"%s",
+#ifdef CONFIG_IEEE80211BE
+			(iface_params.hwModeParams.enable80211BE && !is_60Ghz_used) ? 1 : 0,
+#endif
 #ifdef CONFIG_IEEE80211AX
 			(iface_params.hwModeParams.enable80211AX && !is_60Ghz_used) ? 1 : 0,
 #endif
-			iface_params.hwModeParams.enable80211AC ? 1 : 0);
+			iface_params.hwModeParams.enable80211AC ? 1 : 0,
+			(band & band6Ghz) ? "op_class=133" : "");
 		break;
 	case ChannelBandwidth::BANDWIDTH_160:
-		ht_cap_vht_oper_he_oper_chwidth_as_string = StringPrintf(
+		ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string = StringPrintf(
 			"ht_capab=[HT40+]\n"
+#ifdef CONFIG_IEEE80211BE
+			"eht_oper_chwidth=%d\n"
+#endif /* CONFIG_IEEE80211BE */
 #ifdef CONFIG_IEEE80211AX
 			"he_oper_chwidth=%d\n"
 #endif
-			"vht_oper_chwidth=%d",
+			"vht_oper_chwidth=%d\n"
+			"%s",
+#ifdef CONFIG_IEEE80211BE
+			(iface_params.hwModeParams.enable80211BE && !is_60Ghz_used) ? 2 : 0,
+#endif
 #ifdef CONFIG_IEEE80211AX
 			(iface_params.hwModeParams.enable80211AX && !is_60Ghz_used) ? 2 : 0,
 #endif
-			iface_params.hwModeParams.enable80211AC ? 2 : 0);
+			iface_params.hwModeParams.enable80211AC ? 2 : 0,
+			(band & band6Ghz) ? "op_class=134" : "");
 		break;
 	default:
 		if (!is_2Ghz_band_only && !is_60Ghz_used) {
 			if (iface_params.hwModeParams.enable80211AC) {
-				ht_cap_vht_oper_he_oper_chwidth_as_string =
+				ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string =
 					"ht_capab=[HT40+]\n"
 					"vht_oper_chwidth=1\n";
 			}
+			if (band & band6Ghz) {
+#ifdef CONFIG_IEEE80211BE
+				if (iface_params.hwModeParams.enable80211BE)
+					ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string += "op_class=137\n";
+				else
+					ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string += "op_class=134\n";
+#else /* CONFIG_IEEE80211BE */
+				ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string += "op_class=134\n";
+#endif /* CONFIG_IEEE80211BE */
+			}
 #ifdef CONFIG_IEEE80211AX
 			if (iface_params.hwModeParams.enable80211AX) {
-				ht_cap_vht_oper_he_oper_chwidth_as_string += "he_oper_chwidth=1";
+				ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string += "he_oper_chwidth=1\n";
+			}
+#endif
+#ifdef CONFIG_IEEE80211BE
+			if (iface_params.hwModeParams.enable80211BE) {
+				ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string += "eht_oper_chwidth=1";
 			}
 #endif
 		}
@@ -672,7 +768,7 @@
 		iface_params.hwModeParams.enable80211AC ? 1 : 0,
 		he_params_as_string.c_str(),
 		eht_params_as_string.c_str(),
-		hw_mode_as_string.c_str(), ht_cap_vht_oper_he_oper_chwidth_as_string.c_str(),
+		hw_mode_as_string.c_str(), ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string.c_str(),
 		nw_params.isHidden ? 1 : 0,
 #ifdef CONFIG_INTERWORKING
 		access_network_params_as_string.c_str(),
@@ -1012,9 +1108,13 @@
 				// Invoke the failure callback on all registered
 				// clients.
 				for (const auto& callback : callbacks_) {
-					callback->onFailure(strlen(iface_hapd->conf->bridge) > 0 ?
+					auto status = callback->onFailure(
+						strlen(iface_hapd->conf->bridge) > 0 ?
 						iface_hapd->conf->bridge : iface_hapd->conf->iface,
 							    iface_hapd->conf->iface);
+					if (!status.isOk()) {
+						wpa_printf(MSG_ERROR, "Failed to invoke onFailure");
+					}
 				}
 			}
 		};
@@ -1033,7 +1133,10 @@
 		info.clientAddress.assign(mac_addr, mac_addr + ETH_ALEN);
 		info.isConnected = authorized;
 		for (const auto &callback : callbacks_) {
-			callback->onConnectedClientsChanged(info);
+			auto status = callback->onConnectedClientsChanged(info);
+			if (!status.isOk()) {
+				wpa_printf(MSG_ERROR, "Failed to invoke onConnectedClientsChanged");
+			}
 		}
 		};
 
@@ -1057,16 +1160,23 @@
 			info.apIfaceInstanceMacAddress.assign(iface_hapd->own_addr,
 				iface_hapd->own_addr + ETH_ALEN);
 			for (const auto &callback : callbacks_) {
-				callback->onApInstanceInfoChanged(info);
+				auto status = callback->onApInstanceInfoChanged(info);
+				if (!status.isOk()) {
+					wpa_printf(MSG_ERROR,
+						   "Failed to invoke onApInstanceInfoChanged");
+				}
 			}
 		} else if (os_strncmp(txt, AP_EVENT_DISABLED, strlen(AP_EVENT_DISABLED)) == 0
                            || os_strncmp(txt, INTERFACE_DISABLED, strlen(INTERFACE_DISABLED)) == 0)
 		{
 			// Invoke the failure callback on all registered clients.
 			for (const auto& callback : callbacks_) {
-				callback->onFailure(strlen(iface_hapd->conf->bridge) > 0 ?
+				auto status = callback->onFailure(strlen(iface_hapd->conf->bridge) > 0 ?
 					iface_hapd->conf->bridge : iface_hapd->conf->iface,
 						    iface_hapd->conf->iface);
+				if (!status.isOk()) {
+					wpa_printf(MSG_ERROR, "Failed to invoke onFailure");
+				}
 			}
 		}
 	};
@@ -1130,6 +1240,14 @@
 		return createStatus(HostapdStatusCode::FAILURE_UNKNOWN);
 	}
 	callbacks_.push_back(callback);
+	if (aidl_service_version == 0) {
+	    aidl_service_version = Hostapd::version;
+	    wpa_printf(MSG_INFO, "AIDL service version: %d", aidl_service_version);
+	}
+	if (aidl_client_version == 0) {
+	    callback->getInterfaceVersion(&aidl_client_version);
+	    wpa_printf(MSG_INFO, "AIDL client version: %d", aidl_client_version);
+	}
 	return ndk::ScopedAStatus::ok();
 }
 
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 244b38e..a895f9c 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -2955,11 +2955,13 @@
 #define WFA_CAPA_QM_UNSOLIC_DSCP BIT(1)
 #define WFA_CAPA_QM_NON_EHT_SCS_TRAFFIC_DESC BIT(2)
 
-#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
+#if (defined(CONFIG_DRIVER_NL80211_BRCM) && !defined(WIFI_BRCM_OPEN_SOURCE_MULTI_AKM)) ||   \
+	defined(CONFIG_DRIVER_NL80211_SYNA)
 #define WPA_KEY_MGMT_CROSS_AKM_ROAM (WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_PSK)
 #define IS_CROSS_AKM_ROAM_KEY_MGMT(key_mgmt) \
 	((key_mgmt & WPA_KEY_MGMT_CROSS_AKM_ROAM) == WPA_KEY_MGMT_CROSS_AKM_ROAM)
-#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
+#endif /* (CONFIG_DRIVER_NL80211_BRCM && !WIFI_BRCM_OPEN_SOURCE_MULTI_AKM) ||
+	* CONFIG_DRIVER_NL80211_SYNA */
 
 struct ieee80211_neighbor_ap_info {
 	u8 tbtt_info_hdr;
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 3b96d55..ac2f457 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -3348,7 +3348,8 @@
 }
 #endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
 
-#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
+#if (defined(CONFIG_DRIVER_NL80211_BRCM) && !defined(WIFI_BRCM_OPEN_SOURCE_MULTI_AKM)) ||   \
+	defined(CONFIG_DRIVER_NL80211_SYNA)
 static int wpa_cross_akm_key_mgmt_to_suites(unsigned int key_mgmt_suites, u32 suites[],
                         int max_suites)
 {
@@ -3364,7 +3365,8 @@
 
     return num_suites;
 }
-#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
+#endif /* (CONFIG_DRIVER_NL80211_BRCM && !WIFI_BRCM_OPEN_SOURCE_MULTI_AKM) ||
+	* CONFIG_DRIVER_NL80211_SYNA */
 
 #ifdef CONFIG_DRIVER_NL80211_QCA
 static int issue_key_mgmt_set_key(struct wpa_driver_nl80211_data *drv,
@@ -7051,7 +7053,8 @@
 		os_free(mgmt);
 	}
 
-#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
+#if (defined(CONFIG_DRIVER_NL80211_BRCM) && !defined(WIFI_BRCM_OPEN_SOURCE_MULTI_AKM)) ||   \
+	defined(CONFIG_DRIVER_NL80211_SYNA)
 	if (IS_CROSS_AKM_ROAM_KEY_MGMT(params->key_mgmt_suite)) {
 		int num_suites;
 		u32 suites[NL80211_MAX_NR_AKM_SUITES];
@@ -7066,7 +7069,8 @@
 			return -1;
 		}
 	}
-#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
+#endif /* (CONFIG_DRIVER_NL80211_BRCM && !WIFI_BRCM_OPEN_SOURCE_MULTI_AKM) ||
+	* CONFIG_DRIVER_NL80211_SYNA */
 	if (params->req_handshake_offload &&
 	    (drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X)) {
 		    wpa_printf(MSG_DEBUG, "  * WANT_1X_4WAY_HS");
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
index fdfe8f6..11a32af 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -1262,11 +1262,11 @@
 		drv->capa.flags |= WPA_DRIVER_FLAGS_UPDATE_FT_IES;
 
 	if (!drv->capa.max_num_akms)
-#ifdef CONFIG_DRIVER_NL80211_BRCM
+#if defined(CONFIG_DRIVER_NL80211_BRCM) && !defined(WIFI_BRCM_OPEN_SOURCE_MULTI_AKM)
 		drv->capa.max_num_akms = 1;
 #else
 		drv->capa.max_num_akms = NL80211_MAX_NR_AKM_SUITES;
-#endif /* CONFIG_DRIVER_NL80211_BRCM */
+#endif /* CONFIG_DRIVER_NL80211_BRCM && !WIFI_BRCM_OPEN_SOURCE_MULTI_AKM */
 
 	return 0;
 }
diff --git a/wpa_supplicant/Android.bp b/wpa_supplicant/Android.bp
index ca56d14..e6ba165 100644
--- a/wpa_supplicant/Android.bp
+++ b/wpa_supplicant/Android.bp
@@ -332,10 +332,12 @@
         "src/common/sae_pk.c",
         "src/common/wpa_common.c",
         "src/crypto/aes-ctr.c",
+        "src/crypto/aes-encblock.c",
         "src/crypto/aes-siv.c",
         "src/crypto/crypto_openssl.c",
         "src/crypto/dh_groups.c",
         "src/crypto/fips_prf_openssl.c",
+        "src/crypto/milenage.c",
         "src/crypto/ms_funcs.c",
         "src/crypto/sha1-prf.c",
         "src/crypto/sha1-tlsprf.c",
@@ -438,6 +440,7 @@
         "src/wps/wps_upnp_event.c",
         "src/wps/wps_upnp_ssdp.c",
         "src/wps/wps_upnp_web.c",
+        "twt.c",
         "wifi_display.c",
         "wmm_ac.c",
         "wnm_sta.c",
@@ -446,3 +449,36 @@
         "wps_supplicant.c",
     ],
 }
+
+// Generated by building wpa_cli and printing LOCAL_SRC_FILES
+filegroup {
+    name: "wpa_cli_srcs",
+    srcs: [
+        "src/common/cli.c",
+        "src/common/wpa_ctrl.c",
+        "src/utils/common.c",
+        "src/utils/edit.c",
+        "src/utils/eloop.c",
+        "src/utils/os_unix.c",
+        "src/utils/wpa_debug.c",
+        "wpa_cli.c",
+    ],
+}
+
+// Generated by building libwpa_client and printing LOCAL_SRC_FILES
+filegroup {
+    name: "libwpa_client_srcs",
+    srcs: [
+        "src/common/wpa_ctrl.c",
+        "src/utils/os_unix.c",
+    ],
+}
+
+cc_library_headers {
+    name: "libwpa_client_headers",
+    export_include_dirs: [
+        ".",
+        "wpa_client_include/libwpa_client",
+    ],
+    soc_specific: true,
+}
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 509dbbc..98152be 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -75,6 +75,12 @@
 L_CFLAGS += -DENABLE_PRIV_CMD_UPDATE_MBO_CELL_STATUS
 endif
 
+# TODO(b/246871098): we plan to have all Broadcom projects to follow open
+# source way after the multiple AKMs is fully supported by driver and verified.
+ifeq ($(WIFI_BRCM_OPEN_SOURCE_MULTI_AKM), enabled)
+L_CFLAGS += -DWIFI_BRCM_OPEN_SOURCE_MULTI_AKM
+endif
+
 # Use Android specific directory for control interface sockets
 L_CFLAGS += -DCONFIG_CTRL_IFACE_CLIENT_DIR=\"/data/vendor/wifi/wpa/sockets\"
 L_CFLAGS += -DCONFIG_CTRL_IFACE_DIR=\"/data/vendor/wifi/wpa/sockets\"
diff --git a/wpa_supplicant/aidl/Android.bp b/wpa_supplicant/aidl/Android.bp
index 481ad0b..2175462 100644
--- a/wpa_supplicant/aidl/Android.bp
+++ b/wpa_supplicant/aidl/Android.bp
@@ -30,7 +30,10 @@
 cc_library_static {
     name: "libwpa_aidl_bp",
     srcs: ["*.cpp"],
-    defaults: ["wpa_supplicant_cflags_defaults"],
+    defaults: [
+        "libwpa_aidl_cflags_defaults",
+        "wpa_supplicant_cflags_defaults",
+    ],
     soc_specific: true,
     shared_libs: [
         "android.hardware.wifi.supplicant-V3-ndk",
@@ -60,3 +63,22 @@
     name: "android.hardware.wifi.supplicant.xml",
     srcs: ["android.hardware.wifi.supplicant.xml"],
 }
+
+soong_config_module_type {
+    name: "libwpa_aidl_cflags_cc_defaults",
+    module_type: "cc_defaults",
+    config_namespace: "libwpa_aidl",
+    value_variables: [
+        "nl80211_driver",
+    ],
+    properties: ["cflags"],
+}
+
+libwpa_aidl_cflags_cc_defaults {
+    name: "libwpa_aidl_cflags_defaults",
+    soong_config_variables: {
+        nl80211_driver: {
+            cflags: ["-D%s"],
+        },
+    },
+}
diff --git a/wpa_supplicant/aidl/aidl_manager.cpp b/wpa_supplicant/aidl/aidl_manager.cpp
index 0daa8ef..707299d 100644
--- a/wpa_supplicant/aidl/aidl_manager.cpp
+++ b/wpa_supplicant/aidl/aidl_manager.cpp
@@ -16,6 +16,7 @@
 #include <android/binder_process.h>
 #include <android/binder_manager.h>
 #include <aidl/android/hardware/wifi/supplicant/IpVersion.h>
+#include <cutils/properties.h>
 
 extern "C" {
 #include "scan.h"
@@ -38,6 +39,7 @@
 constexpr size_t kUmtsAutnLenBytes = EAP_AKA_AUTN_LEN;
 const std::vector<uint8_t> kZeroBssid = {0, 0, 0, 0, 0, 0};
 int32_t aidl_service_version = 0;
+int32_t aidl_client_version = 0;
 
 using aidl::android::hardware::wifi::supplicant::GsmRand;
 using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
@@ -85,6 +87,10 @@
 		return 1;
 	}
 	callback_list.push_back(callback);
+	if (aidl_client_version == 0) {
+	    callback->getInterfaceVersion(&aidl_client_version);
+	    wpa_printf(MSG_INFO, "AIDL client version: %d", aidl_client_version);
+	}
 	return 0;
 }
 
@@ -414,6 +420,11 @@
 	return expected_version <= aidl_service_version;
 }
 
+int32_t AidlManager::isAidlClientVersionAtLeast(int32_t expected_version)
+{
+	return expected_version <= aidl_client_version;
+}
+
 int AidlManager::registerAidlService(struct wpa_global *global)
 {
 	// Create the main aidl service object and register it.
@@ -1345,7 +1356,7 @@
 			std::back_inserter(aidl_vendor_elems));
 	}
 
-	if (isAidlServiceVersionAtLeast(3)) {
+	if (isAidlServiceVersionAtLeast(3) && isAidlClientVersionAtLeast(3)) {
 		P2pDeviceFoundEventParams params;
 		params.srcAddress = macAddrToArray(addr);
 		params.p2pDeviceAddress = macAddrToArray(info->p2p_device_addr);
@@ -1363,6 +1374,7 @@
 			&ISupplicantP2pIfaceCallback::onDeviceFoundWithParams,
 			std::placeholders::_1, params));
 	} else {
+	    // Use legacy callback if service or client interface version < 3
 		const std::function<
 			ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
 			func = std::bind(
@@ -1607,7 +1619,7 @@
 	}
 	bool aidl_is_request = (request == 1);
 
-	if (isAidlServiceVersionAtLeast(3)) {
+	if (isAidlServiceVersionAtLeast(3) && isAidlClientVersionAtLeast(3)) {
 		P2pProvisionDiscoveryCompletedEventParams params;
 		params.p2pDeviceAddress =  macAddrToArray(dev_addr);
 		params.isRequest = aidl_is_request;
@@ -1623,7 +1635,7 @@
 			&ISupplicantP2pIfaceCallback::onProvisionDiscoveryCompletedEvent,
 			std::placeholders::_1, params));
 	} else {
-		// Use legacy callback if interface version < 3
+		// Use legacy callback if service or client interface version < 3
 		callWithEachP2pIfaceCallback(
 			misc_utils::charBufToString(wpa_s->ifname),
 			std::bind(
@@ -1663,7 +1675,7 @@
 	if (!wpa_s)
 		return;
 
-	if (isAidlServiceVersionAtLeast(3)) {
+	if (isAidlServiceVersionAtLeast(3) && isAidlClientVersionAtLeast(3)) {
 		P2pPeerClientJoinedEventParams params;
 		params.groupInterfaceName = misc_utils::charBufToString(wpa_group_s->ifname);
 		params.clientInterfaceAddress = macAddrToArray(sta);
@@ -1680,7 +1692,7 @@
 			&ISupplicantP2pIfaceCallback::onPeerClientJoined,
 			std::placeholders::_1, params));
 	} else {
-		// Use legacy callback if interface version < 3
+		// Use legacy callback if service or client interface version < 3
 		callWithEachP2pIfaceCallback(
 			misc_utils::charBufToString(wpa_s->ifname),
 			std::bind(
@@ -1699,7 +1711,7 @@
 	if (!wpa_s)
 		return;
 
-	if (isAidlServiceVersionAtLeast(3)) {
+	if (isAidlServiceVersionAtLeast(3) && isAidlClientVersionAtLeast(3)) {
 		P2pPeerClientDisconnectedEventParams params;
 		params.groupInterfaceName = misc_utils::charBufToString(wpa_group_s->ifname);
 		params.clientInterfaceAddress = macAddrToArray(sta);
@@ -1712,7 +1724,7 @@
 			&ISupplicantP2pIfaceCallback::onPeerClientDisconnected,
 			std::placeholders::_1, params));
 	} else {
-		// Use legacy callback if interface version < 3
+		// Use legacy callback if service or client interface version < 3
 		callWithEachP2pIfaceCallback(
 			misc_utils::charBufToString(wpa_s->ifname),
 			std::bind(
diff --git a/wpa_supplicant/aidl/aidl_manager.h b/wpa_supplicant/aidl/aidl_manager.h
index b11a760..b3dfa82 100644
--- a/wpa_supplicant/aidl/aidl_manager.h
+++ b/wpa_supplicant/aidl/aidl_manager.h
@@ -172,6 +172,7 @@
 
 	// Methods called from aidl objects.
 	int32_t isAidlServiceVersionAtLeast(int32_t expected_version);
+	int32_t isAidlClientVersionAtLeast(int32_t expected_version);
 	void notifyExtRadioWorkStart(struct wpa_supplicant *wpa_s, uint32_t id);
 	void notifyExtRadioWorkTimeout(
 		struct wpa_supplicant *wpa_s, uint32_t id);
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index fc93305..f386119 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -3558,7 +3558,8 @@
 	if (((wpa_s->key_mgmt == WPA_KEY_MGMT_FT_PSK) ||
 		(wpa_s->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) ||
 		(wpa_s->key_mgmt == WPA_KEY_MGMT_FT_SAE) ||
-		(wpa_s->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X_SHA384)) &&
+		(wpa_s->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X_SHA384) ||
+		(wpa_s->key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY)) &&
 		wpa_ft_is_completed(wpa_s->wpa)) {
 		return 0;
 	}
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 6e34e87..d4401ff 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -2086,7 +2086,8 @@
 		wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_DENY_PTK0_REKEY, 0);
 	}
 
-#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
+#if (defined(CONFIG_DRIVER_NL80211_BRCM) && !defined(WIFI_BRCM_OPEN_SOURCE_MULTI_AKM)) ||   \
+	defined(CONFIG_DRIVER_NL80211_SYNA)
 	if ((wpa_s->key_mgmt & WPA_KEY_MGMT_CROSS_AKM_ROAM) &&
 		IS_CROSS_AKM_ROAM_KEY_MGMT(ssid->key_mgmt) &&
 		(wpa_s->group_cipher == WPA_CIPHER_CCMP) &&
@@ -2100,7 +2101,8 @@
 	if (wpa_key_mgmt_cross_akm(wpa_s->key_mgmt) &&
 	    !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME))
 		wpas_update_allowed_key_mgmt(wpa_s, ssid);
-#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
+#endif /* (CONFIG_DRIVER_NL80211_BRCM && !WIFI_BRCM_OPEN_SOURCE_MULTI_AKM) ||
+	* CONFIG_DRIVER_NL80211_SYNA */
 
 	return 0;
 }
@@ -2555,8 +2557,11 @@
 		}
 		if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
 			wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
-			if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
+			if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION ||
+				ssid->mode == WPAS_MODE_P2P_GO) {
+				wpa_msg(wpa_s, MSG_ERROR, "create ap failed. clean up the states");
 				wpas_p2p_ap_setup_failed(wpa_s);
+			}
 			return;
 		}
 		wpa_s->current_bss = bss;
@@ -4302,15 +4307,23 @@
 #endif /* CONFIG_WEP */
 
 	if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
-#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
+#if (defined(CONFIG_DRIVER_NL80211_BRCM) && !defined(WIFI_BRCM_OPEN_SOURCE_MULTI_AKM)) ||   \
+	defined(CONFIG_DRIVER_NL80211_SYNA)
 	     ((params.key_mgmt_suite & WPA_KEY_MGMT_PSK) ||
 	      (params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK))) {
+#elif (defined(CONFIG_DRIVER_NL80211_BRCM) && defined(WIFI_BRCM_OPEN_SOURCE_MULTI_AKM)) ||   \
+	defined(CONFIG_DRIVER_NL80211_SYNA)
+	    (params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
+	     params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK ||
+	      params.key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
+	      wpa_key_mgmt_wpa_psk_no_sae(params.allowed_key_mgmts))) {
 #else
 	    (params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
 	     params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK ||
 	     (params.allowed_key_mgmts &
 	      (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK)))) {
-#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
+#endif /* (CONFIG_DRIVER_NL80211_BRCM && !WIFI_BRCM_OPEN_SOURCE_MULTI_AKM) ||
+	* CONFIG_DRIVER_NL80211_SYNA */
 		params.passphrase = ssid->passphrase;
 		if (wpa_supplicant_get_psk(wpa_s, bss, ssid, psk) == 0)
 			params.psk = psk;
@@ -4337,14 +4350,16 @@
 		else
 			params.req_key_mgmt_offload = 1;
 
-#if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
+#if (defined(CONFIG_DRIVER_NL80211_BRCM) && !defined(WIFI_BRCM_OPEN_SOURCE_MULTI_AKM)) ||   \
+	defined(CONFIG_DRIVER_NL80211_SYNA)
 		if (((params.key_mgmt_suite & WPA_KEY_MGMT_PSK) ||
 		     params.key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
 		     params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK) &&
 #else
 		if ((wpa_key_mgmt_wpa_psk_no_sae(params.key_mgmt_suite) ||
 		     wpa_key_mgmt_wpa_psk_no_sae(params.allowed_key_mgmts)) &&
-#endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
+#endif /* (CONFIG_DRIVER_NL80211_BRCM && !WIFI_BRCM_OPEN_SOURCE_MULTI_AKM) ||
+	* CONFIG_DRIVER_NL80211_SYNA */
 		    wpa_supplicant_get_psk(wpa_s, bss, ssid, psk) == 0)
 			params.psk = psk;
 	}
@@ -4511,7 +4526,11 @@
 		eapol_sm_invalidate_cached_session(wpa_s->eapol);
 	}
 
-	if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
+	if (!wpas_driver_bss_selection(wpa_s) ||
+#ifdef CONFIG_P2P
+	    wpa_s->p2p_in_invitation ||
+#endif /* CONFIG_P2P */
+	    ssid->bssid_set) {
 		wpa_s->current_bss = bss;
 #ifdef CONFIG_HS20
 		hs20_configure_frame_filters(wpa_s);