[PATCH 06/97] NAN: Add locally_generated parameter to ndp_disconnected callback

Andrei Otcheretianski andrei.otcheretianski at intel.com
Tue Apr 28 13:05:07 PDT 2026


Add locally_generated parameter to the ndp_disconnected callback to
indicate whether the NDP disconnection was initiated locally or
triggered by the peer. This helps upper layers distinguish between:
- Local disconnections (timeouts, send failures, local setup failures)
- Peer-triggered disconnections (peer rejected NDP/NDL, termination NAF)

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
 src/nan/nan.c                   | 35 ++++++++++++++++++++-------------
 src/nan/nan.h                   |  5 ++++-
 src/nan/nan_module_tests.c      |  4 +++-
 wpa_supplicant/nan_supplicant.c |  5 +++--
 wpa_supplicant/notify.c         |  8 +++++---
 wpa_supplicant/notify.h         |  3 ++-
 6 files changed, 38 insertions(+), 22 deletions(-)

diff --git a/src/nan/nan.c b/src/nan/nan.c
index 1dd583a471..f06d37cb63 100644
--- a/src/nan/nan.c
+++ b/src/nan/nan.c
@@ -22,7 +22,8 @@
 
 static void nan_peer_state_timeout(void *eloop_ctx, void *timeout_ctx);
 static void nan_ndp_disconnected(struct nan_data *nan, struct nan_peer *peer,
-				 enum nan_reason reason);
+				 enum nan_reason reason,
+				 bool locally_generated);
 
 
 struct nan_data * nan_init(const struct nan_config *cfg)
@@ -1378,7 +1379,7 @@ static void nan_peer_state_timeout(void *eloop_ctx, void *timeout_ctx)
 	if (!peer->ndp_setup.ndp)
 		return;
 
-	nan_ndp_disconnected(nan, peer, NAN_REASON_UNSPECIFIED_REASON);
+	nan_ndp_disconnected(nan, peer, NAN_REASON_UNSPECIFIED_REASON, true);
 }
 
 
@@ -1481,7 +1482,8 @@ static int nan_ndp_connected(struct nan_data *nan, struct nan_peer *peer)
 
 
 static void nan_ndp_disconnected(struct nan_data *nan, struct nan_peer *peer,
-				 enum nan_reason reason)
+				 enum nan_reason reason,
+				 bool locally_generated)
 {
 	const u8 *local_ndi, *peer_ndi;
 	struct nan_ndp_id ndp_id;
@@ -1506,7 +1508,8 @@ static void nan_ndp_disconnected(struct nan_data *nan, struct nan_peer *peer,
 
 	if (nan->cfg->ndp_disconnected)
 		nan->cfg->ndp_disconnected(nan->cfg->cb_ctx, &ndp_id,
-					   local_ndi, peer_ndi, reason);
+					   local_ndi, peer_ndi, reason,
+					   locally_generated);
 
 	nan_ndp_setup_stop(nan, peer);
 }
@@ -1557,7 +1560,7 @@ static int nan_action_rx_ndp(struct nan_data *nan, struct nan_peer *peer,
 	if (peer->ndp_setup.status == NAN_NDP_STATUS_REJECTED) {
 		wpa_printf(MSG_DEBUG, "NAN: NAF: NDP rejected");
 
-		nan_ndp_disconnected(nan, peer, peer->ndp_setup.reason);
+		nan_ndp_disconnected(nan, peer, peer->ndp_setup.reason, false);
 		return 0;
 	}
 
@@ -1585,7 +1588,7 @@ static int nan_action_rx_ndp(struct nan_data *nan, struct nan_peer *peer,
 			ret = nan_action_send(nan, peer, resp_oui);
 		}
 
-		nan_ndp_disconnected(nan, peer, reason);
+		nan_ndp_disconnected(nan, peer, reason, false);
 		return 0;
 	}
 
@@ -1602,7 +1605,8 @@ static int nan_action_rx_ndp(struct nan_data *nan, struct nan_peer *peer,
 		if (nan_configure_peer_schedule(nan, peer, &peer->ndl->sched) ||
 		    nan_ndp_connected(nan, peer))
 			nan_ndp_disconnected(nan, peer,
-					     NAN_REASON_UNSPECIFIED_REASON);
+					     NAN_REASON_UNSPECIFIED_REASON,
+					     true);
 		return 0;
 	}
 
