[PATCH 80/97] wpa_supplicant: Support tracking NAN transmit requests

Andrei Otcheretianski andrei.otcheretianski at intel.com
Tue Apr 28 13:06:21 PDT 2026


From: Ilan Peer <ilan.peer at intel.com>

Extended the NAN transmit API to also include a cookie,
so that when the NAN DE finishes transmitting the frame
it would notify the higher layers whether the frame was
acknowledged or not.

Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 src/common/wpa_ctrl.h                   |  1 +
 wpa_supplicant/ctrl_iface.c             | 17 ++++++++++++++++-
 wpa_supplicant/dbus/dbus_new_handlers.c |  2 +-
 wpa_supplicant/nan_supplicant.c         | 19 +++++++++++++++++--
 wpa_supplicant/nan_supplicant.h         |  3 ++-
 wpa_supplicant/notify.c                 |  8 ++++++++
 wpa_supplicant/notify.h                 |  2 ++
 7 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index e5aa42649a..411d22ace9 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -246,6 +246,7 @@ extern "C" {
 #define NAN_PUBLISH_TERMINATED "NAN-PUBLISH-TERMINATED "
 #define NAN_SUBSCRIBE_TERMINATED "NAN-SUBSCRIBE-TERMINATED "
 #define NAN_RECEIVE "NAN-RECEIVE "
+#define NAN_TRANSMIT_STATUS "NAN-TRANSMIT-STATUS "
 #define NAN_CLUSTER_JOIN "NAN-CLUSTER-JOIN "
 #define NAN_NDP_REQUEST "NAN-NDP-REQUEST "
 #define NAN_NDP_COUNTER_REQUEST "NAN-NDP-COUNTER-REQUEST "
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 8a96b4f812..7a9444c62c 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -13261,6 +13261,8 @@ static int wpas_ctrl_nan_transmit(struct wpa_supplicant *wpa_s, char *cmd)
 	struct wpabuf *ssi = NULL;
 	u8 peer_addr[ETH_ALEN];
 	int ret = -1;
+	u32 cookie = 0;
+	u32 *cookie_ptr = NULL;
 
 	os_memset(peer_addr, 0, ETH_ALEN);
 
@@ -13286,6 +13288,19 @@ static int wpas_ctrl_nan_transmit(struct wpa_supplicant *wpa_s, char *cmd)
 			continue;
 		}
 
+		if (os_strncmp(token, "cookie=", 7) == 0) {
+			cookie = strtoul(token + 7, NULL, 0);
+			if (!cookie) {
+				wpa_printf(MSG_INFO,
+					   "CTRL: Invalid cookie value: %s",
+					   token + 7);
+				goto fail;
+			}
+
+			cookie_ptr = &cookie;
+			continue;
+		}
+
 		wpa_printf(MSG_INFO,
 			   "CTRL: Invalid NAN_TRANSMIT parameter: %s",
 			   token);
@@ -13305,7 +13320,7 @@ static int wpas_ctrl_nan_transmit(struct wpa_supplicant *wpa_s, char *cmd)
 	}
 
 	ret = wpas_nan_transmit(wpa_s, handle, ssi, NULL, peer_addr,
-				req_instance_id);
+				req_instance_id, cookie_ptr);
 fail:
 	wpabuf_free(ssi);
 	return ret;
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index cb4a8a6d38..a9f5679443 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -7035,7 +7035,7 @@ DBusMessage * wpas_dbus_handler_nan_transmit(DBusMessage *message,
 		goto fail;
 
 	if (wpas_nan_transmit(wpa_s, handle, ssi, NULL, peer_addr,
-			      req_instance_id) < 0)
+			      req_instance_id, NULL) < 0)
 		reply = wpas_dbus_error_unknown_error(
 			message, "failed to transmit follow-up");
 out:
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index a4cc5597fd..82dd82f3a5 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -4000,6 +4000,14 @@ static void wpas_nan_de_receive(void *ctx, int id, int peer_instance_id,
 }
 
 
