[PATCH 84/97] wpa_supplicant: Add NAN_STATUS command

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


Add NAN_STATUS command, which prints current NAN state, services and
peers.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
 src/common/nan_de.c             | 38 ++++++++++++++++++++++++++++++
 src/common/nan_de.h             |  1 +
 src/nan/nan.c                   | 41 +++++++++++++++++++++++++++++++++
 src/nan/nan.h                   |  1 +
 wpa_supplicant/ctrl_iface.c     |  2 ++
 wpa_supplicant/nan_supplicant.c | 21 +++++++++++++++++
 wpa_supplicant/nan_supplicant.h |  2 ++
 wpa_supplicant/wpa_cli.c        |  7 ++++++
 8 files changed, 113 insertions(+)

diff --git a/src/common/nan_de.c b/src/common/nan_de.c
index f15836bebe..6850a5aa66 100644
--- a/src/common/nan_de.c
+++ b/src/common/nan_de.c
@@ -2794,6 +2794,44 @@ bool nan_de_service_supports_csid(struct nan_de *de, int handle, int csid)
 	return int_array_includes(srv->cipher_suites_list, csid);
 }
 
+
+int nan_de_get_status(struct nan_de *de, char *buf, size_t buflen)
+{
+	char *pos, *end;
+	unsigned int i;
+
+	if (!de)
+		return -1;
+
+	pos = buf;
+	end = buf + buflen;
+
+	pos += os_snprintf(pos, end - pos, "num_services=%u\n",
+			   de->num_service);
+	if (pos >= end)
+		return pos - buf;
+
+	for (i = 0; i < NAN_DE_MAX_SERVICE; i++) {
+		struct nan_de_service *srv = de->service[i];
+
+		if (!srv)
+			continue;
+
+		pos += os_snprintf(pos, end - pos,
+				   "service=%u type=%s name=%s sync=%d\n",
+				   srv->id,
+				   srv->type == NAN_DE_PUBLISH ? "publish" :
+				   (srv->type == NAN_DE_SUBSCRIBE ? "subscribe" :
+				    "unknown"),
+				   srv->service_name ? srv->service_name : "",
+				   srv->sync);
+		if (pos >= end)
+			return pos - buf;
+	}
+
+	return pos - buf;
+}
+
 #ifdef CONFIG_TESTING_OPTIONS
 
 void nan_de_set_tx_mcast_fu_dual_prot(struct nan_de *de,
diff --git a/src/common/nan_de.h b/src/common/nan_de.h
index bf11659efb..fa0e4ce277 100644
--- a/src/common/nan_de.h
+++ b/src/common/nan_de.h
@@ -277,6 +277,7 @@ u16 nan_de_get_service_bootstrap_methods(struct nan_de *de, int handle);
 bool nan_de_service_supports_csid(struct nan_de *de, int handle, int csid);
 void nan_de_set_tx_mcast_fu_dual_prot(struct nan_de *de,
 				      bool tx_mcast_fu_dual_prot);
+int nan_de_get_status(struct nan_de *de, char *buf, size_t buflen);
 
 int nan_de_stop_listen(struct nan_de *de, int handle);
 
diff --git a/src/nan/nan.c b/src/nan/nan.c
index 7badf419cf..869d379acb 100644
--- a/src/nan/nan.c
+++ b/src/nan/nan.c
@@ -3548,3 +3548,44 @@ void nan_local_sched_update(struct nan_data *nan, struct nan_schedule *sched)
 			nan_peer_update_schedule(nan, peer, sched);
 	}
 }
+
+
+int nan_get_status(struct nan_data *nan, char *buf, size_t buflen)
+{
+	char *pos, *end;
+	struct nan_peer *peer;
+
+	if (!nan)
+		return -1;
+
+	pos = buf;
+	end = buf + buflen;
+
+	pos += os_snprintf(pos, end - pos,
+			   "nan_started=%d\n"
+			   "nmi=" MACSTR "\n"
+			   "cluster_id=" MACSTR "\n",
+			   nan->nan_started, MAC2STR(nan->cfg->nmi_addr),
+			   MAC2STR(nan->cluster_id));
+	if (pos >= end)
+		return pos - buf;
+
+	dl_list_for_each(peer, &nan->peer_list, struct nan_peer, list) {
+		struct nan_ndp *ndp;
+		unsigned int ndp_count = 0;
+
+		dl_list_for_each(ndp, &peer->ndps, struct nan_ndp, list)
+			ndp_count++;
+
+		pos += os_snprintf(pos, end - pos,
+				   "peer=" MACSTR " paired=%d ndp_count=%u\n",
+				   MAC2STR(peer->nmi_addr),
+				   !!(peer->pairing.flags &
+				      NAN_PAIRING_FLAG_PAIRED),
+				   ndp_count);
+		if (pos >= end)
+			return pos - buf;
+	}
+
+	return pos - buf;
+}
diff --git a/src/nan/nan.h b/src/nan/nan.h
index 811516ac53..0af1c90f43 100644
--- a/src/nan/nan.h
+++ b/src/nan/nan.h
@@ -874,6 +874,7 @@ int nan_set_mgmt_group_cipher(struct nan_data *nan, int cipher);
 int nan_set_beacon_prot(struct nan_data *nan, bool enable);
 int nan_set_max_ndl_idle_period(struct nan_data *nan, u16 max_idle_period);
 bool nan_has_active_ndp(struct nan_data *nan);
