diff mbox series

[v6] Add the similar USD APIs to dbus control interface that other apps can use the functions

Message ID DU0PR04MB939662076009BAC24D452E0DA2B42@DU0PR04MB9396.eurprd04.prod.outlook.com
State Changes Requested
Headers show
Series [v6] Add the similar USD APIs to dbus control interface that other apps can use the functions | expand

Commit Message

Chin-Ran Lo July 26, 2024, 12:38 p.m. UTC
From 30b1dc4bf38a19dda2f8a67c06fbefb430498ff9 Mon Sep 17 00:00:00 2001
From: "Lo,Chin-Ran" <chin-ran.lo@nxp.com>
Date: Mon, 15 Jul 2024 14:01:11 +0800
Subject: [Patch v6] Add the similar USD APIs to dbus control interface that
 other apps can use the functions

Signed-off-by: Lo,Chin-Ran <chin-ran.lo@nxp.com>
---
Changelog since v5:
        * Use the dynamic buffers in dbus functions, instead of predefined buffers

 wpa_supplicant/dbus/dbus_new.c          | 261 +++++++++++++++
 wpa_supplicant/dbus/dbus_new.h          |  35 ++
 wpa_supplicant/dbus/dbus_new_handlers.c | 416 ++++++++++++++++++++++++
 wpa_supplicant/dbus/dbus_new_handlers.h |  13 +-
 wpa_supplicant/dbus/dbus_new_helpers.h  |  14 +
 wpa_supplicant/events.c                 |   2 +-
 wpa_supplicant/nan_usd.c                |   9 +-
 wpa_supplicant/notify.c                 |  27 ++
 wpa_supplicant/notify.h                 |  11 +
 9 files changed, 785 insertions(+), 3 deletions(-)

Comments

Jouni Malinen July 31, 2024, 5:01 p.m. UTC | #1
On Fri, Jul 26, 2024 at 12:38:01PM +0000, Chin-Ran Lo wrote:
>  wpa_supplicant/dbus/dbus_new.c          | 261 +++++++++++++++
>  wpa_supplicant/dbus/dbus_new.h          |  35 ++
>  wpa_supplicant/dbus/dbus_new_handlers.c | 416 ++++++++++++++++++++++++
>  wpa_supplicant/dbus/dbus_new_handlers.h |  13 +-
>  wpa_supplicant/dbus/dbus_new_helpers.h  |  14 +
>  wpa_supplicant/events.c                 |   2 +-
>  wpa_supplicant/nan_usd.c                |   9 +-
>  wpa_supplicant/notify.c                 |  27 ++
>  wpa_supplicant/notify.h                 |  11 +
>  9 files changed, 785 insertions(+), 3 deletions(-)

It would be cleaner to split this into two commits: one for handling the
move of the control interface specific code from nan_usd.c into notify.c/h
and another one to add the dbus specific changes.

As far as the proposed dbus interface is concerned, my main concern is
on how the commands are defined to take in a single string argument that
is then parsed to determine the set of actual arguments. That is not
really a clean interface for dbus. Instead, this should add the
individual arguments as separate dbus arguments with each having their
own (in most cases, non-string) type.

Why does this not add NANReplied event?

Why does this leave out some of the arguments from events (like
FSD/FSD-GAS)?

It would be good to update doc/dbus.doxygen to cover the new extension
to the dbus interface.

It would be nice to get a new tests/hwsim/test_dbus.py test case for
validating the new interface.

I'm attaching patches showing the two commits after a cleanup I did when
reviewing this. The first one should be ready to be applied as-is. The
second one needs those comments mentioned above addressed.
Chin-Ran Lo Aug. 23, 2024, 9:42 a.m. UTC | #2
Hi Jouni,
Thank you for the suggestions. I have pushed a new v7 patch
V7 1/2: It's the 1st one you sent back
V7 2/2: Please see the comment below.

Thank you
Chin-Ran

> -----Original Message-----
> From: Jouni Malinen <j@w1.fi>
> Sent: Thursday, August 1, 2024 1:02 AM
> To: Chin-Ran Lo <chin-ran.lo@nxp.com>
> Cc: hostap@lists.infradead.org; Pete Hsieh <tsung-hsien.hsieh@nxp.com>
> Subject: [EXT] Re: [PATCH v6] Add the similar USD APIs to dbus control
> interface that other apps can use the functions
> 
> Caution: This is an external email. Please take care when clicking links or
> opening attachments. When in doubt, report the message using the 'Report
> this email' button
> 
> 
> On Fri, Jul 26, 2024 at 12:38:01PM +0000, Chin-Ran Lo wrote:
> >  wpa_supplicant/dbus/dbus_new.c          | 261 +++++++++++++++
> >  wpa_supplicant/dbus/dbus_new.h          |  35 ++
> >  wpa_supplicant/dbus/dbus_new_handlers.c | 416
> > ++++++++++++++++++++++++  wpa_supplicant/dbus/dbus_new_handlers.h
> |
> > 13 +-  wpa_supplicant/dbus/dbus_new_helpers.h  |  14 +
> >  wpa_supplicant/events.c                 |   2 +-
> >  wpa_supplicant/nan_usd.c                |   9 +-
> >  wpa_supplicant/notify.c                 |  27 ++
> >  wpa_supplicant/notify.h                 |  11 +
> >  9 files changed, 785 insertions(+), 3 deletions(-)
> 
> It would be cleaner to split this into two commits: one for handling the move
> of the control interface specific code from nan_usd.c into notify.c/h and
> another one to add the dbus specific changes.
> 
> As far as the proposed dbus interface is concerned, my main concern is on how
> the commands are defined to take in a single string argument that is then
> parsed to determine the set of actual arguments. That is not really a clean
> interface for dbus. Instead, this should add the individual arguments as
> separate dbus arguments with each having their own (in most cases, non-string)
> type.

