Wi-Fi Direct R2 implementation

This CL includes,

1. Implementation of USD based service discovery.
2. Added bootstrapping methods in device found event.
3. Added support for PCC mode.
4. Added support for connection using pairing protocol.

Bug: 388057182
Test: Manual - P2P connection via Wi-Fi Direct Window
Test: Manual - File sharing using Quick share
Test: Vts Test
Change-Id: Ic4fcd4f7014ab37dae11619fda2917a9da046836
diff --git a/wpa_supplicant/aidl/vendor/aidl_manager.cpp b/wpa_supplicant/aidl/vendor/aidl_manager.cpp
index 52ac6ab..60ce800 100644
--- a/wpa_supplicant/aidl/vendor/aidl_manager.cpp
+++ b/wpa_supplicant/aidl/vendor/aidl_manager.cpp
@@ -1313,6 +1313,33 @@
 		std::placeholders::_1));
 }
 
+int32_t convertP2pPairingBootstrappingMethodsToAidl(u16 bootstrap_methods)
+{
+	int32_t pairingBootstrappingMethods = 0;
+
+	if (bootstrap_methods & P2P_PBMA_OPPORTUNISTIC) {
+		pairingBootstrappingMethods |=
+			P2pPairingBootstrappingMethodMask::BOOTSTRAPPING_OPPORTUNISTIC;
+	}
+	if (bootstrap_methods & P2P_PBMA_PIN_CODE_DISPLAY) {
+		pairingBootstrappingMethods |=
+			P2pPairingBootstrappingMethodMask::BOOTSTRAPPING_DISPLAY_PINCODE;
+	}
+	if (bootstrap_methods & P2P_PBMA_PASSPHRASE_DISPLAY) {
+		pairingBootstrappingMethods |=
+			P2pPairingBootstrappingMethodMask::BOOTSTRAPPING_DISPLAY_PASSPHRASE;
+	}
+	if (bootstrap_methods & P2P_PBMA_PIN_CODE_KEYPAD) {
+		pairingBootstrappingMethods |=
+			P2pPairingBootstrappingMethodMask::BOOTSTRAPPING_KEYPAD_PINCODE;
+	}
+	if (bootstrap_methods & P2P_PBMA_PASSPHRASE_KEYPAD) {
+		pairingBootstrappingMethods |=
+			P2pPairingBootstrappingMethodMask::BOOTSTRAPPING_KEYPAD_PASSPHRASE;
+	}
+
+	return pairingBootstrappingMethods;
+}
 void AidlManager::notifyP2pDeviceFound(
 	struct wpa_supplicant *wpa_s, const u8 *addr,
 	const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
@@ -1375,8 +1402,9 @@
 		params.wfdR2DeviceInfo = aidl_peer_wfd_r2_device_info;
 		params.vendorElemBytes = aidl_vendor_elems;
 		if (areAidlServiceAndClientAtLeastVersion(4)) {
-			// TODO Fill the field when supplicant implementation is ready
-			params.pairingBootstrappingMethods = 0;
+			// TODO Fill the DIRA info when supplicant implementation is ready
+			params.pairingBootstrappingMethods = convertP2pPairingBootstrappingMethodsToAidl(
+				info->pairing_config.bootstrap_methods);
 		}
 		callWithEachP2pIfaceCallback(
 			misc_utils::charBufToString(wpa_s->ifname),
@@ -1485,6 +1513,18 @@
 		std::placeholders::_1, reason));
 }
 
+uint32_t convertSupplicantKeyMgmtForP2pGroupConnectionToAidl(int supp_key_mgmt)
+{
+	uint32_t aidl_key_mgmt = 0;
+	if (supp_key_mgmt & WPA_KEY_MGMT_PSK) {
+		aidl_key_mgmt |= static_cast<uint32_t>(KeyMgmtMask::WPA_PSK);
+	}
+	if (supp_key_mgmt & WPA_KEY_MGMT_SAE) {
+		aidl_key_mgmt |= static_cast<uint32_t>(KeyMgmtMask::SAE);
+	}
+	return aidl_key_mgmt;
+}
+
 void AidlManager::notifyP2pGroupStarted(
 	struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
 	int persistent, int client, const u8 *ip)
@@ -1538,10 +1578,10 @@
 			   params.p2pClientIpInfo.ipAddressClient,
 			   params.p2pClientIpInfo.ipAddressMask,
 			   params.p2pClientIpInfo.ipAddressGo);
-        }
+    }
 	if (areAidlServiceAndClientAtLeastVersion(4)) {
-		// TODO Fill the field when supplicant implementation is ready
-		params.keyMgmtMask = 0;
+		params.keyMgmtMask = convertSupplicantKeyMgmtForP2pGroupConnectionToAidl(
+			wpa_group_s->key_mgmt);
 	}
 	callWithEachP2pIfaceCallback(
 		misc_utils::charBufToString(wpa_s->ifname),
@@ -1679,75 +1719,6 @@
 		byteArrToVec(tlvs, tlvs_len)));
 }
 
