Merge "Add skeleton implementation to supplicant for the MSCS configuration APIs." into main
diff --git a/src/rsn_supp/pmksa_cache.c b/src/rsn_supp/pmksa_cache.c
index e7b4d54..eb434fa 100644
--- a/src/rsn_supp/pmksa_cache.c
+++ b/src/rsn_supp/pmksa_cache.c
@@ -224,22 +224,22 @@
 	if (pmk_len > PMK_LEN_MAX)
 		return NULL;
 
-	if (wpa_key_mgmt_suite_b(akmp) && !kck)
-		return NULL;
-
 	entry = os_zalloc(sizeof(*entry));
 	if (entry == NULL)
 		return NULL;
 	os_memcpy(entry->pmk, pmk, pmk_len);
 	entry->pmk_len = pmk_len;
-	if (pmkid)
-		os_memcpy(entry->pmkid, pmkid, PMKID_LEN);
-	else if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
-		rsn_pmkid_suite_b_192(kck, kck_len, aa, spa, entry->pmkid);
-	else if (wpa_key_mgmt_suite_b(akmp))
-		rsn_pmkid_suite_b(kck, kck_len, aa, spa, entry->pmkid);
-	else
-		rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid, akmp);
+	if (pmkid) {
+ 		os_memcpy(entry->pmkid, pmkid, PMKID_LEN);
+	} else if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
+		if (kck)
+			rsn_pmkid_suite_b_192(kck, kck_len, aa, spa, entry->pmkid);
+	} else if (wpa_key_mgmt_suite_b(akmp)) {
+		if (kck)
+			rsn_pmkid_suite_b(kck, kck_len, aa, spa, entry->pmkid);
+	} else {
+ 		rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid, akmp);
+	}
 	os_get_reltime(&now);
 	if (pmksa->sm) {
 		pmk_lifetime = pmksa->sm->dot11RSNAConfigPMKLifetime;
diff --git a/wpa_supplicant/aidl/aidl_manager.cpp b/wpa_supplicant/aidl/aidl_manager.cpp
index a0ce54b..cac9ddb 100644
--- a/wpa_supplicant/aidl/aidl_manager.cpp
+++ b/wpa_supplicant/aidl/aidl_manager.cpp
@@ -37,11 +37,21 @@
 constexpr size_t kUmtsRandLenBytes = EAP_AKA_RAND_LEN;
 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;
 
 using aidl::android::hardware::wifi::supplicant::GsmRand;
 using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
 
 /**
+  * 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;
+}
+/**
  * Check if the provided |wpa_supplicant| structure represents a P2P iface or
  * not.
  */
@@ -407,8 +417,11 @@
 {
 	// Create the main aidl service object and register it.
 	wpa_printf(MSG_INFO, "Starting AIDL supplicant");
-	wpa_printf(MSG_INFO, "Interface version: %d", Supplicant::version);
 	supplicant_object_ = ndk::SharedRefBase::make<Supplicant>(global);
+	if (!supplicant_object_->getInterfaceVersion(&aidl_service_version).isOk()) {
+		aidl_service_version = Supplicant::version;
+	}
+	wpa_printf(MSG_INFO, "AIDL Interface version: %d", aidl_service_version);
 	wpa_global_ = global;
 	std::string instance = std::string() + Supplicant::descriptor + "/default";
 	if (AServiceManager_addService(supplicant_object_->asBinder().get(),
@@ -1331,16 +1344,35 @@
 			std::back_inserter(aidl_vendor_elems));
 	}
 
-	const std::function<
-		ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
-		func = std::bind(
-		&ISupplicantP2pIfaceCallback::onDeviceFoundWithVendorElements,
-		std::placeholders::_1, macAddrToVec(addr), macAddrToVec(info->p2p_device_addr),
-		byteArrToVec(info->pri_dev_type, 8), misc_utils::charBufToString(info->device_name),
-		static_cast<WpsConfigMethods>(info->config_methods),
-		info->dev_capab, static_cast<P2pGroupCapabilityMask>(info->group_capab), aidl_peer_wfd_device_info,
-		aidl_peer_wfd_r2_device_info, aidl_vendor_elems);
-	callWithEachP2pIfaceCallback(wpa_s->ifname, func);
+	if (isAidlServiceVersionAtLeast(3)) {
+		P2pDeviceFoundEventParams params;
+		params.srcAddress = macAddrToArray(addr);
+		params.p2pDeviceAddress = macAddrToArray(info->p2p_device_addr);
+		params.primaryDeviceType = byteArrToVec(info->pri_dev_type, 8);
+		params.deviceName = misc_utils::charBufToString(info->device_name);
+		params.configMethods = info->config_methods;
+		params.deviceCapabilities = info->dev_capab;
+		params.groupCapabilities = info->group_capab;
+		params.wfdDeviceInfo = aidl_peer_wfd_device_info;
+		params.wfdR2DeviceInfo = aidl_peer_wfd_r2_device_info;
+		params.vendorElemBytes = aidl_vendor_elems;
+		callWithEachP2pIfaceCallback(
+			misc_utils::charBufToString(wpa_s->ifname),
+			std::bind(
+			&ISupplicantP2pIfaceCallback::onDeviceFoundWithParams,
+			std::placeholders::_1, params));
+	} else {
+		const std::function<
+			ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
+			func = std::bind(
+			&ISupplicantP2pIfaceCallback::onDeviceFoundWithVendorElements,
+			std::placeholders::_1, macAddrToVec(addr), macAddrToVec(info->p2p_device_addr),
+			byteArrToVec(info->pri_dev_type, 8), misc_utils::charBufToString(info->device_name),
+			static_cast<WpsConfigMethods>(info->config_methods),
+			info->dev_capab, static_cast<P2pGroupCapabilityMask>(info->group_capab), aidl_peer_wfd_device_info,
+			aidl_peer_wfd_r2_device_info, aidl_vendor_elems);
+		callWithEachP2pIfaceCallback(wpa_s->ifname, func);
+	}
 }
 
 void AidlManager::notifyP2pDeviceLost(
@@ -1567,24 +1599,38 @@
 		p2p_iface_object_map_.end())
 		return;
 
-	P2pProvisionDiscoveryCompletedEventParams params;
-	params.p2pDeviceAddress =  macAddrToArray(dev_addr);
-	params.isRequest = (request == 1);
-	params.status = static_cast<P2pProvDiscStatusCode>(status);
-	params.configMethods = static_cast<WpsConfigMethods>(config_methods);
+	std::string aidl_generated_pin;
 	if (generated_pin > 0) {
-		params.generatedPin =
+		aidl_generated_pin =
 			misc_utils::convertWpsPinToString(generated_pin);
 	}
-	if (group_ifname != NULL) {
-		params.groupInterfaceName = misc_utils::charBufToString(group_ifname);
-	}
+	bool aidl_is_request = (request == 1);
 
-	callWithEachP2pIfaceCallback(
-		misc_utils::charBufToString(wpa_s->ifname),
-		std::bind(
-		&ISupplicantP2pIfaceCallback::onProvisionDiscoveryCompletedEvent,
-		std::placeholders::_1, params));
+	if (isAidlServiceVersionAtLeast(3)) {
+		P2pProvisionDiscoveryCompletedEventParams params;
+		params.p2pDeviceAddress =  macAddrToArray(dev_addr);
+		params.isRequest = aidl_is_request;
+		params.status = static_cast<P2pProvDiscStatusCode>(status);
+		params.configMethods = static_cast<WpsConfigMethods>(config_methods);
+		params.generatedPin = aidl_generated_pin;
+		if (group_ifname != NULL) {
+			params.groupInterfaceName = misc_utils::charBufToString(group_ifname);
+		}
+		callWithEachP2pIfaceCallback(
+			misc_utils::charBufToString(wpa_s->ifname),
+			std::bind(
+			&ISupplicantP2pIfaceCallback::onProvisionDiscoveryCompletedEvent,
+			std::placeholders::_1, params));
+	} else {
+		// Use legacy callback if interface version < 3
+		callWithEachP2pIfaceCallback(
+			misc_utils::charBufToString(wpa_s->ifname),
+			std::bind(
+			&ISupplicantP2pIfaceCallback::onProvisionDiscoveryCompleted,
+			std::placeholders::_1, macAddrToVec(dev_addr), aidl_is_request,
+			static_cast<P2pProvDiscStatusCode>(status),
+			static_cast<WpsConfigMethods>(config_methods), aidl_generated_pin));
+	}
 }
 
 void AidlManager::notifyP2pSdResponse(
@@ -1616,23 +1662,31 @@
 	if (!wpa_s)
 		return;
 
-	int aidl_ip = 0;
-	if (NULL != ip) {
-		os_memcpy(&aidl_ip, &ip[0], 4);
+	if (isAidlServiceVersionAtLeast(3)) {
+		P2pPeerClientJoinedEventParams params;
+		params.groupInterfaceName = misc_utils::charBufToString(wpa_group_s->ifname);
+		params.clientInterfaceAddress = macAddrToArray(sta);
+		params.clientDeviceAddress = p2p_dev_addr ?
+				macAddrToArray(p2p_dev_addr) : macAddrToArray(kZeroBssid.data());
+		int aidl_ip = 0;
+		if (NULL != ip) {
+			os_memcpy(&aidl_ip, &ip[0], 4);
+		}
+		params.clientIpAddress = aidl_ip;
+		callWithEachP2pIfaceCallback(
+			misc_utils::charBufToString(wpa_s->ifname),
+			std::bind(
+			&ISupplicantP2pIfaceCallback::onPeerClientJoined,
+			std::placeholders::_1, params));
+	} else {
+		// Use legacy callback if interface version < 3
+		callWithEachP2pIfaceCallback(
+			misc_utils::charBufToString(wpa_s->ifname),
+			std::bind(
+			&ISupplicantP2pIfaceCallback::onStaAuthorized,
+			std::placeholders::_1, macAddrToVec(sta),
+			p2p_dev_addr ? macAddrToVec(p2p_dev_addr) : kZeroBssid));
 	}
-
-	P2pPeerClientJoinedEventParams params;
-	params.groupInterfaceName = misc_utils::charBufToString(wpa_group_s->ifname);
-	params.clientInterfaceAddress = macAddrToArray(sta);
-	params.clientDeviceAddress = p2p_dev_addr ?
-			macAddrToArray(p2p_dev_addr) : macAddrToArray(kZeroBssid.data());
-	params.clientIpAddress = aidl_ip;
-
-	callWithEachP2pIfaceCallback(
-		misc_utils::charBufToString(wpa_s->ifname),
-		std::bind(
-		&ISupplicantP2pIfaceCallback::onPeerClientJoined,
-		std::placeholders::_1, params));
 }
 
 void AidlManager::notifyApStaDeauthorized(
@@ -1644,17 +1698,27 @@
 	if (!wpa_s)
 		return;
 
-	P2pPeerClientDisconnectedEventParams params;
-	params.groupInterfaceName = misc_utils::charBufToString(wpa_group_s->ifname);
-	params.clientInterfaceAddress = macAddrToArray(sta);
-	params.clientDeviceAddress = p2p_dev_addr ?
-			macAddrToArray(p2p_dev_addr) : macAddrToArray(kZeroBssid.data());
+	if (isAidlServiceVersionAtLeast(3)) {
+		P2pPeerClientDisconnectedEventParams params;
+		params.groupInterfaceName = misc_utils::charBufToString(wpa_group_s->ifname);
+		params.clientInterfaceAddress = macAddrToArray(sta);
+		params.clientDeviceAddress = p2p_dev_addr ?
+				macAddrToArray(p2p_dev_addr) : macAddrToArray(kZeroBssid.data());
 
-	callWithEachP2pIfaceCallback(
-		misc_utils::charBufToString(wpa_s->ifname),
-		std::bind(
-		&ISupplicantP2pIfaceCallback::onPeerClientDisconnected,
-		std::placeholders::_1, params));
+		callWithEachP2pIfaceCallback(
+			misc_utils::charBufToString(wpa_s->ifname),
+			std::bind(
+			&ISupplicantP2pIfaceCallback::onPeerClientDisconnected,
+			std::placeholders::_1, params));
+	} else {
+		// Use legacy callback if interface version < 3
+		callWithEachP2pIfaceCallback(
+			misc_utils::charBufToString(wpa_s->ifname),
+			std::bind(
+			&ISupplicantP2pIfaceCallback::onStaDeauthorized,
+			std::placeholders::_1, macAddrToVec(sta),
+			p2p_dev_addr ? macAddrToVec(p2p_dev_addr) : kZeroBssid));
+	}
 }
 
 void AidlManager::notifyExtRadioWorkStart(
diff --git a/wpa_supplicant/aidl/p2p_iface.cpp b/wpa_supplicant/aidl/p2p_iface.cpp
index 33db802..ec52b44 100644
--- a/wpa_supplicant/aidl/p2p_iface.cpp
+++ b/wpa_supplicant/aidl/p2p_iface.cpp
@@ -815,6 +815,21 @@
 		in_ipAddressGo, in_ipAddressMask, in_ipAddressStart, in_ipAddressEnd);
 }
 