Chin-Ran> The interface has been modified in 2/2 patch. Please review

> 
> Why does this not add NANReplied event?

Chin-Ran> It's added in 2/2 patch. Please review.

> 
> Why does this leave out some of the arguments from events (like
> FSD/FSD-GAS)?
> 

Chin-Ran> They are added in 2/2 patch. Please review.


> It would be good to update doc/dbus.doxygen to cover the new extension to
> the dbus interface.

Chin-Ran> It's added in 2/2 patch. Please review.


> 
> It would be nice to get a new tests/hwsim/test_dbus.py test case for validating
> the new interface.

Chin-Ran> The functions are verified by using the Matter code now. I will also add the test code to here later.


> 
> I'm attaching patches showing the two commits after a cleanup I did when
> reviewing this. The first one should be ready to be applied as-is. The second
> one needs those comments mentioned above addressed.
> 
> --
> Jouni Malinen                                            PGP id
> EFC895FA
diff mbox series

Patch

diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 00b38edf5..f783016f6 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -220,6 +220,196 @@  void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
 	dbus_message_unref(msg);
 }
 
+#ifdef CONFIG_NAN_USD
+/**
+ * wpas_dbus_signal_nan_discoveryresult - send discovery result signal
+ * @wpa_s: %wpa_supplicant network interface data
+ * @success: indicates if scanning succeed or failed
+ * @subscribe_id: subscribe id of the session
+ * @peer_publish_id: publish id of the sender
+ * @peer_addr: address of the remote site
+ * @ssi_len: length of the ssi field
+ * @ssi: ssi payload
+ *
+ * Notify the discovery-result
+ */
+void wpas_dbus_signal_nan_discoveryresult(struct wpa_supplicant *wpa_s,
+				 int success, int subscribe_id, int peer_publish_id,
+				 const u8 *peer_addr, size_t ssi_len, const u8 *ssi)
+{
+	struct wpas_dbus_priv *iface;
+	DBusMessage *msg;
+	DBusMessageIter iter, dict_iter;
+	dbus_bool_t succ;
+	struct wpa_dbus_discov_info disc_info;
+
+	iface = wpa_s->global->dbus;
+
+	/* Do nothing if the interface is not turned on */
+	if (iface == NULL || !wpa_s->dbus_new_path)
+		return;
+
+	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+				      WPAS_DBUS_NEW_IFACE_INTERFACE,
+				      "NanDiscoveryresult");
+	if (msg == NULL)
+		return;
+
+	dbus_message_iter_init_append(msg, &iter);
+	succ = success ? TRUE : FALSE;
+	disc_info.subscribe_id = subscribe_id;
+	disc_info.peer_publish_id = peer_publish_id;
+	memcpy(disc_info.peer_addr, peer_addr, ETH_ALEN);
+	disc_info.ssi_len = ssi_len;
+
+	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &succ) ||
+		!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
+		!wpa_dbus_dict_append_byte_array(&dict_iter, "discov_info",
+						 (const char *) &disc_info,
+						 sizeof(disc_info)) ||
+		!wpa_dbus_dict_append_byte_array(&dict_iter, "ssi",
+						 (const char *) ssi,
+						 ssi_len) ||
+		!wpa_dbus_dict_close_write(&iter, &dict_iter))
+		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
+	else
+		dbus_connection_send(iface->con, msg, NULL);
+	dbus_message_unref(msg);
+}
+
+/**
+ * wpas_dbus_signal_nan_receive - send receive nan-usd packet signal
+ * @wpa_s: %wpa_supplicant network interface data
+ * @id: subscribe id
+ * @peer_id: id of the sender
+ * @peer_addr: address of the sender
+ * @ssi_len: Length of the ssi
+ * @ssi: ssi payload
+ *
+ * Notify while getting the follow-up packet
+ */
+void wpas_dbus_signal_nan_receive(struct wpa_supplicant *wpa_s,
+				 int id, int peer_id, const u8 *peer_addr,
+				 size_t ssi_len, const u8 *ssi)
+{
+	struct wpas_dbus_priv *iface;
+	DBusMessage *msg;
+	DBusMessageIter iter, dict_iter;
+	struct wpa_dbus_nanrx_info nanrx_info;
+
+	iface = wpa_s->global->dbus;
+
+	/* Do nothing if the interface is not turned on */
+	if (iface == NULL || !wpa_s->dbus_new_path)
+		return;
+
+	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+				      WPAS_DBUS_NEW_IFACE_INTERFACE,
+				      "NanReceive");
+	if (msg == NULL)
+		return;
+
+	dbus_message_iter_init_append(msg, &iter);
+	nanrx_info.id = id;
+	nanrx_info.peer_id = peer_id;
+	memcpy(nanrx_info.peer_addr, peer_addr, ETH_ALEN);
+	nanrx_info.ssi_len = ssi_len;
+
+	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
+		!wpa_dbus_dict_append_byte_array(&dict_iter, "nanrx_info",
+					     (const char *) &nanrx_info,
+					     sizeof(nanrx_info)) ||
+		!wpa_dbus_dict_append_byte_array(&dict_iter, "ssi",
+					     (const char *) ssi,
+					     ssi_len) ||
+		!wpa_dbus_dict_close_write(&iter, &dict_iter))
+		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
+	else
+		dbus_connection_send(iface->con, msg, NULL);
+	dbus_message_unref(msg);
+}
+
+/**
+ * wpas_dbus_signal_nan_publish_terminated - send publish-terminated signal
+ * @wpa_s: %wpa_supplicant network interface data
+ * @publish_id: The publish_id of the session
+ * @reason: The reason of the termination
+ *
+ * Notify while the session is expired
+ */
+void wpas_dbus_signal_nan_publish_terminated(struct wpa_supplicant *wpa_s,
+				 int publish_id, int reason)
+{
+	struct wpas_dbus_priv *iface;
+	DBusMessage *msg;
+	dbus_int32_t dpub_id = publish_id;
+	dbus_int32_t dreason = reason;
+
+	iface = wpa_s->global->dbus;
+	/* Do nothing if the interface is not turned on */
+	if (iface == NULL || !wpa_s->dbus_new_path)
+		return;
+
+	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+				      WPAS_DBUS_NEW_IFACE_INTERFACE,
+				      "NanPublishterminated");
+	if (msg == NULL)
+		return;
+
+	if (!dbus_message_append_args(msg, DBUS_TYPE_INT32, &dpub_id,
+				     DBUS_TYPE_INVALID) ||
+		!dbus_message_append_args(msg, DBUS_TYPE_INT32, &dreason,
+				     DBUS_TYPE_INVALID))
+		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
+	else {
+		dbus_connection_send(iface->con, msg, NULL);
+		wpa_msg(wpa_s, MSG_INFO, NAN_SUBSCRIBE_TERMINATED
+			"wpas_dbus_signal_nan_subscribe_terminated() dbus_connection_send (int)");
+	}
+	dbus_message_unref(msg);
+}
+
+/**
+ * wpas_dbus_signal_nan_subscribe_terminated - send subscribe-terminated signal
+ * @wpa_s: %wpa_supplicant network interface data
+ * @subscribe_id: The subscribe_id of the session
+ * @reason: The reason of the termination
+ *
+ * Notify while the session is expired
+ */
+void wpas_dbus_signal_nan_subscribe_terminated(struct wpa_supplicant *wpa_s,
+				 int subscribe_id, int reason)
+{
+	struct wpas_dbus_priv *iface;
+	DBusMessage *msg;
+	dbus_int32_t dsub_id = subscribe_id;
+	dbus_int32_t dreason = reason;
+
+	iface = wpa_s->global->dbus;
+	/* Do nothing if the interface is not turned on */
+	if (iface == NULL || !wpa_s->dbus_new_path)
+		return;
+
+	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+				      WPAS_DBUS_NEW_IFACE_INTERFACE,
+				      "NanSubscribeterminated");
+	if (msg == NULL)
+		return;
+
+	if (!dbus_message_append_args(msg, DBUS_TYPE_INT32, &dsub_id,
+				     DBUS_TYPE_INVALID) ||
+		!dbus_message_append_args(msg, DBUS_TYPE_INT32, &dreason,
+				     DBUS_TYPE_INVALID))
+		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
+	else {
+		dbus_connection_send(iface->con, msg, NULL);
+		wpa_msg(wpa_s, MSG_INFO, NAN_SUBSCRIBE_TERMINATED
+			"wpas_dbus_signal_nan_subscribe_terminated() dbus_connection_send (int)");
+	}
+
+	dbus_message_unref(msg);
+}
+#endif
 
 /**
  * wpas_dbus_signal_bss - Send a BSS related event signal
@@ -3605,6 +3795,45 @@  static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
 	  }
 	},
 #endif /* CONFIG_AUTOSCAN */
