wpa_supplicant(hidl): Implementation of P2p callbacks

Implementation of all the P2P callbacks exposed in
ISupplicantP2pIfaceCallback interface.

Few callbacks are intentionally left out because there are other
callbacks which already provide the necessary info:
1. The various onProvisionDiscovery* callbacks can be inferred from the
onProvisionDiscoveryCompleted callback.
2. onGroupFormationSuccess can be inferred from onGroupStarted callback.
These will be removed from the .hal files.

Bug:34221586
Test: Compiles
Change-Id: I03fb2cb2c5a1579a5357b4f5578e1152f5cb49a5
diff --git a/wpa_supplicant/hidl/hidl.cpp b/wpa_supplicant/hidl/hidl.cpp
index e38288b..21a2fd4 100644
--- a/wpa_supplicant/hidl/hidl.cpp
+++ b/wpa_supplicant/hidl/hidl.cpp
@@ -336,3 +336,261 @@
 
 	hidl_manager->notifyWpsEventPbcOverlap(wpa_s);
 }
+
+void wpas_hidl_notify_p2p_device_found(
+    struct wpa_supplicant *wpa_s, const u8 *addr,
+    const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
+    u8 peer_wfd_device_info_len)
+{
+	if (!wpa_s || !addr || !info || !peer_wfd_device_info)
+		return;
+
+	wpa_printf(
+	    MSG_DEBUG, "Notifying P2P device found to hidl control " MACSTR,
+	    MAC2STR(info->p2p_device_addr));
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager)
+		return;
+
+	hidl_manager->notifyP2pDeviceFound(
+	    wpa_s, addr, info, peer_wfd_device_info, peer_wfd_device_info_len);
+}
+
+void wpas_hidl_notify_p2p_device_lost(
+    struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr)
+{
+	if (!wpa_s || !p2p_device_addr)
+		return;
+
+	wpa_printf(
+	    MSG_DEBUG, "Notifying P2P device lost to hidl control " MACSTR,
+	    MAC2STR(p2p_device_addr));
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager)
+		return;
+
+	hidl_manager->notifyP2pDeviceLost(wpa_s, p2p_device_addr);
+}
+
+void wpas_hidl_notify_p2p_find_stopped(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notifying P2P find stop to hidl control");
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager)
+		return;
+
+	hidl_manager->notifyP2pFindStopped(wpa_s);
+}
+
+void wpas_hidl_notify_p2p_go_neg_req(
+    struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
+    u8 go_intent)
+{
+	if (!wpa_s || !src_addr)
+		return;
+
+	wpa_printf(
+	    MSG_DEBUG,
+	    "Notifying P2P GO negotiation request to hidl control " MACSTR,
+	    MAC2STR(src_addr));
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager)
+		return;
+
+	hidl_manager->notifyP2pGoNegReq(
+	    wpa_s, src_addr, dev_passwd_id, go_intent);
+}
+
+void wpas_hidl_notify_p2p_go_neg_completed(
+    struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res)
+{
+	if (!wpa_s || !res)
+		return;
+
+	wpa_printf(
+	    MSG_DEBUG,
+	    "Notifying P2P GO negotiation completed to hidl control: %d",
+	    res->status);
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager)
+		return;
+
+	hidl_manager->notifyP2pGoNegCompleted(wpa_s, res);
+}
+
+void wpas_hidl_notify_p2p_group_formation_failure(
+    struct wpa_supplicant *wpa_s, const char *reason)
+{
+	if (!wpa_s || !reason)
+		return;
+
+	wpa_printf(
+	    MSG_DEBUG,
+	    "Notifying P2P Group formation failure to hidl control: %s",
+	    reason);
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager)
+		return;
+
+	hidl_manager->notifyP2pGroupFormationFailure(wpa_s, reason);
+}
+
+void wpas_hidl_notify_p2p_group_started(
+    struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, int persistent,
+    int client, const u8 *ip)
+{
+	if (!wpa_s || !ssid || !ip)
+		return;
+
+	wpa_printf(
+	    MSG_DEBUG, "Notifying P2P Group start to hidl control: %d",
+	    ssid->id);
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager)
+		return;
+
+	hidl_manager->notifyP2pGroupStarted(
+	    wpa_s, ssid, persistent, client, ip);
+}
+
+void wpas_hidl_notify_p2p_group_removed(
+    struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, const char *role)
+{
+	if (!wpa_s || !ssid || !role)
+		return;
+
+	wpa_printf(
+	    MSG_DEBUG, "Notifying P2P Group removed to hidl control: %d",
+	    ssid->id);
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager)
+		return;
+
+	hidl_manager->notifyP2pGroupRemoved(wpa_s, ssid, role);
+}
+
+void wpas_hidl_notify_p2p_invitation_received(
+    struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
+    const u8 *bssid, int id, int op_freq)
+{
+	if (!wpa_s || !sa || !go_dev_addr || !bssid)
+		return;
+
+	wpa_printf(
+	    MSG_DEBUG,
+	    "Notifying P2P invitation received to hidl control: %d " MACSTR, id,
+	    MAC2STR(bssid));
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager)
+		return;
+
+	hidl_manager->notifyP2pInvitationReceived(
+	    wpa_s, sa, go_dev_addr, bssid, id, op_freq);
+}
+
+void wpas_hidl_notify_p2p_invitation_result(
+    struct wpa_supplicant *wpa_s, int status, const u8 *bssid)
+{
+	if (!wpa_s || !bssid)
+		return;
+
+	wpa_printf(
+	    MSG_DEBUG,
+	    "Notifying P2P invitation result to hidl control: " MACSTR,
+	    MAC2STR(bssid));
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager)
+		return;
+
+	hidl_manager->notifyP2pInvitationResult(wpa_s, status, bssid);
+}
+
+void wpas_hidl_notify_p2p_provision_discovery(
+    struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
+    enum p2p_prov_disc_status status, u16 config_methods,
+    unsigned int generated_pin)
+{
+	if (!wpa_s || !dev_addr)
+		return;
+
+	wpa_printf(
+	    MSG_DEBUG,
+	    "Notifying P2P provision discovery to hidl control " MACSTR,
+	    MAC2STR(dev_addr));
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager)
+		return;
+
+	hidl_manager->notifyP2pProvisionDiscovery(
+	    wpa_s, dev_addr, request, status, config_methods, generated_pin);
+}
+
+void wpas_hidl_notify_p2p_sd_response(
+    struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
+    const u8 *tlvs, size_t tlvs_len)
+{
+	if (!wpa_s || !sa || !tlvs)
+		return;
+
+	wpa_printf(
+	    MSG_DEBUG,
+	    "Notifying P2P service discovery response to hidl control " MACSTR,
+	    MAC2STR(sa));
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager)
+		return;
+
+	hidl_manager->notifyP2pSdResponse(
+	    wpa_s, sa, update_indic, tlvs, tlvs_len);
+}
+
+void wpas_hidl_notify_ap_sta_authorized(
+    struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
+{
+	if (!wpa_s || !sta || !p2p_dev_addr)
+		return;
+
+	wpa_printf(
+	    MSG_DEBUG,
+	    "Notifying P2P AP STA authorized to hidl control " MACSTR,
+	    MAC2STR(sta));
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager)
+		return;
+
+	hidl_manager->notifyApStaAuthorized(wpa_s, sta, p2p_dev_addr);
+}
+
+void wpas_hidl_notify_ap_sta_deauthorized(
+    struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
+{
+	if (!wpa_s || !sta || !p2p_dev_addr)
+		return;
+
+	wpa_printf(
+	    MSG_DEBUG,
+	    "Notifying P2P AP STA deauthorized to hidl control " MACSTR,
+	    MAC2STR(sta));
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager)
+		return;
+
+	hidl_manager->notifyApStaDeauthorized(wpa_s, sta, p2p_dev_addr);
+}
diff --git a/wpa_supplicant/hidl/hidl.h b/wpa_supplicant/hidl/hidl.h
index e191c26..dc88a11 100644
--- a/wpa_supplicant/hidl/hidl.h
+++ b/wpa_supplicant/hidl/hidl.h
@@ -53,6 +53,42 @@
     uint16_t error_indication);
 void wpas_hidl_notify_wps_event_success(struct wpa_supplicant *wpa_s);
 void wpas_hidl_notify_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s);