+static void wpas_nan_de_transmit_req_status(void *ctx, u32 cookie, bool ack)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+
+	wpas_notify_nan_transmit_req_status(wpa_s, cookie, ack);
+}
+
+
 #ifdef CONFIG_P2P
 static void wpas_nan_process_p2p_usd_elems(void *ctx, const u8 *buf,
 					   u16 buf_len, const u8 *peer_addr,
@@ -4051,6 +4059,7 @@ int wpas_nan_de_init(struct wpa_supplicant *wpa_s)
 	cb.offload_cancel_publish = wpas_nan_usd_offload_cancel_publish;
 	cb.offload_cancel_subscribe = wpas_nan_usd_offload_cancel_subscribe;
 	cb.receive = wpas_nan_de_receive;
+	cb.transmit_req_status = wpas_nan_de_transmit_req_status;
 #ifdef CONFIG_P2P
 	cb.process_p2p_usd_elems = wpas_nan_process_p2p_usd_elems;
 #endif /* CONFIG_P2P */
@@ -4387,12 +4396,13 @@ int wpas_nan_usd_subscribe_stop_listen(struct wpa_supplicant *wpa_s,
 
 int wpas_nan_transmit(struct wpa_supplicant *wpa_s, int handle,
 		      const struct wpabuf *ssi, const struct wpabuf *elems,
-		      const u8 *peer_addr, u8 req_instance_id)
+		      const u8 *peer_addr, u8 req_instance_id,
+		      u32 *cookie)
 {
 	if (!wpa_s->nan_de)
 		return -1;
 	return nan_de_transmit(wpa_s->nan_de, handle, ssi, elems, peer_addr,
-			       req_instance_id, NULL, NULL);
+			       req_instance_id, NULL, cookie);
 }
 
 
@@ -4527,6 +4537,11 @@ int wpas_nan_tx_status(struct wpa_supplicant *wpa_s,
 		(const struct ieee80211_mgmt *) data;
 
 	wpa_s = wpas_nan_get_mgmt_iface(wpa_s);
+
+	if (wpa_s->nan_de)
+		nan_de_tx_status(wpa_s->nan_de, 0, mgmt->da, data, data_len,
+				 acked);
+
 	if (!wpas_nan_ndp_allowed(wpa_s))
 		return -1;
 
diff --git a/wpa_supplicant/nan_supplicant.h b/wpa_supplicant/nan_supplicant.h
index 415934fc35..0ebbc545a6 100644
--- a/wpa_supplicant/nan_supplicant.h
+++ b/wpa_supplicant/nan_supplicant.h
@@ -140,7 +140,8 @@ void wpas_nan_cancel_subscribe(struct wpa_supplicant *wpa_s,
 			       int subscribe_id);
 int wpas_nan_transmit(struct wpa_supplicant *wpa_s, int handle,
 		      const struct wpabuf *ssi, const struct wpabuf *elems,
-		      const u8 *peer_addr, u8 req_instance_id);
+		      const u8 *peer_addr, u8 req_instance_id,
+		      u32 *cookie);
 int wpas_nan_tx_status(struct wpa_supplicant *wpa_s,
 		       const u8 *data, size_t data_len, int acked);
 
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index d8aba5a331..d73bb2aced 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -1268,6 +1268,14 @@ void wpas_notify_nan_subscribe_terminated(struct wpa_supplicant *wpa_s,
 }
 
 
+void wpas_notify_nan_transmit_req_status(struct wpa_supplicant *wpa_s,
+					 u32 cookie, bool acked)
+{
+	wpa_msg_global(wpa_s, MSG_INFO, NAN_TRANSMIT_STATUS
+		       "cookie=%u acked=%u", cookie, acked);
+}
+
+
 void wpas_notify_nan_bootstrap_request(struct wpa_supplicant *wpa_s,
 				       const u8 *peer_nmi, u16 pbm,
 				       int handle, u8 requestor_instance_id)
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 260173e928..9c7609ee3d 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -201,6 +201,8 @@ void wpas_notify_nan_publish_terminated(struct wpa_supplicant *wpa_s,
 void wpas_notify_nan_subscribe_terminated(struct wpa_supplicant *wpa_s,
 					  int subscribe_id,
 					  enum nan_de_reason reason);
+void wpas_notify_nan_transmit_req_status(struct wpa_supplicant *wpa_s,
+					 u32 cookie, bool acked);
 void wpas_notify_nan_nik_received(struct wpa_supplicant *wpa_s,
 				  const u8 *nik, size_t nik_len,
 				  int cipher_ver, int akmp,
-- 
2.53.0




More information about the Hostap mailing list