-void AidlManager::notifyUsdBasedServiceDiscoveryResult(
-	struct wpa_supplicant *wpa_s, const u8 *peer_addr, int subscribe_id,
-	int peer_publish_id, int srv_proto_type, const u8 *ssi, size_t ssi_len)
-{
-	// TODO define the reason and map to AIDL defenition.
-	if (!wpa_s)
-		return;
-
-	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
-		p2p_iface_object_map_.end())
-		return;
-
-	if (!areAidlServiceAndClientAtLeastVersion(4)) {
-	      return;
-	}
-	// TODO Fill the fields when supplicant implementation is ready
-	P2pUsdBasedServiceDiscoveryResultParams params;
-
-	callWithEachP2pIfaceCallback(
-		misc_utils::charBufToString(wpa_s->ifname),
-		std::bind(
-		&ISupplicantP2pIfaceCallback::onUsdBasedServiceDiscoveryResult,
-		std::placeholders::_1, params));
-}
-
-void AidlManager::notifyUsdBasedServiceDiscoveryTerminated(
-	struct wpa_supplicant *wpa_s, int subscribe_id, int reason)
-{
-	// TODO define the reason and map to AIDL defenition.
-	if (!wpa_s)
-		return;
-
-	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
-		p2p_iface_object_map_.end())
-		return;
-
-	if (!areAidlServiceAndClientAtLeastVersion(4)) {
-	      return;
-	}
-
-	callWithEachP2pIfaceCallback(
-		misc_utils::charBufToString(wpa_s->ifname),
-		std::bind(
-		&ISupplicantP2pIfaceCallback::onUsdBasedServiceDiscoveryTerminated,
-		std::placeholders::_1, subscribe_id, UsdTerminateReasonCode::UNKNOWN));
-}
-
-void AidlManager::notifyUsdBasedServiceAdvertisementTerminated(
-	struct wpa_supplicant *wpa_s, int publish_id, int reason)
-{
-	// TODO define the reason and map to AIDL defenition.
-	if (!wpa_s)
-		return;
-
-	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
-		p2p_iface_object_map_.end())
-		return;
-
-	if (!areAidlServiceAndClientAtLeastVersion(4)) {
-	      return;
-	}
-
-	callWithEachP2pIfaceCallback(
-		misc_utils::charBufToString(wpa_s->ifname),
-		std::bind(
-		&ISupplicantP2pIfaceCallback::onUsdBasedServiceAdvertisementTerminated,
-		std::placeholders::_1, publish_id, UsdTerminateReasonCode::UNKNOWN));
-}
-
 void AidlManager::notifyApStaAuthorized(
 	struct wpa_supplicant *wpa_group_s, const u8 *sta, const u8 *p2p_dev_addr,
 	const u8 *ip)
@@ -3032,6 +3003,21 @@
 	}
 }
 