+void wpas_hidl_notify_p2p_device_found(
+    struct wpa_supplicant *wpa_s, const u8 *addr,
+    const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
+    u8 peer_wfd_device_info_len);
+void wpas_hidl_notify_p2p_device_lost(
+    struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr);
+void wpas_hidl_notify_p2p_find_stopped(struct wpa_supplicant *wpa_s);
+void wpas_hidl_notify_p2p_go_neg_req(
+    struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
+    u8 go_intent);
+void wpas_hidl_notify_p2p_go_neg_completed(
+    struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res);
+void wpas_hidl_notify_p2p_group_formation_failure(
+    struct wpa_supplicant *wpa_s, const char *reason);
+void wpas_hidl_notify_p2p_group_started(
+    struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, int persistent,
+    int client, const u8 *ip);
+void wpas_hidl_notify_p2p_group_removed(
+    struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid,
+    const char *role);
+void wpas_hidl_notify_p2p_invitation_received(
+    struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
+    const u8 *bssid, int id, int op_freq);
+void wpas_hidl_notify_p2p_invitation_result(
+    struct wpa_supplicant *wpa_s, int status, const u8 *bssid);
+void wpas_hidl_notify_p2p_provision_discovery(
+    struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
+    enum p2p_prov_disc_status status, u16 config_methods,
+    unsigned int generated_pin);
+void wpas_hidl_notify_p2p_sd_response(
+    struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
+    const u8 *tlvs, size_t tlvs_len);
+void wpas_hidl_notify_ap_sta_authorized(
+    struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr);
+void wpas_hidl_notify_ap_sta_deauthorized(
+    struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr);
 #else   // CONFIG_CTRL_IFACE_HIDL
 static inline int wpas_hidl_register_interface(struct wpa_supplicant *wpa_s)
 {
@@ -111,6 +147,67 @@
 static void wpas_hidl_notify_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s)
 {
 }