+#ifdef CONFIG_NAN_USD
+	{ "NANPublish", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) wpas_dbus_handler_nan_publish,
+	  {
+		  { "nan_args", "s", ARG_IN },
+		  { "publish_id", "i", ARG_OUT },
+		  END_ARGS
+	  }
+	},
+	{ "NANCancelPublish", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) wpas_dbus_handler_nan_cancel_publish,
+	  {
+		  { "nan_args", "s", ARG_IN },
+		  END_ARGS
+	  }
+	},
+	{ "NANSubscribe", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) wpas_dbus_handler_nan_subscribe,
+	  {
+		  { "nan_args", "s", ARG_IN },
+		  { "subscribe_id", "i", ARG_OUT },
+		  END_ARGS
+	  }
+	},
+	{ "NANCancelSubscribe", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) wpas_dbus_handler_nan_cancel_subscribe,
+	  {
+		  { "nan_args", "s", ARG_IN },
+		  END_ARGS
+	  }
+	},
+	{ "NANTransmit", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) wpas_dbus_handler_nan_transmit,
+	  {
+		  { "nan_args", "s", ARG_IN },
+		  END_ARGS
+	  }
+	},
+#endif /* CONFIG_NAN_USD */
 #ifdef CONFIG_TDLS
 	{ "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE,
 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_discover,
@@ -3983,6 +4212,38 @@  static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
 		  END_ARGS
 	  }
 	},