+P2pUsdBasedServiceDiscoveryResultParams createP2pUsdBasedServiceDiscoveryResult(
+		enum nan_service_protocol_type srv_proto_type,
+		int own_id, int peer_id, const u8 *peer_addr,
+		const u8 *ssi, size_t ssi_len) {
+	P2pUsdBasedServiceDiscoveryResultParams p2pServiceDiscoveryInfo;
+	p2pServiceDiscoveryInfo.peerMacAddress = macAddrToArray(peer_addr);
+	p2pServiceDiscoveryInfo.sessionId = own_id;
+	p2pServiceDiscoveryInfo.peerSessionId = peer_id;
+	p2pServiceDiscoveryInfo.serviceProtocolType = static_cast<int>(srv_proto_type);
+	if (ssi != NULL) {
+		p2pServiceDiscoveryInfo.serviceSpecificInfo = byteArrToVec(ssi, ssi_len);
+	}
+	return p2pServiceDiscoveryInfo;
+}
+
 UsdServiceDiscoveryInfo createUsdServiceDiscoveryInfo(
 		enum nan_service_protocol_type srv_proto_type,
 		int own_id, int peer_id, const u8 *peer_addr,
@@ -3052,14 +3038,25 @@
 		int subscribe_id, int peer_publish_id, const u8 *peer_addr,
 		bool fsd, const u8 *ssi, size_t ssi_len)
 {
-	if (!wpa_s || !peer_addr || !ssi) return;
+	if (!wpa_s || !peer_addr) return;
 	if (!areAidlServiceAndClientAtLeastVersion(4)) return;
-	UsdServiceDiscoveryInfo discoveryInfo = createUsdServiceDiscoveryInfo(
-		srv_proto_type, subscribe_id, peer_publish_id, peer_addr, fsd, ssi, ssi_len);
-	callWithEachStaIfaceCallback(
-		misc_utils::charBufToString(wpa_s->ifname), std::bind(
-			&ISupplicantStaIfaceCallback::onUsdServiceDiscovered,
-			std::placeholders::_1, discoveryInfo));
+	if (p2p_iface_object_map_.find(wpa_s->ifname) != p2p_iface_object_map_.end()) {
+		// Notify service discovered event on P2P device interface.
+		P2pUsdBasedServiceDiscoveryResultParams p2pServiceDiscoveryInfo =
+			createP2pUsdBasedServiceDiscoveryResult(srv_proto_type, subscribe_id,
+				peer_publish_id, peer_addr, ssi, ssi_len);
+		callWithEachP2pIfaceCallback(misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(&ISupplicantP2pIfaceCallback::onUsdBasedServiceDiscoveryResult,
+			std::placeholders::_1, p2pServiceDiscoveryInfo));
+	} else {
+		// Notify service discovered event on STA interface.
+		UsdServiceDiscoveryInfo discoveryInfo = createUsdServiceDiscoveryInfo(
+			srv_proto_type, subscribe_id, peer_publish_id, peer_addr, fsd, ssi, ssi_len);
+		callWithEachStaIfaceCallback(
+				misc_utils::charBufToString(wpa_s->ifname), std::bind(
+					&ISupplicantStaIfaceCallback::onUsdServiceDiscovered,
+					std::placeholders::_1, discoveryInfo));
+	}
 }
 
 void AidlManager::notifyUsdPublishReplied(struct wpa_supplicant *wpa_s,
@@ -3115,11 +3112,21 @@
 {
 	if (!wpa_s) return;
 	if (!areAidlServiceAndClientAtLeastVersion(4)) return;
-	callWithEachStaIfaceCallback(
-		misc_utils::charBufToString(wpa_s->ifname), std::bind(
+	UsdTerminateReasonCode aidlReasonCode = convertUsdTerminateReasonCodeToAidl(reason);
+	if (p2p_iface_object_map_.find(wpa_s->ifname) != p2p_iface_object_map_.end()) {
+		// Notify publish terminated event on P2P device interface.
+		callWithEachP2pIfaceCallback(
+			misc_utils::charBufToString(wpa_s->ifname),
+			std::bind(
+			&ISupplicantP2pIfaceCallback::onUsdBasedServiceAdvertisementTerminated,
+			std::placeholders::_1, publish_id, aidlReasonCode));
+	} else {
+		// Notify publish terminated event on STA interface.
+		callWithEachStaIfaceCallback(
+			misc_utils::charBufToString(wpa_s->ifname), std::bind(
 			&ISupplicantStaIfaceCallback::onUsdPublishTerminated,
-			std::placeholders::_1, publish_id,
-			convertUsdTerminateReasonCodeToAidl(reason)));
+			std::placeholders::_1, publish_id, aidlReasonCode));
+	}
 }
 
 void AidlManager::notifyUsdSubscribeTerminated(struct wpa_supplicant *wpa_s,
@@ -3127,11 +3134,21 @@
 {
 	if (!wpa_s) return;
 	if (!areAidlServiceAndClientAtLeastVersion(4)) return;
-	callWithEachStaIfaceCallback(
-		misc_utils::charBufToString(wpa_s->ifname), std::bind(
+	UsdTerminateReasonCode aidlReasonCode = convertUsdTerminateReasonCodeToAidl(reason);
+	if (p2p_iface_object_map_.find(wpa_s->ifname) != p2p_iface_object_map_.end()) {
+		// Notify subscribe terminated event on P2P device interface.
+		callWithEachP2pIfaceCallback(
+			misc_utils::charBufToString(wpa_s->ifname),
+			std::bind(
+			&ISupplicantP2pIfaceCallback::onUsdBasedServiceDiscoveryTerminated,
+			std::placeholders::_1, subscribe_id, aidlReasonCode));
+	} else {
+		// Notify subscribe terminated event on STA interface.
+		callWithEachStaIfaceCallback(
+			misc_utils::charBufToString(wpa_s->ifname), std::bind(
 			&ISupplicantStaIfaceCallback::onUsdSubscribeTerminated,
-			std::placeholders::_1, subscribe_id,
-			convertUsdTerminateReasonCodeToAidl(reason)));
+			std::placeholders::_1, subscribe_id, aidlReasonCode));
+	}
 }
 
 }  // namespace supplicant
diff --git a/wpa_supplicant/aidl/vendor/aidl_manager.h b/wpa_supplicant/aidl/vendor/aidl_manager.h
index b217749..667422f 100644
--- a/wpa_supplicant/aidl/vendor/aidl_manager.h
+++ b/wpa_supplicant/aidl/vendor/aidl_manager.h
@@ -120,15 +120,6 @@
 	void notifyP2pSdResponse(
 		struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
 		const u8 *tlvs, size_t tlvs_len);
-	void notifyUsdBasedServiceDiscoveryResult(
-		struct wpa_supplicant *wpa_s, const u8 *peer_addr, int subscribe_id,
-		int peer_publish_id, int srv_proto_type, const u8 *ssi, size_t ssi_len);
-	void notifyUsdBasedServiceDiscoveryTerminated(
-		struct wpa_supplicant *wpa_s, int subscribe_id,
-		int reason);
-	void notifyUsdBasedServiceAdvertisementTerminated(
-		struct wpa_supplicant *wpa_s, int publish_id,
-		int reason);
 	void notifyApStaAuthorized(
 		struct wpa_supplicant *wpa_s, const u8 *sta,
 		const u8 *p2p_dev_addr, const u8 *ip);
diff --git a/wpa_supplicant/aidl/vendor/p2p_iface.cpp b/wpa_supplicant/aidl/vendor/p2p_iface.cpp
index 8590693..16c5536 100644
--- a/wpa_supplicant/aidl/vendor/p2p_iface.cpp
+++ b/wpa_supplicant/aidl/vendor/p2p_iface.cpp
@@ -24,6 +24,10 @@
 }
 
 #define P2P_JOIN_LIMIT 3
