[RFC 49/56] NAN: Add an API to get the potential availability of a peer

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


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

Add an API to retrieve the potential availability of a
peer device.

In addition add a function to dump this schedule to a
buffer in a readable form.

Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 src/nan/nan.c      | 64 ++++++++++++++++++++++++++++++++++++++++++++++
 src/nan/nan.h      | 36 ++++++++++++++++++++++++++
 src/nan/nan_util.c | 55 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 155 insertions(+)

diff --git a/src/nan/nan.c b/src/nan/nan.c
index 2aa76fd982..3e2839381b 100644
--- a/src/nan/nan.c
+++ b/src/nan/nan.c
@@ -1982,3 +1982,67 @@ int nan_peer_get_schedule_info(struct nan_data *nan, const u8 *addr,
 
 	return 0;
 }
+
+/*
+ * nan_peer_get_pot_avail - Get peer's potential availability entries
+ * @nan: NAN module context from nan_init()
+ * @addr: NAN MAC address of the peer
+ * @pot_avail: On return would hold the potential availability entries.
+ * Return 0 on success; -1 otherwise.
+ */
+int nan_peer_get_pot_avail(struct nan_data *nan, const u8 *addr,
+			   struct nan_peer_potential_avail *pot_avail)
+{
+	struct nan_avail_entry *avail;
+	struct nan_peer *peer;
+	u8 i;
+
+	if (!nan || !pot_avail)
+		return -1;
+
+	os_memset(pot_avail, 0, sizeof(*pot_avail));
+
+	peer = nan_get_peer(nan, addr);
+	if (!peer)
+		return -1;
+
+	dl_list_for_each(avail, &peer->info.avail_entries,
+			 struct nan_avail_entry, list) {
+		struct pot_entry *pot;
+
+		if (avail->type != NAN_AVAIL_ENTRY_CTRL_TYPE_POTENTIAL)
+			continue;
+
+		if (pot_avail->n_maps == NAN_MAX_MAPS) {
+			wpa_printf(MSG_DEBUG,
+				   "NAN: Too many potential maps stored");
+			break;
+		}
+
+		pot = &pot_avail->maps[pot_avail->n_maps++];
+		pot->rx_nss = avail->rx_nss;
+		pot->preference = avail->preference;
+		pot->utilization = avail->utilization;
+		pot->is_band = avail->band_chan_type == NAN_TYPE_BAND;
+
+		for (i = 0; i < avail->n_band_chan; i++, pot->n_band_chan++) {
+			if (pot->n_band_chan == NAN_MAX_CHAN_ENTRIES) {
+				wpa_printf(MSG_DEBUG,
+					   "NAN: Too many band_chan entries stored for potential entry");
+				break;
+			}
+
+			if (pot->is_band) {
+				pot->entries[i].band_id =
+					avail->band_chan[i].u.band_id;
+			} else {
+				pot->entries[i].op_class =
+					avail->band_chan[i].u.chan.op_class;
+				pot->entries[i].chan_bitmap =
+					le_to_host16(avail->band_chan[i].u.chan.chan_bitmap);
+			}
+		}
+	}
+
+	return 0;
+}
diff --git a/src/nan/nan.h b/src/nan/nan.h
index 1f9e4edfb1..74686a3b28 100644
--- a/src/nan/nan.h
+++ b/src/nan/nan.h
@@ -355,6 +355,38 @@ struct nan_peer_schedule {
 	} maps[NAN_MAX_MAPS];
 };
 
+/**
+ * struct nan_peer_potential_avail - NAN peer potential availability
+ *
+ * @n_maps: Number of maps
+ * @maps: Array of maps
+ * @is_band: Indicates whether the entries are bands or channels
+ * @preference: Preference value for the availability entry
+ * @utilization: Utilization value for the availability entry
+ * @rx_nss: Number of spatial streams supported by the peer for RX during
+ *     the time indicated by the availability entry
+ * @n_band_chan: Number of band/channel entries
+ * @entries: Array of band/channel entries
+ */
+struct nan_peer_potential_avail {
+	u8 n_maps;
+	struct pot_entry {
+		bool is_band;
+		u8 preference;
+		u8 utilization;
+		u8 rx_nss;
+
+		u8 n_band_chan;
+		union pot_band_chan{
+			u8 band_id;
+			struct {
+				u8 op_class;
+				u16 chan_bitmap;
+			};
+		} entries[NAN_MAX_CHAN_ENTRIES];
+	} maps[NAN_MAX_MAPS];
+};
+
 struct nan_config {
 	void *cb_ctx;
 	u8 nmi_addr[ETH_ALEN];
@@ -495,4 +527,8 @@ int nan_peer_get_schedule_info(struct nan_data *nan, const u8 *addr,
 			       struct nan_peer_schedule *sched);
 int nan_peer_dump_sched_to_buf(struct nan_peer_schedule *sched,
 			       char *buf, size_t buflen);
+int nan_peer_get_pot_avail(struct nan_data *nan, const u8 *addr,
+			   struct nan_peer_potential_avail *pot_avail);
+int nan_peer_dump_pot_avail_to_buf(struct nan_peer_potential_avail *pot_avail,
+				   char *buf, size_t buflen);
 #endif /* NAN_H */
diff --git a/src/nan/nan_util.c b/src/nan/nan_util.c
index 2b7afc1fb9..2288f889f3 100644
--- a/src/nan/nan_util.c
+++ b/src/nan/nan_util.c
@@ -1555,3 +1555,58 @@ err:
 	wpa_printf(MSG_DEBUG, "NAN: Buffer too small to dump peer schedule");
 	return -1;
 }
+
+
+/**
+ * nan_peer_dump_pot_avail_to_buf - Dump peer potential availability to a
+ * buffer.
+ *
+ * @pot_avail: Peer potential availability
+ * @buf: Output buffer
+ * @buflen: Length of &buf in bytes
+ *
+ * Returns: The number of characters written to the buffer, or -1 on error,
+ * which indicates that the buffer was too small.
+ */
+int nan_peer_dump_pot_avail_to_buf(struct nan_peer_potential_avail *pot_avail,
+				   char *buf, size_t buflen)
+{
+	u8 i, j;
+	int ret;
+	char *pos = buf;
+	char *end = buf + buflen;
+
+	for (i = 0; i < pot_avail->n_maps; i++) {
+		struct pot_entry *pot = &pot_avail->maps[i];
+
+		ret = wpa_scnprintf(pos, end - pos,
+				    "entry[%u]: rx_nss=%u pref=%u util=%u\n",
+				    i, pot->rx_nss, pot->preference,
+				    pot->utilization);
+		if (os_snprintf_error(end - pos, ret))
+			goto err;
+		pos += ret;
+
+		for (j = 0; j < pot->n_band_chan; j++) {
+			if (pot->is_band) {
+				ret = wpa_scnprintf(pos, end - pos,
+						    "\tband[%u]: band_id=%u\n",
+						    j, pot->entries[j].band_id);
+			} else {
+				ret = wpa_scnprintf(pos, end - pos,
+						    "\tchan[%u]: op_class=%u chan_bitmap=0x%04x\n",
+						    j, pot->entries[j].op_class,
+						    pot->entries[j].chan_bitmap);
+			}
+			if (os_snprintf_error(end - pos, ret))
+				goto err;
+			pos += ret;
+		}
+	}
+
+	return pos - buf;
+err:
+	wpa_printf(MSG_DEBUG,
+		   "NAN: Buffer too small to dump peer potential availability");
+	return -1;
+}
-- 
2.49.0




More information about the Hostap mailing list