Merge "wifi: implement onStateChangedWithAkm"
diff --git a/hostapd/Android.bp b/hostapd/Android.bp
index 2a25208..3194d36 100644
--- a/hostapd/Android.bp
+++ b/hostapd/Android.bp
@@ -318,3 +318,9 @@
     ],
 
 }
+
+// This manifest can used by a vendor apex module for hostapd as well.
+filegroup {
+    name: "android.hardware.wifi.hostapd.xml",
+    srcs: ["android.hardware.wifi.hostapd.xml"],
+}
diff --git a/wpa_supplicant/aidl/aidl_manager.cpp b/wpa_supplicant/aidl/aidl_manager.cpp
index 684eab0..33ad650 100644
--- a/wpa_supplicant/aidl/aidl_manager.cpp
+++ b/wpa_supplicant/aidl/aidl_manager.cpp
@@ -1362,10 +1362,8 @@
 	params.passphrase = misc_utils::charBufToString(ssid->passphrase);
 	params.isPersistent = aidl_is_persistent;
 	params.goDeviceAddress = macAddrToVec(wpa_group_s->go_dev_addr);
-	if (!aidl_is_go) {
-		// Send the GO interface MAC address in GC for link-local IPv6 calculation.
-		params.goInterfaceAddress = macAddrToVec(wpa_group_s->current_bss->bssid);
-	}
+	params.goInterfaceAddress = aidl_is_go ? macAddrToVec(wpa_group_s->own_addr) :
+			macAddrToVec(wpa_group_s->current_bss->bssid);
 
 	callWithEachP2pIfaceCallback(
 		misc_utils::charBufToString(wpa_s->ifname),
diff --git a/wpa_supplicant/aidl/sta_iface.cpp b/wpa_supplicant/aidl/sta_iface.cpp
index ec9efff..d88f6f0 100644
--- a/wpa_supplicant/aidl/sta_iface.cpp
+++ b/wpa_supplicant/aidl/sta_iface.cpp
@@ -1823,6 +1823,12 @@
 
 	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::TRUST_ON_FIRST_USE);
 
+	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::SET_TLS_MINIMUM_VERSION);
+
+#ifdef EAP_TLSV1_3
+	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::TLS_V1_3);
+#endif
+
 	wpa_printf(MSG_DEBUG, "Driver capability mask: 0x%x", mask);
 
 	return {static_cast<WpaDriverCapabilitiesMask>(mask),
diff --git a/wpa_supplicant/aidl/sta_network.cpp b/wpa_supplicant/aidl/sta_network.cpp
index 61c71a1..f9f980c 100644
--- a/wpa_supplicant/aidl/sta_network.cpp
+++ b/wpa_supplicant/aidl/sta_network.cpp
@@ -871,6 +871,14 @@
 		&StaNetwork::setRoamingConsortiumSelectionInternal, in_selectedRcoi);
 }
 
+::ndk::ScopedAStatus StaNetwork::setMinimumTlsVersionEapPhase1Param(
+	TlsVersion in_tlsVersion)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setMinimumTlsVersionEapPhase1ParamInternal, in_tlsVersion);
+}
+
 std::pair<uint32_t, ndk::ScopedAStatus> StaNetwork::getIdInternal()
 {
 	return {network_id_, ndk::ScopedAStatus::ok()};
@@ -2005,10 +2013,13 @@
 {
 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
 	int val = enable == true ? 1 : 0;
-	std::string suiteb_phase1("tls_suiteb=" + std::to_string(val));
+	std::string phase1_params("tls_suiteb=" + std::to_string(val));
+	if (wpa_ssid->eap.phase1 != NULL) {
+		phase1_params.append(wpa_ssid->eap.phase1);
+	}
 
 	if (setStringKeyFieldAndResetState(
-		suiteb_phase1.c_str(), &(wpa_ssid->eap.phase1), "phase1")) {
+		phase1_params.c_str(), &(wpa_ssid->eap.phase1), "phase1")) {
 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
 	}
 	return ndk::ScopedAStatus::ok();
@@ -2597,6 +2608,41 @@
 #endif
 }
 
+ndk::ScopedAStatus StaNetwork::setMinimumTlsVersionEapPhase1ParamInternal(TlsVersion tlsVersion)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	std::string phase1_params;
+	if (wpa_ssid->eap.phase1 != NULL) {
+		phase1_params.append(wpa_ssid->eap.phase1);
+	}
+	if (tlsVersion < TlsVersion::TLS_V1_0) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	// Fallback to disable lower version TLS cascadingly.
+	switch (tlsVersion) {
+		case TlsVersion::TLS_V1_3:
+			phase1_params.append("tls_disable_tlsv1_2=1");
+			FALLTHROUGH_INTENDED;
+		case TlsVersion::TLS_V1_2:
+			phase1_params.append("tls_disable_tlsv1_1=1");
+			FALLTHROUGH_INTENDED;
+		case TlsVersion::TLS_V1_1:
+			phase1_params.append("tls_disable_tlsv1_0=1");
+			FALLTHROUGH_INTENDED;
+		case TlsVersion::TLS_V1_0:
+			FALLTHROUGH_INTENDED;
+		default:
+			// no restriction
+			break;
+	}
+
+	if (setStringKeyFieldAndResetState(
+		phase1_params.c_str(), &(wpa_ssid->eap.phase1), "phase1")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
 }  // namespace supplicant
 }  // namespace wifi
 }  // namespace hardware
diff --git a/wpa_supplicant/aidl/sta_network.h b/wpa_supplicant/aidl/sta_network.h
index 524f44a..6661130 100644
--- a/wpa_supplicant/aidl/sta_network.h
+++ b/wpa_supplicant/aidl/sta_network.h
@@ -22,6 +22,7 @@
 #include <aidl/android/hardware/wifi/supplicant/NetworkResponseEapSimUmtsAuthParams.h>
 #include <aidl/android/hardware/wifi/supplicant/SaeH2eMode.h>
 #include <aidl/android/hardware/wifi/supplicant/DppConnectionKeys.h>
+#include <aidl/android/hardware/wifi/supplicant/TlsVersion.h>
 
 extern "C"
 {
@@ -173,6 +174,8 @@
 	::ndk::ScopedAStatus enableSaePkOnlyMode(bool in_enable) override;
 	::ndk::ScopedAStatus setRoamingConsortiumSelection(
 		const std::vector<uint8_t>& in_selectedRcoi) override;
+	::ndk::ScopedAStatus setMinimumTlsVersionEapPhase1Param(
+		TlsVersion in_tlsVersion) override;
 
 private:
 	// Corresponding worker functions for the AIDL methods.
@@ -302,6 +305,7 @@
 	ndk::ScopedAStatus enableSaePkOnlyModeInternal(bool enable);
 	ndk::ScopedAStatus setRoamingConsortiumSelectionInternal(
 		const std::vector<uint8_t>& selectedRcoi);
+	ndk::ScopedAStatus setMinimumTlsVersionEapPhase1ParamInternal(TlsVersion tlsVersion);
 
 	struct wpa_ssid* retrieveNetworkPtr();
 	struct wpa_supplicant* retrieveIfacePtr();
diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config
index 52e4c04..bfdd53e 100644
--- a/wpa_supplicant/android.config
+++ b/wpa_supplicant/android.config
@@ -80,6 +80,7 @@
 
 # EAP-TLS
 CONFIG_EAP_TLS=y
+CONFIG_EAP_TLSV1_3=y
 
 # EAL-PEAP
 CONFIG_EAP_PEAP=y