+#define WPA_KEY_MGMT_P2P_MODE_WFD_PCC (WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_PSK)
+#define IS_P2P_MODE_WFD_PCC_KEY_MGMT(key_mgmt_mask) \
+	((key_mgmt_mask & WPA_KEY_MGMT_P2P_MODE_WFD_PCC) == WPA_KEY_MGMT_P2P_MODE_WFD_PCC)
+#define DEFAULT_QUERY_PERIOD_MS 40
 
 namespace {
 const char kConfigMethodStrPbc[] = "pbc";
@@ -40,9 +44,14 @@
 
 using aidl::android::hardware::wifi::supplicant::ISupplicantP2pIface;
 using aidl::android::hardware::wifi::supplicant::ISupplicantStaNetwork;
+using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
 using aidl::android::hardware::wifi::supplicant::MiracastMode;
 using aidl::android::hardware::wifi::supplicant::P2pFrameTypeMask;
 
+constexpr uint32_t kAllowedKeyMgmtMask =
+	(static_cast<uint32_t>(KeyMgmtMask::WPA_PSK) |
+	 static_cast<uint32_t>(KeyMgmtMask::SAE));
+
 uint8_t convertAidlMiracastModeToInternal(
 	MiracastMode mode)
 {
@@ -168,13 +177,23 @@
 	const uint8_t *group_owner_bssid,
 	const std::vector<uint8_t>& ssid,
 	const std::string& passphrase,
-	uint32_t freq)
+	uint32_t freq,
+	uint32_t key_mgmt_mask)
 {
 	int ret = 0;
 	int he = wpa_s->conf->p2p_go_he;
 	int vht = wpa_s->conf->p2p_go_vht;
 	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
 
+	if (key_mgmt_mask != 0 && key_mgmt_mask & ~kAllowedKeyMgmtMask) {
+		return -1;
+	}
+
+	if (key_mgmt_mask == WPA_KEY_MGMT_SAE) {
+		wpa_s->p2p2 = true;
+		wpa_s->p2p_mode = WPA_P2P_MODE_WFD_R2;
+	}
+
 	// Construct a network for adding group.
 	// Group client follows the persistent attribute of Group Owner.
 	// If joined group is persistent, it adds a persistent network on GroupStarted.
@@ -401,7 +420,7 @@
 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
 		&P2pIface::connectInternal, _aidl_return, in_peerAddress,
 		in_provisionMethod, in_preSelectedPin, in_joinExistingGroup,
-		in_persistent, in_goIntent);
+		in_persistent, in_goIntent, 0, "", 0, false, "");
 }
 
 ::ndk::ScopedAStatus P2pIface::cancelConnect()
@@ -418,7 +437,7 @@
 	return validateAndCall(
 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
 		&P2pIface::provisionDiscoveryInternal, in_peerAddress,
-		in_provisionMethod);
+		in_provisionMethod, 0);
 }
 
 ndk::ScopedAStatus P2pIface::addGroup(
@@ -427,7 +446,7 @@
 	return validateAndCall(
 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
 		&P2pIface::addGroupInternal, in_persistent,
-		in_persistentNetworkId);
+		in_persistentNetworkId, false);
 }
 
 ::ndk::ScopedAStatus P2pIface::addGroupWithConfig(
@@ -440,7 +459,8 @@
 		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
 		&P2pIface::addGroupWithConfigInternal, in_ssid,
 		in_pskPassphrase, in_persistent, in_freq,
-		in_peerAddress, in_joinExistingGroup);
+		in_peerAddress, in_joinExistingGroup,
+		static_cast<uint32_t>(KeyMgmtMask::WPA_PSK));
 }
 
 ::ndk::ScopedAStatus P2pIface::removeGroup(
@@ -1099,13 +1119,38 @@
 	return ndk::ScopedAStatus::ok();
 }
 
