diff mbox series

[v9,1/2] Add the similar USD APIs to dbus control interface that other apps can use the functions

Message ID DU0PR04MB93966D31BC1B80DB7A2875AFA29D2@DU0PR04MB9396.eurprd04.prod.outlook.com
State Accepted
Headers show
Series [v9,1/2] Add the similar USD APIs to dbus control interface that other apps can use the functions | expand

Commit Message

Chin-Ran Lo Sept. 5, 2024, 1:43 p.m. UTC
From 21d54563ae8d2282b799319f797463f69f6e3ed3 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: [v9 1/2] dbus: Add API for USD

USD had a control interface commands and events defined for it. Extend
this by providing similar USD APIs through the dbus control interface.

Signed-off-by: Lo,Chin-Ran <chin-ran.lo@nxp.com>
---
Changed since v8:
	* Rectify the series
Changed since v7:
	* Change the function name by the rule: "NANWord1Word2.."
	* Change the parameters by using the dictionary of named arguments
	* Miscellaneous fix
	* Add the signal functions to dbus.doxygen and separate the patch because of the size limitation
    
 wpa_supplicant/dbus/dbus_new.c          | 329 ++++++++++++
 wpa_supplicant/dbus/dbus_new.h          |  55 ++
 wpa_supplicant/dbus/dbus_new_handlers.c | 636 ++++++++++++++++++++++++
 wpa_supplicant/dbus/dbus_new_handlers.h |  14 +
 wpa_supplicant/dbus/dbus_new_helpers.h  |  23 +
 wpa_supplicant/notify.c                 |  16 +
 6 files changed, 1073 insertions(+)

Comments

Jouni Malinen Sept. 15, 2024, 9:45 a.m. UTC | #1
On Thu, Sep 05, 2024 at 01:43:38PM +0000, Chin-Ran Lo wrote:
> USD had a control interface commands and events defined for it. Extend
> this by providing similar USD APIs through the dbus control interface.

I applied these with quite a bit cleanup, including changes to the
interface definition:

https://w1.fi/cgit/hostap/commit/?id=dcf58aec8d3d2598f84e2789da16db16b8fa2bf3
https://w1.fi/cgit/hostap/commit/?id=85cd98976d0e2bbcb8d3e27330da47a6fd4f0403

> diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
> +void wpas_dbus_signal_nan_discovery_result(struct wpa_supplicant *wpa_s,

> +	dbus_bool_t succ;
> +	struct wpa_dbus_discov_info disc_info;

> +	succ = TRUE;
> +	disc_info.subscribe_id = subscribe_id;
> +	disc_info.peer_publish_id = peer_publish_id;
> +	os_memcpy(disc_info.peer_addr, peer_addr, ETH_ALEN);
> +	disc_info.fsd = fsd;
> +	disc_info.fsd_gas = fsd_gas;
> +	disc_info.ssi_len = ssi_len;
> +
> +	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &succ) ||

I don't see any point in sending out a hardcoded succ=TRUE in the
signals, so I removed it.

> +		!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)) ||

Sending out a binary structure looks really wrong. The exact encoding of
this depends on implementation specific differences in the compiler,
e.g., as far as padding is concerned, and this might even leak private
memory in padding. I replaced this type of cases with struct members
getting encoded separately into the dict with appropriate type
information.

For the methods, I did not want to add new helper functions for parsing
dict members, so I replaced those with use of dbus_dict_helpers.c.
diff mbox series

Patch

diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 5ad5bcd74..1c92d55e7 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -3652,6 +3652,52 @@  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", "a{sv}", ARG_IN },
+		  { "publish_id", "i", ARG_OUT },
+		  END_ARGS
+	  }
+	},
+	{ "NANCancelPublish", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) wpas_dbus_handler_nan_cancel_publish,
+	  {
+		  { "nan_args", "i", ARG_IN },
+		  END_ARGS
+	  }
+	},
+	{ "NANUpdatePublish", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) wpas_dbus_handler_nan_update_publish,
+	  {
+		  { "nan_args", "a{sv}", ARG_IN },
+		  END_ARGS
+	  }
+	},
+	{ "NANSubscribe", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) wpas_dbus_handler_nan_subscribe,
+	  {
+		  { "nan_args", "a{sv}", ARG_IN },
+		  { "subscribe_id", "i", ARG_OUT },
+		  END_ARGS
+	  }
+	},
+	{ "NANCancelSubscribe", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) wpas_dbus_handler_nan_cancel_subscribe,
+	  {
+		  { "nan_args", "i", ARG_IN },
+		  END_ARGS
+	  }
+	},
+	{ "NANTransmit", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) wpas_dbus_handler_nan_transmit,
+	  {
+		  { "nan_args", "a{sv}", ARG_IN },
+		  END_ARGS
+	  }
+	},
+#endif /* CONFIG_NAN_USD */
 #ifdef CONFIG_TDLS
 	{ "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE,
 	  (WPADBusMethodHandler) wpas_dbus_handler_tdls_discover,
@@ -4048,6 +4094,43 @@  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 },
+		  { "args", "a{sv}", ARG_OUT },
+		  END_ARGS
+	  }
+	},
+	{ "NANReplied", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  {
+		  { "success", "b", ARG_OUT },
+		  { "args", "a{sv}", ARG_OUT },
+		  END_ARGS
+	  }
+	},
+	{ "NANReceive", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  {
+		  { "nanrx", "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,
+	  {
+		  { "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 },
@@ -5253,3 +5336,249 @@  void wpas_dbus_signal_hs20_t_c_acceptance(struct wpa_supplicant *wpa_s,
 	dbus_message_unref(msg);
 }
 #endif /* CONFIG_HS20 */
+
+
+#ifdef CONFIG_NAN_USD
+/**
+ * wpas_dbus_signal_nan_discoveryresult - Send NAN discovery result signal
+ * @wpa_s: %wpa_supplicant network interface data
+ * @subscribe_id: Subscribe id of the session
+ * @peer_publish_id: Publish id of the sender
+ * @peer_addr: MAC address of the peer device
+ * @ssi: Service specific information payload
+ * @ssi_len: Length of the SSI field
+ *
+ * Notify the discovery-result
+ */
+void wpas_dbus_signal_nan_discovery_result(struct wpa_supplicant *wpa_s,
+					   int subscribe_id,
+					   int peer_publish_id,
+					   const u8 *peer_addr,
+					   bool fsd, bool fsd_gas,
+					   const u8 *ssi, size_t ssi_len)
+{
+	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 || !wpa_s->dbus_new_path)
+		return;
+	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+				      WPAS_DBUS_NEW_IFACE_INTERFACE,
+				      "NANDiscoveryResult");
+	if (!msg)
+		return;
+
+	dbus_message_iter_init_append(msg, &iter);
+	succ = TRUE;
+	disc_info.subscribe_id = subscribe_id;
+	disc_info.peer_publish_id = peer_publish_id;
+	os_memcpy(disc_info.peer_addr, peer_addr, ETH_ALEN);
+	disc_info.fsd = fsd;
+	disc_info.fsd_gas = fsd_gas;
+	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_replied - Send NAN Replied signal
+ * @wpa_s: %wpa_supplicant network interface data
+ * @publish_id: Publish id of the session
+ * @peer_subscribe_id: Subscribe id of the sender
+ * @peer_addr: MAC address of the peer device
+ * @ssi: Service specific information payload
+ * @ssi_len: Length of the SSI field
+ *
+ * Notify the nan-reply
+ */
+void wpas_dbus_signal_nan_replied(struct wpa_supplicant *wpa_s,
+					   int publish_id,
+					   int peer_subscribe_id,
+					   const u8 *peer_addr,
+					   const u8 *ssi, size_t ssi_len)
+{
+	struct wpas_dbus_priv *iface;
+	DBusMessage *msg;
+	DBusMessageIter iter, dict_iter;
+	dbus_bool_t succ;
+	struct wpa_dbus_reply_info reply_info;
+
+	iface = wpa_s->global->dbus;
+	/* Do nothing if the interface is not turned on */
+	if (!iface || !wpa_s->dbus_new_path)
+		return;
+
+	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+				      WPAS_DBUS_NEW_IFACE_INTERFACE,
+				      "NANReplied");
+	if (!msg)
+		return;
+
+	dbus_message_iter_init_append(msg, &iter);
+	succ = TRUE;
+	reply_info.publish_id = publish_id;
+	reply_info.peer_subscribe_id = peer_subscribe_id;
+	os_memcpy(reply_info.peer_addr, peer_addr, ETH_ALEN);
+	reply_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, "reply_info",
+						 (const char *) &reply_info,
+						 sizeof(reply_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: Service specific information payload
+ * @ssi_len: Length of the SSID
+ *
+ * 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,
+				  const u8 *ssi, size_t ssi_len)
+{
+	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 || !wpa_s->dbus_new_path)
+		return;
+
+	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+				      WPAS_DBUS_NEW_IFACE_INTERFACE,
+				      "NANReceive");
+	if (!msg)
+		return;
+
+	dbus_message_iter_init_append(msg, &iter);
+	nanrx_info.id = id;
+	nanrx_info.peer_id = peer_id;
+	os_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 || !wpa_s->dbus_new_path)
+		return;
+
+	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+				      WPAS_DBUS_NEW_IFACE_INTERFACE,
+				      "NANPublishTerminated");
+	if (!msg)
+		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);
+	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 || !wpa_s->dbus_new_path)
+		return;
+
+	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+				      WPAS_DBUS_NEW_IFACE_INTERFACE,
+				      "NANSubscribeTerminated");
+	if (!msg)
+		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);
+	dbus_message_unref(msg);
+}
+
+#endif /* CONFIG_NAN_USD */
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index 1db5fe8ae..9751eef80 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -285,6 +285,24 @@  void wpas_dbus_signal_anqp_query_done(struct wpa_supplicant *wpa_s,
 				      const u8 *dst, const char *result);
 void wpas_dbus_signal_hs20_t_c_acceptance(struct wpa_supplicant *wpa_s,
 					  const char *url);