+int nan_get_status(struct nan_data *nan, char *buf, size_t buflen);
 #ifdef CONFIG_PASN
 int nan_pairing_add_attrs(struct nan_data *nan_data, struct wpabuf *buf);
 int nan_pairing_initiate_pasn_auth(struct nan_data *nan_data, const u8 *addr,
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 7a9444c62c..ba0d3124c9 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -14502,6 +14502,8 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
 	} else if (os_strncmp(buf, "NAN_PEER_INFO ", 14) == 0) {
 		reply_len = wpas_nan_peer_info(wpa_s, buf + 14, reply,
 					       reply_size);
+	} else if (os_strcmp(buf, "NAN_STATUS") == 0) {
+		reply_len = wpas_nan_status(wpa_s, reply, reply_size);
 	} else if (os_strncmp(buf, "NAN_BOOTSTRAP ", 14) == 0) {
 		if (wpas_nan_bootstrap_request(wpa_s, buf + 14) < 0)
 			reply_len = -1;
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index 82dd82f3a5..83de8dd441 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -3099,6 +3099,27 @@ int wpas_nan_ndp_terminate(struct wpa_supplicant *wpa_s, char *cmd)
 }
 
 
+int wpas_nan_status(struct wpa_supplicant *wpa_s, char *reply,
+		    size_t reply_size)
+{
+	char *pos = reply;
+	char *end = reply + reply_size;
+	int ret;
+
+	if (!wpas_nan_ready(wpa_s))
+		return -1;
+
+	ret = nan_get_status(wpa_s->nan, pos, end - pos);
+	if (ret > 0)
+		pos += ret;
+
+	ret = nan_de_get_status(wpa_s->nan_de, pos, end - pos);
+	if (ret > 0)
+		pos += ret;
+	return pos - reply;
+}
+
+
 #ifdef CONFIG_PASN
 static int wpas_nan_append_ik_info(char *reply, size_t reply_size,
 				   const struct wpa_dev_ik *ik)
diff --git a/wpa_supplicant/nan_supplicant.h b/wpa_supplicant/nan_supplicant.h
index 0ebbc545a6..463016c9a5 100644
--- a/wpa_supplicant/nan_supplicant.h
+++ b/wpa_supplicant/nan_supplicant.h
@@ -36,6 +36,8 @@ int wpas_nan_ndp_response(struct wpa_supplicant *wpa_s, char *cmd);
 int wpas_nan_ndp_terminate(struct wpa_supplicant *wpa_s, char *cmd);
 int wpas_nan_peer_info(struct wpa_supplicant *wpa_s, const char *cmd,
 		       char *reply, size_t reply_size);
+int wpas_nan_status(struct wpa_supplicant *wpa_s, char *reply,
+		    size_t reply_size);
 int wpas_nan_bootstrap_request(struct wpa_supplicant *wpa_s, char *cmd);
 int wpas_nan_bootstrap_reset(struct wpa_supplicant *wpa_s, char *cmd);
 bool wpas_nan_is_peer_paired(struct wpa_supplicant *wpa_s, const u8 *peer_addr);
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 9a5d631021..62f01ca2f1 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -3455,6 +3455,11 @@ static int wpa_cli_cmd_nan_peer_info(struct wpa_ctrl *ctrl, int argc,
 	return wpa_cli_cmd(ctrl, "NAN_PEER_INFO", 2, argc, argv);
 }
 
+static int wpa_cli_cmd_nan_status(struct wpa_ctrl *ctrl, int argc,
+				  char *argv[])
+{
+	return wpa_ctrl_command(ctrl, "NAN_STATUS");
+}
 
 static int wpa_cli_cmd_nan_bootstrap(struct wpa_ctrl *ctrl, int argc,
 				     char *argv[])
@@ -4292,6 +4297,8 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
 	{ "nan_peer_info", wpa_cli_cmd_nan_peer_info, NULL,
 	  cli_cmd_flag_none,
 	  "<addr> <schedule|potential|capa> [map_id] = Get NAN peer information" },
+	{ "nan_status", wpa_cli_cmd_nan_status, NULL,
+	  cli_cmd_flag_none, "= Get NAN status" },
 	{ "nan_bootstrap", wpa_cli_cmd_nan_bootstrap, NULL,
 	  cli_cmd_flag_none,
 	  " = <peer_mac> <handle=<service handle>> <req_instance_id=<peer requestor id>> <method=<Bootstrap method>> [auth] = Request or authorize NAN boostrapping with peer" },
-- 
2.53.0




More information about the Hostap mailing list