+u16 convertAidlPairingBootstrappingMethodToWpa(uint32_t pairing_bootstrapping_method)
+{
+	switch (pairing_bootstrapping_method) {
+		case P2pPairingBootstrappingMethodMask::BOOTSTRAPPING_OPPORTUNISTIC:
+			return P2P_PBMA_OPPORTUNISTIC;
+		case P2pPairingBootstrappingMethodMask::BOOTSTRAPPING_DISPLAY_PINCODE:
+			return P2P_PBMA_PIN_CODE_DISPLAY;
+		case P2pPairingBootstrappingMethodMask::BOOTSTRAPPING_DISPLAY_PASSPHRASE:
+			return P2P_PBMA_PASSPHRASE_DISPLAY;
+		case P2pPairingBootstrappingMethodMask::BOOTSTRAPPING_KEYPAD_PINCODE:
+			return P2P_PBMA_PIN_CODE_KEYPAD;
+		case P2pPairingBootstrappingMethodMask::BOOTSTRAPPING_KEYPAD_PASSPHRASE:
+			return P2P_PBMA_PASSPHRASE_KEYPAD;
+		case P2pPairingBootstrappingMethodMask::BOOTSTRAPPING_OUT_OF_BAND:
+			return P2P_PBMA_HANDSHAKE_SKIP;
+		default:
+			return 0;
+	}
+}
+
 // This method only implements support for subset (needed by Android framework)
 // of parameters that can be specified for connect.
 std::pair<std::string, ndk::ScopedAStatus> P2pIface::connectInternal(
 	const std::vector<uint8_t>& peer_address,
 	WpsProvisionMethod provision_method,
 	const std::string& pre_selected_pin, bool join_existing_group,
-	bool persistent, uint32_t go_intent)
+	bool persistent, uint32_t go_intent,
+	uint32_t pairing_bootstrapping_method,
+	const std::string& password,
+	uint32_t frequency,
+	bool authorize,
+	const std::string& group_ifname)
 {
 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
 	if (go_intent > 15) {
@@ -1130,6 +1175,28 @@
 		wps_method = WPS_NOT_READY;
 		break;
 	}
+
+	bool p2p2 = false;
+	u16 bootstrap = 0;
+	const char* pairing_password = nullptr;
+	bool skip_prov = false;
+	int auto_join = 0;
+	if (wps_method == WPS_NOT_READY) {
+		bootstrap = convertAidlPairingBootstrappingMethodToWpa(
+			pairing_bootstrapping_method);
+		if (bootstrap == 0) {
+			return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+		}
+		if (bootstrap == P2P_PBMA_HANDSHAKE_SKIP) {
+			skip_prov = true;
+		}
+		p2p2 = true;
+		pairing_password = password.length() > 0 ? password.data() : nullptr;
+		if (authorize) {
+			auto_join = 1;
+		}
+	}
+
 	int he = wpa_s->conf->p2p_go_he;
 	int vht = wpa_s->conf->p2p_go_vht;
 	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
@@ -1137,10 +1204,10 @@
 	const char* pin =
 		pre_selected_pin.length() > 0 ? pre_selected_pin.data() : nullptr;
 	int new_pin = wpas_p2p_connect(
-		wpa_s, peer_address.data(), pin, wps_method, persistent, false,
-		join_existing_group, false, go_intent_signed, 0, 0, -1, false, ht40,
+		wpa_s, peer_address.data(), pin, wps_method, persistent, auto_join,
+		join_existing_group, authorize, go_intent_signed, 0, 0, -1, false, ht40,
 		vht, CONF_OPER_CHWIDTH_USE_HT, he, edmg, nullptr, 0, is6GhzAllowed(wpa_s),
-		false, 0, NULL, false);
+		p2p2, bootstrap, pairing_password, skip_prov);
 	if (new_pin < 0) {
 		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
 	}
@@ -1168,7 +1235,8 @@
 
 ndk::ScopedAStatus P2pIface::provisionDiscoveryInternal(
 	const std::vector<uint8_t>& peer_address,
-	WpsProvisionMethod provision_method)
+	WpsProvisionMethod provision_method,
+	uint32_t pairingBootstrappingMethod)
 {
 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
 	p2ps_provision* prov_param;
@@ -1186,11 +1254,11 @@
 	case WpsProvisionMethod::KEYPAD:
 		config_method_str = kConfigMethodStrKeypad;
 		break;
-	// TODO Handle pairing bootstrapping method when supplicant implementation is ready
 	case WpsProvisionMethod::NONE:
 		config_method_str = kConfigMethodStrNone;
 		break;
 	}
