diff mbox series

[v3,02/25] P2P: Allow P2P IE to be added into NAN SDFs

Message ID 1722850403-8852-3-git-send-email-quic_shivbara@quicinc.com
State Accepted
Headers show
Series Add support for P2P2 | expand

Commit Message

Shivani Baranwal Aug. 5, 2024, 9:33 a.m. UTC
Extend the NAN Subscribe and Publish methods to allow p2p=1 to be
specified to include P2P attributes in a P2P IE to be added into the NAN
Element Container attribute.

Signed-off-by: Shivani Baranwal <quic_shivbara@quicinc.com>
---
 hostapd/ctrl_iface.c            | 16 ++++++++++++++--
 src/ap/nan_usd_ap.c             |  8 ++++----
 src/ap/nan_usd_ap.h             |  4 ++--
 src/common/ieee802_11_defs.h    |  1 +
 src/common/nan_de.c             |  7 +++++--
 src/common/nan_de.h             |  4 ++--
 src/p2p/p2p.c                   | 40 ++++++++++++++++++++++++++++++++++++++++
 src/p2p/p2p.h                   |  1 +
 src/p2p/p2p_build.c             | 18 ++++++++++++++++++
 src/p2p/p2p_i.h                 |  2 ++
 wpa_supplicant/ctrl_iface.c     | 16 ++++++++++++++--
 wpa_supplicant/nan_usd.c        | 32 ++++++++++++++++++++++++--------
 wpa_supplicant/nan_usd.h        |  4 ++--
 wpa_supplicant/p2p_supplicant.c | 10 ++++++++++
 wpa_supplicant/p2p_supplicant.h |  6 ++++++
 15 files changed, 145 insertions(+), 24 deletions(-)
diff mbox series

Patch

diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 39b9ef5..fcdbb5c 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -3705,6 +3705,7 @@  static int hostapd_ctrl_nan_publish(struct hostapd_data *hapd, char *cmd,
 	struct wpabuf *ssi = NULL;
 	int ret = -1;
 	enum nan_service_protocol_type srv_proto_type = 0;
+	bool p2p = false;
 
 	os_memset(&params, 0, sizeof(params));
 	/* USD shall use both solicited and unsolicited transmissions */
@@ -3738,6 +3739,11 @@  static int hostapd_ctrl_nan_publish(struct hostapd_data *hapd, char *cmd,
 			continue;
 		}
 
+		if (os_strcmp(token, "p2p=1") == 0) {
+			p2p = true;
+			continue;
+		}
+
 		if (os_strcmp(token, "solicited=0") == 0) {
 			params.solicited = false;
 			continue;
@@ -3759,7 +3765,7 @@  static int hostapd_ctrl_nan_publish(struct hostapd_data *hapd, char *cmd,
 	}
 
 	publish_id = hostapd_nan_usd_publish(hapd, service_name, srv_proto_type,
-					     ssi, &params);
+					     ssi, &params, p2p);
 	if (publish_id > 0)
 		ret = os_snprintf(buf, buflen, "%d", publish_id);
 fail:
@@ -3842,6 +3848,7 @@  static int hostapd_ctrl_nan_subscribe(struct hostapd_data *hapd, char *cmd,
 	struct wpabuf *ssi = NULL;
 	int ret = -1;
 	enum nan_service_protocol_type srv_proto_type = 0;
+	bool p2p = false;
 
 	os_memset(&params, 0, sizeof(params));
 
@@ -3875,6 +3882,11 @@  static int hostapd_ctrl_nan_subscribe(struct hostapd_data *hapd, char *cmd,
 			continue;
 		}
 
+		if (os_strcmp(token, "p2p=1") == 0) {
+			p2p = true;
+			continue;
+		}
+
 		wpa_printf(MSG_INFO,
 			   "CTRL: Invalid NAN_SUBSCRIBE parameter: %s",
 			   token);
@@ -3883,7 +3895,7 @@  static int hostapd_ctrl_nan_subscribe(struct hostapd_data *hapd, char *cmd,
 
 	subscribe_id = hostapd_nan_usd_subscribe(hapd, service_name,
 						 srv_proto_type, ssi,
-						 &params);
+						 &params, p2p);
 	if (subscribe_id > 0)
 		ret = os_snprintf(buf, buflen, "%d", subscribe_id);
 fail:
diff --git a/src/ap/nan_usd_ap.c b/src/ap/nan_usd_ap.c
index 70c6139..570abfc 100644
--- a/src/ap/nan_usd_ap.c
+++ b/src/ap/nan_usd_ap.c
@@ -192,7 +192,7 @@  void hostapd_nan_usd_flush(struct hostapd_data *hapd)
 int hostapd_nan_usd_publish(struct hostapd_data *hapd, const char *service_name,
 			    enum nan_service_protocol_type srv_proto_type,
 			    const struct wpabuf *ssi,
-			    struct nan_publish_params *params)
+			    struct nan_publish_params *params, bool p2p)
 {
 	int publish_id;
 	struct wpabuf *elems = NULL;
@@ -201,7 +201,7 @@  int hostapd_nan_usd_publish(struct hostapd_data *hapd, const char *service_name,
 		return -1;
 
 	publish_id = nan_de_publish(hapd->nan_de, service_name, srv_proto_type,
-				    ssi, elems, params);
+				    ssi, elems, params, p2p);
 	wpabuf_free(elems);
 	return publish_id;
 }
@@ -231,7 +231,7 @@  int hostapd_nan_usd_subscribe(struct hostapd_data *hapd,
 			      const char *service_name,
 			      enum nan_service_protocol_type srv_proto_type,
 			      const struct wpabuf *ssi,
-			      struct nan_subscribe_params *params)
+			      struct nan_subscribe_params *params, bool p2p)
 {
 	int subscribe_id;
 	struct wpabuf *elems = NULL;
@@ -240,7 +240,7 @@  int hostapd_nan_usd_subscribe(struct hostapd_data *hapd,
 		return -1;
 
 	subscribe_id = nan_de_subscribe(hapd->nan_de, service_name,
-					srv_proto_type, ssi, elems, params);
+					srv_proto_type, ssi, elems, params, p2p);
 	wpabuf_free(elems);
 	return subscribe_id;
 }