+static void wpas_hidl_notify_p2p_device_found(
+    struct wpa_supplicant *wpa_s, const u8 *addr,
+    const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
+    u8 peer_wfd_device_info_len);
+{
+}
+static void wpas_hidl_notify_p2p_device_lost(
+    struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr)
+{
+}
+static void wpas_hidl_notify_p2p_find_stopped(struct wpa_supplicant *wpa_s) {}
+static void wpas_hidl_notify_p2p_go_neg_req(
+    struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
+    u8 go_intent)
+{
+}
+static void wpas_hidl_notify_p2p_go_neg_completed(
+    struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res)
+{
+}
+static void wpas_hidl_notify_p2p_group_formation_failure(
+    struct wpa_supplicant *wpa_s, const char *reason)
+{
+}
+static void wpas_hidl_notify_p2p_group_started(
+    struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, int persistent,
+    int client, const u8 *ip)
+{
+}
+static void wpas_hidl_notify_p2p_group_removed(
+    struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, const char *role)
+{
+}
+static void wpas_hidl_notify_p2p_invitation_received(
+    struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
+    const u8 *bssid, int id, int op_freq)
+{
+}
+static void wpas_hidl_notify_p2p_invitation_result(
+    struct wpa_supplicant *wpa_s, int status, const u8 *bssid)
+{
+}
+static void wpas_hidl_notify_p2p_provision_discovery(
+    struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
+    enum p2p_prov_disc_status status, u16 config_methods,
+    unsigned int generated_pin)
+{
+}
+static void wpas_hidl_notify_p2p_sd_response(
+    struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
+    const u8 *tlvs, size_t tlvs_len)
+{
+}
+static void wpas_hidl_notify_ap_sta_authorized(
+    struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
+{
+}
+static void wpas_hidl_notify_ap_sta_deauthorized(
+    struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
+{
+}
 #endif  // CONFIG_CTRL_IFACE_HIDL
 
 #ifdef _cplusplus
diff --git a/wpa_supplicant/hidl/hidl_manager.cpp b/wpa_supplicant/hidl/hidl_manager.cpp
index 2490151..81dfd8c 100644
--- a/wpa_supplicant/hidl/hidl_manager.cpp
+++ b/wpa_supplicant/hidl/hidl_manager.cpp
@@ -12,6 +12,8 @@
 #include "hidl_manager.h"
 
 namespace {
+constexpr uint8_t kWfdDeviceInfoLen = 8;
+
 /**
  * Check if the provided |wpa_supplicant| structure represents a P2P iface or
  * not.
@@ -344,29 +346,28 @@
 	if (!wpa_s)
 		return 1;
 
-	// Using the corresponding ifname as key to our object map.
-	const std::string ifname(wpa_s->ifname);
-
 	if (isP2pIface(wpa_s)) {
 		if (addHidlObjectToMap<P2pIface>(
-			ifname, new P2pIface(wpa_s->global, wpa_s->ifname),
+			wpa_s->ifname,
+			new P2pIface(wpa_s->global, wpa_s->ifname),
 			p2p_iface_object_map_))
 			return 1;
-		p2p_iface_callbacks_map_[ifname] =
+		p2p_iface_callbacks_map_[wpa_s->ifname] =
 		    std::vector<android::sp<ISupplicantP2pIfaceCallback>>();
 	} else {
 		if (addHidlObjectToMap<StaIface>(
-			ifname, new StaIface(wpa_s->global, wpa_s->ifname),
+			wpa_s->ifname,
+			new StaIface(wpa_s->global, wpa_s->ifname),
 			sta_iface_object_map_))
 			return 1;
-		sta_iface_callbacks_map_[ifname] =
+		sta_iface_callbacks_map_[wpa_s->ifname] =
 		    std::vector<android::sp<ISupplicantStaIfaceCallback>>();
 	}
 
 	// Invoke the |onInterfaceCreated| method on all registered callbacks.
 	callWithEachSupplicantCallback(std::bind(
 	    &ISupplicantCallback::onInterfaceCreated, std::placeholders::_1,
-	    ifname));
+	    wpa_s->ifname));
 	return 0;
 }
 
@@ -382,20 +383,20 @@
 	if (!wpa_s)
 		return 1;
 
-	const std::string ifname(wpa_s->ifname);
-
 	if (isP2pIface(wpa_s)) {
-		if (removeHidlObjectFromMap(ifname, p2p_iface_object_map_))
+		if (removeHidlObjectFromMap(
+			wpa_s->ifname, p2p_iface_object_map_))
 			return 1;
 		if (removeAllIfaceCallbackHidlObjectsFromMap(
-			ifname, p2p_iface_callbacks_map_)) {
+			wpa_s->ifname, p2p_iface_callbacks_map_)) {
 			return 1;
 		}
 	} else {
-		if (removeHidlObjectFromMap(ifname, sta_iface_object_map_))
+		if (removeHidlObjectFromMap(
+			wpa_s->ifname, sta_iface_object_map_))
 			return 1;
 		if (removeAllIfaceCallbackHidlObjectsFromMap(
-			ifname, sta_iface_callbacks_map_)) {
+			wpa_s->ifname, sta_iface_callbacks_map_)) {
 			return 1;
 		}
 	}
@@ -403,7 +404,7 @@
 	// Invoke the |onInterfaceRemoved| method on all registered callbacks.
 	callWithEachSupplicantCallback(std::bind(
 	    &ISupplicantCallback::onInterfaceRemoved, std::placeholders::_1,
-	    ifname));
+	    wpa_s->ifname));
 	return 0;
 }
 
@@ -522,15 +523,11 @@
 	if (!wpa_s)
 		return 1;
 
-	const std::string ifname(wpa_s->ifname);
-	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+	    sta_iface_object_map_.end())
 		return 1;
 
 	// Invoke the |onStateChanged| method on all registered callbacks.
-	ISupplicantStaIfaceCallback::State hidl_state =
-	    static_cast<ISupplicantStaIfaceCallback::State>(wpa_s->wpa_state);
-	std::array<uint8_t, ETH_ALEN> hidl_bssid;
-	os_memcpy(hidl_bssid.data(), wpa_s->bssid, ETH_ALEN);
 	uint32_t hidl_network_id = UINT32_MAX;
 	std::vector<uint8_t> hidl_ssid;
 	if (wpa_s->current_ssid) {
@@ -542,8 +539,10 @@
 	callWithEachStaIfaceCallback(
 	    wpa_s->ifname, std::bind(
 			       &ISupplicantStaIfaceCallback::onStateChanged,
-			       std::placeholders::_1, hidl_state, hidl_bssid,
-			       hidl_network_id, hidl_ssid));
+			       std::placeholders::_1,
+			       static_cast<ISupplicantStaIfaceCallback::State>(
+				   wpa_s->wpa_state),
+			       wpa_s->bssid, hidl_network_id, hidl_ssid));
 	return 0;
 }
 
@@ -589,8 +588,8 @@
 	if (!wpa_s || !bssid || !result || !anqp)
 		return;
 
-	const std::string ifname(wpa_s->ifname);
-	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+	    sta_iface_object_map_.end())
 		return;
 
 	ISupplicantStaIfaceCallback::AnqpData hidl_anqp_data;
@@ -619,13 +618,11 @@
 		    convertWpaBufToVector(anqp->hs20_osu_providers_list);
 	}
 
-	std::array<uint8_t, ETH_ALEN> hidl_bssid;
-	os_memcpy(hidl_bssid.data(), bssid, ETH_ALEN);
 	callWithEachStaIfaceCallback(
 	    wpa_s->ifname, std::bind(
 			       &ISupplicantStaIfaceCallback::onAnqpQueryDone,
-			       std::placeholders::_1, hidl_bssid,
-			       hidl_anqp_data, hidl_hs20_anqp_data));
+			       std::placeholders::_1, bssid, hidl_anqp_data,
+			       hidl_hs20_anqp_data));
 }
 
 /**
@@ -644,18 +641,16 @@
 	if (!wpa_s || !bssid || !file_name || !image)
 		return;
 
-	const std::string ifname(wpa_s->ifname);
-	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+	    sta_iface_object_map_.end())
 		return;
 
-	std::vector<uint8_t> hidl_image(image, image + image_length);
-	std::array<uint8_t, ETH_ALEN> hidl_bssid;
-	os_memcpy(hidl_bssid.data(), bssid, ETH_ALEN);
 	callWithEachStaIfaceCallback(
 	    wpa_s->ifname,
 	    std::bind(
 		&ISupplicantStaIfaceCallback::onHs20IconQueryDone,
-		std::placeholders::_1, hidl_bssid, file_name, hidl_image));
+		std::placeholders::_1, bssid, file_name,
+		std::vector<uint8_t>(image, image + image_length)));
 }
 
 /**
@@ -672,8 +667,8 @@
 	if (!wpa_s || !url)
 		return;
 
-	const std::string ifname(wpa_s->ifname);
-	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+	    sta_iface_object_map_.end())
 		return;
 
 	ISupplicantStaIfaceCallback::OsuMethod hidl_osu_method = {};
@@ -706,8 +701,8 @@
 	if (!wpa_s || !url)
 		return;
 
-	const std::string ifname(wpa_s->ifname);
-	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+	    sta_iface_object_map_.end())
 		return;
 
 	callWithEachStaIfaceCallback(
@@ -729,22 +724,20 @@
 	if (!wpa_s)
 		return;
 
-	const std::string ifname(wpa_s->ifname);
-	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+	    sta_iface_object_map_.end())
 		return;
 
 	const u8 *bssid = wpa_s->bssid;
 	if (is_zero_ether_addr(bssid)) {
 		bssid = wpa_s->pending_bssid;
 	}
-	std::array<uint8_t, ETH_ALEN> hidl_bssid;
-	os_memcpy(hidl_bssid.data(), bssid, ETH_ALEN);
 
 	callWithEachStaIfaceCallback(
 	    wpa_s->ifname,
 	    std::bind(
 		&ISupplicantStaIfaceCallback::onDisconnected,
-		std::placeholders::_1, hidl_bssid, wpa_s->disconnect_reason < 0,
+		std::placeholders::_1, bssid, wpa_s->disconnect_reason < 0,
 		wpa_s->disconnect_reason));
 }
 
@@ -760,22 +753,20 @@
 	if (!wpa_s)
 		return;
 
-	const std::string ifname(wpa_s->ifname);
-	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+	    sta_iface_object_map_.end())
 		return;
 
 	const u8 *bssid = wpa_s->bssid;
 	if (is_zero_ether_addr(bssid)) {
 		bssid = wpa_s->pending_bssid;
 	}
-	std::array<uint8_t, ETH_ALEN> hidl_bssid;
-	os_memcpy(hidl_bssid.data(), bssid, ETH_ALEN);
 
 	callWithEachStaIfaceCallback(
 	    wpa_s->ifname,
 	    std::bind(
 		&ISupplicantStaIfaceCallback::onAssociationRejected,
-		std::placeholders::_1, hidl_bssid, wpa_s->assoc_status_code));
+		std::placeholders::_1, bssid, wpa_s->assoc_status_code));
 }
 
 void HidlManager::notifyWpsEventFail(
@@ -785,25 +776,19 @@
 	if (!wpa_s || !peer_macaddr)
 		return;
 
-	const std::string ifname(wpa_s->ifname);
-	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+	    sta_iface_object_map_.end())
 		return;
 
-	std::array<uint8_t, ETH_ALEN> hidl_bssid;
-	os_memcpy(hidl_bssid.data(), peer_macaddr, ETH_ALEN);
-
-	ISupplicantStaIfaceCallback::WpsConfigError hidl_config_error =
-	    static_cast<ISupplicantStaIfaceCallback::WpsConfigError>(
-		config_error);
-	ISupplicantStaIfaceCallback::WpsErrorIndication hidl_error_indication =
-	    static_cast<ISupplicantStaIfaceCallback::WpsErrorIndication>(
-		error_indication);
-
 	callWithEachStaIfaceCallback(
-	    wpa_s->ifname, std::bind(
-			       &ISupplicantStaIfaceCallback::onWpsEventFail,
-			       std::placeholders::_1, hidl_bssid,
-			       hidl_config_error, hidl_error_indication));
+	    wpa_s->ifname,
+	    std::bind(
+		&ISupplicantStaIfaceCallback::onWpsEventFail,
+		std::placeholders::_1, peer_macaddr,
+		static_cast<ISupplicantStaIfaceCallback::WpsConfigError>(
+		    config_error),
+		static_cast<ISupplicantStaIfaceCallback::WpsErrorIndication>(
+		    error_indication)));
 }
 
 void HidlManager::notifyWpsEventSuccess(struct wpa_supplicant *wpa_s)
@@ -811,8 +796,8 @@
 	if (!wpa_s)
 		return;
 
-	const std::string ifname(wpa_s->ifname);
-	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+	    sta_iface_object_map_.end())
 		return;
 
 	callWithEachStaIfaceCallback(
@@ -826,8 +811,8 @@
 	if (!wpa_s)
 		return;
 
-	const std::string ifname(wpa_s->ifname);
-	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+	    sta_iface_object_map_.end())
 		return;
 
 	callWithEachStaIfaceCallback(
@@ -837,14 +822,309 @@
 		std::placeholders::_1));
 }
 
+void HidlManager::notifyP2pDeviceFound(
+    struct wpa_supplicant *wpa_s, const u8 *addr,
+    const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
+    u8 peer_wfd_device_info_len)
+{
+	if (!wpa_s || !addr || !info || !peer_wfd_device_info)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+	    p2p_iface_object_map_.end())
+		return;
+
+	if (peer_wfd_device_info_len != kWfdDeviceInfoLen) {
+		wpa_printf(
+		    MSG_ERROR, "Unexpected WFD device info len: %d",
+		    peer_wfd_device_info_len);
+	}
+
+	callWithEachP2pIfaceCallback(
+	    wpa_s->ifname,
+	    std::bind(
+		&ISupplicantP2pIfaceCallback::onDeviceFound,
+		std::placeholders::_1, addr, info->p2p_device_addr,
+		info->pri_dev_type, info->device_name, info->config_methods,
+		info->dev_capab, info->group_capab, peer_wfd_device_info));
+}
+
+void HidlManager::notifyP2pDeviceLost(
+    struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr)
+{
+	if (!wpa_s || !p2p_device_addr)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+	    p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+	    wpa_s->ifname, std::bind(
+			       &ISupplicantP2pIfaceCallback::onDeviceLost,
+			       std::placeholders::_1, p2p_device_addr));
+}
+
+void HidlManager::notifyP2pFindStopped(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+	    p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+	    wpa_s->ifname, std::bind(
+			       &ISupplicantP2pIfaceCallback::onFindStopped,
+			       std::placeholders::_1));
+}
+
+void HidlManager::notifyP2pGoNegReq(
+    struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
+    u8 /* go_intent */)
+{
+	if (!wpa_s || !src_addr)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+	    p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+	    wpa_s->ifname,
+	    std::bind(
+		&ISupplicantP2pIfaceCallback::onGoNegotiationRequest,
+		std::placeholders::_1, src_addr,
+		static_cast<ISupplicantP2pIfaceCallback::WpsDevPasswordId>(
+		    dev_passwd_id)));
+}
+
+void HidlManager::notifyP2pGoNegCompleted(
+    struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res)
+{
+	if (!wpa_s || !res)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+	    p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+	    wpa_s->ifname,
+	    std::bind(
+		&ISupplicantP2pIfaceCallback::onGoNegotiationCompleted,
+		std::placeholders::_1,
+		static_cast<ISupplicantP2pIfaceCallback::P2pStatusCode>(
+		    res->status)));
+}
+
+void HidlManager::notifyP2pGroupFormationFailure(
+    struct wpa_supplicant *wpa_s, const char *reason)
+{
+	if (!wpa_s || !reason)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+	    p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+	    wpa_s->ifname,
+	    std::bind(
+		&ISupplicantP2pIfaceCallback::onGroupFormationFailure,
+		std::placeholders::_1, reason));
+}
+
+void HidlManager::notifyP2pGroupStarted(
+    struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
+    int persistent, int client, const u8 *ip)
+{
+	if (!wpa_group_s || !wpa_group_s->parent || !ssid || !ip)
+		return;
+
+	// For group notifications, need to use the parent iface for callbacks.
+	struct wpa_supplicant *wpa_s = wpa_group_s->parent;
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+	    p2p_iface_object_map_.end())
+		return;
+
+	uint32_t hidl_freq = wpa_group_s->current_bss
+				 ? wpa_group_s->current_bss->freq
+				 : wpa_group_s->assoc_freq;
+	std::array<uint8_t, 32> hidl_psk;
+	if (ssid->psk_set) {
+		os_memcpy(hidl_psk.data(), ssid->psk, 32);
+	}
+	bool hidl_is_go = (client == 0 ? true : false);
+	bool hidl_is_persistent = (persistent == 1 ? true : false);
+
+	callWithEachP2pIfaceCallback(
+	    wpa_s->ifname,
+	    std::bind(
+		&ISupplicantP2pIfaceCallback::onGroupStarted,
+		std::placeholders::_1, wpa_group_s->ifname, hidl_is_go,
+		std::vector<uint8_t>{ssid->ssid, ssid->ssid + ssid->ssid_len},
+		hidl_freq, hidl_psk, ssid->passphrase, wpa_group_s->go_dev_addr,
+		hidl_is_persistent));
+}
+
+void HidlManager::notifyP2pGroupRemoved(
+    struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
+    const char *role)
+{
+	if (!wpa_group_s || !wpa_group_s->parent || !ssid || !role)
+		return;
+
+	// For group notifications, need to use the parent iface for callbacks.
+	struct wpa_supplicant *wpa_s = wpa_group_s->parent;
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+	    p2p_iface_object_map_.end())
+		return;
+
+	bool hidl_is_go = (std::string(role) == "GO");
+
+	callWithEachP2pIfaceCallback(
+	    wpa_s->ifname,
+	    std::bind(
+		&ISupplicantP2pIfaceCallback::onGroupRemoved,
+		std::placeholders::_1, wpa_group_s->ifname, hidl_is_go));
+}
+
+void HidlManager::notifyP2pInvitationReceived(
+    struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
+    const u8 *bssid, int id, int op_freq)
+{
+	if (!wpa_s || !sa || !go_dev_addr || !bssid)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+	    p2p_iface_object_map_.end())
+		return;
+
+	SupplicantNetworkId hidl_network_id;
+	if (id < 0) {
+		hidl_network_id = UINT32_MAX;
+	}
+	hidl_network_id = id;
+
+	callWithEachP2pIfaceCallback(
+	    wpa_s->ifname,
+	    std::bind(
+		&ISupplicantP2pIfaceCallback::onInvitationReceived,
+		std::placeholders::_1, sa, go_dev_addr, bssid, hidl_network_id,
+		op_freq));
+}
+
+void HidlManager::notifyP2pInvitationResult(
+    struct wpa_supplicant *wpa_s, int status, const u8 *bssid)
+{
+	if (!wpa_s || !bssid)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+	    p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+	    wpa_s->ifname,
+	    std::bind(
+		&ISupplicantP2pIfaceCallback::onInvitationResult,
+		std::placeholders::_1, bssid,
+		static_cast<ISupplicantP2pIfaceCallback::P2pStatusCode>(
+		    status)));
+}
+
+void HidlManager::notifyP2pProvisionDiscovery(
+    struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
+    enum p2p_prov_disc_status status, u16 config_methods,
+    unsigned int generated_pin)
+{
+	if (!wpa_s || !dev_addr)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+	    p2p_iface_object_map_.end())
+		return;
+
+	std::string hidl_generated_pin;
+	if (generated_pin > 0) {
+		hidl_generated_pin.reserve(9);
+		os_snprintf(
+		    &hidl_generated_pin[0], hidl_generated_pin.size(), "%08d",
+		    generated_pin);
+	}
+	bool hidl_is_request = (request == 1 ? true : false);
+
+	callWithEachP2pIfaceCallback(
+	    wpa_s->ifname,
+	    std::bind(
+		&ISupplicantP2pIfaceCallback::onProvisionDiscoveryCompleted,
+		std::placeholders::_1, dev_addr, hidl_is_request,
+		static_cast<ISupplicantP2pIfaceCallback::P2pProvDiscStatusCode>(
+		    status),
+		config_methods, hidl_generated_pin));
+}
+
+void HidlManager::notifyP2pSdResponse(
+    struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
+    const u8 *tlvs, size_t tlvs_len)
+{
+	if (!wpa_s || !sa || !tlvs)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+	    p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+	    wpa_s->ifname,
+	    std::bind(
+		&ISupplicantP2pIfaceCallback::onServiceDiscoveryResponse,
+		std::placeholders::_1, sa, update_indic,
+		std::vector<uint8_t>{tlvs, tlvs + tlvs_len}));
+}
+
+void HidlManager::notifyApStaAuthorized(
+    struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
+{
+	if (!wpa_s || !sta || !p2p_dev_addr)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+	    p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+	    wpa_s->ifname, std::bind(
+			       &ISupplicantP2pIfaceCallback::onStaAuthorized,
+			       std::placeholders::_1, sta, p2p_dev_addr));
+}
+
+void HidlManager::notifyApStaDeauthorized(
+    struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
+{
+	if (!wpa_s || !sta || !p2p_dev_addr)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+	    p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+	    wpa_s->ifname, std::bind(
+			       &ISupplicantP2pIfaceCallback::onStaDeauthorized,
+			       std::placeholders::_1, sta, p2p_dev_addr));
+}
+
 void HidlManager::notifyExtRadioWorkStart(
     struct wpa_supplicant *wpa_s, uint32_t id)
 {
 	if (!wpa_s)
 		return;
 
-	const std::string ifname(wpa_s->ifname);
-	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+	    sta_iface_object_map_.end())
 		return;
 
 	callWithEachStaIfaceCallback(
@@ -860,8 +1140,8 @@
 	if (!wpa_s)
 		return;
 
-	const std::string ifname(wpa_s->ifname);
-	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+	    sta_iface_object_map_.end())
 		return;
 
 	callWithEachStaIfaceCallback(
diff --git a/wpa_supplicant/hidl/hidl_manager.h b/wpa_supplicant/hidl/hidl_manager.h
index 14fd726..d723ad9 100644
--- a/wpa_supplicant/hidl/hidl_manager.h
+++ b/wpa_supplicant/hidl/hidl_manager.h
@@ -81,6 +81,44 @@
 	    uint16_t config_error, uint16_t error_indication);
 	void notifyWpsEventSuccess(struct wpa_supplicant *wpa_s);
 	void notifyWpsEventPbcOverlap(struct wpa_supplicant *wpa_s);