+#ifdef CONFIG_NAN_USD
+	{ "NANDiscoveryresult", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  {
+		  { "success", "b", ARG_OUT },
+		  { "discov_info", "a{sv}", ARG_OUT },
+		  { "ssi", "a{sv}", ARG_OUT },
+		  END_ARGS
+	  }
+	},
+	{ "NANReceive", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  {
+		  { "nanrx_info", "a{sv}", ARG_OUT },
+		  { "ssi", "a{sv}", ARG_OUT },
+		  END_ARGS
+	  }
+	},
+	{ "NanPublishterminated", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  {
+		  { "publish_id", "i", ARG_OUT },
+		  { "reason", "i", ARG_OUT },
+		  END_ARGS
+	  }
+	},
+	{ "NanSubscribeterminated", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  {
+		  { "term_subscribe_id", "i", ARG_OUT },
+		  { "reason", "i", ARG_OUT },
+		  END_ARGS
+	  }
+	},
+
+#endif /* CONFIG_NAN_USD */
 	{ "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
 	  {
 		  { "path", "o", ARG_OUT },
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index b653f10f9..3bbccb474 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -21,6 +21,9 @@  struct wpa_bss;
 struct wps_event_m2d;
 struct wps_event_fail;
 struct wps_credential;
+#ifdef CONFIG_NAN_USD
+struct wpa_dbus_discov_info;
+#endif /* CONFIG_NAN_USD */
 
 enum wpas_dbus_prop {
 	WPAS_DBUS_PROP_AP_SCAN,
@@ -168,6 +171,15 @@  void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s,
 				      enum wpa_ctrl_req_type rtype,
 				      const char *default_text);
 void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success);
+#ifdef CONFIG_NAN_USD
+void wpas_dbus_signal_nan_discoveryresult(struct wpa_supplicant *wpa_s,
+				      int success, int subscribe_id, int peer_publish_id,
+				      const u8 *peer_addr, size_t ssi_len, const u8 *ssi);
+void wpas_dbus_signal_nan_receive(struct wpa_supplicant *wpa_s,
+				      int id, int peer_id, const u8 *peer_addr, size_t ssi_len, const u8 *ssi);
+void wpas_dbus_signal_nan_publish_terminated(struct wpa_supplicant *wpa_s, int publish_id, int reason);
+void wpas_dbus_signal_nan_subscribe_terminated(struct wpa_supplicant *wpa_s, int subscribe_id, int reason);
+#endif /* CONFIG_NAN_USD */
 void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
 			       const struct wps_credential *cred);
 void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
@@ -328,6 +340,29 @@  static inline void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s,
 {
 }
 