+::ndk::ScopedAStatus P2pIface::connectWithParams(
+		const P2pConnectInfo& in_connectInfo, std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::connectWithParamsInternal, _aidl_return, in_connectInfo);
+}
+
+::ndk::ScopedAStatus P2pIface::findWithParams(const P2pDiscoveryInfo& in_discoveryInfo)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::findWithParamsInternal, in_discoveryInfo);
+}
+
 std::pair<std::string, ndk::ScopedAStatus> P2pIface::getNameInternal()
 {
 	return {ifname_, ndk::ScopedAStatus::ok()};
@@ -1852,6 +1867,33 @@
 	return ndk::ScopedAStatus::ok();
 }
 
+std::pair<std::string, ndk::ScopedAStatus> P2pIface::connectWithParamsInternal(
+		const P2pConnectInfo& connectInfo)
+{
+	std::vector<uint8_t> peerAddressVec {
+		connectInfo.peerAddress.begin(), connectInfo.peerAddress.end()};
+	return connectInternal(peerAddressVec, connectInfo.provisionMethod,
+		connectInfo.preSelectedPin, connectInfo.joinExistingGroup,
+		connectInfo.persistent, connectInfo.goIntent);
+}
+
+ndk::ScopedAStatus P2pIface::findWithParamsInternal(const P2pDiscoveryInfo& discoveryInfo)
+{
+	switch (discoveryInfo.scanType) {
+		case P2pScanType::FULL:
+			return findInternal(discoveryInfo.timeoutInSec);
+		case P2pScanType::SOCIAL:
+			return findOnSocialChannelsInternal(discoveryInfo.timeoutInSec);
+		case P2pScanType::SPECIFIC_FREQ:
+			return findOnSpecificFrequencyInternal(
+				discoveryInfo.frequencyMhz, discoveryInfo.timeoutInSec);
+		default:
+			wpa_printf(MSG_DEBUG,
+				"findWithParams received invalid scan type %d", discoveryInfo.scanType);
+			return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+}
+
 /**
  * Retrieve the underlying |wpa_supplicant| struct
  * pointer for this iface.
diff --git a/wpa_supplicant/aidl/p2p_iface.h b/wpa_supplicant/aidl/p2p_iface.h
index 61972f2..c4f036c 100644
--- a/wpa_supplicant/aidl/p2p_iface.h
+++ b/wpa_supplicant/aidl/p2p_iface.h
@@ -175,6 +175,9 @@
 	::ndk::ScopedAStatus configureEapolIpAddressAllocationParams(
 		int32_t in_ipAddressGo, int32_t in_ipAddressMask,
 		int32_t in_ipAddressStart, int32_t in_ipAddressEnd) override;
+	::ndk::ScopedAStatus connectWithParams(
+		const P2pConnectInfo& in_connectInfo, std::string* _aidl_return) override;
+	::ndk::ScopedAStatus findWithParams(const P2pDiscoveryInfo& in_discoveryInfo) override;
 
 private:
 	// Corresponding worker functions for the AIDL methods.
@@ -298,6 +301,9 @@
 	::ndk::ScopedAStatus configureEapolIpAddressAllocationParamsInternal(
 		uint32_t ipAddressGo, uint32_t ipAddressMask,
 		uint32_t ipAddressStart, uint32_t ipAddressEnd);
+	std::pair<std::string, ndk::ScopedAStatus> connectWithParamsInternal(
+		const P2pConnectInfo& connectInfo);
+	ndk::ScopedAStatus findWithParamsInternal(const P2pDiscoveryInfo& discoveryInfo);
 
 	struct wpa_supplicant* retrieveIfacePtr();
 	struct wpa_supplicant* retrieveGroupIfacePtr(
diff --git a/wpa_supplicant/aidl/sta_network.cpp b/wpa_supplicant/aidl/sta_network.cpp
index 2604d2e..f373e71 100644
--- a/wpa_supplicant/aidl/sta_network.cpp
+++ b/wpa_supplicant/aidl/sta_network.cpp
@@ -891,6 +891,21 @@
 		&StaNetwork::setMinimumTlsVersionEapPhase1ParamInternal, in_tlsVersion);
 }
 
+::ndk::ScopedAStatus StaNetwork::disableEht()
+{
+    return validateAndCall(
+            this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+                &StaNetwork::disableEhtInternal);
+}
+
+::ndk::ScopedAStatus StaNetwork::setVendorData(
+	const std::vector<common::OuiKeyedData>& in_vendorData)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setVendorDataInternal, in_vendorData);
+}
+
 std::pair<uint32_t, ndk::ScopedAStatus> StaNetwork::getIdInternal()
 {
 	return {network_id_, ndk::ScopedAStatus::ok()};
@@ -2698,6 +2713,23 @@
 	return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus StaNetwork::disableEhtInternal()
+{
+  struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+  if (wpa_ssid == nullptr ) {
+    return createStatus(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+  }
+  wpa_ssid->disable_eht = 1;
+  resetInternalStateAfterParamsUpdate();
+  return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setVendorDataInternal(
+		const std::vector<common::OuiKeyedData>& /* vendorData */) {
+	// Not implemented in the default implementation.
+	return ndk::ScopedAStatus::ok();
+}
+
 /**
  * WPA3-Enterprise 192-bit mode workaround to force the connection to EAP-TLSv1.2 due to
  * interoperability issues in TLSv1.3 which disables the SSL_SIGN_RSA_PKCS1_SHA384
diff --git a/wpa_supplicant/aidl/sta_network.h b/wpa_supplicant/aidl/sta_network.h
index 1c24702..b0cb3de 100644
--- a/wpa_supplicant/aidl/sta_network.h
+++ b/wpa_supplicant/aidl/sta_network.h
@@ -178,6 +178,9 @@
 		const std::vector<uint8_t>& in_selectedRcoi) override;
 	::ndk::ScopedAStatus setMinimumTlsVersionEapPhase1Param(
 		TlsVersion in_tlsVersion) override;
+	::ndk::ScopedAStatus disableEht() override;
+	::ndk::ScopedAStatus setVendorData(
+		const std::vector<common::OuiKeyedData>& in_vendorData) override;
 
 private:
 	// Corresponding worker functions for the AIDL methods.
@@ -310,6 +313,9 @@
 	ndk::ScopedAStatus setRoamingConsortiumSelectionInternal(
 		const std::vector<uint8_t>& selectedRcoi);
 	ndk::ScopedAStatus setMinimumTlsVersionEapPhase1ParamInternal(TlsVersion tlsVersion);
+	ndk::ScopedAStatus disableEhtInternal();
+	ndk::ScopedAStatus setVendorDataInternal(
+		const std::vector<common::OuiKeyedData>& vendorData);
 
 	struct wpa_ssid* retrieveNetworkPtr();
 	struct wpa_supplicant* retrieveIfacePtr();
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index bba7777..0047531 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -380,6 +380,12 @@
 		wpa_printf(MSG_DEBUG, "Failed to set PMK to the driver");
 	}
 
+	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X) {
+		/* Add PMKSA cache entry */
+		wpa_printf(MSG_INFO, "add pmksa entry for the PMK");
+		wpa_sm_set_pmk(wpa_s->wpa, pmk, pmk_len, NULL, wpa_sm_get_auth_addr(wpa_s->wpa));
+	}
+
 	wpa_supplicant_cancel_scan(wpa_s);
 	wpa_supplicant_cancel_auth_timeout(wpa_s);
 	wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);