[PATCH 03/18] NAN: Match availability channels by their control channel

Andrei Otcheretianski andrei.otcheretianski at intel.com
Mon Oct 12 08:46:37 PDT 2026


Two devices may describe the very same channel differently: a device
limited to 20 MHz advertises an operating class of 20 MHz, while a
device that can use the whole 80 MHz advertises the wider operating
class with a primary channel bitmap. Such devices can still talk to
each other, so the channels have to be compared by the control channel
they resolve to rather than by the encoding used to advertise them.

nan_avail_entries_to_bf() already does that, but
nan_sched_bf_from_avail_and_chan() only compared the operating class
and the channel bitmap.

Compare the control channel there as well, and take the channel to
match as a struct nan_sched_chan, as the callers already have one.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
 src/nan/nan_i.h    |  3 ++-
 src/nan/nan_ndl.c  | 11 +++++------
 src/nan/nan_util.c | 24 ++++++++++++++----------
 3 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/src/nan/nan_i.h b/src/nan/nan_i.h
index 4b4deca0dd..635a65817a 100644
--- a/src/nan/nan_i.h
+++ b/src/nan/nan_i.h
@@ -827,7 +827,8 @@ bool nan_sched_covered_by_avail_entries(struct nan_data *nan,
 					const u8 *sched, size_t sched_len);
 bool nan_sched_bf_covered_by_avail_entries_and_chan(
 	struct nan_data *nan, const struct dl_list *avail_entries,
-	struct bitfield *sched_bf, u8 map_id, u8 op_class, u16 cbm);
+	struct bitfield *sched_bf, u8 map_id,
+	const struct nan_sched_chan *chan);
 struct bitfield * nan_avail_entries_to_bf(struct nan_data *nan,
 					  const struct dl_list *avail_entries,
 					  u8 op_class, u16 cbm, u16 pri_cbm);