+	// TODO Handle pairing bootstrapping method when supplicant implementation is ready
 	if (wpas_p2p_prov_disc(
 		wpa_s, peer_address.data(), config_method_str,
 		WPAS_P2P_PD_FOR_GO_NEG, nullptr)) {
@@ -1715,20 +1783,21 @@
 }
 
 ndk::ScopedAStatus P2pIface::addGroupInternal(
-	bool persistent, int32_t persistent_network_id)
+	bool persistent, int32_t persistent_network_id, bool p2p2)
 {
 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
 	int he = wpa_s->conf->p2p_go_he;
 	int vht = wpa_s->conf->p2p_go_vht;
 	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
 	int edmg = wpa_s->conf->p2p_go_edmg;
+	enum wpa_p2p_mode p2p_mode = p2p2 ? WPA_P2P_MODE_WFD_R2 : WPA_P2P_MODE_WFD_R1;
 	struct wpa_ssid* ssid =
 		wpa_config_get_network(wpa_s->conf, persistent_network_id);
 	if (ssid == NULL) {
 		if (wpas_p2p_group_add(
 			wpa_s, persistent, 0, 0, ht40, vht,
 			CONF_OPER_CHWIDTH_USE_HT, he, edmg, is6GhzAllowed(wpa_s),
-			false, WPA_P2P_MODE_WFD_R1)) {
+			p2p2, p2p_mode)) {
 			return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
 		} else {
 			return ndk::ScopedAStatus::ok();
@@ -1747,10 +1816,21 @@
 	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
 }
 
+enum wpa_p2p_mode convertAidlKeyMgmtMaskToWpaP2pMode(uint32_t key_mgmt_mask)
+{
+	if (IS_P2P_MODE_WFD_PCC_KEY_MGMT(key_mgmt_mask)) {
+		return WPA_P2P_MODE_WFD_PCC;
+	} else if (wpa_key_mgmt_sae(key_mgmt_mask)) {
+		return WPA_P2P_MODE_WFD_R2;
+	} else {
+		return WPA_P2P_MODE_WFD_R1;
+	}
+}
+
 ndk::ScopedAStatus P2pIface::addGroupWithConfigInternal(
 	const std::vector<uint8_t>& ssid, const std::string& passphrase,
 	bool persistent, uint32_t freq, const std::vector<uint8_t>& peer_address,
-	bool joinExistingGroup)
+	bool joinExistingGroup, uint32_t key_mgmt_mask)
 {
 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
 	int he = wpa_s->conf->p2p_go_he;
@@ -1772,10 +1852,17 @@
 			"Passphrase is invalid.");
 	}
 
+	if (key_mgmt_mask != 0 && key_mgmt_mask & ~kAllowedKeyMgmtMask) {
+		return createStatusWithMsg(SupplicantStatusCode::FAILURE_ARGS_INVALID,
+			"Unknown key_mgmt_mask");
+	}
+
+	enum wpa_p2p_mode p2p_mode = convertAidlKeyMgmtMaskToWpaP2pMode(key_mgmt_mask);
+
 	wpa_printf(MSG_DEBUG,
-		    "P2P: Add group with config Role: %s network name: %s freq: %d",
+		    "P2P: Add group with config Role: %s network name: %s freq: %d p2p_mode: %d",
 		    joinExistingGroup ? "CLIENT" : "GO",
-		    wpa_ssid_txt(ssid.data(), ssid.size()), freq);
+		    wpa_ssid_txt(ssid.data(), ssid.size()), freq, p2p_mode);
 	if (!joinExistingGroup) {
 		struct p2p_data *p2p = wpa_s->global->p2p;
 		os_memcpy(p2p->ssid, ssid.data(), ssid.size());
@@ -1789,7 +1876,7 @@
 		if (wpas_p2p_group_add(
 			wpa_s, persistent, freq, 0, ht40, vht,
 			CONF_OPER_CHWIDTH_USE_HT, he, edmg, is6GhzAllowed(wpa_s),
-			false, WPA_P2P_MODE_WFD_R1)) {
+			false, p2p_mode)) {
 			return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
 		}
 		return ndk::ScopedAStatus::ok();
@@ -1802,7 +1889,7 @@
 		return createStatusWithMsg(SupplicantStatusCode::FAILURE_ARGS_INVALID,
 			"Peer address is invalid.");
 	}
-	if (joinGroup(wpa_s, peer_address.data(), ssid, passphrase, freq)) {
+	if (joinGroup(wpa_s, peer_address.data(), ssid, passphrase, freq, key_mgmt_mask)) {
 		return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
 			"Failed to start scan.");
 	}
