Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.0/patches/2198416/?format=api
{ "id": 2198416, "url": "http://patchwork.ozlabs.org/api/1.0/patches/2198416/?format=api", "project": { "id": 22, "url": "http://patchwork.ozlabs.org/api/1.0/projects/22/?format=api", "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-19-andrei.otcheretianski@intel.com>", "date": "2026-02-19T20:24:34", "name": "[18/58] NAN: Initial support for NDL state machine and operations", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "60faaf5402ed407dd10ecd039357f1ae5c2080a0", "submitter": { "id": 62065, "url": "http://patchwork.ozlabs.org/api/1.0/people/62065/?format=api", "name": "Andrei Otcheretianski", "email": "andrei.otcheretianski@intel.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/hostap/patch/20260219202514.5781-19-andrei.otcheretianski@intel.com/mbox/", "series": [ { "id": 492721, "url": "http://patchwork.ozlabs.org/api/1.0/series/492721/?format=api", "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/2198416/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=lRaU1CeT;\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=LUIIrLDv;\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 4fH4fr52Vgz1xpY\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 20 Feb 2026 07:27:00 +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 1vtAbX-0000000BwnM-2XlN;\n\tThu, 19 Feb 2026 20:26:31 +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 1vtAbO-0000000BwCB-2loL\n\tfor hostap@lists.infradead.org;\n\tThu, 19 Feb 2026 20:26:25 +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:23 -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:19 -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=zXAzji2+BWz2ca2EWaCZuE8mr5QlgnRPfplxM7kQ1FE=; b=lRaU1CeTgHYKfU\n\tWZjO4nC5ydWtVru0tPQ+wE159MrXtzf5ZpSTyz5RJnouO3d3ZDn9f6hAZGkN7Olr8ADpxPz1AK869\n\tQjPenKVgC2wrRUMnAIfCKm+Mp74ExBMW6Qp0cGOyG7Rbd9wWOIP7cqAC+erDLQ+RxQH0vA4GEbV8a\n\tYH3GqHSYRfOATaDZEARy1/UoS9F+TXhno8Hr1aNx//T94TfMjWqVbcYLaELCOPfUvsJwYld79mHNo\n\t16MjcaiyNfCkDWH1KHDaEmePAt7ugWF3kUFKbSJ2fCEZEU0IUX3z3ntyWMOyRK2uOBE5OAjY61M9Y\n\trujbMV893srTAAWke36Q==;", "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1771532783; x=1803068783;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=Ahm9CXOfLojV/JmAMr3CtBbUDBrVF1bJ0lszSIAqbYQ=;\n b=LUIIrLDvqWgsAfUFjXjt5dYVduOScUqexzj2/uroOzn1WdSPQx0IJ7NY\n 8MWYMq6I67rTzUx8M6kXYfRw8ZcGf3P4wAWXMyM+A5nkp/tiFs2+pLVHp\n O5vHhTyVW3K0toL+fnhuTDjIewnzp7sJyu5kFOMeai5QD4CK2kDuwZZgp\n AbJzW8htkQSTIc5hQkFa0vBfSSCiEgnc4zmFAddOjI2YiZQfMT07kysNh\n z8281JdkdPisQXJ80zu3KvQi4+xONX2r9i6ShXaHDBs9OyuMPrSIXdPvq\n ns5P3fi01TfFD+yTdTtTI7KE0YXg45P9Lib5KZm14dt1QaYQK6yCq1LAL\n Q==;" ], "X-CSE-ConnectionGUID": [ "hxxmbQ1wRSWGo20gADWXPA==", "UkEwOCILSRWnQFYsxnh/mQ==" ], "X-CSE-MsgGUID": [ "B0qXhUH5QDCqThI1BQKMJA==", "THN3vuQBQGaqeDwXuQNeew==" ], "X-IronPort-AV": [ "E=McAfee;i=\"6800,10657,11706\"; a=\"90039994\"", "E=Sophos;i=\"6.21,300,1763452800\";\n d=\"scan'208\";a=\"90039994\"", "E=Sophos;i=\"6.21,300,1763452800\";\n d=\"scan'208\";a=\"219153813\"" ], "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 18/58] NAN: Initial support for NDL state machine and\n operations", "Date": "Thu, 19 Feb 2026 22:24:34 +0200", "Message-ID": "<20260219202514.5781-19-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_122622_829306_8639B624 ", "X-CRM114-Status": "GOOD ( 30.50 )", "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 NDL state machine\n and states and support for parsing the NDL, NDC and QoS attributes. This\n is only a partial implementation of the state machine and not all\n operations\n are supported. Following patches would complete the implementation.\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 NDL state machine and states and support for parsing\nthe NDL, NDC and QoS attributes.\n\nThis is only a partial implementation of the state machine and\nnot all operations are supported. Following patches would complete\nthe implementation.\n\nSigned-off-by: Ilan Peer <ilan.peer@intel.com>\n---\n src/nan/Makefile | 2 +-\n src/nan/nan.c | 2 +\n src/nan/nan.h | 7 +-\n src/nan/nan_i.h | 91 +++++\n src/nan/nan_ndl.c | 880 ++++++++++++++++++++++++++++++++++++++++\n wpa_supplicant/Makefile | 1 +\n 6 files changed, 981 insertions(+), 2 deletions(-)\n create mode 100644 src/nan/nan_ndl.c", "diff": "diff --git a/src/nan/Makefile b/src/nan/Makefile\nindex 64e1ae4849..38665ea234 100644\n--- a/src/nan/Makefile\n+++ b/src/nan/Makefile\n@@ -1,3 +1,3 @@\n-LIB_OBJS= nan.o nan_util.o nan_ndp.o\n+LIB_OBJS= nan.o nan_util.o nan_ndp.o nan_ndl.o\n \n include ../lib.rules\ndiff --git a/src/nan/nan.c b/src/nan/nan.c\nindex c5ec3f446e..92d0c9deba 100644\n--- a/src/nan/nan.c\n+++ b/src/nan/nan.c\n@@ -113,6 +113,8 @@ static void nan_del_peer(struct nan_data *nan, struct nan_peer *peer)\n \tnan_peer_flush_avail(&peer->info);\n \tnan_peer_flush_dev_capa(&peer->info);\n \tnan_peer_flush_elem_container(&peer->info);\n+\n+\tnan_ndl_reset(nan, peer);\n \tos_free(peer);\n }\n \ndiff --git a/src/nan/nan.h b/src/nan/nan.h\nindex 9e35432d72..7a6cc47ccb 100644\n--- a/src/nan/nan.h\n+++ b/src/nan/nan.h\n@@ -200,6 +200,8 @@ struct nan_schedule {\n * NAN_NDP_ACTION_REQ).\n * @status: Response status.\n * @reason_code: In case of rejected response, the rejection reason.\n+ * @sched_valid: Indicates whether the schedule field is valid.\n+ * @sched: The NAN schedule associated with the NDP parameters.\n */\n struct nan_ndp_params {\n \tenum nan_ndp_action type;\n@@ -219,13 +221,16 @@ struct nan_ndp_params {\n \t\t * Used with both NAN_NDP_ACTION_RESP (as a response to an NDP\n \t\t * request) and NAN_NDP_ACTION_CONF (as a response to an NDP\n \t\t * response with a counter).\n-\t\t * */\n+\t\t */\n \t\tstruct nan_ndp_setup_resp {\n \t\t\tu8 resp_ndi[ETH_ALEN];\n \t\t\tu8 status;\n \t\t\tu8 reason_code;\n \t\t} resp;\n \t} u;\n+\n+\tbool sched_valid;\n+\tstruct nan_schedule sched;\n };\n \n /*\ndiff --git a/src/nan/nan_i.h b/src/nan/nan_i.h\nindex 923195f456..a2ac279636 100644\n--- a/src/nan/nan_i.h\n+++ b/src/nan/nan_i.h\n@@ -205,6 +205,87 @@ struct nan_peer_info {\n };\n \n /**\n+ * enum nan_ndl_state - State of NDL establishment\n+ *\n+ * @NAN_NDL_STATE_NONE: No NDL with the peer\n+ * @NAN_NDL_STATE_START: NDL setup initiated by local device\n+ * @NAN_NDL_STATE_REQ_SENT: Sent NDL request\n+ * @NAN_NDL_STATE_REQ_RECV: Got NDL request\n+ * @NAN_NDL_STATE_RES_SENT: Sent NDL response\n+ * @NAN_NDL_STATE_RES_RECV: Got NDL response\n+ * @NAN_NDL_STATE_CON_SENT: Sent NDL confirm\n+ * @NAN_NDL_STATE_CON_RECV: Got NDL confirm\n+ * @NAN_NDL_STATE_DONE: NDL establishment is done (either success or reject).\n+ */\n+enum nan_ndl_state {\n+\tNAN_NDL_STATE_NONE = 0,\n+\tNAN_NDL_STATE_START,\n+\tNAN_NDL_STATE_REQ_SENT,\n+\tNAN_NDL_STATE_REQ_RECV,\n+\tNAN_NDL_STATE_RES_SENT,\n+\tNAN_NDL_STATE_RES_RECV,\n+\tNAN_NDL_STATE_CON_SENT,\n+\tNAN_NDL_STATE_CON_RECV,\n+\tNAN_NDL_STATE_DONE,\n+};\n+\n+/**\n+ * enum nan_ndl_setup_reason - NAN NDL setup reason\n+ * @NAN_NDL_SETUP_REASON_NONE: none\n+ * @NAN_NDL_SETUP_REASON_NDP: NDL setup request for NDP operation\n+ */\n+enum nan_ndl_setup_reason {\n+\tNAN_NDL_SETUP_REASON_NONE = 0,\n+\tNAN_NDL_SETUP_REASON_NDP,\n+};\n+\n+/**\n+ * struct nan_ndl - NAN NDL data\n+ *\n+ * @state: Current state. See &enum nan_ndl_state\n+ * @status: Current status. See &enum nan_ndl_status\n+ * @send_naf_on_error: When set, indicates that in case that the NDL processing\n+ * returned an error, a NAF still needs to be sent to the peer, i.e., the\n+ * error cannot be silently ignored.\n+ * @reason: In case of status == NAN_NDL_STATUS_REJECTED, indicates the reason.\n+ * See &enum nan_ndl_status\n+ * @sched: Holds the local schedule. See &struct nan_schedule.\n+ * @dialog_token: The dialog token for the current NDL negotiation.\n+ * @max_idle_period: Indicate a period of time in units of 1024TU during which\n+ * the peer device can refrain from transmitting over the NDL without\n+ * being terminated.\n+ * @setup_reason: The reason for the NDL setup. See &enum nan_ndl_setup_reason.\n+ * @ndc_id: NDC identifier\n+ * @peer_qos: Peer QoS requirements\n+ * @local_qos: Local QoS requirements (for the current NDP establishment)\n+ * @ndc_sched: The NDC schedule entries. See &struct nan_sched_entry\n+ * @ndc_sched_len: The length in octets of ndc_sched.\n+ * @immut_sched: The immutable schedule entries. See &enum nan_sched_entry\n+ * @immut_sched_len: The length in octets of immut_sched.\n+ */\n+struct nan_ndl {\n+\tenum nan_ndl_state state;\n+\tenum nan_ndl_status status;\n+\tu8 send_naf_on_error;\n+\tenum nan_reason reason;\n+\tstruct nan_schedule sched;\n+\n+\tu8 dialog_token;\n+\tu16 max_idle_period;\n+\tenum nan_ndl_setup_reason setup_reason;\n+\n+\tu8 ndc_id[ETH_ALEN];\n+\n+\tstruct nan_qos peer_qos, local_qos;\n+\n+\tu8 *ndc_sched;\n+\tu16 ndc_sched_len;\n+\n+\tu8 *immut_sched;\n+\tu16 immut_sched_len;\n+};\n+\n+/*\n * struct nan_peer - Represents a known NAN peer\n * @list: List node for linking peers.\n * @nmi_addr: NAN MAC address of the peer.\n@@ -213,6 +294,7 @@ struct nan_peer_info {\n * @ndps: List of NDPs associated with this peer.\n * @ndp_setup: Used to hold an NDP object while NDP establishment is in\n * progress.\n+ * @ndl: NDL data associated with this peer.\n */\n struct nan_peer {\n \tstruct dl_list list;\n@@ -223,6 +305,8 @@ struct nan_peer {\n \tstruct dl_list ndps;\n \n \tstruct nan_ndp_setup ndp_setup;\n+\n+\tstruct nan_ndl *ndl;\n };\n \n /**\n@@ -324,6 +408,13 @@ int nan_ndp_naf_sent(struct nan_data *nan, struct nan_peer *peer,\n \t\t enum nan_subtype subtype);\n int nan_parse_device_attrs(struct nan_data *nan, struct nan_peer *peer,\n \t\t\t const u8 *attrs_data, size_t attrs_len);\n+int nan_ndl_setup(struct nan_data *nan, struct nan_peer *peer,\n+\t\t struct nan_ndp_params *params);\n+void nan_ndl_setup_failure(struct nan_data *nan, struct nan_peer *peer,\n+\t\t\t enum nan_reason reason, bool reset_state);\n+void nan_ndl_reset(struct nan_data *nan, struct nan_peer *peer);\n+int nan_ndl_handle_ndl_attr(struct nan_data *nan, struct nan_peer *peer,\n+\t\t\t struct nan_msg *msg);\n int nan_chan_to_chan_idx_map(struct nan_data *nan,\n \t\t\t u8 op_class, u8 channel, u16 *chan_idx_map);\n #endif /* NAN_I_H */\ndiff --git a/src/nan/nan_ndl.c b/src/nan/nan_ndl.c\nnew file mode 100644\nindex 0000000000..0337ac97a6\n--- /dev/null\n+++ b/src/nan/nan_ndl.c\n@@ -0,0 +1,880 @@\n+/*\n+ * Wi-Fi Aware - NAN Data link\n+ * Copyright (C) 2025 Intel Corporation\n+ *\n+ * This software may be distributed under the terms of the BSD license.\n+ * See README for more details.\n+ */\n+\n+#include \"includes.h\"\n+#include \"common.h\"\n+#include \"nan_i.h\"\n+\n+struct ndl_attr_params {\n+\tu8 dialog_token;\n+\tu8 type;\n+\tu8 status;\n+\tu8 reason;\n+\tenum nan_ndl_setup_reason setup_reason;\n+\n+\tu16 max_idle_period;\n+\tu8 min_slots;\n+\tu16 max_latency;\n+\n+\tu8 ndc_id[ETH_ALEN];\n+\tconst u8 *ndc_sched;\n+\tu16 ndc_sched_len;\n+\n+\tconst u8 *immut_sched; u16 immut_sched_len;\n+};\n+\n+static const char *nan_ndl_state_str(enum nan_ndl_state state)\n+{\n+#define C2S(x) case x: return #x;\n+\tswitch (state) {\n+\tC2S(NAN_NDL_STATE_NONE)\n+\tC2S(NAN_NDL_STATE_START)\n+\tC2S(NAN_NDL_STATE_REQ_SENT)\n+\tC2S(NAN_NDL_STATE_REQ_RECV)\n+\tC2S(NAN_NDL_STATE_RES_SENT)\n+\tC2S(NAN_NDL_STATE_RES_RECV)\n+\tC2S(NAN_NDL_STATE_CON_SENT)\n+\tC2S(NAN_NDL_STATE_CON_RECV)\n+\tC2S(NAN_NDL_STATE_DONE)\n+\tdefault:\n+\t\treturn \"Invalid NAN NDL state\";\n+\t}\n+}\n+\n+\n+static void nan_ndl_set_state(struct nan_data *nan, struct nan_ndl *ndl,\n+\t\t\t enum nan_ndl_state state)\n+{\n+\twpa_printf(MSG_DEBUG, \"NAN: NDL: State %s (%u) --> %s (%u)\",\n+\t\t nan_ndl_state_str(ndl->state), ndl->state,\n+\t\t nan_ndl_state_str(state), state);\n+\n+\tndl->state = state;\n+}\n+\n+\n+static void nan_ndl_time_bitmap_print(struct nan_data *nan,\n+\t\t\t\t struct nan_time_bitmap *tbm,\n+\t\t\t\t const char *type)\n+{\n+\tif (!tbm->len)\n+\t\treturn;\n+\n+\twpa_printf(MSG_DEBUG,\n+\t\t \"channel sched: %s: dur=%u, per=%u, off=%u, len=%u\",\n+\t\t type, tbm->duration, tbm->period, tbm->offset, tbm->len);\n+\n+\twpa_printf(MSG_DEBUG,\n+\t\t \"bitmap[0:3]: 0x%x:0x%x:0x%x:0x%x\",\n+\t\t tbm->bitmap[0], tbm->bitmap[1],\n+\t\t tbm->bitmap[2], tbm->bitmap[3]);\n+}\n+\n+\n+static void nan_ndl_chan_sched_print(struct nan_data *nan, size_t idx,\n+\t\t\t\t struct nan_chan_schedule *cs)\n+{\n+\twpa_printf(MSG_DEBUG, \"NAN: sched: index=%zu, map_id=%u\",\n+\t\t idx, cs->map_id);\n+\n+\twpa_printf(MSG_DEBUG,\n+\t\t \"channel sched: chan: freq=%u, c1=%d, c2=%d, bandwidth=%d\",\n+\t\t cs->chan.freq, cs->chan.center_freq1, cs->chan.center_freq2,\n+\t\t cs->chan.bandwidth);\n+\n+\tnan_ndl_time_bitmap_print(nan, &cs->committed, \"committed\");\n+\tnan_ndl_time_bitmap_print(nan, &cs->conditional, \"conditional\");\n+}\n+\n+\n+static void nan_ndl_sched_print(struct nan_data *nan,\n+\t\t\t\tstruct nan_schedule *sched)\n+{\n+\tsize_t i;\n+\n+\twpa_printf(MSG_DEBUG,\n+\t\t \"NAN: sched: map_ids=0x%x, n_chans=%u, seq_id=%u\",\n+\t\t sched->map_ids_bitmap,\n+\t\t sched->n_chans, sched->sequence_id);\n+\n+\tfor (i = 0; i < sched->n_chans; i++)\n+\t\tnan_ndl_chan_sched_print(nan, i, &sched->chans[i]);\n+}\n+\n+\n+static void nan_ndl_clear(struct nan_data *nan, struct nan_peer *peer)\n+{\n+\tstruct nan_ndl *ndl = peer->ndl;\n+\n+\twpa_printf(MSG_DEBUG,\n+\t\t \"NAN: NDL: Clear info for peer=\" MACSTR \" state=%s (%u)\",\n+\t\t MAC2STR(peer->nmi_addr),\n+\t\t nan_ndl_state_str(peer->ndl->state), peer->ndl->state);\n+\n+\tos_free(ndl->ndc_sched);\n+\tndl->ndc_sched = NULL;\n+\tndl->ndc_sched_len = 0;\n+\n+\tos_free(ndl->immut_sched);\n+\tndl->immut_sched = NULL;\n+\tndl->immut_sched_len = 0;\n+\n+\tndl->dialog_token = 0;\n+\tndl->max_idle_period = 0;\n+\n+\tos_memset(ndl->ndc_id, 0, sizeof(ndl->ndc_id));\n+\n+\tndl->peer_qos.max_latency = NAN_QOS_MAX_LATENCY_NO_PREF;\n+\tndl->local_qos.max_latency = NAN_QOS_MAX_LATENCY_NO_PREF;\n+\n+\tndl->setup_reason = NAN_NDL_SETUP_REASON_NONE;\n+\n+\twpabuf_free(ndl->sched.elems);\n+\tos_memset(&ndl->sched, 0, sizeof(ndl->sched));\n+}\n+\n+\n+/*\n+ * nan_ndl_reset - Reset the NDL state\n+ *\n+ * @nan: NAN module context from nan_init()\n+ * @peer: The peer that requires NDL setup reset\n+ */\n+void nan_ndl_reset(struct nan_data *nan, struct nan_peer *peer)\n+{\n+\twpa_printf(MSG_DEBUG, \"NAN: NDL: Reset state for peer=\" MACSTR,\n+\t\t MAC2STR(peer->nmi_addr));\n+\n+\tif (!peer->ndl) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: NDL: Reset: no NDL\");\n+\t\treturn;\n+\t}\n+\n+\tnan_ndl_clear(nan, peer);\n+\n+\tos_free(peer->ndl);\n+\tpeer->ndl = NULL;\n+}\n+\n+\n+struct nan_ndl *nan_ndl_alloc(struct nan_data *nan)\n+{\n+\tstruct nan_ndl *ndl;\n+\n+\twpa_printf(MSG_DEBUG, \"NAN: NDL: Allocating a new NDL\");\n+\n+\tndl = os_zalloc(sizeof(struct nan_ndl));\n+\tif (!ndl) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: NDL: Failed to allocate NDL\");\n+\t\treturn NULL;\n+\t}\n+\n+\tndl->status = NAN_NDL_STATUS_ACCEPTED;\n+\tndl->reason = NAN_REASON_RESERVED;\n+\n+\tndl->local_qos.min_slots = NAN_QOS_MIN_SLOTS_NO_PREF;\n+\tndl->local_qos.max_latency = NAN_QOS_MAX_LATENCY_NO_PREF;\n+\n+\tndl->peer_qos.min_slots = NAN_QOS_MIN_SLOTS_NO_PREF;\n+\tndl->peer_qos.max_latency = NAN_QOS_MAX_LATENCY_NO_PREF;\n+\n+\tnan_ndl_set_state(nan, ndl, NAN_NDL_STATE_NONE);\n+\n+\treturn ndl;\n+}\n+\n+\n+static enum nan_ndl_status nan_ndl_res_status(struct nan_data *nan,\n+\t\t\t\t\t struct nan_peer *peer)\n+{\n+\t/* TODO: properly set the status */\n+\treturn NAN_NDL_STATUS_ACCEPTED;\n+}\n+\n+\n+/*\n+ * nan_ndl_setup - Handle NDL setup either as an initiator or a responder\n+ *\n+ * @nan: NAN module context from nan_init()\n+ * @peer: The peer for which the NDL is being setup\n+ * @params: NDP setup request parameters\n+ * Returns: 0 on success, negative on failure.\n+\n+ * It is possible that an NDL with the peer already exists in which case it\n+ * would be reused. Otherwise, new NDL establishment will be started.\n+ */\n+int nan_ndl_setup(struct nan_data *nan, struct nan_peer *peer,\n+\t\t struct nan_ndp_params *params)\n+{\n+\tstruct nan_ndl *ndl;\n+\tenum nan_reason reason;\n+\n+\tif (!peer->ndl) {\n+\t\tif (params->type != NAN_NDP_ACTION_REQ) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t \"NAN: NDL: Invalid action; expecting request\");\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tpeer->ndl = nan_ndl_alloc(nan);\n+\t\tif (!peer->ndl)\n+\t\t\treturn -1;\n+\n+\t\tndl = peer->ndl;\n+\t} else {\n+\t\tndl = peer->ndl;\n+\n+\t\tndl->send_naf_on_error = 0;\n+\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t \"NAN: NDL: peer=\" MACSTR \". state=%s (%u)\",\n+\t\t\t MAC2STR(peer->nmi_addr),\n+\t\t\t nan_ndl_state_str(ndl->state),\n+\t\t\t ndl->state);\n+\n+\t\tif (ndl->state == NAN_NDL_STATE_DONE) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t \"NAN: NDL: Already established\");\n+\t\t\treturn 0;\n+\t\t}\n+\n+\t\tif (!((params->type == NAN_NDP_ACTION_RESP &&\n+\t\t ndl->state == NAN_NDL_STATE_REQ_RECV) ||\n+\t\t (params->type == NAN_NDP_ACTION_CONF &&\n+\t\t ndl->state == NAN_NDL_STATE_RES_RECV))) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t \"NAN: NDL: Invalid action type=%u, state=%u\",\n+\t\t\t\t params->type, ndl->state);\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tif (params->u.resp.status == NAN_NDP_STATUS_REJECTED) {\n+\t\t\treason = params->u.resp.reason_code;\n+\t\t\tgoto out_fail;\n+\t\t}\n+\t}\n+\n+\tif (!params->sched_valid) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: NDL: no valid schedule\");\n+\t\treason = NAN_REASON_INVALID_PARAMETERS;\n+\t\tgoto out_fail;\n+\t}\n+\n+\twpabuf_free(ndl->sched.elems);\n+\tos_memcpy(&ndl->sched, ¶ms->sched, sizeof(ndl->sched));\n+\tnan_ndl_sched_print(nan, &peer->ndl->sched);\n+\n+\t/* Copy elems buffer */\n+\tif (params->sched.elems) {\n+\t\tndl->sched.elems =\n+\t\t\twpabuf_alloc_copy(wpabuf_head(params->sched.elems),\n+\t\t\t\t\t wpabuf_len(params->sched.elems));\n+\t\tif (!ndl->sched.elems) {\n+\t\t\treason = NAN_REASON_UNSPECIFIED_REASON;\n+\t\t\tgoto out_fail;\n+\t\t}\n+\t}\n+\n+\tif (is_zero_ether_addr(ndl->ndc_id)) {\n+\t\tos_get_random(ndl->ndc_id, ETH_ALEN);\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t \"NAN: NDL: generated NDC ID \" MACSTR,\n+\t\t\t MAC2STR(ndl->ndc_id));\n+\t}\n+\n+\tndl->local_qos.min_slots = params->qos.min_slots;\n+\tndl->local_qos.max_latency = params->qos.max_latency;\n+\n+\tif (ndl->state == NAN_NDL_STATE_NONE) {\n+\t\tndl->dialog_token = nan_get_next_dialog_token(nan);\n+\t\tnan_ndl_set_state(nan, ndl, NAN_NDL_STATE_START);\n+\t\tndl->status = NAN_NDL_STATUS_CONTINUED;\n+\t} else {\n+\t\tndl->status = nan_ndl_res_status(nan, peer);\n+\t}\n+\n+\tndl->setup_reason = NAN_NDL_SETUP_REASON_NDP;\n+\n+\twpa_printf(MSG_DEBUG,\n+\t\t \"NAN: NDL: success: state=%s (%u). Dialog token=%u\",\n+\t\t nan_ndl_state_str(ndl->state), ndl->state,\n+\t\t ndl->dialog_token);\n+\n+\treturn 0;\n+out_fail:\n+\twpa_printf(MSG_DEBUG, \"NAN: NDL: Failed. reason=%u\", reason);\n+\tif (ndl->state == NAN_NDL_STATE_REQ_RECV ||\n+\t ndl->state == NAN_NDL_STATE_RES_RECV) {\n+\t\tndl->status = NAN_NDL_STATUS_REJECTED;\n+\t\tndl->reason = reason;\n+\t\tndl->send_naf_on_error = 1;\n+\t}\n+\n+\t/* clear the NDL info but leave the state, status and reason, full\n+\t * cleanup would be done on Tx status handling\n+\t */\n+\tnan_ndl_clear(nan, peer);\n+\treturn -1;\n+}\n+\n+\n+/*\n+ * nan_ndl_setup_failure - Indicate failure during NDL setup\n+ *\n+ * @nan: NAN module context from nan_init()\n+ * @peer: NAN peer.\n+ * @reason: Failure reason\n+ * @reset_state: Reset the NDL state if true.\n+ */\n+void nan_ndl_setup_failure(struct nan_data *nan, struct nan_peer *peer,\n+\t\t\t enum nan_reason reason, bool reset_state)\n+{\n+\tstruct nan_ndl *ndl = peer->ndl;\n+\n+\twpa_printf(MSG_DEBUG,\n+\t\t \"NAN: NDL: Setup failure: peer \" MACSTR \". state=%s (%u). reason=%u\",\n+\t\t MAC2STR(peer->nmi_addr), nan_ndl_state_str(ndl->state),\n+\t\t ndl->state, reason);\n+\n+\tif (reset_state) {\n+\t\tnan_ndl_reset(nan, peer);\n+\t} else {\n+\t\tndl->status = NAN_NDL_STATUS_REJECTED;\n+\t\tndl->reason = reason;\n+\t}\n+}\n+\n+\n+static int nan_ndl_parse_ndc_attr(struct nan_data *nan,\n+\t\t\t\t const struct ieee80211_ndc *ndc_attr,\n+\t\t\t\t u16 ndc_attr_len, u8 *ndc_id,\n+\t\t\t\t const u8 **ndc_schedule,\n+\t\t\t\t u16 *ndc_schedule_len)\n+{\n+\tu16 ext_ndc_len;\n+\n+\t/* consider only the selected NDC */\n+\tif (!(ndc_attr->ctrl & NAN_NDC_CTRL_SELECTED))\n+\t\treturn -1;\n+\n+\text_ndc_len = ndc_attr_len - sizeof(*ndc_attr);\n+\n+\tif (ext_ndc_len <= sizeof(struct nan_sched_entry)) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: NDL: Request with invalid len=%u\",\n+\t\t\t ndc_attr_len);\n+\t\treturn -1;\n+\t}\n+\n+\tos_memcpy(ndc_id, ndc_attr->ndc_id, sizeof(ndc_attr->ndc_id));\n+\t*ndc_schedule_len = ext_ndc_len;\n+\t*ndc_schedule = (u8 *)(ndc_attr + 1);\n+\n+\twpa_printf(MSG_DEBUG, \"NAN: NDL: ndc_id=\" MACSTR \" schedule_len=%u\",\n+\t\t MAC2STR(ndc_id), *ndc_schedule_len);\n+\treturn 0;\n+}\n+\n+\n+static int nan_ndl_parse_qos_attr(struct nan_data *nan,\n+\t\t\t\t struct ieee80211_nan_qos *qos_attr,\n+\t\t\t\t u16 qos_attr_len,\n+\t\t\t\t u8 *min_slots, u16 *max_latency)\n+{\n+\t*min_slots = qos_attr->min_slots;\n+\t*max_latency = le_to_host16(qos_attr->max_latency);\n+\n+\twpa_printf(MSG_DEBUG, \"NAN: QoS attr: min_slots=%u, max_latency=%u\",\n+\t\t *min_slots, *max_latency);\n+\treturn 0;\n+}\n+\n+\n+static int nan_ndl_attr_handle_req(struct nan_data *nan, struct nan_peer *peer,\n+\t\t\t\t const struct ndl_attr_params *params)\n+{\n+\tstruct nan_ndl *ndl;\n+\n+\twpa_printf(MSG_DEBUG, \"NAN: NDL: Handle request\");\n+\n+\tif (peer->ndl) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t \"NAN: NDL: Request while another establishment is ongoing\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (params->status != NAN_NDL_STATUS_CONTINUED) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t \"NAN: NDL: Request with invalid status=%u\",\n+\t\t\t params->status);\n+\t\treturn -1;\n+\t}\n+\n+\tpeer->ndl = nan_ndl_alloc(nan);\n+\tif (!peer->ndl)\n+\t\treturn -1;\n+\n+\tndl = peer->ndl;\n+\n+\tndl->status = NAN_NDL_STATUS_CONTINUED;\n+\n+\tndl->dialog_token = params->dialog_token;\n+\tndl->max_idle_period = params->max_idle_period;\n+\tndl->setup_reason = params->setup_reason;\n+\n+\tif (!is_zero_ether_addr(params->ndc_id)) {\n+\t\tos_memcpy(ndl->ndc_id, params->ndc_id, sizeof(ndl->ndc_id));\n+\n+\t\tif (params->ndc_sched && params->ndc_sched_len) {\n+\t\t\tos_free(ndl->ndc_sched);\n+\t\t\tndl->ndc_sched_len = 0;\n+\n+\t\t\tndl->ndc_sched = os_memdup(params->ndc_sched,\n+\t\t\t\t\t\t params->ndc_sched_len);\n+\t\t\tif (!ndl->ndc_sched) {\n+\t\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t\t \"NAN: NDL: Failed to copy NDC schedule\");\n+\t\t\t\tgoto fail;\n+\t\t\t}\n+\n+\t\t\tndl->ndc_sched_len = params->ndc_sched_len;\n+\t\t}\n+\t}\n+\n+\tndl->peer_qos.min_slots = params->min_slots;\n+\tndl->peer_qos.max_latency = params->max_latency;\n+\n+\tif (params->immut_sched && params->immut_sched_len) {\n+\t\tndl->immut_sched = os_memdup(params->immut_sched,\n+\t\t\t\t\t params->immut_sched_len);\n+\t\tif (!ndl->immut_sched) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t \"NAN: NDL: Failed to copy immutable schedule\");\n+\t\t\tgoto fail;\n+\t\t}\n+\t\tndl->immut_sched_len = params->immut_sched_len;\n+\t}\n+\n+\tnan_ndl_set_state(nan, ndl, NAN_NDL_STATE_REQ_RECV);\n+\n+\twpa_printf(MSG_DEBUG, \"NAN: NDL: Handle request done\");\n+\treturn 0;\n+fail:\n+\tnan_ndl_reset(nan, peer);\n+\treturn -1;\n+}\n+\n+\n+static int nan_ndl_attr_handle_resp(struct nan_data *nan, struct nan_peer *peer,\n+\t\t\t\t const struct ndl_attr_params *params)\n+{\n+\tstruct nan_ndl *ndl = peer->ndl;\n+\n+\twpa_printf(MSG_DEBUG, \"NAN: NDL: Handle response\");\n+\n+\tif (!ndl) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: NDL: unexpected response\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (ndl->state != NAN_NDL_STATE_REQ_SENT) {\n+\t\tif (ndl->state != NAN_NDL_STATE_START) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t \"NAN: NDL: Response while state=%s (%u)\",\n+\t\t\t\t nan_ndl_state_str(ndl->state), ndl->state);\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\t/*\n+\t\t * Due to races with the driver, it is possible that the\n+\t\t * response is received before an ACK is indicated. Allow the\n+\t\t * processing of the attribute, and if all parameters are OK,\n+\t\t * fast forward the state machine below.\n+\t\t */\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t \"NAN: NDL: Response received before Tx status.\");\n+\t}\n+\n+\tndl->send_naf_on_error = 0;\n+\tndl->status = params->status;\n+\tnan_ndl_set_state(nan, ndl, NAN_NDL_STATE_RES_RECV);\n+\n+\tif (ndl->dialog_token != params->dialog_token) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t \"NAN: NDL: Resp: Invalid dialog token (%u != %u)\",\n+\t\t\t ndl->dialog_token, params->dialog_token);\n+\t\treturn -1;\n+\t}\n+\n+\tif (params->status != NAN_NDL_STATUS_CONTINUED &&\n+\t params->status != NAN_NDL_STATUS_ACCEPTED) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t \"NAN: NDL: Resp: Rejected. status=%u, reason=%u\",\n+\t\t\t params->status, params->reason);\n+\n+\t\tndl->reason = params->reason;\n+\t\tndl->status = NAN_NDL_STATUS_REJECTED;\n+\t\treturn 0;\n+\t}\n+\n+\tif (is_zero_ether_addr(params->ndc_id)) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: NDL: Response without NDC\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (os_memcmp(ndl->ndc_id, params->ndc_id, sizeof(ndl->ndc_id)) != 0) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: NDL: Resp: ndc_id changed\");\n+\t\tos_memcpy(ndl->ndc_id, params->ndc_id, sizeof(ndl->ndc_id));\n+\t}\n+\n+\tndl->max_idle_period = params->max_idle_period;\n+\tndl->peer_qos.min_slots = params->min_slots;\n+\tndl->peer_qos.max_latency = params->max_latency;\n+\n+\t/* TODO: validate that in case an ACCEPTED NDL and an NDC, the NDC\n+\t * schedule is covered by the local device committed availability.\n+\t */\n+\tif (params->ndc_sched && params->ndc_sched_len) {\n+\t\tos_free(ndl->ndc_sched);\n+\t\tndl->ndc_sched_len = 0;\n+\n+\t\tndl->ndc_sched = os_memdup(params->ndc_sched,\n+\t\t\t\t\t params->ndc_sched_len);\n+\t\tif (!ndl->ndc_sched) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t \"NAN: NDL: Resp: Failed to allocate NDC schedule\");\n+\t\t\tgoto fail;\n+\t\t}\n+\n+\t\tndl->ndc_sched_len = params->ndc_sched_len;\n+\t}\n+\n+\tif (params->immut_sched && params->immut_sched_len) {\n+\t\tif (params->status == NAN_NDL_STATUS_ACCEPTED) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t \"NAN: NDL: Resp: Immutable not allowed with status == accept\");\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tos_free(ndl->immut_sched);\n+\t\tndl->immut_sched_len = 0;\n+\t\tndl->immut_sched = os_memdup(params->immut_sched,\n+\t\t\t\t\t params->immut_sched_len);\n+\t\tif (!ndl->immut_sched) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t \"NAN: NDL: Resp: fail allocate immutable schedule\");\n+\t\t\tgoto fail;\n+\t\t}\n+\t\tndl->immut_sched_len = params->immut_sched_len;\n+\t}\n+\n+\twpa_printf(MSG_DEBUG, \"NAN: NDL: Resp: status=%u\", params->status);\n+\n+\tndl->status = params->status;\n+\tif (params->status == NAN_NDL_STATUS_ACCEPTED)\n+\t\tnan_ndl_set_state(nan, ndl, NAN_NDL_STATE_DONE);\n+\n+\treturn 0;\n+fail:\n+\tnan_ndl_clear(nan, peer);\n+\tndl->status = NAN_NDL_STATUS_REJECTED;\n+\tndl->reason = NAN_REASON_RESOURCE_LIMITATION;\n+\tndl->send_naf_on_error = 1;\n+\treturn 0;\n+}\n+\n+\n+static int nan_ndl_attr_handle_conf(struct nan_data *nan, struct nan_peer *peer,\n+\t\t\t\t const struct ndl_attr_params *params)\n+{\n+\tstruct nan_ndl *ndl = peer->ndl;\n+\n+\tif (!ndl) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t \"NAN: NDL: Confirm without an NDL\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (ndl->state != NAN_NDL_STATE_RES_SENT) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t \"NAN: NDL: Confirm while not expecting one\");\n+\n+\t\tif (ndl->state != NAN_NDL_STATE_REQ_RECV ||\n+\t\t ndl->status != NAN_NDL_STATUS_CONTINUED)\n+\t\t\treturn -1;\n+\n+\t\t/*\n+\t\t * Due to races with the driver, it is possible that the\n+\t\t * response is received before an ACK is indicated. Allow the\n+\t\t * processing of the attribute, and if all parameters are OK,\n+\t\t * fast forward the state machine below.\n+\t\t */\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t \"NAN: NDL: Confirm received before Tx status\");\n+\t}\n+\n+\tndl->send_naf_on_error = 0;\n+\tndl->status = params->status;\n+\tnan_ndl_set_state(nan, ndl, NAN_NDL_STATE_CON_RECV);\n+\n+\tif (params->status != NAN_NDL_STATUS_ACCEPTED) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t \"NAN: NDL: Confirm was not accepted. status=%u, reason=%u\",\n+\t\t\t params->status, params->reason);\n+\t\tndl->status = NAN_NDL_STATUS_REJECTED;\n+\t\tndl->reason = params->reason;\n+\t\treturn 0;\n+\t}\n+\n+\tif (ndl->dialog_token != params->dialog_token) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t \"NAN: NDL: Confirm with invalid dialog token (%u != %u)\",\n+\t\t\t ndl->dialog_token, params->dialog_token);\n+\t\treturn -1;\n+\t}\n+\n+\tif (!is_zero_ether_addr(params->ndc_id) &&\n+\t os_memcmp(ndl->ndc_id, params->ndc_id, sizeof(ndl->ndc_id)) != 0) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: NDL: Confirm: ndc_id changed\");\n+\t\tos_memcpy(ndl->ndc_id, params->ndc_id, sizeof(ndl->ndc_id));\n+\t}\n+\n+\tndl->max_idle_period = params->max_idle_period;\n+\tndl->peer_qos.min_slots = params->min_slots;\n+\tndl->peer_qos.max_latency = params->max_latency;\n+\n+\t/* TODO: validate that the NDC schedule is covered by the local device\n+\t * committed availability.\n+\t */\n+\tif (params->ndc_sched && params->ndc_sched_len) {\n+\t\tos_free(ndl->ndc_sched);\n+\t\tndl->ndc_sched_len = 0;\n+\n+\t\tndl->ndc_sched = os_memdup(params->ndc_sched,\n+\t\t\t\t\t params->ndc_sched_len);\n+\t\tif (!ndl->ndc_sched) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t \"NAN: NDL: Failed to allocate NDC schedule\");\n+\t\t\tgoto fail;\n+\t\t}\n+\t\tndl->ndc_sched_len = params->ndc_sched_len;\n+\t}\n+\n+\t/* TODO: validate that the immutable schedule is covered by the local\n+\t * device committed availability.\n+\t */\n+\tif (params->immut_sched && params->immut_sched_len) {\n+\t\tos_free(ndl->immut_sched);\n+\t\tndl->immut_sched_len = 0;\n+\n+\t\tndl->immut_sched = os_memdup(params->immut_sched,\n+\t\t\t\t\t params->immut_sched_len);\n+\t\tif (!ndl->immut_sched) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t \"NAN: NDL: Failed to allocate immutable schedule\");\n+\t\t\tgoto fail;\n+\t\t}\n+\t\tndl->immut_sched_len = params->immut_sched_len;\n+\t}\n+\n+\tnan_ndl_set_state(nan, ndl, NAN_NDL_STATE_DONE);\n+\treturn 0;\n+\n+fail:\n+\tndl->reason = NAN_REASON_RESOURCE_LIMITATION;\n+\tndl->send_naf_on_error = 1;\n+\treturn -1;\n+}\n+\n+\n+/*\n+ * nan_ndl_handle_ndl_attr - Handle ndl attribute and update local state\n+ *\n+ * @nan: NAN module context from nan_init()\n+ * @peer: the peer from which the original message was received\n+ * @msg: parsed nan action frame\n+ * Returns: 0 on success, negative on failure to parse the attributes etc.\n+ *\n+ * As part of the NDL attribute handling, the function also parses NDC and QoS\n+ * attributes.\n+ */\n+int nan_ndl_handle_ndl_attr(struct nan_data *nan, struct nan_peer *peer,\n+\t\t\t struct nan_msg *msg)\n+{\n+\tstruct ieee80211_ndl *ndl_attr;\n+\tconst u8 *ndl_attr_ext;\n+\tstruct ndl_attr_params params;\n+\tu16 ndl_attr_len, ndl_attr_ext_len;\n+\tu16 control;\n+\tu8 ctrl_setup_reason;\n+\tu8 ndc_ok;\n+\tint ret;\n+\n+\tos_memset(¶ms, 0, sizeof(params));\n+\n+\tif (!msg || !peer)\n+\t\treturn -1;\n+\n+\t/*\n+\t * It is possible that we receive a confirm NAF before the TX status\n+\t * of the previous NAF was processed. If NDL was accepted,\n+\t * the confirm would not include the NDL attribute, thus fast forward to\n+\t * state \"done\" here.\n+\t */\n+\tif (msg->oui_subtype == NAN_SUBTYPE_DATA_PATH_CONFIRM &&\n+\t peer->ndl->state == NAN_NDL_STATE_REQ_RECV &&\n+\t peer->ndl->status == NAN_NDL_STATUS_ACCEPTED) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: NDL is accepted - fast forward to state done\");\n+\t\tnan_ndl_set_state(nan, peer->ndl, NAN_NDL_STATE_DONE);\n+\t}\n+\n+\tif (peer->ndl && peer->ndl->state == NAN_NDL_STATE_DONE) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: NDL: NDL already done\");\n+\t\treturn 0;\n+\t}\n+\n+\tif (!msg->attrs.ndl)\n+\t\treturn 0;\n+\n+\tndl_attr = (struct ieee80211_ndl *)msg->attrs.ndl;\n+\tndl_attr_len = msg->attrs.ndl_len;\n+\n+\tndl_attr_ext = (u8 *)(ndl_attr + 1);\n+\tndl_attr_ext_len = ndl_attr_len - sizeof(struct ieee80211_ndl);\n+\n+\tparams.type = BITS(ndl_attr->type_and_status, NAN_NDL_TYPE_MASK,\n+\t\t\t NAN_NDL_TYPE_POS);\n+\n+\tparams.status = BITS(ndl_attr->type_and_status, NAN_NDL_STATUS_MASK,\n+\t\t\t NAN_NDL_STATUS_POS);\n+\tcontrol = le_to_host16(ndl_attr->ctrl);\n+\n+\tif (peer->ndl)\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t \"NAN: NDL: curr: state=%s (%d), status=%d\",\n+\t\t\t nan_ndl_state_str(peer->ndl->state),\n+\t\t\t peer->ndl->state, peer->ndl->status);\n+\telse\n+\t\twpa_printf(MSG_DEBUG, \"NAN: NDL: NDL does not exist\");\n+\n+\tparams.dialog_token = ndl_attr->dialog_token;\n+\n+\twpa_printf(MSG_DEBUG,\n+\t\t \"NAN: NDL: dialog=%u, type=0x%x, status=0x%x, ctrl=0x%x\",\n+\t\t params.dialog_token, params.type, params.status, control);\n+\n+\tif (control & NAN_NDL_CTRL_PEER_ID_PRESENT) {\n+\t\tif (ndl_attr_ext_len < 1) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t \"NAN: NDL: Request with invalid len=%u, control=0x%x\",\n+\t\t\t\t ndl_attr_len, control);\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\t/*\n+\t\t * Peer ID is not longer used. It is considered as reserved in\n+\t\t * Wi-Fi Aware Specification v4.0 Table 107. Just skip it\n+\t\t */\n+\t\tndl_attr_ext++;\n+\t\tndl_attr_ext_len--;\n+\t}\n+\n+\tif (control & NAN_NDL_CTRL_MAX_IDLE_PERIOD_PRESENT) {\n+\t\tif (ndl_attr_ext_len < 2) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t \"NAN: NDL: Request with invalid len=%u, control=0x%x\",\n+\t\t\t\t ndl_attr_len, control);\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tparams.max_idle_period = WPA_GET_LE16(ndl_attr_ext);\n+\t\tndl_attr_ext += 2;\n+\t\tndl_attr_ext_len -= 2;\n+\t}\n+\n+\tndc_ok = 1;\n+\tif (control & NAN_NDL_CTRL_NDC_ATTR_PRESENT) {\n+\t\tstruct nan_attrs_entry *n;\n+\n+\t\tret = -1;\n+\t\tdl_list_for_each(n, &msg->attrs.ndc, struct nan_attrs_entry,\n+\t\t\t\t list) {\n+\t\t\tret = nan_ndl_parse_ndc_attr(nan,\n+\t\t\t\t\t\t (struct ieee80211_ndc *)n->ptr,\n+\t\t\t\t\t\t n->len,\n+\t\t\t\t\t\t params.ndc_id,\n+\t\t\t\t\t\t ¶ms.ndc_sched,\n+\t\t\t\t\t\t ¶ms.ndc_sched_len);\n+\t\t\tif (!ret)\n+\t\t\t\tbreak;\n+\t\t}\n+\n+\t\tif (ret)\n+\t\t\tndc_ok = 0;\n+\t} else if (params.type == NAN_NDL_TYPE_RESPONSE) {\n+\t\tndc_ok = 0;\n+\t}\n+\n+\tif (!ndc_ok) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: NDL: Missing valid selected NDC\");\n+\t\treturn -1;\n+\t}\n+\n+\tparams.min_slots = NAN_QOS_MIN_SLOTS_NO_PREF;\n+\tparams.max_latency = NAN_QOS_MAX_LATENCY_NO_PREF;\n+\tif (control & NAN_NDL_CTRL_NDL_QOS_ATTR_PRESENT) {\n+\t\tif (!msg->attrs.ndl_qos) {\n+\t\t\twpa_printf(MSG_DEBUG, \"NAN: NDL QoS attribute not present but control flag is set\");\n+\t\t\treturn -1;\n+\t\t}\n+\t\tret = nan_ndl_parse_qos_attr(nan,\n+\t\t\t\t\t (struct ieee80211_nan_qos *)msg->attrs.ndl_qos,\n+\t\t\t\t\t msg->attrs.ndl_qos_len,\n+\t\t\t\t\t ¶ms.min_slots,\n+\t\t\t\t\t ¶ms.max_latency);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\tif (control & NAN_NDL_CTRL_IMMUT_SCHED_PRESENT) {\n+\t\tif (ndl_attr_ext_len <= sizeof(struct nan_sched_entry)) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t \"NAN: NDL: Request with invalid len=%u, control=0x%x\",\n+\t\t\t\tndl_attr_len, control);\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tparams.immut_sched = ndl_attr_ext;\n+\t\tparams.immut_sched_len = ndl_attr_ext_len;\n+\t}\n+\n+\tctrl_setup_reason = (control & NAN_NDL_CTRL_NDL_SETUP_REASON_MASK) >>\n+\t\tNAN_NDL_CTRL_NDL_SETUP_REASON_POS;\n+\n+\tif (ctrl_setup_reason == NAN_NDL_CTRL_NDL_SETUP_REASON_NDP) {\n+\t\tparams.setup_reason = NAN_NDL_SETUP_REASON_NDP;\n+\t} else {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t \"NAN: NDL: Unknown setup reason. Assume NDP\");\n+\t\tparams.setup_reason = NAN_NDL_SETUP_REASON_NDP;\n+\t}\n+\n+\twpa_printf(MSG_DEBUG,\n+\t\t \"NAN: NDL: max_idle_period=%u, immutable len=%u\",\n+\t\t params.max_idle_period, params.immut_sched_len);\n+\n+\tswitch (params.type) {\n+\tcase NAN_NDL_TYPE_REQUEST:\n+\t\treturn nan_ndl_attr_handle_req(nan, peer, ¶ms);\n+\tcase NAN_NDL_TYPE_RESPONSE:\n+\t\treturn nan_ndl_attr_handle_resp(nan, peer, ¶ms);\n+\tcase NAN_NDL_TYPE_CONFIRM:\n+\t\treturn nan_ndl_attr_handle_conf(nan, peer, ¶ms);\n+\tdefault:\n+\t\treturn -1;\n+\t}\n+}\ndiff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile\nindex 59defd6d25..7714d326a5 100644\n--- a/wpa_supplicant/Makefile\n+++ b/wpa_supplicant/Makefile\n@@ -334,6 +334,7 @@ OBJS += ../src/nan/nan.o\n OBJS += ../src/common/nan_de.o\n OBJS += ../src/nan/nan_util.o\n OBJS += ../src/nan/nan_ndp.o\n+OBJS += ../src/nan/nan_ndl.o\n endif\n \n ifdef CONFIG_PR\n", "prefixes": [ "18/58" ] }