diff --git a/src/ap/nan_usd_ap.h b/src/ap/nan_usd_ap.h
index 58ff5fc..0571643 100644
--- a/src/ap/nan_usd_ap.h
+++ b/src/ap/nan_usd_ap.h
@@ -21,7 +21,7 @@  void hostapd_nan_usd_flush(struct hostapd_data *hapd);
 int hostapd_nan_usd_publish(struct hostapd_data *hapd, const char *service_name,
 			    enum nan_service_protocol_type srv_proto_type,
 			    const struct wpabuf *ssi,
-			    struct nan_publish_params *params);
+			    struct nan_publish_params *params, bool p2p);
 void hostapd_nan_usd_cancel_publish(struct hostapd_data *hapd, int publish_id);
 int hostapd_nan_usd_update_publish(struct hostapd_data *hapd, int publish_id,
 				   const struct wpabuf *ssi);
@@ -29,7 +29,7 @@  int hostapd_nan_usd_subscribe(struct hostapd_data *hapd,
 			      const char *service_name,
 			      enum nan_service_protocol_type srv_proto_type,
 			      const struct wpabuf *ssi,
-			      struct nan_subscribe_params *params);
+			      struct nan_subscribe_params *params, bool p2p);
 void hostapd_nan_usd_cancel_subscribe(struct hostapd_data *hapd,
 				      int subscribe_id);
 int hostapd_nan_usd_transmit(struct hostapd_data *hapd, int handle,
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index db9e903..434844a 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -1425,6 +1425,7 @@  struct ieee80211_ampe_ie {
 #define WPS_IE_VENDOR_TYPE 0x0050f204
 #define OUI_WFA 0x506f9a
 #define P2P_IE_VENDOR_TYPE 0x506f9a09
+#define P2P2_IE_VENDOR_TYPE 0x506f9a28
 #define WFD_IE_VENDOR_TYPE 0x506f9a0a
 #define WFD_OUI_TYPE 10
 #define HS20_IE_VENDOR_TYPE 0x506f9a10
diff --git a/src/common/nan_de.c b/src/common/nan_de.c
index 0b54f11..5a68cc9 100644
--- a/src/common/nan_de.c
+++ b/src/common/nan_de.c
@@ -58,6 +58,7 @@  struct nan_de_service {
 	struct os_reltime next_publish_state;
 	struct os_reltime next_publish_chan;
 	unsigned int next_publish_duration;
+	bool is_p2p;
 };
 
 struct nan_de {
@@ -1215,7 +1216,7 @@  const u8 * nan_de_get_service_id(struct nan_de *de, int id)
 int nan_de_publish(struct nan_de *de, const char *service_name,
 		   enum nan_service_protocol_type srv_proto_type,
 		   const struct wpabuf *ssi, const struct wpabuf *elems,
-		   struct nan_publish_params *params)
+		   struct nan_publish_params *params, bool p2p)
 {
 	int publish_id;
 	struct nan_de_service *srv;
@@ -1277,6 +1278,7 @@  int nan_de_publish(struct nan_de *de, const char *service_name,
 	wpa_printf(MSG_DEBUG, "NAN: Assigned new publish handle %d for %s",
 		   publish_id, service_name);
 	srv->id = publish_id;
+	srv->is_p2p = p2p;
 	nan_de_add_srv(de, srv);
 	nan_de_run_timer(de);
 	return publish_id;
@@ -1328,7 +1330,7 @@  int nan_de_update_publish(struct nan_de *de, int publish_id,
 int nan_de_subscribe(struct nan_de *de, const char *service_name,
 		     enum nan_service_protocol_type srv_proto_type,
 		     const struct wpabuf *ssi, const struct wpabuf *elems,
-		     struct nan_subscribe_params *params)
+		     struct nan_subscribe_params *params, bool p2p)
 {
 	int subscribe_id;
 	struct nan_de_service *srv;
@@ -1368,6 +1370,7 @@  int nan_de_subscribe(struct nan_de *de, const char *service_name,
 	wpa_printf(MSG_DEBUG, "NAN: Assigned new subscribe handle %d for %s",
 		   subscribe_id, service_name);
 	srv->id = subscribe_id;
+	srv->is_p2p = p2p;
 	nan_de_add_srv(de, srv);
 	nan_de_run_timer(de);
 	return subscribe_id;
diff --git a/src/common/nan_de.h b/src/common/nan_de.h
index ae77cf3..bdac284 100644
--- a/src/common/nan_de.h
+++ b/src/common/nan_de.h
@@ -106,7 +106,7 @@  struct nan_publish_params {
 int nan_de_publish(struct nan_de *de, const char *service_name,
 		   enum nan_service_protocol_type srv_proto_type,
 		   const struct wpabuf *ssi, const struct wpabuf *elems,
-		   struct nan_publish_params *params);
+		   struct nan_publish_params *params, bool p2p);
 
 void nan_de_cancel_publish(struct nan_de *de, int publish_id);
 
@@ -133,7 +133,7 @@  struct nan_subscribe_params {
 int nan_de_subscribe(struct nan_de *de, const char *service_name,
 		     enum nan_service_protocol_type srv_proto_type,
 		     const struct wpabuf *ssi, const struct wpabuf *elems,
-		     struct nan_subscribe_params *params);
+		     struct nan_subscribe_params *params, bool p2p);
 
 void nan_de_cancel_subscribe(struct nan_de *de, int subscribe_id);
 
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 8e0fc35..0c26086 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -5688,3 +5688,43 @@  void set_p2p_allow_6ghz(struct p2p_data *p2p, bool value)
 {
 	p2p->allow_6ghz = value;
 }
+
+
+struct wpabuf * p2p_usd_elems(struct p2p_data *p2p)
+{
+	struct wpabuf *buf;
+	u8 *len;
+	u8 group_capab;
+
+	buf = wpabuf_alloc(1000);
+	if (!buf)
+		return NULL;
+
+	len = p2p_buf_add_ie_hdr(buf);
+
+	/* P2P Capability attribute */
+	group_capab = 0;
+	if (p2p->num_groups) {
+		group_capab |= P2P_GROUP_CAPAB_GROUP_OWNER;
+		if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) &&
+		    (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED) &&
+		    p2p->cross_connect)
+			group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
+	}
+	if (p2p->cfg->p2p_intra_bss)
+		group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
+	p2p_buf_add_capability(buf, p2p->dev_capab &
+			       ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
+			       group_capab);
+
+	/* P2P Device Info attribute */
+	p2p_buf_add_device_info(buf, p2p, NULL);
+
+	p2p_buf_update_ie_hdr(buf, len);
+
+	len = p2p_buf_add_p2p2_ie_hdr(buf);
+
+	p2p_buf_update_p2p2_ie_hdr(buf, len);
+
+	return buf;
+}
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index 27bdac3..ab6e9ca 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -2429,5 +2429,6 @@  bool is_p2p_allow_6ghz(struct p2p_data *p2p);
 void set_p2p_allow_6ghz(struct p2p_data *p2p, bool value);
 int p2p_remove_6ghz_channels(struct weighted_pcl *pref_freq_list, int size);
 int p2p_channel_to_freq(int op_class, int channel);
+struct wpabuf * p2p_usd_elems(struct p2p_data *p2p);
 
 #endif /* P2P_H */
diff --git a/src/p2p/p2p_build.c b/src/p2p/p2p_build.c
index e4f40fe..0bb0903 100644
--- a/src/p2p/p2p_build.c
+++ b/src/p2p/p2p_build.c
@@ -59,6 +59,24 @@  void p2p_buf_update_ie_hdr(struct wpabuf *buf, u8 *len)
 	*len = (u8 *) wpabuf_put(buf, 0) - len - 1;
 }
 
+u8 * p2p_buf_add_p2p2_ie_hdr(struct wpabuf *buf)
+{
+	u8 *len;
+
+	/* P2P2 IE header */
+	wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
+	len = wpabuf_put(buf, 1); /* IE length to be filled */
+	wpabuf_put_be32(buf, P2P2_IE_VENDOR_TYPE);
+	wpa_printf(MSG_DEBUG, "P2P: * P2P2 IE header");
+	return len;
+}
+
+
+void p2p_buf_update_p2p2_ie_hdr(struct wpabuf *buf, u8 *len)
+{
+	/* Update P2P2 IE Length */
+	*len = (u8 *) wpabuf_put(buf, 0) - len - 1;
+}
 
 void p2p_buf_add_capability(struct wpabuf *buf, u8 dev_capab, u8 group_capab)
 {
diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h
index 0a487e0..d6826c7 100644
--- a/src/p2p/p2p_i.h
+++ b/src/p2p/p2p_i.h
@@ -748,11 +748,13 @@  void p2p_buf_add_action_hdr(struct wpabuf *buf, u8 subtype, u8 dialog_token);
 void p2p_buf_add_public_action_hdr(struct wpabuf *buf, u8 subtype,
 				   u8 dialog_token);
 u8 * p2p_buf_add_ie_hdr(struct wpabuf *buf);
+u8 * p2p_buf_add_p2p2_ie_hdr(struct wpabuf *buf);
 void p2p_buf_add_status(struct wpabuf *buf, u8 status);
 void p2p_buf_add_device_info(struct wpabuf *buf, struct p2p_data *p2p,
 			     struct p2p_device *peer);
 void p2p_buf_add_device_id(struct wpabuf *buf, const u8 *dev_addr);
 void p2p_buf_update_ie_hdr(struct wpabuf *buf, u8 *len);
+void p2p_buf_update_p2p2_ie_hdr(struct wpabuf *buf, u8 *len);
 void p2p_buf_add_capability(struct wpabuf *buf, u8 dev_capab, u8 group_capab);
 void p2p_buf_add_go_intent(struct wpabuf *buf, u8 go_intent);
 void p2p_buf_add_listen_channel(struct wpabuf *buf, const char *country,
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 96e0740..f3d74a8 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -12202,6 +12202,7 @@  static int wpas_ctrl_nan_publish(struct wpa_supplicant *wpa_s, char *cmd,
 	int ret = -1;
 	enum nan_service_protocol_type srv_proto_type = 0;
 	int *freq_list = NULL;
+	bool p2p = false;
 
 	os_memset(&params, 0, sizeof(params));
 	/* USD shall use both solicited and unsolicited transmissions */
@@ -12262,6 +12263,11 @@  static int wpas_ctrl_nan_publish(struct wpa_supplicant *wpa_s, char *cmd,
 			continue;
 		}
 
+		if (os_strcmp(token, "p2p=1") == 0) {
+			p2p = true;
+			continue;
+		}
+
 		if (os_strcmp(token, "solicited=0") == 0) {
 			params.solicited = false;
 			continue;
@@ -12283,7 +12289,7 @@  static int wpas_ctrl_nan_publish(struct wpa_supplicant *wpa_s, char *cmd,
 	}
 
 	publish_id = wpas_nan_usd_publish(wpa_s, service_name, srv_proto_type,
-					  ssi, &params);
+					  ssi, &params, p2p);
 	if (publish_id > 0)
 		ret = os_snprintf(buf, buflen, "%d", publish_id);
 fail:
@@ -12367,6 +12373,7 @@  static int wpas_ctrl_nan_subscribe(struct wpa_supplicant *wpa_s, char *cmd,
 	struct wpabuf *ssi = NULL;
 	int ret = -1;
 	enum nan_service_protocol_type srv_proto_type = 0;
+	bool p2p = false;
 
 	os_memset(&params, 0, sizeof(params));
 	params.freq = NAN_USD_DEFAULT_FREQ;
@@ -12406,6 +12413,11 @@  static int wpas_ctrl_nan_subscribe(struct wpa_supplicant *wpa_s, char *cmd,
 			continue;
 		}
 
+		if (os_strcmp(token, "p2p=1") == 0) {
+			p2p = true;
+			continue;
+		}
+
 		wpa_printf(MSG_INFO,
 			   "CTRL: Invalid NAN_SUBSCRIBE parameter: %s",
 			   token);
@@ -12414,7 +12426,7 @@  static int wpas_ctrl_nan_subscribe(struct wpa_supplicant *wpa_s, char *cmd,
 
 	subscribe_id = wpas_nan_usd_subscribe(wpa_s, service_name,
 					      srv_proto_type, ssi,
-					      &params);
+					      &params, p2p);
 	if (subscribe_id > 0)
 		ret = os_snprintf(buf, buflen, "%d", subscribe_id);
 fail:
diff --git a/wpa_supplicant/nan_usd.c b/wpa_supplicant/nan_usd.c
index 884e416..eb84019 100644
--- a/wpa_supplicant/nan_usd.c
+++ b/wpa_supplicant/nan_usd.c
@@ -13,6 +13,7 @@ 
 #include "wpa_supplicant_i.h"
 #include "offchannel.h"
 #include "driver_i.h"
+#include "p2p_supplicant.h"
 #include "nan_usd.h"
 
 
@@ -386,21 +387,28 @@  void wpas_nan_usd_flush(struct wpa_supplicant *wpa_s)
 int wpas_nan_usd_publish(struct wpa_supplicant *wpa_s, const char *service_name,
 			 enum nan_service_protocol_type srv_proto_type,
 			 const struct wpabuf *ssi,
-			 struct nan_publish_params *params)
+			 struct nan_publish_params *params, bool p2p)
 {
 	int publish_id;
 	struct wpabuf *elems = NULL;
+	const u8 *addr;
 
 	if (!wpa_s->nan_de)
 		return -1;
 
+	if (p2p) {
+		elems = wpas_p2p_usd_elems(wpa_s);
+		addr = wpa_s->global->p2p_dev_addr;
+	} else {
+		addr = wpa_s->own_addr;
+	}
+
 	publish_id = nan_de_publish(wpa_s->nan_de, service_name, srv_proto_type,
-				    ssi, elems, params);
+				    ssi, elems, params, p2p);
 	if (publish_id <= 0)
 		goto fail;
 	if ((wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_OFFLOAD) &&
-	    wpas_drv_nan_publish(wpa_s, wpa_s->own_addr, publish_id,
-				 service_name,
+	    wpas_drv_nan_publish(wpa_s, addr, publish_id, service_name,
 				 nan_de_get_service_id(wpa_s->nan_de,
 						       publish_id),
 				 srv_proto_type, ssi, elems, params) < 0) {
@@ -444,21 +452,29 @@  int wpas_nan_usd_subscribe(struct wpa_supplicant *wpa_s,
 			   const char *service_name,
 			   enum nan_service_protocol_type srv_proto_type,
 			   const struct wpabuf *ssi,
-			   struct nan_subscribe_params *params)
+			   struct nan_subscribe_params *params, bool p2p)
 {
 	int subscribe_id;
 	struct wpabuf *elems = NULL;
+	const u8 *addr;
 
 	if (!wpa_s->nan_de)
 		return -1;
 
+	if (p2p) {
+		elems = wpas_p2p_usd_elems(wpa_s);
+		addr = wpa_s->global->p2p_dev_addr;
+	} else {
+		addr = wpa_s->own_addr;
+	}
+
 	subscribe_id = nan_de_subscribe(wpa_s->nan_de, service_name,
-					srv_proto_type, ssi, elems, params);
+					srv_proto_type, ssi, elems, params,
+					p2p);
 	if (subscribe_id <= 0)
 		goto fail;
 	if ((wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_OFFLOAD) &&
-	    wpas_drv_nan_subscribe(wpa_s, wpa_s->own_addr, subscribe_id,
-				   service_name,
+	    wpas_drv_nan_subscribe(wpa_s, addr, subscribe_id, service_name,
 				   nan_de_get_service_id(wpa_s->nan_de,
 							 subscribe_id),
 				   srv_proto_type, ssi, elems, params) < 0) {
diff --git a/wpa_supplicant/nan_usd.h b/wpa_supplicant/nan_usd.h
index 149ac9e..ecb4973 100644
--- a/wpa_supplicant/nan_usd.h
+++ b/wpa_supplicant/nan_usd.h
@@ -21,7 +21,7 @@  void wpas_nan_usd_flush(struct wpa_supplicant *wpa_s);
 int wpas_nan_usd_publish(struct wpa_supplicant *wpa_s, const char *service_name,
 			 enum nan_service_protocol_type srv_proto_type,
 			 const struct wpabuf *ssi,
-			 struct nan_publish_params *params);
+			 struct nan_publish_params *params, bool p2p);
 void wpas_nan_usd_cancel_publish(struct wpa_supplicant *wpa_s, int publish_id);
 int wpas_nan_usd_update_publish(struct wpa_supplicant *wpa_s, int publish_id,
 				const struct wpabuf *ssi);
@@ -29,7 +29,7 @@  int wpas_nan_usd_subscribe(struct wpa_supplicant *wpa_s,
 			   const char *service_name,
 			   enum nan_service_protocol_type srv_proto_type,
 			   const struct wpabuf *ssi,
-			   struct nan_subscribe_params *params);
+			   struct nan_subscribe_params *params, bool p2p);
 void wpas_nan_usd_cancel_subscribe(struct wpa_supplicant *wpa_s,
 				   int subscribe_id);
 int wpas_nan_usd_transmit(struct wpa_supplicant *wpa_s, int handle,
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 70025f1..2df2d10 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -10242,3 +10242,13 @@  int wpas_p2p_lo_stop(struct wpa_supplicant *wpa_s)
 	wpa_s->p2p_lo_started = 0;
 	return ret;
 }
+
+
+struct wpabuf * wpas_p2p_usd_elems(struct wpa_supplicant *wpa_s)
+{
+	struct p2p_data *p2p = wpa_s->global->p2p;
+
+	if (wpa_s->global->p2p_disabled || !p2p)
+		return NULL;
+	return p2p_usd_elems(p2p);
+}
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index d71f770..441e063 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -225,6 +225,7 @@  int wpas_p2p_lo_start(struct wpa_supplicant *wpa_s, unsigned int freq,
 		      unsigned int count);
 int wpas_p2p_lo_stop(struct wpa_supplicant *wpa_s);
 int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s);
+struct wpabuf * wpas_p2p_usd_elems(struct wpa_supplicant *wpa_s);
 
 #else /* CONFIG_P2P */
 
@@ -351,6 +352,11 @@  static inline int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s,
 	return 0;
 }
 
+static inline struct wpabuf * wpas_p2p_usd_elems(struct wpa_supplicant *wpa_s)
+{
+	return NULL;
+}
+
 #endif /* CONFIG_P2P */
 
 #endif /* P2P_SUPPLICANT_H */