@@ -1983,7 +2070,12 @@
 		connectInfo.peerAddress.begin(), connectInfo.peerAddress.end()};
 	return connectInternal(peerAddressVec, connectInfo.provisionMethod,
 		connectInfo.preSelectedPin, connectInfo.joinExistingGroup,
-		connectInfo.persistent, connectInfo.goIntent);
+		connectInfo.persistent, connectInfo.goIntent,
+		connectInfo.pairingBootstrappingMethod,
+		connectInfo.password.has_value() ? connectInfo.password.value() : "",
+		connectInfo.frequencyMHz, connectInfo.authorizeConnectionFromPeer,
+		connectInfo.groupInterfaceName.has_value() ?
+			connectInfo.groupInterfaceName.value() : "");
 }
 
 ndk::ScopedAStatus P2pIface::findWithParamsInternal(const P2pDiscoveryInfo& discoveryInfo)
@@ -2019,14 +2111,16 @@
 		groupConfigurationParams.ssid, groupConfigurationParams.passphrase,
 		groupConfigurationParams.isPersistent, groupConfigurationParams.frequencyMHzOrBand,
 		goInterfaceAddressVec,
-		groupConfigurationParams.joinExistingGroup);
+		groupConfigurationParams.joinExistingGroup,
+		groupConfigurationParams.keyMgmtMask);
 }
 
 ndk::ScopedAStatus P2pIface::createGroupOwnerInternal(
 	const P2pCreateGroupOwnerInfo& groupOwnerInfo)
 {
 	return addGroupInternal(
-		groupOwnerInfo.persistent, groupOwnerInfo.persistentNetworkId);
+		groupOwnerInfo.persistent, groupOwnerInfo.persistentNetworkId,
+		groupOwnerInfo.isP2pV2);
 }
 
 std::pair<int64_t, ndk::ScopedAStatus> P2pIface::getFeatureSetInternal()
@@ -2039,30 +2133,109 @@
 P2pIface::startUsdBasedServiceDiscoveryInternal(
 	const P2pUsdBasedServiceDiscoveryConfig& serviceDiscoveryConfig)
 {
-	// TODO Fill the field when supplicant implementation is ready
-	return {0, ndk::ScopedAStatus::ok()};
+#ifdef CONFIG_NAN_USD
+	int sessionId;
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	struct nan_subscribe_params params;
+	struct wpabuf *service_specific_info = NULL;
+
+	os_memset(&params, 0, sizeof(params));
+
+	if (serviceDiscoveryConfig.serviceSpecificInfo.size() > 0) {
+		auto ssiBuffer = misc_utils::convertVectorToWpaBuf(
+			serviceDiscoveryConfig.serviceSpecificInfo);
+		if (ssiBuffer && ssiBuffer.get() != nullptr) {
+			service_specific_info = ssiBuffer.get();
+		}
+	}
+
+	params.active = true;
+	params.ttl = serviceDiscoveryConfig.timeoutInSeconds;
+	params.query_period = DEFAULT_QUERY_PERIOD_MS;
+	if (serviceDiscoveryConfig.bandMask != 0) {
+		// TODO convert band to channel instead of scanning all channel frequencies.
+		params.freq_list = wpas_nan_usd_all_freqs(wpa_s);
+	} else {
+		if (serviceDiscoveryConfig.frequencyListMhz.size() != 0) {
+			params.freq_list = serviceDiscoveryConfig.frequencyListMhz.data();
+		} else {
+			params.freq = NAN_USD_DEFAULT_FREQ;
+		}
+	}
+	sessionId = wpas_nan_usd_subscribe(wpa_s, serviceDiscoveryConfig.serviceName.c_str(),
+					      (enum nan_service_protocol_type)
+						  serviceDiscoveryConfig.serviceProtocolType,
+						  service_specific_info, &params, true);
+	if (service_specific_info != NULL) {
+		freeWpaBuf(service_specific_info);
+	}
+	if (sessionId > 0) {
+		return {sessionId, ndk::ScopedAStatus::ok()};
+	}
+	return {-1, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+#else
+	return {-1, createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED)};
+#endif
 }
 
 ndk::ScopedAStatus P2pIface::stopUsdBasedServiceDiscoveryInternal(
 	uint32_t sessionId)
 {
-	// TODO Fill the field when supplicant implementation is ready
+#ifdef CONFIG_NAN_USD
+	wpas_nan_usd_cancel_subscribe(retrieveIfacePtr(), sessionId);
 	return ndk::ScopedAStatus::ok();
+#else
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+#endif
 }
 
 std::pair<uint32_t, ndk::ScopedAStatus>
 P2pIface::startUsdBasedServiceAdvertisementInternal(
 	const P2pUsdBasedServiceAdvertisementConfig& serviceAdvertisementConfig)
 {
-	// TODO Fill the field when supplicant implementation is ready
-	return {0, ndk::ScopedAStatus::ok()};
+#ifdef CONFIG_NAN_USD
+	int sessionId;
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	struct nan_publish_params params;
+	struct wpabuf *service_specific_info = NULL;
+	os_memset(&params, 0, sizeof(params));
+
+	if (serviceAdvertisementConfig.serviceSpecificInfo.size() > 0) {
+		auto ssiBuffer = misc_utils::convertVectorToWpaBuf(
+			serviceAdvertisementConfig.serviceSpecificInfo);
+		if (ssiBuffer && ssiBuffer.get() != nullptr) {
+			service_specific_info = ssiBuffer.get();
+		}
+	}
+
+	params.solicited = true;
+	params.ttl = serviceAdvertisementConfig.timeoutInSeconds;
+	params.freq = serviceAdvertisementConfig.frequencyMHz;
+	sessionId = wpas_nan_usd_publish(wpa_s, serviceAdvertisementConfig.serviceName.c_str(),
+					      (enum nan_service_protocol_type)
+						  serviceAdvertisementConfig.serviceProtocolType,
+						  service_specific_info, &params, true);
+	if (service_specific_info != NULL) {
+		freeWpaBuf(service_specific_info);
+	}
+	if (sessionId > 0) {
+		return {sessionId, ndk::ScopedAStatus::ok()};
+	}
+	return {-1, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+#else
+	return {-1, createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED)};
+#endif
 }
 
 ndk::ScopedAStatus P2pIface::stopUsdBasedServiceAdvertisementInternal(
 	uint32_t sessionId)
 {
-	// TODO Fill the field when supplicant implementation is ready
+#ifdef CONFIG_NAN_USD
+	wpas_nan_usd_cancel_publish(retrieveIfacePtr(), sessionId);
 	return ndk::ScopedAStatus::ok();
+#else
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+#endif
 }
 
 ndk::ScopedAStatus P2pIface::provisionDiscoveryWithParamsInternal(
@@ -2071,8 +2244,8 @@
 	std::vector<uint8_t> peerMacAddressVec {
 		params.peerMacAddress.begin(),
 		params.peerMacAddress.end()};
-	// TODO Add the pairing method when supplicant implementation is ready
-	return provisionDiscoveryInternal(peerMacAddressVec, params.provisionMethod);
+	return provisionDiscoveryInternal(peerMacAddressVec, params.provisionMethod,
+		params.pairingBootstrappingMethod);
 }
 
 std::pair<P2pDirInfo, ndk::ScopedAStatus> P2pIface::getDirInfoInternal()