@@ -1611,7 +1615,8 @@ static int nan_action_rx_ndp(struct nan_data *nan, struct nan_peer *peer,
 	if (ret) {
 		wpa_printf(MSG_DEBUG,
 			   "NAN: NAF: Failed to send NAF. Resetting..");
-		nan_ndp_disconnected(nan, peer, NAN_REASON_UNSPECIFIED_REASON);
+		nan_ndp_disconnected(nan, peer, NAN_REASON_UNSPECIFIED_REASON,
+				     true);
 	}
 
 	nan_set_peer_timeout(nan, peer, NAN_NDP_SETUP_TIMEOUT_SHORT, 0);
@@ -1892,7 +1897,8 @@ int nan_tx_status(struct nan_data *nan, const u8 *dst, const u8 *data,
 			   ret);
 
 		if (peer->ndp_setup.ndp)
-			nan_ndp_disconnected(nan, peer, peer->ndp_setup.reason);
+			nan_ndp_disconnected(nan, peer, peer->ndp_setup.reason,
+					     true);
 		return 0;
 	}
 
@@ -1903,7 +1909,8 @@ int nan_tx_status(struct nan_data *nan, const u8 *dst, const u8 *data,
 		if (nan_configure_peer_schedule(nan, peer, &peer->ndl->sched) ||
 		    nan_ndp_connected(nan, peer))
 			nan_ndp_disconnected(nan, peer,
-					     NAN_REASON_UNSPECIFIED_REASON);
+					     NAN_REASON_UNSPECIFIED_REASON,
+					     true);
 	}
 
 	return 0;
@@ -2046,7 +2053,7 @@ int nan_handle_ndp_setup(struct nan_data *nan, struct nan_ndp_params *params)
 	if (ret) {
 		wpa_printf(MSG_DEBUG,
 			   "NAN: Failed sending NAF. Resetting: ret=%d", ret);
-		nan_ndp_disconnected(nan, peer, peer->ndp_setup.reason);
+		nan_ndp_disconnected(nan, peer, peer->ndp_setup.reason, true);
 		return 0;
 	}
 