+	void notifyP2pDeviceFound(
+	    struct wpa_supplicant *wpa_s, const u8 *addr,
+	    const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
+	    u8 peer_wfd_device_info_len);
+	void notifyP2pDeviceLost(
+	    struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr);
+	void notifyP2pFindStopped(struct wpa_supplicant *wpa_s);
+	void notifyP2pGoNegReq(
+	    struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
+	    u8 go_intent);
+	void notifyP2pGoNegCompleted(
+	    struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res);
+	void notifyP2pGroupFormationFailure(
+	    struct wpa_supplicant *wpa_s, const char *reason);
+	void notifyP2pGroupStarted(
+	    struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
+	    int persistent, int client, const u8 *ip);
+	void notifyP2pGroupRemoved(
+	    struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
+	    const char *role);
+	void notifyP2pInvitationReceived(
+	    struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
+	    const u8 *bssid, int id, int op_freq);
+	void notifyP2pInvitationResult(
+	    struct wpa_supplicant *wpa_s, int status, const u8 *bssid);
+	void notifyP2pProvisionDiscovery(
+	    struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
+	    enum p2p_prov_disc_status status, u16 config_methods,
+	    unsigned int generated_pin);
+	void notifyP2pSdResponse(
+	    struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
+	    const u8 *tlvs, size_t tlvs_len);
+	void notifyApStaAuthorized(
+	    struct wpa_supplicant *wpa_s, const u8 *sta,
+	    const u8 *p2p_dev_addr);
+	void notifyApStaDeauthorized(
+	    struct wpa_supplicant *wpa_s, const u8 *sta,
+	    const u8 *p2p_dev_addr);
 
 	// Methods called from hidl objects.
 	void notifyExtRadioWorkStart(struct wpa_supplicant *wpa_s, uint32_t id);
