[RFC 32/56] NAN: Add Tx status handling

Andrei Otcheretianski andrei.otcheretianski at intel.com
Sun Dec 7 03:18:41 PST 2025


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

Add handling of Tx status notification for the NAN
module:

1. If the NAN Action Frame (NAF) was not acked, stop
   the NDP establishment.
2. If the NAF was acked, forward the notification to
   NDP and NDL state machines. If they indicate error,
   stop the NDP establishment.
3. If both state machines return with success, and both
   indicate that they are done, complete the NDP establishment.

Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 src/nan/nan.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/nan/nan.h |  3 ++-
 2 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/src/nan/nan.c b/src/nan/nan.c
index cb872c10f2..396a3af37a 100644
--- a/src/nan/nan.c
+++ b/src/nan/nan.c
@@ -1404,3 +1404,62 @@ void nan_set_cluster_id(struct nan_data *nan, const u8 *cluster_id)
 {
 	os_memcpy(nan->cluster_id, cluster_id, sizeof(nan->cluster_id));
 }
+
+/*
+ * nan_tx_status - Notification of the result of a transmitted NAN Action Frame
+ * @nan: NAN module context from nan_init()
+ * @dst: Destination address of the transmitted frame
+ * @data: The transmitted frame
+ * @data_len: Length of the transmitted frame in octets
+ * @acked: Whether the frame was acknowledged
+ * Return 0 if the frame is a NAF and -1 if not.
+ */
+int nan_tx_status(struct nan_data *nan, const u8 *dst, const u8 *data,
+		  size_t data_len, u8 acked)
+{
+	struct nan_peer *peer;
+	const struct ieee80211_mgmt *mgmt = (const struct ieee80211_mgmt *)data;
+	u8 subtype;
+	int ret;
+
+	if (!nan_is_naf(nan, mgmt, data_len) || !dst)
+		return -1;
+
+	wpa_printf(MSG_DEBUG,
+		   "NAN: TX status: peer=" MACSTR " ,acked=%u",
+		   MAC2STR(dst), acked);
+
+	peer = nan_get_peer(nan, dst);
+	if (!peer) {
+		wpa_printf(MSG_DEBUG,
+			   "NAN: TX status: peer not found");
+		return 0;
+	}
+
+	subtype = mgmt->u.action.u.naf.subtype;
+
+	ret = nan_ndp_naf_sent(nan, peer, subtype);
+	ret |= nan_ndl_naf_sent(nan, peer, subtype);
+
+	if (ret || peer->ndp_setup.status == NAN_NDP_STATUS_REJECTED ||
+	    !peer->ndl || peer->ndl->status == NAN_NDL_STATUS_REJECTED) {
+		wpa_printf(MSG_DEBUG,
+			   "NAN: TX status: stopping NDP establishment. ret=%d",
+			ret);
+
+		if (peer->ndp_setup.ndp)
+			nan_ndp_disconnected(nan, peer,
+					     peer->ndp_setup.reason);
+		return 0;
+	}
+
+	/* Both state machines are done */
+	if (peer->ndp_setup.state == NAN_NDP_STATE_DONE &&
+	    peer->ndl->state == NAN_NDL_STATE_DONE) {
+		wpa_printf(MSG_DEBUG, "NAN: TX status:  NDP setup done");
+
+		nan_ndp_connected(nan, peer);
+	}
+
+	return 0;
+}
diff --git a/src/nan/nan.h b/src/nan/nan.h
index ab42711408..99dd962df0 100644
--- a/src/nan/nan.h
+++ b/src/nan/nan.h
@@ -415,5 +415,6 @@ bool nan_publish_instance_id_valid(struct nan_data *nan, u8 instance_id,
 void nan_set_cluster_id(struct nan_data *nan, const u8 *cluster_id);
 int nan_action_rx(struct nan_data *nan, const struct ieee80211_mgmt *mgmt,
 		  size_t len);
-
+int nan_tx_status(struct nan_data *nan, const u8 *dst, const u8 *data,
+		  size_t data_len, u8 acked);
 #endif /* NAN_H */
-- 
2.49.0




More information about the Hostap mailing list