@@ -2061,7 +2068,7 @@ void nan_ndp_terminated(struct nan_data *nan, struct nan_peer *peer,
 {
 	if (nan->cfg->ndp_disconnected)
 		nan->cfg->ndp_disconnected(nan->cfg->cb_ctx, ndp_id, local_ndi,
-					   peer_ndi, reason);
+					   peer_ndi, reason, false);
 
 	/* Need to also remove the NDL if it is not needed */
 	if (dl_list_empty(&peer->ndps) && !peer->ndp_setup.ndp)
@@ -2595,8 +2602,8 @@ int nan_peer_del_all_ndps(struct nan_data *nan, const u8 *addr)
 	dl_list_for_each_safe(ndp, tndp, &peer->ndps, struct nan_ndp, list) {
 		dl_list_del(&ndp->list);
 		peer->ndp_setup.ndp = ndp;
-		nan_ndp_disconnected(nan, peer,
-				     NAN_REASON_UNSPECIFIED_REASON);
+		nan_ndp_disconnected(nan, peer, NAN_REASON_UNSPECIFIED_REASON,
+				     true);
 	}
 
 	nan_ndl_reset(nan, peer);
diff --git a/src/nan/nan.h b/src/nan/nan.h
index b4f47dcf78..983e81b56c 100644
--- a/src/nan/nan.h
+++ b/src/nan/nan.h
@@ -488,6 +488,8 @@ struct nan_config {
 	 * @local_ndi: Local NDI MAC address
 	 * @peer_ndi: Peer NDI MAC address
 	 * @reason: Disconnection reason
+	 * @locally_generated: true if the disconnection was locally generated,
+	 *     false if triggered by the peer
 	 *
 	 * This callback notifies that an NDP has been disconnected. It can be
 	 * called both during NDP establishment (indicating failure) or after
@@ -495,7 +497,8 @@ struct nan_config {
 	 */
 	void (*ndp_disconnected)(void *ctx, struct nan_ndp_id *ndp_id,
 				 const u8 *local_ndi, const u8 *peer_ndi,
-				 enum nan_reason reason);
+				 enum nan_reason reason,
+				 bool locally_generated);
 
 	/**
 	 * get_chans - Get the prioritized allowed channel information to be
diff --git a/src/nan/nan_module_tests.c b/src/nan/nan_module_tests.c
index 7181729500..30d559642b 100644
--- a/src/nan/nan_module_tests.c
+++ b/src/nan/nan_module_tests.c
@@ -639,6 +639,7 @@ static int nan_test_ndp_connected_cb(void *ctx,
  * @local_ndi: Local NDI address
  * @peer_ndi: Peer NDI address
  * @reason: Reason for disconnection
+ * @locally_generated: true if locally generated, false if triggered by peer
  *
  * The handling of the event is done asynchronously through the NAN test actions
  * processing.
@@ -646,7 +647,8 @@ static int nan_test_ndp_connected_cb(void *ctx,
 static void nan_test_ndp_disconnected_cb(void *ctx, struct nan_ndp_id *ndp_id,
 					 const u8 *local_ndi,
 					 const u8 *peer_ndi,
-					 enum nan_reason reason)
+					 enum nan_reason reason,
+					 bool locally_generated)
 {
 	struct nan_device *dev = ctx;
 
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index 7c9e7c3e79..93c65694bf 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -610,14 +610,15 @@ static int wpas_nan_ndp_connected_cb(void *ctx,
 static void wpas_nan_ndp_disconnected_cb(void *ctx, struct nan_ndp_id *ndp_id,
 					 const u8 *local_ndi,
 					 const u8 *peer_ndi,
-					 enum nan_reason reason)
+					 enum nan_reason reason,
+					 bool locally_generated)
 {
 	struct wpa_supplicant *wpa_s = ctx;
 
 	wpas_nan_remove_ndi_sta(wpa_s, local_ndi, peer_ndi);
 	wpas_notify_nan_ndp_disconnected(wpa_s, ndp_id->peer_nmi,
 					 ndp_id->id, local_ndi, peer_ndi,
-					 reason);
+					 reason, locally_generated);
 }
 
 
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index f36f667618..c445aba316 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -1435,13 +1435,15 @@ void wpas_notify_nan_ndp_disconnected(struct wpa_supplicant *wpa_s,
 				      const u8 *peer_nmi, u32 ndp_id,
 				      const u8 *local_ndi,
 				      const u8 *peer_ndi,
-				      enum nan_reason reason)
+				      enum nan_reason reason,
+				      bool locally_generated)
 {
 	wpa_msg_global(wpa_s, MSG_INFO, NAN_NDP_DISCONNECTED
 		       "peer=" MACSTR " ndp_id=%u local_ndi=" MACSTR
-		       " peer_ndi=" MACSTR " reason=%u",
+		       " peer_ndi=" MACSTR " reason=%u locally_generated=%d",
 		       MAC2STR(peer_nmi), ndp_id,
-		       MAC2STR(local_ndi), MAC2STR(peer_ndi), reason);
+		       MAC2STR(local_ndi), MAC2STR(peer_ndi), reason,
+		       locally_generated);
 }
 
 
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index f51cdbeef4..1a593a4fdb 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -242,7 +242,8 @@ void wpas_notify_nan_ndp_connected(struct wpa_supplicant *wpa_s,
 void wpas_notify_nan_ndp_disconnected(struct wpa_supplicant *wpa_s,
 				      const u8 *peer_nmi, u32 ndp_id,
 				      const u8 *local_ndi, const u8 *peer_ndi,
-				      enum nan_reason reason);
+				      enum nan_reason reason,
+				      bool locally_generated);
 void wpas_notify_nan_cluster_join(struct wpa_supplicant *wpa_s,
 				  const u8 *cluster_id, bool new_cluster);
 void wpas_notify_nan_pairing_status(struct wpa_supplicant *wpa_s,
-- 
2.53.0




More information about the Hostap mailing list