{"id":2218825,"url":"http://patchwork.ozlabs.org/api/1.0/patches/2218825/?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":"<20260401220220.4418-37-andrei.otcheretianski@intel.com>","date":"2026-04-01T22:01:45","name":"[36/71] NAN: Configure peer NMI station and schedule","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"541b8a60a80e65c11fd9cf19cbc5e7c588a0ca6a","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/20260401220220.4418-37-andrei.otcheretianski@intel.com/mbox/","series":[{"id":498402,"url":"http://patchwork.ozlabs.org/api/1.0/series/498402/?format=json","date":"2026-04-01T22:01:09","name":"NAN Data Path and Bootstrapping support","version":1,"mbox":"http://patchwork.ozlabs.org/series/498402/mbox/"}],"check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2218825/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=UAy5ihZy;\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=cGUXOu+t;\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 4fmJyM5fcRz1yFv\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 02 Apr 2026 09:07:55 +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 1w83iY-0000000GCPv-3V7N;\n\tWed, 01 Apr 2026 22:07:18 +0000","from mgamail.intel.com ([198.175.65.20])\n\tby bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1w83hD-0000000G9is-3Tu6\n\tfor hostap@lists.infradead.org;\n\tWed, 01 Apr 2026 22:06:00 +0000","from fmviesa003.fm.intel.com ([10.60.135.143])\n  by orvoesa112.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 01 Apr 2026 15:05:51 -0700","from iapp347.iil.intel.com (HELO 87c02287900a.iil.intel.com)\n ([10.167.28.6])\n  by fmviesa003-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 01 Apr 2026 15:05:50 -0700"],"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:To:From:Reply-To:Cc:Content-ID:Content-Description:\n\tResent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:\n\tList-Owner; bh=p+mx9MMrphwlzRanUg0TjFV47xFCFuR0B0s3moQqXZA=; b=UAy5ihZymXOlnK\n\tKEn6ffW4ch4iUgRE5TArLInxVPUE285SI3vHXnGxZk38pCF40Pt4HUL1MMjQvQl0ELr2rzNHDHXop\n\toSWIJgAGpybnzpnOZIHjWwkQYNyJWyVoXnkkyPLiIk0RRMkjch6UawhJy3H7y9Xa0H//b+IiXUB4L\n\t1INQZ5NNlGL6CVgqqw8rcYxbp+1XEZ0wzsCWip+dYKv2KhkdYcgUbxB63ek/vaUgQau/iwCxx/95H\n\tJshGFm4cFV6IJulkkncpIZoBceAwtaXhmobhKw2+ROp2yQK6KcUWbhXprYhnkXrSzSvieEX4JSiQX\n\t93sZhQY+qnaRSs3oLDag==;","v=1; a=rsa-sha256; c=relaxed/simple;\n  d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n  t=1775081155; x=1806617155;\n  h=from:to:subject:date:message-id:in-reply-to:references:\n   mime-version:content-transfer-encoding;\n  bh=Hr3/dwyG1lpoWWaddKvsGS6ZALbq7/XQgRnu5SgayzE=;\n  b=cGUXOu+trj+hGQamkkrg8/fNTHMzRZWXA2XwbNleBQGveuUiLZrrrm2L\n   ir6yJYDD/GbjdND5dttAKsJ3t5petKG3X2TC8TlfWWmT9/OorOpJ9QjOz\n   rgxpKjbEY+FyB3Wkq4/QluFQMgiXlvOcrnJA/f6ad9dZWmsnXJZO21GPc\n   2VcRTbpVfsPyHM493hRUllIzV3u8CWpbdtjM9KtDzJ536b2qu8rrhsnvE\n   w6Ey/F723BvKa99YsOuDVbN2nf+0EP25wKm+QmbsknD6f9BBi2XcEDHcq\n   Tl+gqkVlIbPVrI5JiAoerNttnetzTImsWoUyb6F5KnMr5zetmC44GC3Zc\n   g==;"],"X-CSE-ConnectionGUID":["UvFsa6Y5TSe7QGG/CqtoOQ==","BSdsbh4gS5mT3hvlnGa9ag=="],"X-CSE-MsgGUID":["sqoMgHKFSU6K0xqTi9/2JA==","XbXwnDScR1WeLuEr9XvnHA=="],"X-IronPort-AV":["E=McAfee;i=\"6800,10657,11746\"; a=\"75851623\"","E=Sophos;i=\"6.23,153,1770624000\";\n   d=\"scan'208\";a=\"75851623\""],"X-ExtLoop1":"1","From":"Andrei Otcheretianski <andrei.otcheretianski@intel.com>","To":"hostap@lists.infradead.org","Subject":"[PATCH 36/71] NAN: Configure peer NMI station and schedule","Date":"Thu,  2 Apr 2026 01:01:45 +0300","Message-ID":"<20260401220220.4418-37-andrei.otcheretianski@intel.com>","X-Mailer":"git-send-email 2.53.0","In-Reply-To":"<20260401220220.4418-1-andrei.otcheretianski@intel.com>","References":"<20260401220220.4418-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-20260401_150556_201675_86B6BF42 ","X-CRM114-Status":"GOOD (  25.17  )","X-Spam-Score":"-1.9 (-)","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:  Add a new callback for peer schedule configuration and call\n    it during NDL establishment (as peer schedule may change while NDL is\n being\n    negotiated). Signed-off-by: Andrei Otcheretianski\n <andrei.otcheretianski@intel.com>\n    --- src/nan/nan.c | 84 ++++++++++++++++++++++++++++++++++++--\n src/nan/nan.h\n    | 20 +++++++++ src/nan/nan_i.h | 4 ++ src/nan/nan_mod [...]\n Content analysis details:   (-1.9 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.20 listed in list.dnswl.org]\n  1.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.20 listed in\n bl.score.senderscore.com]\n  1.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.20 listed in\n sa-trusted.bondedsender.org]\n  1.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.20 listed in sa-accredit.habeas.com]\n  0.0 SPF_HELO_NONE          SPF: HELO does not publish an SPF Record\n -0.0 SPF_PASS               SPF: sender matches SPF record\n  0.1 DKIM_SIGNED            Message has a DKIM or DK signature,\n not necessarily valid\n -0.1 DKIM_VALID_EF          Message has a valid DKIM or DK signature from\n                             envelope-from domain\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             Message has at least one valid DKIM or DK\n signature\n -1.9 BAYES_00               BODY: Bayes spam probability is 0 to 1%\n                             [score: 0.0000]\n -0.5 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":"Add a new callback for peer schedule configuration and call it during\nNDL establishment (as peer schedule may change while NDL is being\nnegotiated).\n\nSigned-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>\n---\n src/nan/nan.c              | 84 ++++++++++++++++++++++++++++++++++++--\n src/nan/nan.h              | 20 +++++++++\n src/nan/nan_i.h            |  4 ++\n src/nan/nan_module_tests.c | 45 ++++++++++++++++++--\n src/nan/nan_ndl.c          | 81 ++++++++++++++++++++++++++++++++++++\n 5 files changed, 227 insertions(+), 7 deletions(-)","diff":"diff --git a/src/nan/nan.c b/src/nan/nan.c\nindex 6b0bd2b6fd..487e5a8ba5 100644\n--- a/src/nan/nan.c\n+++ b/src/nan/nan.c\n@@ -1177,7 +1177,8 @@ static bool nan_ndp_supported(struct nan_data *nan)\n \tif (nan->cfg->ndp_action_notif && nan->cfg->ndp_connected &&\n \t    nan->cfg->ndp_disconnected &&\n \t    nan->cfg->send_naf && nan->cfg->get_chans &&\n-\t    nan->cfg->is_valid_publish_id)\n+\t    nan->cfg->is_valid_publish_id &&\n+\t    nan->cfg->set_peer_schedule)\n \t\treturn true;\n \n \twpa_printf(MSG_DEBUG, \"NAN: NDP operations are not supported\");\n@@ -1185,6 +1186,62 @@ static bool nan_ndp_supported(struct nan_data *nan)\n }\n \n \n+static void nan_peer_get_committed_avail(const struct nan_data *nan,\n+\t\t\t\t\t const struct nan_peer *peer,\n+\t\t\t\t\t struct nan_peer_schedule *sched);\n+\n+\n+static int nan_configure_peer_schedule(struct nan_data *nan,\n+\t\t\t\t       struct nan_peer *peer)\n+{\n+\tint ret;\n+\tstruct nan_dev_capa_entry *cur;\n+\tstruct nan_device_capabilities *capa = NULL;\n+\tstruct nan_peer_schedule sched;\n+\n+\twpa_printf(MSG_DEBUG, \"NAN: Configure peer schedule\");\n+\n+\tif (!nan_ndl_peer_schedule_intersects(nan, peer)) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: Cannot configure peer NMI STA - no intersecting schedule\");\n+\t\treturn 0;\n+\t}\n+\n+\tdl_list_for_each(cur, &peer->info.dev_capa,\n+\t\t\t struct nan_dev_capa_entry, list) {\n+\t\t/*\n+\t\t * Take the first one, as both CDW and channel switch time are\n+\t\t * identical across all attributes\n+\t\t */\n+\t\tcapa = &cur->capa;\n+\t\tbreak;\n+\t}\n+\n+\tif (!capa) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: Cannot configure peer NMI STA - no device capabilities\");\n+\t\treturn -1;\n+\t}\n+\n+\tos_memset(&sched, 0, sizeof(sched));\n+\tnan_peer_get_committed_avail(nan, peer, &sched);\n+\n+\tret = nan->cfg->set_peer_schedule(nan->cfg->cb_ctx, peer->nmi_addr,\n+\t\t\t\t\t  !peer->configured, capa->cdw_info,\n+\t\t\t\t\t  peer->info.seq_id,\n+\t\t\t\t\t  capa->channel_switch_time, &sched,\n+\t\t\t\t\t  NULL);\n+\tif (ret) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: Failed to set peer schedule\");\n+\t\treturn ret;\n+\t}\n+\n+\tpeer->configured = true;\n+\treturn 0;\n+}\n+\n+\n static void nan_peer_state_timeout(void *eloop_ctx, void *timeout_ctx)\n {\n \tstruct nan_data *nan = eloop_ctx;\n@@ -1416,8 +1473,8 @@ static int nan_action_rx_ndp(struct nan_data *nan, struct nan_peer *peer,\n \tif (peer->ndp_setup.state == NAN_NDP_STATE_DONE &&\n \t    peer->ndl->state == NAN_NDL_STATE_DONE) {\n \t\twpa_printf(MSG_DEBUG, \"NAN: NAF: NDP setup done\");\n-\n-\t\tif (nan_ndp_connected(nan, peer))\n+\t\tif (nan_configure_peer_schedule(nan, peer) ||\n+\t\t    nan_ndp_connected(nan, peer))\n \t\t\tnan_ndp_disconnected(nan, peer,\n \t\t\t\t\t     NAN_REASON_UNSPECIFIED_REASON);\n \t\treturn 0;\n@@ -1591,7 +1648,8 @@ int nan_tx_status(struct nan_data *nan, const u8 *dst, const u8 *data,\n \tif (peer->ndp_setup.state == NAN_NDP_STATE_DONE &&\n \t    peer->ndl->state == NAN_NDL_STATE_DONE) {\n \t\twpa_printf(MSG_DEBUG, \"NAN: TX status: NDP setup done\");\n-\t\tif (nan_ndp_connected(nan, peer))\n+\t\tif (nan_configure_peer_schedule(nan, peer) ||\n+\t\t    nan_ndp_connected(nan, peer))\n \t\t\tnan_ndp_disconnected(nan, peer,\n \t\t\t\t\t     NAN_REASON_UNSPECIFIED_REASON);\n \t}\n@@ -1631,6 +1689,12 @@ int nan_handle_ndp_setup(struct nan_data *nan, struct nan_ndp_params *params)\n \n \t\tnaf_oui = NAN_SUBTYPE_DATA_PATH_REQUEST;\n \t\ttimeout = NAN_NDP_SETUP_TIMEOUT_LONG;\n+\t\tret = nan_configure_peer_schedule(nan, peer);\n+\t\tif (ret) {\n+\t\t\tnan_ndp_setup_stop(nan, peer);\n+\t\t\treturn ret;\n+\t\t}\n+\n \t\tbreak;\n \tcase NAN_NDP_ACTION_RESP:\n \t\t/*\n@@ -1646,6 +1710,12 @@ int nan_handle_ndp_setup(struct nan_data *nan, struct nan_ndp_params *params)\n \n \t\tif (peer->ndp_setup.status != NAN_NDP_STATUS_REJECTED) {\n \t\t\tret = nan_ndl_setup(nan, peer, params);\n+\t\t\tif (!ret) {\n+\t\t\t\tret = nan_configure_peer_schedule(nan, peer);\n+\t\t\t\tif (ret)\n+\t\t\t\t\tpeer->ndl->send_naf_on_error = 1;\n+\t\t\t}\n+\n \t\t\tif (ret) {\n \t\t\t\tif (peer->ndl && peer->ndl->send_naf_on_error) {\n \t\t\t\t\tnan_ndp_setup_failure(\n@@ -1665,6 +1735,12 @@ int nan_handle_ndp_setup(struct nan_data *nan, struct nan_ndp_params *params)\n \t\tbreak;\n \tcase NAN_NDP_ACTION_CONF:\n \t\tret = nan_ndl_setup(nan, peer, params);\n+\t\tif (!ret) {\n+\t\t\tret = nan_configure_peer_schedule(nan, peer);\n+\t\t\tif (ret)\n+\t\t\t\tpeer->ndl->send_naf_on_error = 1;\n+\t\t}\n+\n \t\tif (ret) {\n \t\t\tif (peer->ndl && peer->ndl->send_naf_on_error) {\n \t\t\t\tnan_ndp_setup_failure(\ndiff --git a/src/nan/nan.h b/src/nan/nan.h\nindex c6f06382c3..1906d2eed2 100644\n--- a/src/nan/nan.h\n+++ b/src/nan/nan.h\n@@ -494,6 +494,26 @@ struct nan_config {\n \t * instance ID; false otherse\n \t */\n \tbool (*is_valid_publish_id)(void *ctx, u8 instance_id, u8 *service_id);\n+\n+\t/**\n+\t * set_peer_schedule - Configure peer schedule\n+\t *\n+\t * @ctx: Callback context from cb_ctx\n+\t * @nmi_addr: NAN Management Interface address of the peer\n+\t * @new_sta: Indicates whether this is a new STA (true) or an existing\n+\t *     STA that is being re-configured (false).\n+\t * @cdw: Committed DW information (from device capabilities)\n+\t * @sequence_id: Schedule sequence ID\n+\t * @max_channel_switch_time: Maximum channel switch time\n+\t * @sched: Peer schedule information; can be NULL\n+\t * @ulw_elems: ULW elements buffer; can be NULL\n+\t * Returns: 0 on success, -1 on failure\n+\t */\n+\tint (*set_peer_schedule)(void *ctx, const u8 *nmi_addr, bool new_sta,\n+\t\t\t\t u16 cdw, u8 sequence_id,\n+\t\t\t\t u16 max_channel_switch_time,\n+\t\t\t\t const struct nan_peer_schedule *sched,\n+\t\t\t\t const struct wpabuf *ulw_elems);\n };\n \n struct nan_data * nan_init(const struct nan_config *cfg);\ndiff --git a/src/nan/nan_i.h b/src/nan/nan_i.h\nindex b7be2efa3c..701d98f773 100644\n--- a/src/nan/nan_i.h\n+++ b/src/nan/nan_i.h\n@@ -406,6 +406,7 @@ struct nan_ndl {\n  * struct nan_peer - Represents a known NAN peer\n  * @list: List node for linking peers\n  * @nmi_addr: NMI of the peer\n+ * @configured: Indicates if the peer has been configured to the device\n  * @last_seen: Timestamp of the last time this peer was seen\n  * @info: Information about the peer\n  * @ndps: List of NDPs associated with this peer\n@@ -416,6 +417,7 @@ struct nan_ndl {\n struct nan_peer {\n \tstruct dl_list list;\n \tu8 nmi_addr[ETH_ALEN];\n+\tbool configured;\n \tstruct os_reltime last_seen;\n \tstruct nan_peer_info info;\n \n@@ -565,6 +567,8 @@ int nan_ndl_add_avail_attrs(struct nan_data *nan, const struct nan_peer *peer,\n void nan_ndl_add_elem_container_attr(const struct nan_data *nan,\n \t\t\t\t     const struct nan_peer *peer,\n \t\t\t\t     struct wpabuf *buf);\n+bool nan_ndl_peer_schedule_intersects(struct nan_data *nan,\n+\t\t\t\t      struct nan_peer *peer);\n int nan_get_chan_bm(struct nan_data *nan, struct nan_sched_chan *chan,\n \t\t    u8 *op_class, u16 *chan_bm, u16 *pri_chan_bm);\n int nan_add_avail_attrs(struct nan_data *nan, u8 sequence_id,\ndiff --git a/src/nan/nan_module_tests.c b/src/nan/nan_module_tests.c\nindex 9fc0064308..b3369ea19e 100644\n--- a/src/nan/nan_module_tests.c\n+++ b/src/nan/nan_module_tests.c\n@@ -850,6 +850,28 @@ static bool nan_test_is_valid_publish_id_cb(void *ctx, u8 instance_id,\n \treturn true;\n }\n \n+/*\n+ * nan_test_set_peer_schedule_cb - Set peer schedule callback\n+ *\n+ * @ctx: Pointer to &struct nan_device\n+ * @sched: Pointer to &struct nan_peer_schedule to be filled\n+ */\n+static int\n+nan_test_set_peer_schedule_cb(void *ctx, const u8 *nmi_addr, bool new_sta,\n+\t\t\t      u16 cdw, u8 sequence_id,\n+\t\t\t      u16 max_channel_switch_time,\n+\t\t\t      const struct nan_peer_schedule *sched,\n+\t\t\t      const struct wpabuf *ulw_elems)\n+{\n+\tstruct nan_device *dev = (struct nan_device *)ctx;\n+\n+\tDEV_NOT_INIT_ERR(dev);\n+\n+\twpa_printf(MSG_INFO, \"%s: %s: Enter\", dev->name, __func__);\n+\twpa_printf(MSG_INFO, \"%s: nmi_addr=\" MACSTR \" new_sta=%d cdw=%u sequence_id=%u max_channel_switch_time=%u\",\n+\t\t   dev->name, MAC2STR(nmi_addr), new_sta, cdw, sequence_id, max_channel_switch_time);\n+\treturn 0;\n+}\n \n /**\n  * nan_test_dev_init - Initialize a test device instance\n@@ -871,6 +893,7 @@ static int nan_test_dev_init(struct nan_device *dev)\n \tnan.send_naf = nan_test_send_naf_cb;\n \tnan.get_chans = nan_test_get_chans_cb;\n \tnan.is_valid_publish_id = nan_test_is_valid_publish_id_cb;\n+\tnan.set_peer_schedule = nan_test_set_peer_schedule_cb;\n \n \t/* Awake on every DW on 2 GHz and 5 GHz */\n \tnan.dev_capa.cdw_info = 0x9;\n@@ -970,7 +993,23 @@ nan_test_setup_devices(struct nan_test_global *global,\n \t\t.master_pref = 2,\n \t\t.dual_band = 1,\n \t};\n-\tconst u8 pot_avail[] = {\n+\t/*\n+\t * Device attributes containing:\n+\t * 1. Device capability attribute (ID=0x0F, len=10):\n+\t *    - map_id=0\n+\t *    - cdw_info=0x0009 (awake on every DW on 2G and 5G)\n+\t *    - supported_bands=0x07 (2G, 5G, 6G)\n+\t *    - op_mode=0x01\n+\t *    - n_antennas=0x22\n+\t *    - channel_switch_time=0x000a (10)\n+\t *    - capa=0x00\n+\t * 2. Availability attribute (ID=0x12, len=12)\n+\t */\n+\tconst u8 attrs[] = {\n+\t\t/* Device capability attribute */\n+\t\t0x0f, 0x09, 0x00, 0x00, 0x09, 0x00, 0x07, 0x01,\n+\t\t0x22, 0x0a, 0x00, 0x00,\n+\t\t/* Availability attribute */\n \t\t0x12, 0x0c, 0x00, 0x01, 0x20, 0x00, 0x07, 0x00,\n \t\t0x1a, 0x00, 0x11, 0x51, 0xff, 0x07, 0x00,\n \t};\n@@ -989,8 +1028,8 @@ nan_test_setup_devices(struct nan_test_global *global,\n \tif (!sub)\n \t\tgoto fail;\n \n-\tnan_add_peer(pub->nan, sub_nmi, pot_avail, sizeof(pot_avail));\n-\tnan_add_peer(sub->nan, pub_nmi, pot_avail, sizeof(pot_avail));\n+\tnan_add_peer(pub->nan, sub_nmi, attrs, sizeof(attrs));\n+\tnan_add_peer(sub->nan, pub_nmi, attrs, sizeof(attrs));\n \n \twpa_printf(MSG_INFO, \"\\n%s: Done\\n\", __func__);\n \treturn sub;\ndiff --git a/src/nan/nan_ndl.c b/src/nan/nan_ndl.c\nindex 64689bcbe7..701aed18e0 100644\n--- a/src/nan/nan_ndl.c\n+++ b/src/nan/nan_ndl.c\n@@ -119,6 +119,13 @@ static void nan_ndl_clear(struct nan_data *nan, struct nan_peer *peer)\n \t\t   MAC2STR(peer->nmi_addr),\n \t\t   nan_ndl_state_str(peer->ndl->state), peer->ndl->state);\n \n+\tif (peer->configured) {\n+\t\tnan->cfg->set_peer_schedule(nan->cfg->cb_ctx, peer->nmi_addr,\n+\t\t\t\t\t    false, 0, 0, 0, NULL,\n+\t\t\t\t\t    NULL);\n+\t\tpeer->configured = false;\n+\t}\n+\n \tos_free(ndl->ndc_sched);\n \tndl->ndc_sched = NULL;\n \tndl->ndc_sched_len = 0;\n@@ -1751,3 +1758,77 @@ void nan_ndl_add_elem_container_attr(const struct nan_data *nan,\n \twpabuf_put_u8(buf, 0);\n \twpabuf_put_buf(buf, ndl->sched.elems);\n }\n+\n+\n+/*\n+ * nan_ndl_peer_schedule_intersects - Check if local and peer schedules\n+ * intersect\n+ *\n+ * @nan: NAN module context from nan_init()\n+ * @peer: The peer with whom the NDL is being setup\n+ * Returns: True if schedules intersect, false otherwise\n+ *\n+ * The function checks if the local device schedule intersects with the peer\n+ * device schedule.\n+ */\n+bool nan_ndl_peer_schedule_intersects(struct nan_data *nan,\n+\t\t\t\t      struct nan_peer *peer)\n+{\n+\tstruct nan_schedule *sched;\n+\tsize_t i;\n+\n+\tif (!peer->ndl)\n+\t\treturn false;\n+\n+\tsched = &peer->ndl->sched;\n+\n+\t/*\n+\t * Iterate over all the channels included in the local schedule. For\n+\t * each channel convert the committed and conditional slots to a\n+\t * bitfield object and extract the operating class and channel bitmap.\n+\t *\n+\t * Using the operating class and channel bitmap find the peer\n+\t * availability on that channel and check if it intersect with the\n+\t * local one.\n+\t */\n+\twpa_printf(MSG_DEBUG, \"NAN: n_chans=%u, ndc_map_id=%u\",\n+\t\t   sched->n_chans, sched->ndc_map_id);\n+\n+\tfor (i = 0; i < sched->n_chans; i++) {\n+\t\tstruct bitfield *own_chan_bf = NULL, *peer_chan_bf = NULL;\n+\t\tu16 cbm, pri_cbm;\n+\t\tu8 map_id, op_class;\n+\t\tint ret;\n+\n+\t\t/* Convert the schedule for the current channel to bitfield */\n+\t\tret = nan_ndl_convert_chan_sched_to_bf(nan, &sched->chans[i],\n+\t\t\t\t\t\t       &own_chan_bf, &map_id,\n+\t\t\t\t\t\t       &op_class, &cbm,\n+\t\t\t\t\t\t       &pri_cbm);\n+\t\tif (ret) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t   \"NAN: NDL: Failed to convert chan sched to bitfield\");\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\t/* Get the peer availability for the current channel */\n+\t\tpeer_chan_bf =\n+\t\t\tnan_avail_entries_to_bf(nan,\n+\t\t\t\t\t\t&peer->info.avail_entries,\n+\t\t\t\t\t\top_class, cbm, pri_cbm);\n+\t\tif (!peer_chan_bf) {\n+\t\t\tbitfield_free(own_chan_bf);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tret = bitfield_intersects(own_chan_bf, peer_chan_bf);\n+\n+\t\tbitfield_free(peer_chan_bf);\n+\t\tbitfield_free(own_chan_bf);\n+\n+\t\tif (ret == 1)\n+\t\t\treturn true;\n+\t}\n+\n+\treturn false;\n+}\n","prefixes":["36/71"]}