+#ifdef CONFIG_NAN_USD
+static inline void wpas_dbus_signal_nan_discoveryresult(struct wpa_supplicant *wpa_s,
+					      int success, int subscribe_id, int peer_publish_id,
+					      const u8 *peer_addr, size_t ssi_len, const u8 *ssi)
+{
+}
+
+static inline void wpas_dbus_signal_nan_receive(struct wpa_supplicant *wpa_s,
+					      int id, int peer_id, const u8 *peer_addr, size_t ssi_len, const u8 *ssi)
+{
+}
+
+static inline void wpas_dbus_signal_nan_publish_terminated(struct wpa_supplicant *wpa_s,
+					      int publish_id, int reason)
+{
+}
+
+static inline void wpas_dbus_signal_nan_subscribe_terminated(struct wpa_supplicant *wpa_s,
+					      int subscribe_id, int reason)
+{
+}
+#endif /* CONFIG_NAN_USD */
+
 static inline void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
 					     const struct wps_credential *cred)
 {
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 6ad49a136..33dfc73dc 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -12,6 +12,9 @@ 
 
 #include "common.h"
 #include "common/ieee802_11_defs.h"
+#ifdef CONFIG_NAN_USD
+#include "common/nan_de.h"
+#endif /* CONFIG_NAN_USD */
 #include "eap_peer/eap_methods.h"
 #include "eapol_supp/eapol_supp_sm.h"
 #include "rsn_supp/wpa.h"
@@ -27,6 +30,9 @@ 
 #include "../autoscan.h"
 #include "../ap.h"
 #include "../interworking.h"
+#ifdef CONFIG_NAN_USD
+#include "../nan_usd.h"
+#endif /* CONFIG_NAN_USD */
 #include "dbus_new_helpers.h"
 #include "dbus_new.h"
 #include "dbus_new_handlers.h"
@@ -2705,6 +2711,416 @@  DBusMessage * wpas_dbus_handler_eap_logon(DBusMessage *message,
 	return NULL;
 }
 
+#ifdef CONFIG_NAN_USD
+/*
+ * wpas_dbus_handler_nan_publish - Send out nan-publish packets
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL indicating success or DBus error message on failure
+ *
+ * Handler function for "NANPublish" method call of network interface.
+ */
+DBusMessage * wpas_dbus_handler_nan_publish(DBusMessage *message,
+					    struct wpa_supplicant *wpa_s)
+{
+	const char *cmd;
+	struct wpabuf *cmdbuf = NULL;
+	char *token, *context = NULL;
+	int publish_id;
+	struct nan_publish_params params;
+	const char *service_name = NULL;
+	struct wpabuf *ssi = NULL;
+	enum nan_service_protocol_type srv_proto_type = 3;
+	int *freq_list = NULL;
+
+	wpa_printf(MSG_INFO, "DBUS NAN_PUBLISH:");
+	if (!dbus_message_get_args(message, NULL,
+				  DBUS_TYPE_STRING, &cmd,
+				  DBUS_TYPE_INVALID)) {
+		wpa_printf(MSG_DEBUG, " DBUS NAN_PUBLISH, failed to get args ");
+		return NULL;
+	}
+	wpa_printf(MSG_DEBUG, "DBUS NAN_PUBLISH: args: [%s]", cmd);
+
+	os_memset(&params, 0, sizeof(params));
+	/* USD shall use both solicited and unsolicited transmissions */
+	params.unsolicited = true;
+	params.solicited = true;
+	/* USD shall require FSD without GAS */
+	params.fsd = true;
+	params.freq = NAN_USD_DEFAULT_FREQ;
+	cmdbuf = wpabuf_alloc(strlen(cmd)+1);
+	if (cmdbuf == NULL) {
+		goto fail;
+	}
+	strcpy((char*)cmdbuf->buf, cmd);
+	while ((token = str_token((char*)cmdbuf->buf, " ", &context))) {
+		if (os_strncmp(token, "service_name=", 13) == 0) {
+			service_name = token + 13;
+			wpa_printf(MSG_DEBUG, "DBUS NAN_PUBLISH, service_name=[%s]", service_name);
+			continue;
+		}
+
+		if (os_strncmp(token, "ttl=", 4) == 0) {
+			params.ttl = atoi(token + 4);
+			wpa_printf(MSG_DEBUG, "DBUS NAN_PUBLISH, ttl=[%d]", params.ttl);
+			continue;
+		}
+
+		if (os_strncmp(token, "freq=", 5) == 0) {
+			params.freq = atoi(token + 5);
+			wpa_printf(MSG_DEBUG, "DBUS NAN_PUBLISH, freq=[%d]", params.freq);
+			continue;
+		}
+
+		if (os_strncmp(token, "freq_list=", 10) == 0) {
+			char *pos = token + 10;
+			if (os_strcmp(pos, "all") == 0) {
+				os_free(freq_list);
+				freq_list = wpas_nan_usd_all_freqs(wpa_s);
+				params.freq_list = freq_list;
+				continue;
+			}
+
+			while (pos && pos[0]) {
+				int_array_add_unique(&freq_list, atoi(pos));
+				pos = os_strchr(pos, ',');
+				if (pos)
+					pos++;
+			}
+
+			params.freq_list = freq_list;
+			continue;
+		}
+
+		if (os_strncmp(token, "srv_proto_type=", 15) == 0) {
+			srv_proto_type = atoi(token + 15);
+			wpa_printf(MSG_DEBUG, " DBUS NAN_PUBLISH, srv_proto_type=[%d]", srv_proto_type);
+			continue;
+		}
+
+		if (os_strncmp(token, "ssi=", 4) == 0) {
+			if (ssi)
+				goto fail;
+			ssi = wpabuf_parse_bin(token + 4);
+			if (!ssi)
+				goto fail;
+			continue;
+		}
+
+		if (os_strcmp(token, "solicited=0") == 0) {
+			params.solicited = false;
+			continue;
+		}
+
+		if (os_strcmp(token, "unsolicited=0") == 0) {
+			params.unsolicited = false;
+			continue;
+		}
+
+		if (os_strcmp(token, "fsd=0") == 0) {
+			params.fsd = false;
+			continue;
+		}
+
+		wpa_printf(MSG_DEBUG, "CTRL: Invalid NAN_PUBLISH parameter: %s",
+			token);
+		goto fail;
+	}
+	wpabuf_free(cmdbuf);
+	cmdbuf = NULL;
+	publish_id = wpas_nan_usd_publish(wpa_s, service_name, srv_proto_type,
+					  ssi, &params);
+	if (publish_id > 0) {
+		DBusMessage *reply;
+		reply = dbus_message_new_method_return(message);
+		dbus_message_append_args(reply, DBUS_TYPE_INT32,
+					 &publish_id, DBUS_TYPE_INVALID);
+		return reply;
+	}
+fail:
+	wpabuf_free(cmdbuf);
+	wpabuf_free(ssi);
+	os_free(freq_list);
+	return NULL;
+}
+
+/*
+ * wpas_dbus_handler_nan_cancel_publish - Cancel the publish
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL indicating success or DBus error message on failure
+ *
+ * Handler function for "NANCancelPublish" method call of network interface.
+ */
+DBusMessage * wpas_dbus_handler_nan_cancel_publish(DBusMessage *message,
+						   struct wpa_supplicant *wpa_s)
+{
+	const char *cmd;
+	struct wpabuf *cmdbuf = NULL;
+	char *token, *context = NULL;
+	int publish_id = -1;
+
+	wpa_printf(MSG_INFO, "DBUS NAN_CANCEL_PUBLISH:");
+	if (!dbus_message_get_args(message, NULL,
+				   DBUS_TYPE_STRING, &cmd,
+				   DBUS_TYPE_INVALID)) {
+		wpa_printf(MSG_DEBUG, " DBUS NAN_CANCEL_PUBLISH, failed to get args ");
+		return NULL;
+	}
+	wpa_printf(MSG_DEBUG, "DBUS NAN_CANCEL_PUBLISH: args: [%s]", cmd);
+	cmdbuf = wpabuf_alloc(strlen(cmd)+1);
+	if (cmdbuf == NULL) {
+		goto fail;
+	}
+	strcpy((char*)cmdbuf->buf, cmd);
+	while ((token = str_token((char*)cmdbuf->buf, " ", &context))) {
+		if (os_strncmp(token, "publish_id=", 11) == 0) {
+			publish_id = atoi(token + 11);
+			wpa_printf(MSG_DEBUG, "DBUS NAN_CANCEL_PUBLISH, publish_id=[%d]", publish_id);
+			break;
+		}
+		wpa_printf(MSG_DEBUG, "CTRL: Invalid NAN_CANCEL_PUBLISH parameter: %s",
+			token);
+		goto fail;
+	}
+	wpabuf_free(cmdbuf);
+	cmdbuf = NULL;
+	if ((!wpa_s->nan_de) || (publish_id == -1))
+		return NULL;
+	nan_de_cancel_publish(wpa_s->nan_de, publish_id);
+fail:
+	wpabuf_free(cmdbuf);
+	return NULL;
+}
+
+/*
+ * wpas_dbus_handler_nan_subscribe - Send out nan-subscribe packets
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL indicating success or DBus error message on failure
+ *
+ * Handler function for "NANSubscribe" method call of network interface.
+ */
+DBusMessage * wpas_dbus_handler_nan_subscribe(DBusMessage *message,
+											  struct wpa_supplicant *wpa_s)
+{
+	const char *cmd;
+	struct wpabuf *cmdbuf = NULL;
+	char *token, *context = NULL;
+	int subscribe_id;
+	struct nan_subscribe_params params;
+	const char *service_name = NULL;
+	struct wpabuf *ssi = NULL;
+	enum nan_service_protocol_type srv_proto_type = 3;
+
+	wpa_printf(MSG_INFO, "DBUS NAN_SUBSCRIBE: ");
+	if (!dbus_message_get_args(message, NULL,
+				   DBUS_TYPE_STRING, &cmd,
+				   DBUS_TYPE_INVALID)) {
+		wpa_printf(MSG_DEBUG, "DBUS NAN_SUBSCRIBE, failed to get args ");
+		return NULL;
+	}
+	wpa_printf(MSG_DEBUG, "DBUS NAN_SUBSCRIBE, args: [%s]", cmd);
+	os_memset(&params, 0, sizeof(params));
+	params.freq = NAN_USD_DEFAULT_FREQ;
+	cmdbuf = wpabuf_alloc(strlen(cmd)+1);
+	if (cmdbuf == NULL) {
+		goto fail;
+	}
+	strcpy((char*)cmdbuf->buf, cmd);
+	while ((token = str_token((char*)cmdbuf->buf, " ", &context))) {
+		if (os_strncmp(token, "service_name=", 13) == 0) {
+			service_name = token + 13;
+			continue;
+		}
+
+		if (os_strcmp(token, "active=1") == 0) {
+			params.active = true;
+			continue;
+		}
+
+		if (os_strncmp(token, "ttl=", 4) == 0) {
+			params.ttl = atoi(token + 4);
+			continue;
+		}
+
+		if (os_strncmp(token, "freq=", 5) == 0) {
+			params.freq = atoi(token + 5);
+			continue;
+		}
+
+		if (os_strncmp(token, "srv_proto_type=", 15) == 0) {
+			srv_proto_type = atoi(token + 15);
+			continue;
+		}
+
+		if (os_strncmp(token, "ssi=", 4) == 0) {
+			if (ssi)
+				goto fail;
+			ssi = wpabuf_parse_bin(token + 4);
+			if (!ssi)
+				goto fail;
+			continue;
+		}
+		wpa_printf(MSG_INFO,
+			   "DBUS: Invalid NAN_SUBSCRIBE parameter: %s",
+			   token);
+		goto fail;
+	}
+	wpabuf_free(cmdbuf);
+	cmdbuf = NULL;
+	subscribe_id = wpas_nan_usd_subscribe(wpa_s, service_name,
+					      srv_proto_type, ssi,
+					      &params);
+	if (subscribe_id > 0) {
+		DBusMessage *reply;
+		reply = dbus_message_new_method_return(message);
+		dbus_message_append_args(reply, DBUS_TYPE_INT32,
+					 &subscribe_id, DBUS_TYPE_INVALID);
+		return reply;
+	}
+fail:
+	wpabuf_free(cmdbuf);
+	wpabuf_free(ssi);
+	return NULL;
+}
+
+/*
+ * wpas_dbus_handler_nan_cancel_publish - Cancel the subscription
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL indicating success or DBus error message on failure
+ *
+ * Handler function for "NANCancelSubscribe" method call of network interface.
+ */
+DBusMessage * wpas_dbus_handler_nan_cancel_subscribe(DBusMessage *message,
+						     struct wpa_supplicant *wpa_s)
+{
+	const char *cmd;
+	struct wpabuf *cmdbuf = NULL;
+	char *token, *context = NULL;
+	int subscribe_id = -1;
+
+	wpa_printf(MSG_INFO, "DBUS NAN_CANCEL_SUBSCRIBE:");
+	if (!dbus_message_get_args(message, NULL,
+				   DBUS_TYPE_STRING, &cmd,
+				   DBUS_TYPE_INVALID)) {
+		wpa_printf(MSG_DEBUG, " DBUS NAN_CANCEL_SUBSCRIBE, failed to get args ");
+		return NULL;
+	}
+	wpa_printf(MSG_DEBUG, "DBUS NAN_CANCEL_SUBSCRIBE: args: [%s]", cmd);
+	cmdbuf = wpabuf_alloc(strlen(cmd)+1);
+	if (cmdbuf == NULL) {
+		goto fail;
+	}
+	strcpy((char*)cmdbuf->buf, cmd);
+	while ((token = str_token((char*)cmdbuf->buf, " ", &context))) {
+		if (os_strncmp(token, "subscribe_id=", 13) == 0) {
+			subscribe_id = atoi(token + 13);
+			wpa_printf(MSG_DEBUG, "DBUS NAN_CANCEL_SUBSCRIBE, publish_id=[%d]", subscribe_id);
+			break;
+		}
+		wpa_printf(MSG_DEBUG, "DBUS: Invalid NAN_CANCEL_SUBSCRIBE parameter: %s",
+			token);
+		goto fail;
+	}
+	wpabuf_free(cmdbuf);
+	cmdbuf = NULL;
+	if ((!wpa_s->nan_de)||(subscribe_id == -1))
+		return NULL;
+	nan_de_cancel_subscribe(wpa_s->nan_de, subscribe_id);
+fail:
+	wpabuf_free(cmdbuf);
+	return NULL;
+}
+
+
+/*
+ * wpas_dbus_handler_nan_transmit - Send out nan-followup packets
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL indicating success or DBus error message on failure
+ *
+ * Handler function for "NANTransmit" method call of network interface.
+ */
+DBusMessage * wpas_dbus_handler_nan_transmit(DBusMessage *message,
+					     struct wpa_supplicant *wpa_s)
+{
+	const char *cmd;
+	struct wpabuf *cmdbuf = NULL;
+	char *token, *context = NULL;
+	int handle = 0;
+	int req_instance_id = 0;
+	struct wpabuf *ssi = NULL;
+	u8 peer_addr[ETH_ALEN];
+	int ret = -1;
+
+	wpa_printf(MSG_INFO, "DBUS NAN_TRANSMIT:");
+	if (!dbus_message_get_args(message, NULL,
+				   DBUS_TYPE_STRING, &cmd,
+				   DBUS_TYPE_INVALID)) {
+		wpa_printf(MSG_DEBUG, "DBUS NAN_TRANSMIT, failed to get args ");
+		return NULL;
+	}
+	wpa_printf(MSG_DEBUG, "DBUS NAN_TRANSMIT, args: [%s]", cmd);
+	os_memset(peer_addr, 0, ETH_ALEN);
+	cmdbuf = wpabuf_alloc(strlen(cmd)+1);
+	if (cmdbuf == NULL) {
+		goto fail;
+	}
+	strcpy((char*)cmdbuf->buf, cmd);
+	while ((token = str_token((char*)cmdbuf->buf, " ", &context))) {
+		if (sscanf(token, "handle=%i", &handle) == 1)
+			continue;
+
+		if (sscanf(token, "req_instance_id=%i", &req_instance_id) == 1)
+			continue;
+
+		if (os_strncmp(token, "address=", 8) == 0) {
+			if (hwaddr_aton(token + 8, peer_addr) < 0)
+				return NULL;
+			continue;
+		}
+
+		if (os_strncmp(token, "ssi=", 4) == 0) {
+			if (ssi)
+				goto fail;
+			ssi = wpabuf_parse_bin(token + 4);
+			if (!ssi)
+				goto fail;
+			continue;
+		}
+
+		wpa_printf(MSG_INFO,
+			"CTRL: Invalid NAN_TRANSMIT parameter: %s",
+			token);
+		goto fail;
+	}
+	wpabuf_free(cmdbuf);
+	cmdbuf = NULL;
+
+	if (handle <= 0) {
+		wpa_printf(MSG_INFO,
+			"CTRL: Invalid or missing NAN_TRANSMIT handle");
+		goto fail;
+	}
+
+	if (is_zero_ether_addr(peer_addr)) {
+		wpa_printf(MSG_INFO,
+			"CTRL: Invalid or missing NAN_TRANSMIT address");
+		goto fail;
+	}
+
+	ret = wpas_nan_usd_transmit(wpa_s, handle, ssi, NULL, peer_addr,
+				    req_instance_id);
+fail:
+	wpa_printf(MSG_INFO, "DBUS NAN_TRANSMIT Done, %d", ret);
+	wpabuf_free(cmdbuf);
+	wpabuf_free(ssi);
+	return NULL;
+}
+#endif /* CONFIG_NAN_USD */
 
 #ifdef CONFIG_TDLS
 
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index 97fa337bd..ebda6eeb8 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -248,7 +248,18 @@  DECLARE_ACCESSOR(wpas_dbus_getter_mesh_peers);
 DECLARE_ACCESSOR(wpas_dbus_getter_mesh_group);
 
 DECLARE_ACCESSOR(wpas_dbus_getter_signal_change);
-
+#ifdef CONFIG_NAN_USD
+DBusMessage * wpas_dbus_handler_nan_publish(DBusMessage *message,
+					    struct wpa_supplicant *wpa_s);
+DBusMessage * wpas_dbus_handler_nan_cancel_publish(DBusMessage *message,
+					           struct wpa_supplicant *wpa_s);
+DBusMessage * wpas_dbus_handler_nan_subscribe(DBusMessage *message,
+					      struct wpa_supplicant *wpa_s);
+DBusMessage * wpas_dbus_handler_nan_cancel_subscribe(DBusMessage *message,
+						     struct wpa_supplicant *wpa_s);
+DBusMessage * wpas_dbus_handler_nan_transmit(DBusMessage *message,
+					     struct wpa_supplicant *wpa_s);
+#endif /* CONFIG_NAN_USD */
 DBusMessage * wpas_dbus_handler_tdls_discover(DBusMessage *message,
 					      struct wpa_supplicant *wpa_s);
 DBusMessage * wpas_dbus_handler_tdls_setup(DBusMessage *message,
diff --git a/wpa_supplicant/dbus/dbus_new_helpers.h b/wpa_supplicant/dbus/dbus_new_helpers.h
index c8d44a00b..f7d076c11 100644
--- a/wpa_supplicant/dbus/dbus_new_helpers.h
+++ b/wpa_supplicant/dbus/dbus_new_helpers.h
@@ -98,7 +98,21 @@  struct wpa_dbus_property_desc {
 	/* other data */
 	const char *data;
 };
+#ifdef CONFIG_NAN_USD
+struct wpa_dbus_discov_info {
+	u32 subscribe_id;
+	u32 peer_publish_id;
+	u8 peer_addr[ETH_ALEN];
+	u32 ssi_len;
+};
 
+struct wpa_dbus_nanrx_info {
+	u32 id;
+	u32 peer_id;
+	u8 peer_addr[ETH_ALEN];
+	u32 ssi_len;
+};
+#endif /* CONFIG_NAN_USD */
 
 #define WPAS_DBUS_OBJECT_PATH_MAX 150
 #define WPAS_DBUS_INTERFACE_MAX 150
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index cf3b357eb..c94a4e56e 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -6863,7 +6863,7 @@  void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 #ifdef CONFIG_DPP
 		wpas_dpp_tx_wait_expire(wpa_s);
 #endif /* CONFIG_DPP */
-#ifdef CONFIG_DPP
+#ifdef CONFIG_NAN_USD
 		wpas_nan_usd_tx_wait_expire(wpa_s);
 #endif /* CONFIG_DPP */
 		break;
diff --git a/wpa_supplicant/nan_usd.c b/wpa_supplicant/nan_usd.c
index 657b302c1..c27c5c755 100644
--- a/wpa_supplicant/nan_usd.c
+++ b/wpa_supplicant/nan_usd.c
@@ -14,7 +14,7 @@ 
 #include "offchannel.h"
 #include "driver_i.h"
 #include "nan_usd.h"
-
+#include "notify.h"
 
 static const char *
 tx_status_result_txt(enum offchannel_send_action_result result)
@@ -254,6 +254,9 @@  wpas_nan_de_discovery_result(void *ctx, int subscribe_id,
 		subscribe_id, peer_publish_id, MAC2STR(peer_addr),
 		fsd, fsd_gas, srv_proto_type, ssi_hex);
 	os_free(ssi_hex);
+
+	wpas_notify_nan_discoveryresult(wpa_s, 1, subscribe_id, peer_publish_id,
+		peer_addr, ssi_len, ssi);
 }
 
 
@@ -302,6 +305,7 @@  static void wpas_nan_de_publish_terminated(void *ctx, int publish_id,
 	wpa_msg(wpa_s, MSG_INFO, NAN_PUBLISH_TERMINATED
 		"publish_id=%d reason=%s",
 		publish_id, nan_reason_txt(reason));
+	wpas_notify_nan_publish_terminated(wpa_s, publish_id, (int)reason);
 }
 
 
@@ -313,6 +317,7 @@  static void wpas_nan_de_subscribe_terminated(void *ctx, int subscribe_id,
 	wpa_msg(wpa_s, MSG_INFO, NAN_SUBSCRIBE_TERMINATED
 		"subscribe_id=%d reason=%s",
 		subscribe_id, nan_reason_txt(reason));
+	wpas_notify_nan_subscribe_terminated(wpa_s, subscribe_id, (int)reason);
 }
 
 
@@ -331,6 +336,8 @@  static void wpas_nan_de_receive(void *ctx, int id, int peer_instance_id,
 	wpa_msg(wpa_s, MSG_INFO, NAN_RECEIVE
 		"id=%d peer_instance_id=%d address=" MACSTR " ssi=%s",
 		id, peer_instance_id, MAC2STR(peer_addr), ssi_hex);
+
+	wpas_notify_nan_receive(wpa_s, id, peer_instance_id, peer_addr, ssi_len, ssi);
 	os_free(ssi_hex);
 }
 
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 745234dda..f4397dc75 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -281,6 +281,33 @@  void wpas_notify_scan_done(struct wpa_supplicant *wpa_s, int success)
 	wpas_dbus_signal_scan_done(wpa_s, success);
 }
 