diff --git a/wpa_supplicant/hidl/p2p_iface.cpp b/wpa_supplicant/hidl/p2p_iface.cpp
index 706ac1a..4ddb34a 100644
--- a/wpa_supplicant/hidl/p2p_iface.cpp
+++ b/wpa_supplicant/hidl/p2p_iface.cpp
@@ -664,7 +664,7 @@
 	if (provision_method == WpsProvisionMethod::DISPLAY &&
 	    pre_selected_pin.empty()) {
 		pin_ret.reserve(9);
-		snprintf(&pin_ret[0], pin_ret.size(), "%08d", new_pin);
+		os_snprintf(&pin_ret[0], pin_ret.size(), "%08d", new_pin);
 	}
 	return {{SupplicantStatusCode::SUCCESS, ""}, pin_ret};
 }
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 3fdb36f..f94873d 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -591,19 +591,27 @@
 {
 	/* Notify P2P find has stopped */
 	wpas_dbus_signal_p2p_find_stopped(wpa_s);
+
+	wpas_hidl_notify_p2p_find_stopped(wpa_s);
 }
 
 
 void wpas_notify_p2p_device_found(struct wpa_supplicant *wpa_s,
-				  const u8 *dev_addr, int new_device)
+				  const u8 *addr, const struct p2p_peer_info *info,
+				  const u8* peer_wfd_device_info, u8 peer_wfd_device_info_len,
+				  int new_device)
 {
 	if (new_device) {
 		/* Create the new peer object */
-		wpas_dbus_register_peer(wpa_s, dev_addr);
+		wpas_dbus_register_peer(wpa_s, info->p2p_device_addr);
 	}
 
 	/* Notify a new peer has been detected*/
-	wpas_dbus_signal_peer_device_found(wpa_s, dev_addr);
+	wpas_dbus_signal_peer_device_found(wpa_s, info->p2p_device_addr);
+
+	wpas_hidl_notify_p2p_device_found(wpa_s, addr, info,
+					  peer_wfd_device_info,
+					  peer_wfd_device_info_len);
 }
 
 