diff --git a/src/nan/nan_ndl.c b/src/nan/nan_ndl.c
index fe3367d708..8ff1cc10af 100644
--- a/src/nan/nan_ndl.c
+++ b/src/nan/nan_ndl.c
@@ -253,8 +253,7 @@ enum nan_ndl_ver {
  * @sched_len: Length of the &sched array
  * @common_bf: Bitfield representing the intersection of local and peer
  *     availability
- * @op_class: Local operating class
- * @cbm: Local channel bitmap
+ * @chan: Channel to match against, or %NULL to match any channel
  *
  * Returns one of enum nan_ndl_ver. In case of on an error
  * NAN_NDL_VER_SCHED_NONE is returned.
@@ -274,7 +273,7 @@ nan_ndl_match_sched_vs_common(struct nan_data *nan,
 			      struct dl_list *avail_entries,
 			      const u8 *sched, size_t sched_len,
 			      const struct bitfield *common_bf,
-			      u8 op_class, u16 cbm)
+			      const struct nan_sched_chan *chan)
 {
 	struct dl_list sched_entries;
 	struct bitfield *sched_bf;
@@ -304,7 +303,7 @@ nan_ndl_match_sched_vs_common(struct nan_data *nan,
 	 * covered by the peer availability entries for the given channel.
 	 */
 	ret = nan_sched_bf_covered_by_avail_entries_and_chan(
-		nan, avail_entries, sched_bf, map_id, op_class, cbm);
+		nan, avail_entries, sched_bf, map_id, chan);
 	if (ret) {
 		int ret2;
 
@@ -638,7 +637,7 @@ static enum nan_ndl_status nan_ndl_determine_status(struct nan_data *nan,
 						&peer->info.avail_entries,
 						peer->ndl->immut_sched,
 						peer->ndl->immut_sched_len,
-						common_bf, 0, 0);
+						common_bf, NULL);
 	if (verdict != NAN_NDL_VER_SCHED_IDENTICAL_OF_LOCAL &&
 	    verdict != NAN_NDL_VER_SCHED_SUBSET_OF_LOCAL) {
 		wpa_printf(MSG_DEBUG,
@@ -669,7 +668,7 @@ static enum nan_ndl_status nan_ndl_determine_status(struct nan_data *nan,
 	verdict = nan_ndl_match_sched_vs_common(nan, &peer->info.avail_entries,
 						peer->ndl->ndc_sched,
 						peer->ndl->ndc_sched_len,
-						ndc_bf, 0, 0);
+						ndc_bf, NULL);
 	if (verdict != NAN_NDL_VER_SCHED_IDENTICAL_OF_LOCAL) {
 		wpa_printf(MSG_DEBUG,
 			   "NAN: Response NDC does not match req NDC");
diff --git a/src/nan/nan_util.c b/src/nan/nan_util.c
index 95410cd91e..954c3ade00 100644
--- a/src/nan/nan_util.c
+++ b/src/nan/nan_util.c
@@ -1386,13 +1386,15 @@ bool nan_sched_covered_by_avail_entry(struct nan_data *nan,
 static struct bitfield *
 nan_sched_bf_from_avail_and_chan(struct nan_data *nan,
 				 const struct dl_list *avail_entries,
-				 u8 map_id, u8 op_class, u16 cbm)
+				 u8 map_id,
+				 const struct nan_sched_chan *chan)
 {
 	struct nan_avail_entry *avail;
 	struct bitfield *res_bf = NULL;
 
 	dl_list_for_each(avail, avail_entries, struct nan_avail_entry,
 			 list) {
+		struct nan_sched_chan avail_chan;
 		struct bitfield *avail_bf;
 
 		if (avail->map_id != map_id)
@@ -1403,12 +1405,14 @@ nan_sched_bf_from_avail_and_chan(struct nan_data *nan,
 		    avail->type != NAN_AVAIL_ENTRY_CTRL_TYPE_COND)
 			continue;
 
-		/* Now check channel, if it is given */
-		if (op_class && cbm &&
+		/* Now check the channel, if it is given */
+		if (chan &&
 		    (avail->n_band_chan < 1 ||
 		     avail->band_chan_type != NAN_TYPE_CHANNEL ||
-		     avail->band_chan[0].u.chan.op_class != op_class ||
-		     !(avail->band_chan[0].u.chan.chan_bitmap & cbm)))
+		     nan_chan_entry_to_sched_chan(nan,
+						  &avail->band_chan[0].u.chan,
+						  &avail_chan) ||
+		     avail_chan.freq != chan->freq))
 			continue;
 
 		/* Convert the availability entry to bitfield */
@@ -1479,7 +1483,7 @@ bool nan_sched_covered_by_avail_entries(struct nan_data *nan,
 	nan_flush_avail_entries(&sched_entries);
 
 	avail_bf = nan_sched_bf_from_avail_and_chan(nan, avail_entries,
-						    map_id, 0, 0);
+						    map_id, NULL);
 	if (avail_bf)
 		ret = bitfield_is_subset(avail_bf, sched_bf) ? true : false;
 
@@ -1501,13 +1505,13 @@ bool nan_sched_covered_by_avail_entries(struct nan_data *nan,
  * @avail_entries: A list of availability entries. See &struct nan_avail_entry
  * @sched_bf: the bitfield representing the schedule
  * @map_id: Map ID associated with the schedule
- * @op_class: Operating class to match against
- * @cbm: Channel bitmap to match against
+ * @chan: Channel to match against, or %NULL to match any channel
  * Returns: true of schedule is covered by the entries; otherwise false
  */
 bool nan_sched_bf_covered_by_avail_entries_and_chan(
 	struct nan_data *nan, const struct dl_list *avail_entries,
-	struct bitfield *sched_bf, u8 map_id, u8 op_class, u16 cbm)
+	struct bitfield *sched_bf, u8 map_id,
+	const struct nan_sched_chan *chan)
 {
 	struct bitfield *avail_bf;
 	bool ret = false;
@@ -1517,7 +1521,7 @@ bool nan_sched_bf_covered_by_avail_entries_and_chan(
 	 * the map ID and channel configuration.
 	 */
 	avail_bf = nan_sched_bf_from_avail_and_chan(nan, avail_entries,
-						    map_id, op_class, cbm);
+						    map_id, chan);
 
 	/*
 	 * If there is such a schedule, verify that it is a superset of the
-- 
2.53.0




More information about the Hostap mailing list