{"id":2198419,"url":"http://patchwork.ozlabs.org/api/1.0/patches/2198419/?format=json","project":{"id":22,"url":"http://patchwork.ozlabs.org/api/1.0/projects/22/?format=json","name":"HostAP Development","link_name":"hostap","list_id":"hostap.lists.infradead.org","list_email":"hostap@lists.infradead.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20260219202514.5781-23-andrei.otcheretianski@intel.com>","date":"2026-02-19T20:24:38","name":"[22/58] NAN: Add potential availability entries","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"2fc0d0870c2b4155397820a8eb810cc5d5bc4da4","submitter":{"id":62065,"url":"http://patchwork.ozlabs.org/api/1.0/people/62065/?format=json","name":"Andrei Otcheretianski","email":"andrei.otcheretianski@intel.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/hostap/patch/20260219202514.5781-23-andrei.otcheretianski@intel.com/mbox/","series":[{"id":492721,"url":"http://patchwork.ozlabs.org/api/1.0/series/492721/?format=json","date":"2026-02-19T20:24:21","name":"NAN: Add NAN Data Path (NDP) support","version":1,"mbox":"http://patchwork.ozlabs.org/series/492721/mbox/"}],"check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2198419/checks/","tags":{},"headers":{"Return-Path":"\n <hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n secure) header.d=lists.infradead.org header.i=@lists.infradead.org\n header.a=rsa-sha256 header.s=bombadil.20210309 header.b=ICyOzTtJ;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256\n header.s=Intel header.b=nqvMeuWY;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=none (no SPF record) smtp.mailfrom=lists.infradead.org\n (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org;\n envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from bombadil.infradead.org (bombadil.infradead.org\n [IPv6:2607:7c80:54:3::133])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fH4g84y6bz1xpY\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 20 Feb 2026 07:27:16 +1100 (AEDT)","from localhost ([::1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1vtAbm-0000000Bx8A-3j0u;\n\tThu, 19 Feb 2026 20:26:47 +0000","from mgamail.intel.com ([198.175.65.10])\n\tby bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1vtAba-0000000BwCB-46SU\n\tfor hostap@lists.infradead.org;\n\tThu, 19 Feb 2026 20:26:40 +0000","from orviesa004.jf.intel.com ([10.64.159.144])\n  by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 19 Feb 2026 12:26:35 -0800","from aotchere-mobl1.ger.corp.intel.com (HELO\n aotchere-mobl1.intel.com) ([10.245.246.171])\n  by orviesa004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 19 Feb 2026 12:26:31 -0800"],"DKIM-Signature":["v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=lists.infradead.org; s=bombadil.20210309; h=Sender:\n\tContent-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:\n\tList-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:\n\tMessage-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description:\n\tResent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:\n\tList-Owner; bh=YIUQPEtJHf+PA1GF5F6tF68nl65g39odm2V/dNJZjE0=; b=ICyOzTtJ090wl9\n\tEK2kOXhI3zzUzXPCPv9i5U7c16kReMmIs3VSSu31gVjOpyice4kWb9i5rcDW+vUomRx5w8AEjG2zb\n\tcRoSJWqBCFkKmAnEqkhNgBYgkwXgmicsoImfH+iJBFGHkTr2oBGqtXV7HCqFLmbbOU0/57Kyctu5h\n\tGVY3hpWpKTXE7DvQFjKEDLl8diA2DlsEI210GanHSlgcqdLgPYQus0dXNOUH4ZTooKaUF9fR+q0pp\n\tHg2CgqR3HgQraoYLlPmiZjxf3p2/OWVPBN1nRmdVK25fqWN3BVyw6nqa5LuFmTpL6K1hms3G6ou6k\n\tnSwDgUsNQCa1ZcAs8r8A==;","v=1; a=rsa-sha256; c=relaxed/simple;\n  d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n  t=1771532795; x=1803068795;\n  h=from:to:cc:subject:date:message-id:in-reply-to:\n   references:mime-version:content-transfer-encoding;\n  bh=DHFFDjjp0IHIv65uDef0oMZ+XGPmBXK0TNbygN2fWu8=;\n  b=nqvMeuWY4OXE5FdDn+8X+2zwnBx/d5JZUiiIGi7Iiy29xmXYHJegYL25\n   sdDhyxBAWRvR3+0LV5p+zozSGfrUZyHqiqJUJOzo2wkKZQL50lyjN2iZq\n   4HIZGhU5bG4bepMbknmc3Dl+gWZMIgfvqbqF7w0Yw5aGbxN6nxYZI8jt1\n   ovSm09bHp76CyOWz/Mcuwn6CnqY/fuzvjerMYRCyP14gLxY9aqO+VhHAH\n   GSBpClycKJJmBEOKFJrSTlOAtzNL7h5VQVnNvCJzo8vouR06Ps7eFPC7t\n   +e+2wpEGOtShZi0oI2EBXxr5guFXE8K8omQ+v50O60he9v7C3N9C3BDEA\n   A==;"],"X-CSE-ConnectionGUID":["SN+lOmtPTT2wcnyGThDPaw==","y0EWetyaQ9ucjk0QMzZuHw=="],"X-CSE-MsgGUID":["GpFsG7mURS2ZGwzIq+2ffQ==","jtQICj5sRZyCdOfRP6DDMw=="],"X-IronPort-AV":["E=McAfee;i=\"6800,10657,11706\"; a=\"90040014\"","E=Sophos;i=\"6.21,300,1763452800\";\n   d=\"scan'208\";a=\"90040014\"","E=Sophos;i=\"6.21,300,1763452800\";\n   d=\"scan'208\";a=\"219153846\""],"X-ExtLoop1":"1","From":"Andrei Otcheretianski <andrei.otcheretianski@intel.com>","To":"hostap@lists.infradead.org,\n\tvamsin@qti.qualcomm.com,\n\tvganneva@qti.qualcomm.com,\n\tmaheshkkv@google.com","Cc":"Ilan Peer <ilan.peer@intel.com>","Subject":"[PATCH 22/58] NAN: Add potential availability entries","Date":"Thu, 19 Feb 2026 22:24:38 +0200","Message-ID":"<20260219202514.5781-23-andrei.otcheretianski@intel.com>","X-Mailer":"git-send-email 2.52.0","In-Reply-To":"<20260219202514.5781-1-andrei.otcheretianski@intel.com>","References":"<20260219202514.5781-1-andrei.otcheretianski@intel.com>","MIME-Version":"1.0","X-CRM114-Version":"20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 ","X-CRM114-CacheID":"sfid-20260219_122635_192069_A6632586 ","X-CRM114-Status":"GOOD (  28.86  )","X-Spam-Score":"-4.4 (----)","X-Spam-Report":"Spam detection software,\n running on the system \"bombadil.infradead.org\",\n has NOT identified this incoming email as spam.  The original\n message has been attached to this so you can view it or label\n similar future email.  If you have any questions, see\n the administrator of that system for details.\n Content preview:  From: Ilan Peer <ilan.peer@intel.com> Add support for\n adding\n    potential availability entries to the availability attribute. The\n potential\n    availability entries are constructed using the channels supported by the\n   upper layer. These channels are retrieved using a callback that is expected\n    to provide the supported channels and [...]\n Content analysis details:   (-4.4 points, 5.0 required)\n  pts rule name              description\n ---- ----------------------\n --------------------------------------------------\n -2.3 RCVD_IN_DNSWL_MED      RBL: Sender listed at https://www.dnswl.org/,\n                             medium trust\n                             [198.175.65.10 listed in list.dnswl.org]\n  0.0 RCVD_IN_VALIDITY_SAFE_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to\n                              Validity was blocked.  See\n                             https://knowledge.validity.com/hc/en-us/articles/20961730681243\n                              for more information.\n                             [198.175.65.10 listed in sa-accredit.habeas.com]\n  0.0 RCVD_IN_VALIDITY_CERTIFIED_BLOCKED RBL: ADMINISTRATOR NOTICE: The\n                             query to Validity was blocked.  See\n                             https://knowledge.validity.com/hc/en-us/articles/20961730681243\n                              for more information.\n                          [198.175.65.10 listed in\n sa-trusted.bondedsender.org]\n  0.0 RCVD_IN_VALIDITY_RPBL_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to\n                              Validity was blocked.  See\n                             https://knowledge.validity.com/hc/en-us/articles/20961730681243\n                              for more information.\n                             [198.175.65.10 listed in\n bl.score.senderscore.com]\n -0.0 SPF_PASS               SPF: sender matches SPF record\n  0.0 SPF_HELO_NONE          SPF: HELO does not publish an SPF Record\n -0.1 DKIM_VALID_AU          Message has a valid DKIM or DK signature from\n author's\n                             domain\n -0.1 DKIM_VALID_EF          Message has a valid DKIM or DK signature from\n                             envelope-from domain\n -0.1 DKIM_VALID             Message has at least one valid DKIM or DK\n signature\n  0.1 DKIM_SIGNED            Message has a DKIM or DK signature,\n not necessarily valid\n -1.9 BAYES_00               BODY: Bayes spam probability is 0 to 1%\n                             [score: 0.0000]\n -0.0 DKIMWL_WL_HIGH         DKIMwl.org - High trust sender","X-BeenThere":"hostap@lists.infradead.org","X-Mailman-Version":"2.1.34","Precedence":"list","List-Id":"<hostap.lists.infradead.org>","List-Unsubscribe":"<http://lists.infradead.org/mailman/options/hostap>,\n <mailto:hostap-request@lists.infradead.org?subject=unsubscribe>","List-Archive":"<http://lists.infradead.org/pipermail/hostap/>","List-Post":"<mailto:hostap@lists.infradead.org>","List-Help":"<mailto:hostap-request@lists.infradead.org?subject=help>","List-Subscribe":"<http://lists.infradead.org/mailman/listinfo/hostap>,\n <mailto:hostap-request@lists.infradead.org?subject=subscribe>","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Sender":"\"Hostap\" <hostap-bounces@lists.infradead.org>","Errors-To":"hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org"},"content":"From: Ilan Peer <ilan.peer@intel.com>\n\nAdd support for adding potential availability entries to\nthe availability attribute.\n\nThe potential availability entries are constructed using the\nchannels supported by the upper layer. These channels are\nretrieved using a callback that is expected to provide\nthe supported channels and their preference for a given\nmap.\n\nSigned-off-by: Ilan Peer <ilan.peer@intel.com>\n---\n src/nan/nan.h      |  47 ++++++++++\n src/nan/nan_util.c | 214 ++++++++++++++++++++++++++++++++++++++++++---\n 2 files changed, 248 insertions(+), 13 deletions(-)","diff":"diff --git a/src/nan/nan.h b/src/nan/nan.h\nindex 7a6cc47ccb..b5993ebf50 100644\n--- a/src/nan/nan.h\n+++ b/src/nan/nan.h\n@@ -274,6 +274,29 @@ struct nan_ndp_action_notif_params {\n \tsize_t ssi_len;\n };\n \n+/**\n+ * struct nan_channel_info - Channel information for NAN channel selection\n+ * @op_class: Operating class\n+ * @channel: Control channel index\n+ * @pref: Channel Preference (higher is preferred). Valid values are 0-3.\n+ */\n+struct nan_channel_info {\n+\tu8 op_class;\n+\tu8 channel;\n+\tu8 pref;\n+};\n+\n+/**\n+ * struct nan_channels - Array of channel information entries\n+ *\n+ * @n_chans: Number of channel information entries\n+ * @chans: Array of channel information. Sorted by preference.\n+ */\n+struct nan_channels {\n+\tsize_t n_chans;\n+\tstruct nan_channel_info *chans;\n+};\n+\n struct nan_config {\n \tvoid *cb_ctx;\n \n@@ -337,6 +360,30 @@ struct nan_config {\n \tvoid (*ndp_disconnected)(void *ctx, struct nan_ndp_id *ndp_id,\n \t\t\t\t const u8 *local_ndi, const u8 *peer_ndi,\n \t\t\t\t enum nan_reason reason);\n+\n+\t/**\n+\t * get_chans - Get the prioritized allowed channel information to be\n+\t * used for building the potential availability entries associated with\n+\t * the given map id.\n+\t *\n+\t * @ctx: Callback context from cb_ctx\n+\t * @map_id: Map ID of the availability attribute for which\n+\t *     the channels are requested.\n+\t * @chans: Pointer to a nan_channels structure that should be filled\n+\t *     with the prioritized frequencies. On successful return the\n+\t *     channels should be sorted having the higher priority channels\n+\t *     first.\n+\t * Returns 0 on success, -1 on failure.\n+\t *\n+\t * Note: the callback is responsible for allocating chans->chans as\n+\t * needed. The caller (the NAN module) is responsible for freeing the\n+\t * memory allocated for the chans->chans.\n+\t *\n+\t * Note: The callback should add all channels that are considered valid\n+\t * for use by the NAN module for the given map.\n+\t */\n+\tint (*get_chans)(void *ctx, u8 map_id, struct nan_channels *chans);\n+\n };\n \n struct nan_data * nan_init(const struct nan_config *cfg);\ndiff --git a/src/nan/nan_util.c b/src/nan/nan_util.c\nindex afcb28121f..d0e4407fc3 100644\n--- a/src/nan/nan_util.c\n+++ b/src/nan/nan_util.c\n@@ -394,10 +394,7 @@ static u16 nan_add_avail_entry(struct nan_data *nan,\n \n \tlen_ptr = wpabuf_put(buf, 2);\n \n-\t/*\n-\t * TODO: Need to also add potential entries as otherwise the peer would\n-\t * not be able to counter\n-\t */\n+\t/* Potential availability entries are handled separately */\n \tif (type != NAN_AVAIL_ENTRY_CTRL_TYPE_COMMITTED &&\n \t    type != NAN_AVAIL_ENTRY_CTRL_TYPE_COND) {\n \t\twpa_printf(MSG_DEBUG,\n@@ -514,6 +511,148 @@ int nan_get_chan_bm(struct nan_data *nan, struct nan_sched_chan *chan,\n }\n \n \n+static void nan_add_pot_avail_entry(struct nan_data *nan,\n+\t\t\t\t    struct nan_chan_entry *entries,\n+\t\t\t\t    size_t n_entries, u8 pref,\n+\t\t\t\t    struct wpabuf *buf)\n+{\n+\tu16 ctrl;\n+\tu8 chan_ctrl;\n+\tsize_t i;\n+\tu8 nss = BITS(nan->cfg->dev_capa.n_antennas, NAN_DEV_CAPA_RX_ANT_MASK,\n+\t\t      NAN_DEV_CAPA_RX_ANT_POS);\n+\n+\twpa_printf(MSG_DEBUG, \"NAN: Adding potential entry: n_entries=%zu\",\n+\t\t   n_entries);\n+\n+\tif (!n_entries)\n+\t\treturn;\n+\n+\t/* The number of channel entries can be too big for the buffer */\n+\tif (wpabuf_tailroom(buf) < 2 + 2 + 1 + n_entries * 4) {\n+\t\tn_entries = (wpabuf_tailroom(buf) - 5) / 4;\n+\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: Not enough space to add potential entries, reduce to %zu\",\n+\t\t\t   n_entries);\n+\t}\n+\n+\t/*\n+\t * ctrl (2) + chan control (1) + n_entries * (nan_chan_entry without\n+\t * the aux bitmap).\n+\t */\n+\twpabuf_put_le16(buf, 3 + n_entries * 4);\n+\n+\tctrl = NAN_AVAIL_ENTRY_CTRL_TYPE_POTENTIAL;\n+\tctrl |= NAN_AVAIL_ENTRY_DEF_UTIL << NAN_AVAIL_ENTRY_CTRL_UTIL_POS;\n+\tctrl |= nss << NAN_AVAIL_ENTRY_CTRL_RX_NSS_POS;\n+\tctrl |= pref << NAN_AVAIL_ENTRY_CTRL_USAGE_PREF_POS;\n+\twpabuf_put_le16(buf, ctrl);\n+\n+\t/* Add all channel entries */\n+\tchan_ctrl = NAN_BAND_CHAN_CTRL_TYPE;\n+\tchan_ctrl |= n_entries << NAN_BAND_CHAN_CTRL_NUM_ENTRIES_POS;\n+\twpabuf_put_u8(buf, chan_ctrl);\n+\n+\tfor (i = 0; i < n_entries; i++) {\n+\t\tstruct nan_chan_entry *cur = &entries[i];\n+\n+\t\twpabuf_put_u8(buf, cur->op_class);\n+\t\twpabuf_put_le16(buf, cur->chan_bitmap);\n+\t\twpabuf_put_u8(buf, 0);\n+\t}\n+}\n+\n+\n+static void\n+nan_build_pot_avail_entry_with_chans(struct nan_data *nan,\n+\t\t\t\t     struct nan_channels *pot_chans,\n+\t\t\t\t     struct wpabuf *buf,\n+\t\t\t\t     u8 map_id)\n+{\n+\tstruct nan_chan_entry chan_entries[global_op_class_size];\n+\tsize_t i, n_entries;\n+\n+\tos_memset(chan_entries, 0, sizeof(chan_entries));\n+\tn_entries = 0;\n+\n+\twpa_printf(MSG_DEBUG, \"NAN: Adding potential entries: n_chans=%zu\",\n+\t\t   pot_chans->n_chans);\n+\n+\tfor (i = 0; i < pot_chans->n_chans; i++) {\n+\t\tstruct nan_channel_info *chan = &pot_chans->chans[i];\n+\t\tstruct nan_chan_entry *cur;\n+\t\tu16 cbm = 0;\n+\t\tsize_t j;\n+\t\tint ret;\n+\n+\t\tif ((i > 0) && (pot_chans->chans[i - 1].pref != chan->pref)) {\n+\t\t\tnan_add_pot_avail_entry(nan, chan_entries, n_entries,\n+\t\t\t\t\t\tpot_chans->chans[i - 1].pref,\n+\t\t\t\t\t\tbuf);\n+\n+\t\t\tos_memset(chan_entries, 0, sizeof(chan_entries));\n+\t\t\tn_entries = 0;\n+\t\t}\n+\n+\t\tret = nan_chan_to_chan_idx_map(nan, chan->op_class,\n+\t\t\t\t\t       chan->channel, &cbm);\n+\t\tif (ret)\n+\t\t\tcontinue;\n+\n+\t\t/* Try to find and entry that matches the operating class */\n+\t\tfor (j = 0, cur = NULL; j < n_entries; j++) {\n+\t\t\tcur = &chan_entries[j];\n+\n+\t\t\tif (!cur->op_class ||\n+\t\t\t    cur->op_class == chan->op_class)\n+\t\t\t\tbreak;\n+\t\t}\n+\n+\t\tif (!n_entries)\n+\t\t\tcur = &chan_entries[n_entries++];\n+\t\telse if (j == n_entries && n_entries < global_op_class_size)\n+\t\t\tcur = &chan_entries[n_entries++];\n+\t\telse if (!cur)\n+\t\t\tcontinue;\n+\n+\t\tcur->op_class = chan->op_class;\n+\t\tcur->chan_bitmap |= cbm;\n+\t}\n+\n+\tif (n_entries)\n+\t\tnan_add_pot_avail_entry(nan, chan_entries, n_entries,\n+\t\t\t\t\tpot_chans->chans[i - 1].pref, buf);\n+\n+\twpa_printf(MSG_DEBUG, \"NAN: Added potential entries: done\");\n+}\n+\n+\n+static void nan_build_pot_avail_entry(struct nan_data *nan, struct wpabuf *buf,\n+\t\t\t\t      u8 map_id)\n+{\n+\tstruct nan_channels pot_chans;\n+\n+\tos_memset(&pot_chans, 0, sizeof(pot_chans));\n+\n+\tif (nan->cfg->get_chans(nan->cfg->cb_ctx, map_id, &pot_chans) < 0) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: Failed to get channels. Not adding potential\");\n+\t\treturn;\n+\t}\n+\n+\tif (pot_chans.n_chans != 0)\n+\t\tnan_build_pot_avail_entry_with_chans(nan, &pot_chans,\n+\t\t\t\t\t\t     buf, map_id);\n+\telse\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: No channels available. Not adding potential: map_id=%u\",\n+\t\t\t   map_id);\n+\n+\tos_free(pot_chans.chans);\n+}\n+\n+\n /**\n  * nan_add_avail_attrs - Add NAN availability attributes\n  * @nan: NAN module context from nan_init()\n@@ -538,6 +677,7 @@ int nan_add_avail_attrs(struct nan_data *nan, u8 sequence_id,\n \t\t\tstruct wpabuf *buf)\n {\n \tu8 last_map_id = NAN_INVALID_MAP_ID;\n+\tu32 handled_map_ids = 0;\n \tu8 *len_ptr = NULL;\n \tu8 i;\n \n@@ -588,12 +728,14 @@ int nan_add_avail_attrs(struct nan_data *nan, u8 sequence_id,\n \t\t\t\t\t   \"NAN: Add avail attr done: map_id=%u\",\n \t\t\t\t\t   last_map_id);\n \n+\t\t\t\tnan_build_pot_avail_entry(nan, buf,\n+\t\t\t\t\t\t\t  last_map_id);\n \t\t\t\tWPA_PUT_LE16(len_ptr,\n \t\t\t\t\t     (u8 *)wpabuf_put(buf, 0) - len_ptr - 2);\n \t\t\t}\n \n \t\t\tlast_map_id = chan->map_id;\n-\t\t\tmap_ids_bitmap &= ~BIT(last_map_id);\n+\t\t\thandled_map_ids |= BIT(last_map_id);\n \n \t\t\twpa_printf(MSG_DEBUG, \"NAN: Add avail attr map_id=%u\",\n \t\t\t\t   last_map_id);\n@@ -608,9 +750,11 @@ int nan_add_avail_attrs(struct nan_data *nan, u8 sequence_id,\n \t\t\t * The spec states that this bit should be set if the\n \t\t\t * committed changed or if conditional is included. Set\n \t\t\t * it anyway, as it is not known what information the\n-\t\t\t * peer has on our schedule.\n+\t\t\t * peer has on our schedule. Similarly, always set the\n+\t\t\t * potential changed bit.\n \t\t\t */\n-\t\t\tctrl |= NAN_AVAIL_CTRL_COMMITTED_CHANGED;\n+\t\t\tctrl |= NAN_AVAIL_CTRL_COMMITTED_CHANGED |\n+\t\t\t\tNAN_AVAIL_CTRL_POTENTIAL_CHANGED;\n \t\t\twpabuf_put_le16(buf, ctrl);\n \t\t}\n \n@@ -627,16 +771,60 @@ int nan_add_avail_attrs(struct nan_data *nan, u8 sequence_id,\n \t\t\t\t\t    op_class, chan_bm, 0, buf);\n \t}\n \n-\tif (last_map_id == NAN_INVALID_MAP_ID) {\n+\tif (last_map_id != NAN_INVALID_MAP_ID) {\n+\t\tnan_build_pot_avail_entry(nan, buf, last_map_id);\n+\t\tWPA_PUT_LE16(len_ptr, (u8 *)wpabuf_put(buf, 0) - len_ptr - 2);\n+\n+\t\twpa_printf(MSG_DEBUG, \"NAN: Add avail attr done: map_id=%u\",\n+\t\t\t   last_map_id);\n+\t} else {\n \t\twpa_printf(MSG_DEBUG,\n-\t\t\t   \"NAN: No valid availability entries added\");\n-\t\treturn -1;\n+\t\t\t   \"NAN: No committed/conditional entries were added\");\n \t}\n \n-\twpa_printf(MSG_DEBUG, \"NAN: Add avail attr done: map_id=%u\",\n-\t\t   last_map_id);\n+\t/*\n+\t * Add NAN availability attributes with a single potential availability\n+\t * entry for map IDs that are not included in the schedule\n+\t */\n+\tmap_ids_bitmap &= ~handled_map_ids;\n+\twpa_printf(MSG_DEBUG,\n+\t\t   \"NAN: Add avail attrs for remaining map IDs: bitmap=0x%x\",\n+\t\t   map_ids_bitmap);\n+\n+\twhile (map_ids_bitmap) {\n+\t\tstruct nan_channels pot_chans;\n \n-\tWPA_PUT_LE16(len_ptr, (u8 *)wpabuf_put(buf, 0) - len_ptr - 2);\n+\t\tu8 map_id = ffs(map_ids_bitmap) - 1;\n+\t\tu16 ctrl = map_id << NAN_AVAIL_CTRL_MAP_ID_POS |\n+\t\t\t  NAN_AVAIL_CTRL_POTENTIAL_CHANGED;\n+\n+\t\tmap_ids_bitmap &= ~BIT(map_id);\n+\n+\t\twpa_printf(MSG_DEBUG, \"NAN: Add avail attr for map_id=%u\",\n+\t\t\t   map_id);\n+\n+\t\tos_memset(&pot_chans, 0, sizeof(pot_chans));\n+\n+\t\tif (nan->cfg->get_chans(nan->cfg->cb_ctx, map_id,\n+\t\t\t\t\t&pot_chans) < 0 ||\n+\t\t    !pot_chans.chans) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t   \"NAN: No channels available. Not adding potential: map_id=%u\",\n+\t\t\t\t   map_id);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\twpabuf_put_u8(buf, NAN_ATTR_NAN_AVAILABILITY);\n+\t\tlen_ptr = wpabuf_put(buf, 2);\n+\t\twpabuf_put_u8(buf, sequence_id);\n+\t\twpabuf_put_le16(buf, ctrl);\n+\n+\t\tnan_build_pot_avail_entry_with_chans(nan, &pot_chans, buf,\n+\t\t\t\t\t\t     map_id);\n+\t\tos_free(pot_chans.chans);\n+\n+\t\tWPA_PUT_LE16(len_ptr, (u8 *)wpabuf_put(buf, 0) - len_ptr - 2);\n+\t}\n \n \treturn 0;\n }\n","prefixes":["22/58"]}