@@ -614,6 +622,8 @@
 
 	/* Create signal on interface object*/
 	wpas_dbus_signal_peer_device_lost(wpa_s, dev_addr);
+
+	wpas_hidl_notify_p2p_device_lost(wpa_s, dev_addr);
 }
 
 
@@ -624,6 +634,8 @@
 	wpas_dbus_signal_p2p_group_removed(wpa_s, role);
 
 	wpas_dbus_unregister_p2p_group(wpa_s, ssid);
+
+	wpas_hidl_notify_p2p_group_removed(wpa_s, ssid, role);
 }
 
 
@@ -631,6 +643,8 @@
 				const u8 *src, u16 dev_passwd_id, u8 go_intent)
 {
 	wpas_dbus_signal_p2p_go_neg_req(wpa_s, src, dev_passwd_id, go_intent);
+
+	wpas_hidl_notify_p2p_go_neg_req(wpa_s, src, dev_passwd_id, go_intent);
 }
 
 
@@ -638,6 +652,8 @@
 				      struct p2p_go_neg_results *res)
 {
 	wpas_dbus_signal_p2p_go_neg_resp(wpa_s, res);
+
+	wpas_hidl_notify_p2p_go_neg_completed(wpa_s, res);
 }
 
 
@@ -645,6 +661,8 @@
 				       int status, const u8 *bssid)
 {
 	wpas_dbus_signal_p2p_invitation_result(wpa_s, status, bssid);
+
+	wpas_hidl_notify_p2p_invitation_result(wpa_s, status, bssid);
 }
 
 