+#ifdef CONFIG_NAN_USD
+void wpas_notify_nan_discoveryresult(struct wpa_supplicant *wpa_s,
+				     int success, int subscribe_id, int peer_publish_id,
+				     const u8 *peer_addr, size_t ssi_len, const u8 *ssi)
+{
+	wpas_dbus_signal_nan_discoveryresult(wpa_s, success, subscribe_id,
+		peer_publish_id, peer_addr, ssi_len, ssi);
+}
+
+void wpas_notify_nan_receive(struct wpa_supplicant *wpa_s, int id,
+			     int peer_id, const u8 *peer_addr, size_t ssi_len, const u8 *ssi)
+{
+	wpas_dbus_signal_nan_receive(wpa_s, id, peer_id, peer_addr, ssi_len, ssi);
+}
+
+void wpas_notify_nan_publish_terminated(struct wpa_supplicant *wpa_s, int publish_id,
+					int reason)
+{
+	wpas_dbus_signal_nan_publish_terminated(wpa_s, publish_id, reason);
+}
+
+void wpas_notify_nan_subscribe_terminated(struct wpa_supplicant *wpa_s, int subscribe_id,
+					  int reason)
+{
+	wpas_dbus_signal_nan_subscribe_terminated(wpa_s, subscribe_id, reason);
+}
+#endif /* CONFIG_NAN_USD */
 
 void wpas_notify_scan_results(struct wpa_supplicant *wpa_s)
 {
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 2a0cf097a..83e6f411c 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -47,6 +47,17 @@  void wpas_notify_network_request(struct wpa_supplicant *wpa_s,
 				 const char *default_txt);
 void wpas_notify_scanning(struct wpa_supplicant *wpa_s);
 void wpas_notify_scan_done(struct wpa_supplicant *wpa_s, int success);
+#ifdef CONFIG_NAN_USD
+void wpas_notify_nan_discoveryresult(struct wpa_supplicant *wpa_s,
+				     int success, int subscribe_id, int peer_publish_id,
+				     const u8 *peer_addr, size_t ssi_len, const u8 *ssi);
+void wpas_notify_nan_receive(struct wpa_supplicant *wpa_s,
+			     int id, int peer_id, const u8 *peer_addr, size_t ssi_len, const u8 *ssi);
+void wpas_notify_nan_publish_terminated(struct wpa_supplicant *wpa_s, int publish_id,
+					int reason);
+void wpas_notify_nan_subscribe_terminated(struct wpa_supplicant *wpa_s, int subscribe_id,
+					  int reason);
+#endif /* CONFIG_NAN_USD */
 void wpas_notify_scan_results(struct wpa_supplicant *wpa_s);
 void wpas_notify_wps_credential(struct wpa_supplicant *wpa_s,
 				const struct wps_credential *cred);