diff --git a/wpa_supplicant/aidl/vendor/p2p_iface.h b/wpa_supplicant/aidl/vendor/p2p_iface.h
index 545a6c9..1c38437 100644
--- a/wpa_supplicant/aidl/vendor/p2p_iface.h
+++ b/wpa_supplicant/aidl/vendor/p2p_iface.h
@@ -19,6 +19,7 @@
 #include <aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.h>
 #include <aidl/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.h>
 #include <aidl/android/hardware/wifi/supplicant/MiracastMode.h>
+#include <aidl/android/hardware/wifi/supplicant/P2pPairingBootstrappingMethodMask.h>
 #include <aidl/android/hardware/wifi/supplicant/WpsProvisionMethod.h>
 
 extern "C"
@@ -230,16 +231,20 @@
 		const std::vector<uint8_t>& peer_address,
 		WpsProvisionMethod provision_method,
 		const std::string& pre_selected_pin, bool join_existing_group,
-		bool persistent, uint32_t go_intent);
+		bool persistent, uint32_t go_intent,
+		uint32_t pairing_bootstrapping_method, const std::string& password,
+		uint32_t frequency, bool authorize, const std::string& group_ifname);
 	ndk::ScopedAStatus cancelConnectInternal();
 	ndk::ScopedAStatus provisionDiscoveryInternal(
 		const std::vector<uint8_t>& peer_address,
-		WpsProvisionMethod provision_method);
-	ndk::ScopedAStatus addGroupInternal(bool in_persistent, int32_t in_persistentNetworkId);
+		WpsProvisionMethod provision_method,
+		uint32_t pairingBootstrappingMethod);
+	ndk::ScopedAStatus addGroupInternal(bool in_persistent, int32_t in_persistentNetworkId,
+		bool isP2pV2);
 	ndk::ScopedAStatus addGroupWithConfigInternal(
 		const std::vector<uint8_t>& ssid, const std::string& passphrase,
 		bool persistent, uint32_t freq, const std::vector<uint8_t>& peer_address,
-		bool joinExistingGroup);
+		bool joinExistingGroup, uint32_t key_mgmt_mask);
 	ndk::ScopedAStatus removeGroupInternal(const std::string& group_ifname);
 	ndk::ScopedAStatus rejectInternal(
 		const std::vector<uint8_t>& peer_address);