@@ -664,6 +682,9 @@
 {
 	wpas_dbus_signal_p2p_sd_response(wpa_s, sa, update_indic,
 					 tlvs, tlvs_len);
+
+	wpas_hidl_notify_p2p_sd_response(wpa_s, sa, update_indic,
+					 tlvs, tlvs_len);
 }
 
 
@@ -689,6 +710,11 @@
 	wpas_dbus_signal_p2p_provision_discovery(wpa_s, dev_addr, request,
 						 status, config_methods,
 						 generated_pin);
+
+	wpas_hidl_notify_p2p_provision_discovery(wpa_s, dev_addr, request,
+						 status, config_methods,
+						 generated_pin);
+
 }
 
 
@@ -700,6 +726,8 @@
 	wpas_dbus_register_p2p_group(wpa_s, ssid);
 
 	wpas_dbus_signal_p2p_group_started(wpa_s, client, persistent, ip);
+
+	wpas_hidl_notify_p2p_group_started(wpa_s, ssid, persistent, client, ip);
 }
 
 
@@ -708,6 +736,8 @@
 {
 	/* Notify a group formation failed */
 	wpas_dbus_signal_p2p_group_formation_failure(wpa_s, reason);
+
+	wpas_hidl_notify_p2p_group_formation_failure(wpa_s, reason);
 }
 
 