+void wpas_dbus_signal_nan_discovery_result(struct wpa_supplicant *wpa_s,
+                                          int subscribe_id,
+                                          int peer_publish_id,
+                                          const u8 *peer_addr,
+                                          bool fsd, bool fsd_gas,
+                                          const u8 *ssi, size_t ssi_len);
+void wpas_dbus_signal_nan_replied(struct wpa_supplicant *wpa_s,
+                                          int publish_id,
+                                          int peer_subscribe_id,
+                                          const u8 *peer_addr,
+                                          const u8 *ssi, size_t ssi_len);
+void wpas_dbus_signal_nan_receive(struct wpa_supplicant *wpa_s,
+                                 int id, int peer_id, const u8 *peer_addr,
+                                 const u8 *ssi, size_t ssi_len);
+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);
 
 #else /* CONFIG_CTRL_IFACE_DBUS_NEW */
 
@@ -668,6 +686,43 @@  void wpas_dbus_signal_hs20_t_c_acceptance(struct wpa_supplicant *wpa_s,
 {
 }
 
+static inline void
+wpas_dbus_signal_nan_discovery_result(struct wpa_supplicant *wpa_s,
+				      int subscribe_id,
+				      int peer_publish_id, const u8 *peer_addr,
+				      bool fsd, bool fsd_gas,
+				      const u8 *ssi, size_t ssi_len)
+{
+}
+
+static inline void
+wpas_dbus_signal_nan_replied(struct wpa_supplicant *wpa_s,
+				      int publish_id,
+				      int peer_subscribe_id, const u8 *peer_addr,
+				      const u8 *ssi, size_t ssi_len)
+{
+}
+
+
+static inline void
+wpas_dbus_signal_nan_receive(struct wpa_supplicant *wpa_s,
+			     int id, int peer_id, const u8 *peer_addr,
+			     const u8 *ssi, size_t ssi_len)
+{
+}
+
+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_CTRL_IFACE_DBUS_NEW */
 
 #endif /* CTRL_IFACE_DBUS_H_NEW */
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 52e35a770..cc5119313 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -12,6 +12,7 @@ 
 
 #include "common.h"
 #include "common/ieee802_11_defs.h"
+#include "common/nan_de.h"
 #include "eap_peer/eap_methods.h"
 #include "eapol_supp/eapol_supp_sm.h"
 #include "rsn_supp/wpa.h"
@@ -27,6 +28,7 @@ 
 #include "../autoscan.h"
 #include "../ap.h"
 #include "../interworking.h"
+#include "../nan_usd.h"
 #include "dbus_new_helpers.h"
 #include "dbus_new.h"
 #include "dbus_new_handlers.h"
@@ -2814,6 +2816,640 @@  DBusMessage * wpas_dbus_handler_eap_logon(DBusMessage *message,
 }
 
 
+#ifdef CONFIG_NAN_USD
+#define MAX_NAN_FREQS		255
+
+static int wpas_dbus_get_nan_items_vary(DBusMessage *message, DBusMessageIter *var,
+				   void* pitem, DBusMessage **reply, int itype, u32 dat_buf_len, u16 ilen)
+{
+	int rtype = dbus_message_iter_get_arg_type(var);
+	if (rtype == DBUS_TYPE_VARIANT) {
+		DBusMessageIter	subiter;
+		dbus_message_iter_recurse(var, &subiter);
+		dbus_message_iter_next(var);
+		return wpas_dbus_get_nan_items_vary(message, &subiter, pitem, reply, itype, dat_buf_len, ilen);
+	} else if (rtype == DBUS_TYPE_ARRAY) {
+		DBusMessageIter	array_iter;
+		int offset=0;
+		int arytype;
+		dbus_message_iter_recurse(var, &array_iter);
+		dbus_message_iter_next(var);
+		// Loop through the array
+		arytype = dbus_message_iter_get_arg_type(&array_iter);
+		if (arytype != itype) {
+			wpa_printf(MSG_ERROR, "Item type: (exp, get)=(%c, %c)", itype, arytype);
+			return false;
+		}
+		while ((arytype = dbus_message_iter_get_arg_type(&array_iter)) != DBUS_TYPE_INVALID) {
+			if (arytype != itype) {
+				wpa_printf(MSG_ERROR, "Item type: (exp, get)=(%c, %c)", itype, arytype);
+				return false;
+			}
+			dbus_message_iter_get_basic(&array_iter, (pitem+offset));
+			dbus_message_iter_next(&array_iter);
+			offset+= ilen;
+			if ((offset+ilen) > dat_buf_len) {
+				wpa_printf(MSG_WARNING, "end_of_buffer(%d, %d, %u)", offset, ilen, dat_buf_len);
+				break;
+			}
+		}
+	}
+	return 0;
+}
+
+static int wpas_dbus_get_nan_items(DBusMessage *message,
+				      DBusMessageIter *var,
+				      void *pitem,
+				      DBusMessage **reply,
+				      int itype)
+{
+	int rtype = dbus_message_iter_get_arg_type(var);
+	if (rtype != itype) {
+		wpa_printf(MSG_DEBUG, "%s[dbus]: Incorrect Type, exp: %d, got: %d",
+			   __func__, itype, rtype);
+		*reply = wpas_dbus_error_invalid_args(
+			message, "Wrong Type value type. Boolean required");
+		return -1;
+	}
+	dbus_message_iter_get_basic(var, pitem);
+	return 0;
+}
+
+/*
+ * 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)
+{
+	int publish_id;
+	/* Parameters from DBUS */
+	struct wpabuf *service_name = NULL;
+	char *psrv_name;
+	enum nan_service_protocol_type srv_proto_type=0;
+	u16 freq_list_len=0;
+	u16 ssi_len=0;
+	bool p2p=false;
+
+	DBusMessage *reply = NULL;
+	DBusMessageIter iter, dict_iter, entry_iter, variant_iter;
+	char *key = NULL;
+
+	struct nan_publish_params params = {
+		.unsolicited = true,
+		.solicited = true,
+		.solicited_multicast = false,
+		.disable_events = false,
+		.fsd = true,
+		.fsd_gas = false,
+		.announcement_period = 0,
+		};
+	struct wpabuf *freq_list = NULL;
+	struct wpabuf *ssi = NULL;
+
+	wpa_printf(MSG_INFO, "DBUS NAN_PUBLISH:");
+	// Get the parameters from dbus
+	dbus_message_iter_init(message, &iter);
+	dbus_message_iter_recurse(&iter, &dict_iter);
+	while (dbus_message_iter_get_arg_type(&dict_iter) == DBUS_TYPE_DICT_ENTRY) {
+		dbus_message_iter_recurse(&dict_iter, &entry_iter);
+		dbus_message_iter_get_basic(&entry_iter, &key);
+		dbus_message_iter_next(&entry_iter);
+		dbus_message_iter_recurse(&entry_iter, &variant_iter);
+		if (os_strcmp(key, "srv_name") == 0) {
+			if (wpas_dbus_get_nan_items(message, &variant_iter,
+						    (void*)&psrv_name, &reply, DBUS_TYPE_STRING) < 0)
+				goto fail;
+			service_name = wpabuf_alloc(os_strlen(psrv_name)+1);
+			if (service_name == NULL)
+				goto fail;
+			os_strlcpy((char*)service_name->buf, psrv_name, service_name->size);
+			service_name->used = os_strlen((char*)service_name->buf);
+		} else if (os_strcmp(key, "proto_type") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &srv_proto_type,
+						       &reply, DBUS_TYPE_BYTE) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "solicited") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &params.solicited,
+						       &reply, DBUS_TYPE_BOOLEAN) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "unsolicited") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &params.unsolicited,
+						       &reply, DBUS_TYPE_BOOLEAN) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "solicited_mcast") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &params.solicited_multicast,
+						       &reply, DBUS_TYPE_BOOLEAN) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "ttl") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &params.ttl,
+						       &reply, DBUS_TYPE_UINT16) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "disable_event") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &params.disable_events,
+						       &reply, DBUS_TYPE_BOOLEAN) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "fsd") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &params.fsd,
+						       &reply, DBUS_TYPE_BOOLEAN) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "fsd_gas") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &params.fsd_gas,
+						       &reply, DBUS_TYPE_BOOLEAN) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "freq") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &params.freq,
+						       &reply, DBUS_TYPE_UINT16) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "announce_period") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &params.announcement_period,
+						       &reply, DBUS_TYPE_UINT32) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "p2p") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &p2p,
+						       &reply, DBUS_TYPE_BOOLEAN) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "ssi_len") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &ssi_len,
+						       &reply, DBUS_TYPE_UINT16) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "freq_list_len") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &freq_list_len,
+						       &reply, DBUS_TYPE_UINT16) < 0)
+				goto fail;
+		}
+		else if (os_strcmp(key, "ssi") == 0) {
+			if (ssi_len > 0) {
+				ssi = wpabuf_alloc(ssi_len);
+				if (ssi == NULL) {
+					goto fail;
+				}
+				if (wpas_dbus_get_nan_items_vary(message, &variant_iter,
+							ssi->buf, &reply, DBUS_TYPE_BYTE,
+							ssi_len, 1) < 0) {
+					wpa_printf(MSG_ERROR, "Error while fetching ssi");
+					goto fail;
+				}
+				ssi->used = ssi_len;
+			}
+		}
+		else if (os_strcmp(key, "freq_list") == 0) {
+			if (freq_list_len > 0) {
+				if (freq_list_len == MAX_NAN_FREQS) {
+					params.freq_list = wpas_nan_usd_all_freqs(wpa_s);
+				} else if (freq_list_len > 0) {
+					freq_list = wpabuf_alloc(freq_list_len);
+					if (freq_list == NULL) {
+						goto fail;
+					}
+					if (wpas_dbus_get_nan_items_vary(message, &variant_iter,
+								freq_list->buf, &reply, DBUS_TYPE_UINT16,
+								(sizeof(u16)*freq_list_len),
+								sizeof(u16)) < 0) {
+						wpa_printf(MSG_ERROR, "Error while fetching freq_list");
+						goto fail;
+					}
+					params.freq_list = (int *)freq_list->buf;
+				}
+			}
+		}
+		dbus_message_iter_next(&dict_iter);
+	}
+
+	publish_id = wpas_nan_usd_publish(wpa_s, (char*)service_name->buf, srv_proto_type,
+					  ssi, &params, p2p);
+	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);
+		wpabuf_free(ssi);
+		wpabuf_free(freq_list);
+		wpabuf_free(service_name);
+		return reply;
+	}
+fail:
+	wpabuf_free(ssi);
+	wpabuf_free(freq_list);
+	wpabuf_free(service_name);
+	return wpas_dbus_error_unknown_error(
+			message, "error publishing nan-usd");
+}
+
+/*
+ * 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)
+{
+	int publish_id = -1;
+
+	wpa_printf(MSG_INFO, "DBUS NAN_CANCEL_PUBLISH:");
+	if (!dbus_message_get_args(message, NULL,
+				   DBUS_TYPE_INT32, &publish_id,
+				   DBUS_TYPE_INVALID)) {
+		wpa_printf(MSG_DEBUG, " DBUS NAN_CANCEL_PUBLISH, failed to get args ");
+		return NULL;
+	}
+
+	if ((!wpa_s->nan_de) || (publish_id == -1))
+		return NULL;
+	wpa_printf(MSG_INFO, "DBUS NAN_CANCEL_PUBLISH: %d", publish_id);
+	nan_de_cancel_publish(wpa_s->nan_de, publish_id);
+	return NULL;
+}
+
+/*
+ * wpas_dbus_handler_nan_update_publish - Update the publish ssi
+ * @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 "NANUpdatePublish" method call of network interface.
+ */
+DBusMessage * wpas_dbus_handler_nan_update_publish(DBusMessage *message,
+						   struct wpa_supplicant *wpa_s)
+{
+	int publish_id = -1;
+	u16 ssi_len;
+	struct wpabuf *ssi = NULL;
+	DBusMessage *reply = NULL;
+	DBusMessageIter iter, dict_iter, entry_iter, variant_iter;
+	char *key = NULL;
+
+	wpa_printf(MSG_INFO, "DBUS NAN_UPDATE_PUBLISH:");
+	// Get the parameters from dbus
+	dbus_message_iter_init(message, &iter);
+	dbus_message_iter_recurse(&iter, &dict_iter);
+	while (dbus_message_iter_get_arg_type(&dict_iter) ==
+	       DBUS_TYPE_DICT_ENTRY) {
+		dbus_message_iter_recurse(&dict_iter, &entry_iter);
+		dbus_message_iter_get_basic(&entry_iter, &key);
+		dbus_message_iter_next(&entry_iter);
+		dbus_message_iter_recurse(&entry_iter, &variant_iter);
+		if (os_strcmp(key, "publish_id") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &publish_id,
+						       &reply, DBUS_TYPE_INT32) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "ssi_len") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &ssi_len,
+						       &reply, DBUS_TYPE_UINT16) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "ssi") == 0) {
+			if (ssi_len > 0) {
+				ssi = wpabuf_alloc(ssi_len);
+				if (ssi == NULL) {
+					goto fail;
+				}
+				if (wpas_dbus_get_nan_items_vary(message, &variant_iter,
+							ssi->buf, &reply, DBUS_TYPE_BYTE,
+							ssi_len, 1) < 0) {
+					wpa_printf(MSG_ERROR, "Error while fetching ssi");
+					goto fail;
+				}
+				ssi->used = ssi_len;
+			}
+		}
+		dbus_message_iter_next(&dict_iter);
+	}
+	if ((!wpa_s->nan_de) || (publish_id == -1))
+		return NULL;
+	wpa_printf(MSG_INFO, "DBUS NAN_UPDATE_PUBLISH: %d", publish_id);
+	nan_de_update_publish(wpa_s->nan_de, publish_id, ssi);
+
+	return NULL;
+fail:
+	wpabuf_free(ssi);
+	return wpas_dbus_error_unknown_error(
+			message, "error updating nan-usd publish ssi");
+}
+
+/*
+ * 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)
+{
+	int subscribe_id;
+	struct nan_subscribe_params params = {
+		.active = true,
+		.query_period = 0,
+		};
+	struct wpabuf *service_name = NULL;
+	char *psrv_name;
+	enum nan_service_protocol_type srv_proto_type=0;
+	bool p2p=false;
+	u16 ssi_len=0;
+	u16 freq_list_len=0;
+	struct wpabuf *ssi = NULL;
+	struct wpabuf *freq_list = NULL;
+	DBusMessage *reply = NULL;
+	DBusMessageIter iter, dict_iter, entry_iter, variant_iter;
+	char *key = NULL;
+
+	wpa_printf(MSG_INFO, "DBUS NAN_SUBSCRIBE: ");
+	os_memset(&params, 0, sizeof(params));
+
+	// Get the parameters from dbus
+	dbus_message_iter_init(message, &iter);
+	dbus_message_iter_recurse(&iter, &dict_iter);
+	while (dbus_message_iter_get_arg_type(&dict_iter) ==
+	       DBUS_TYPE_DICT_ENTRY) {
+		dbus_message_iter_recurse(&dict_iter, &entry_iter);
+		dbus_message_iter_get_basic(&entry_iter, &key);
+		dbus_message_iter_next(&entry_iter);
+		dbus_message_iter_recurse(&entry_iter, &variant_iter);
+		if (os_strcmp(key, "srv_name") == 0) {
+			if (wpas_dbus_get_nan_items(message, &variant_iter,
+							(void*)&psrv_name, &reply, DBUS_TYPE_STRING) < 0)
+				goto fail;
+			service_name = wpabuf_alloc(os_strlen(psrv_name)+1);
+			wpa_printf(MSG_INFO, "psrv_name len: %lu, %lu", os_strlen(psrv_name),
+					service_name->size);
+			if (service_name == NULL) {
+				goto fail;
+			}
+			os_strlcpy((char*)service_name->buf, psrv_name, service_name->size);
+			service_name->used = os_strlen((char*)service_name->buf);
+			wpa_printf(MSG_INFO, "service_name:[%s], %lu, %lu", service_name->buf,
+					service_name->used, os_strlen(psrv_name));
+		} else if (os_strcmp(key, "proto_type") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &srv_proto_type,
+						       &reply, DBUS_TYPE_BYTE) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "is_active") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &params.active,
+						       &reply, DBUS_TYPE_BOOLEAN) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "p2p") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &p2p,
+						       &reply, DBUS_TYPE_BOOLEAN) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "ttl") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &params.ttl,
+						       &reply, DBUS_TYPE_UINT16) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "freq") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &params.freq,
+						       &reply, DBUS_TYPE_UINT16) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "query_period") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &params.query_period,
+						       &reply, DBUS_TYPE_UINT32) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "ssi_len") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &ssi_len,
+						       &reply, DBUS_TYPE_UINT16) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "freq_list_len") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+							   &variant_iter,
+							   &freq_list_len,
+							   &reply, DBUS_TYPE_UINT16) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "ssi") == 0) {
+			if (ssi_len > 0) {
+				ssi = wpabuf_alloc(ssi_len);
+				if (ssi == NULL) {
+					goto fail;
+				}
+				if (wpas_dbus_get_nan_items_vary(message, &variant_iter, ssi->buf,
+							&reply, DBUS_TYPE_BYTE, ssi_len, 1) < 0) {
+					wpa_printf(MSG_ERROR, "Error while fetching ssi");
+					goto fail;
+				}
+				ssi->used = ssi_len;
+			}
+		} else if (os_strcmp(key, "freq_list") == 0) {
+			if (freq_list_len > 0) {
+				if (freq_list_len == MAX_NAN_FREQS) {
+					params.freq_list = wpas_nan_usd_all_freqs(wpa_s);
+				} else if (freq_list_len > 0) {
+					freq_list = wpabuf_alloc(freq_list_len);
+					if (freq_list == NULL) {
+						goto fail;
+					}
+					if (wpas_dbus_get_nan_items_vary(message, &variant_iter, freq_list->buf,
+								&reply, DBUS_TYPE_UINT16, (sizeof(u16)*freq_list_len),
+								sizeof(u16)) < 0) {
+						wpa_printf(MSG_ERROR, "Error while fetching freq_list");
+						goto fail;
+					}
+					params.freq_list = (int *)freq_list->buf;
+				}
+			}
+		}
+		dbus_message_iter_next(&dict_iter);
+	}
+
+	subscribe_id = wpas_nan_usd_subscribe(wpa_s, (char*)service_name->buf,
+					      srv_proto_type, ssi,
+					      &params, p2p);
+	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);
+		wpabuf_free(ssi);
+		wpabuf_free(freq_list);
+		wpabuf_free(service_name);
+		return reply;
+	}
+fail:
+	wpabuf_free(ssi);
+	wpabuf_free(freq_list);
+	wpabuf_free(service_name);
+	return wpas_dbus_error_unknown_error(
+			message, "error subscribing nan-usd");
+}
+
+
+/*
+ * wpas_dbus_handler_nan_cancel_subscribe - 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)
+{
+	int subscribe_id = -1;
+	wpa_printf(MSG_INFO, "DBUS NAN_CANCEL_SUBSCRIBE:");
+
+	if (!dbus_message_get_args(message, NULL,
+				   DBUS_TYPE_INT32, &subscribe_id,
+				   DBUS_TYPE_INVALID)) {
+		wpa_printf(MSG_DEBUG, " DBUS NAN_CANCEL_SUBSCRIBE, failed to get args ");
+		return NULL;
+	}
+
+	if ((!wpa_s->nan_de)||(subscribe_id == -1))
+		return NULL;
+	nan_de_cancel_subscribe(wpa_s->nan_de, subscribe_id);
+	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)
+{
+	int handle = 0;
+	int req_instance_id = 0;
+	struct wpabuf *ssi = NULL;
+	u8 peer_addr[ETH_ALEN];
+	char* paddr_msg;
+	int ret = -1;
+	u16 ssi_len;
+
+	DBusMessage *reply = NULL;
+	DBusMessageIter iter, dict_iter, entry_iter, variant_iter;
+	char *key = NULL;
+
+	wpa_printf(MSG_INFO, "DBUS NAN_TRANSMIT:");
+	// Get the parameters from dbus
+	dbus_message_iter_init(message, &iter);
+	dbus_message_iter_recurse(&iter, &dict_iter);
+	while (dbus_message_iter_get_arg_type(&dict_iter) ==
+	       DBUS_TYPE_DICT_ENTRY) {
+		dbus_message_iter_recurse(&dict_iter, &entry_iter);
+		dbus_message_iter_get_basic(&entry_iter, &key);
+		dbus_message_iter_next(&entry_iter);
+		dbus_message_iter_recurse(&entry_iter, &variant_iter);
+		if (os_strcmp(key, "handle") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &handle,
+						       &reply, DBUS_TYPE_BYTE) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "req_instance_id") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &req_instance_id,
+						       &reply, DBUS_TYPE_BYTE) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "peer_addr") == 0) {
+			if (wpas_dbus_get_nan_items(message, &variant_iter,
+							(void*)&paddr_msg, &reply, DBUS_TYPE_STRING) < 0)
+				goto fail;
+			if (hwaddr_aton(paddr_msg, peer_addr) < 0) {
+				wpa_printf(MSG_ERROR, "Error while converting peer address");
+				goto fail;
+			}
+		} else if (os_strcmp(key, "ssi_len") == 0) {
+			if (wpas_dbus_get_nan_items(message,
+						       &variant_iter,
+						       &ssi_len,
+						       &reply, DBUS_TYPE_UINT16) < 0)
+				goto fail;
+		} else if (os_strcmp(key, "ssi") == 0) {
+			if (ssi_len > 0) {
+				ssi = wpabuf_alloc(ssi_len);
+				if (ssi == NULL) {
+					goto fail;
+				}
+				if (wpas_dbus_get_nan_items_vary(message, &variant_iter, ssi->buf,
+							&reply, DBUS_TYPE_BYTE, ssi_len, 1) < 0) {
+					wpa_printf(MSG_ERROR, "Error while fetching ssi");
+					goto fail;
+				}
+				ssi->used = ssi_len;
+			}
+		}
+		dbus_message_iter_next(&dict_iter);
+	}
+
+	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(ssi);
+	return wpas_dbus_error_unknown_error(
+			message, "error sending follow-up packets");
+}
+
+#endif /* CONFIG_NAN_USD */
+
+
 #ifdef CONFIG_TDLS
 
 static int get_peer_hwaddr_helper(DBusMessage *message, const char *func_name,
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index 7faf70a77..a5260907a 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -290,4 +290,18 @@  DBusMessage * wpas_dbus_handler_subscribe_preq(
 DBusMessage * wpas_dbus_handler_unsubscribe_preq(
 	DBusMessage *message, struct wpa_supplicant *wpa_s);
 
+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_update_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 /* CTRL_IFACE_DBUS_HANDLERS_NEW_H */
diff --git a/wpa_supplicant/dbus/dbus_new_helpers.h b/wpa_supplicant/dbus/dbus_new_helpers.h
index c8d44a00b..82681dd56 100644
--- a/wpa_supplicant/dbus/dbus_new_helpers.h
+++ b/wpa_supplicant/dbus/dbus_new_helpers.h
@@ -112,6 +112,29 @@  struct wpa_dbus_property_desc {
 #define WPA_DBUS_PROPERTIES_SET "Set"
 #define WPA_DBUS_PROPERTIES_GETALL "GetAll"
 
+struct wpa_dbus_discov_info {
+	u32 subscribe_id;
+	u32 peer_publish_id;
+	u8 peer_addr[ETH_ALEN];
+	bool fsd;
+	bool fsd_gas;
+	u32 ssi_len;
+};
+
+struct wpa_dbus_reply_info {
+	u32 publish_id;
+	u32 peer_subscribe_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;
+};
+
 void free_dbus_object_desc(struct wpa_dbus_object_desc *obj_dsc);
 
 int wpa_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface, char *dbus_path,
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 8c1a817f9..205be1c8a 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -1094,6 +1094,11 @@  void wpas_notify_nan_discovery_result(struct wpa_supplicant *wpa_s,
 		subscribe_id, peer_publish_id, MAC2STR(peer_addr),
 		fsd, fsd_gas, srv_proto_type, ssi_hex);
 	os_free(ssi_hex);
+
+	wpas_dbus_signal_nan_discovery_result(wpa_s, subscribe_id,
+					      peer_publish_id, peer_addr,
+					      fsd, fsd_gas,
+					      ssi, ssi_len);
 }
 
 
@@ -1116,6 +1121,10 @@  void wpas_notify_nan_replied(struct wpa_supplicant *wpa_s,
 		publish_id, MAC2STR(peer_addr), peer_subscribe_id,
 		srv_proto_type, ssi_hex);
 	os_free(ssi_hex);
+
+	wpas_dbus_signal_nan_replied(wpa_s, publish_id,
+					      peer_subscribe_id, peer_addr,
+					      ssi, ssi_len);
 }
 
 
@@ -1134,6 +1143,9 @@  void wpas_notify_nan_receive(struct wpa_supplicant *wpa_s, int id,
 		"id=%d peer_instance_id=%d address=" MACSTR " ssi=%s",
 		id, peer_instance_id, MAC2STR(peer_addr), ssi_hex);
 	os_free(ssi_hex);
+
+	wpas_dbus_signal_nan_receive(wpa_s, id, peer_instance_id, peer_addr,
+				     ssi, ssi_len);
 }
 
 
@@ -1159,6 +1171,8 @@  void wpas_notify_nan_publish_terminated(struct wpa_supplicant *wpa_s,
 	wpa_msg(wpa_s, MSG_INFO, NAN_PUBLISH_TERMINATED
 		"publish_id=%d reason=%s",
 		publish_id, nan_reason_txt(reason));
+
+	wpas_dbus_signal_nan_publish_terminated(wpa_s, publish_id, reason);
 }
 
 
@@ -1169,6 +1183,8 @@  void wpas_notify_nan_subscribe_terminated(struct wpa_supplicant *wpa_s,
 	wpa_msg(wpa_s, MSG_INFO, NAN_SUBSCRIBE_TERMINATED
 		"subscribe_id=%d reason=%s",
 		subscribe_id, nan_reason_txt(reason));
+
+	wpas_dbus_signal_nan_subscribe_terminated(wpa_s, subscribe_id, reason);
 }
 
 #endif /* CONFIG_NAN_USD */