@@ -725,6 +755,9 @@
 	/* Notify a P2P Invitation Request */
 	wpas_dbus_signal_p2p_invitation_received(wpa_s, sa, go_dev_addr, bssid,
 						 id, op_freq);
+
+	wpas_hidl_notify_p2p_invitation_received(wpa_s, sa, go_dev_addr, bssid,
+						 id, op_freq);
 }
 
 #endif /* CONFIG_P2P */
@@ -747,6 +780,8 @@
 
 	/* Notify listeners a new station has been authorized */
 	wpas_dbus_signal_sta_authorized(wpa_s, sta);
+
+	wpas_hidl_notify_ap_sta_authorized(wpa_s, sta, p2p_dev_addr);
 }
 
 
@@ -765,6 +800,8 @@
 
 	/* Notify listeners a station has been deauthorized */
 	wpas_dbus_signal_sta_deauthorized(wpa_s, sta);
+
+	wpas_hidl_notify_ap_sta_deauthorized(wpa_s, sta, p2p_dev_addr);
 }
 
 
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 2590e9a..e2b63b5 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -89,7 +89,9 @@
 				const u8 *p2p_dev_addr);
 void wpas_notify_p2p_find_stopped(struct wpa_supplicant *wpa_s);
 void wpas_notify_p2p_device_found(struct wpa_supplicant *wpa_s,
-				  const u8 *dev_addr, int new_device);
+				 const u8 *addr, const struct p2p_peer_info *info,
+				 const u8* peer_wfd_device_info, u8 peer_wfd_device_info_len,
+				 int new_device);
 void wpas_notify_p2p_device_lost(struct wpa_supplicant *wpa_s,
 				 const u8 *dev_addr);
 void wpas_notify_p2p_group_removed(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 2da92bf..f58808f 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -2289,6 +2289,8 @@
 			   const struct p2p_peer_info *info,
 			   int new_device)
 {
+	u8 *wfd_dev_info = NULL;
+	u8 wfd_dev_info_len = 0;
 #ifndef CONFIG_NO_STDOUT_DEBUG
 	struct wpa_supplicant *wpa_s = ctx;
 	char devtype[WPS_DEV_TYPE_BUFSIZE];
@@ -2297,6 +2299,12 @@
 #ifdef CONFIG_WIFI_DISPLAY
 	wfd_dev_info_hex = wifi_display_subelem_hex(info->wfd_subelems,
 						    WFD_SUBELEM_DEVICE_INFO);
+	if (wfd_dev_info_hex) {
+		wfd_dev_info_len = strlen(wfd_dev_info_hex) / 2;
+		wfd_dev_info = os_zalloc(wfd_dev_info_len);
+		// Only used for notification, so not handling error.
+		hexstr2bin(wfd_dev_info_hex, wfd_dev_info, wfd_dev_info_len);
+	}
 #endif /* CONFIG_WIFI_DISPLAY */
 
 	if (info->p2ps_instance) {
@@ -2363,7 +2371,9 @@
 	os_free(wfd_dev_info_hex);
 #endif /* CONFIG_NO_STDOUT_DEBUG */
 
-	wpas_notify_p2p_device_found(ctx, info->p2p_device_addr, new_device);
+	wpas_notify_p2p_device_found(ctx, addr, info, wfd_dev_info,
+				     wfd_dev_info_len, new_device);
+	os_free(wfd_dev_info);
 }