[RFC v2 18/99] NAN: Add support for building schedule related attributes
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Tue Dec 23 03:51:22 PST 2025
From: Ilan Peer <ilan.peer at intel.com>
Add support for building the NDL, NDC and QoS attributes.
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
src/nan/nan_i.h | 9 +++
src/nan/nan_ndl.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 207 insertions(+)
diff --git a/src/nan/nan_i.h b/src/nan/nan_i.h
index c0f9b41be4..0a5d64c8f9 100644
--- a/src/nan/nan_i.h
+++ b/src/nan/nan_i.h
@@ -401,6 +401,15 @@ void nan_ndl_setup_failure(struct nan_data *nan, struct nan_peer *peer,
void nan_ndl_reset(struct nan_data *nan, struct nan_peer *peer);
int nan_ndl_handle_ndl_attr(struct nan_data *nan, struct nan_peer *peer,
struct nan_msg *msg);
+int nan_ndl_add_ndl_attr(struct nan_data *nan,
+ const struct nan_peer *peer,
+ struct wpabuf *buf);
+int nan_ndl_add_ndc_attr(struct nan_data *nan,
+ const struct nan_peer *peer,
+ struct wpabuf *buf);
+int nan_ndl_add_qos_attr(struct nan_data *nan,
+ const struct nan_peer *peer,
+ struct wpabuf *buf);
int nan_chan_to_chan_idx_map(struct nan_data *nan,
u8 op_class, u8 channel, u16 *chan_idx_map);
#endif
diff --git a/src/nan/nan_ndl.c b/src/nan/nan_ndl.c
index 83e2d1e15c..d398f9e97a 100644
--- a/src/nan/nan_ndl.c
+++ b/src/nan/nan_ndl.c
@@ -861,3 +861,201 @@ int nan_ndl_handle_ndl_attr(struct nan_data *nan, struct nan_peer *peer,
return -1;
}
}
+
+
+/*
+ * nan_ndl_add_ndl_attr - Add NDL attribute to frame
+ *
+ * @nan: NAN module context from nan_init()
+ * @peer: NAN peer for NDL establishment
+ * @buf: Frame buffer to which the attribute would be added
+ *
+ * Returns: 0 on success, negative on failure.
+ */
+int nan_ndl_add_ndl_attr(struct nan_data *nan,
+ const struct nan_peer *peer,
+ struct wpabuf *buf)
+{
+ struct nan_ndl *ndl;
+ u16 ndl_ctrl;
+ u8 type;
+
+ if (!peer || !peer->ndl)
+ return -1;
+
+ ndl = peer->ndl;
+ ndl_ctrl = 0;
+
+ wpa_printf(MSG_DEBUG, "NAN: add NDL attribute. state=%s, status=%u",
+ nan_ndl_state_str(ndl->state), ndl->status);
+
+ switch (ndl->state) {
+ case NAN_NDL_STATE_NONE:
+ case NAN_NDL_STATE_REQ_SENT:
+ case NAN_NDL_STATE_RES_SENT:
+ case NAN_NDL_STATE_CON_SENT:
+ default:
+ return -1;
+ case NAN_NDL_STATE_START:
+ type = NAN_NDL_TYPE_REQUEST;
+ if (ndl->sched.ndc.len)
+ ndl_ctrl |= NAN_NDL_CTRL_NDC_ATTR_PRESENT;
+ break;
+ case NAN_NDL_STATE_REQ_RECV:
+ type = NAN_NDL_TYPE_RESPONSE;
+ if (ndl->sched.ndc.len &&
+ ndl->status != NAN_NDL_STATUS_REJECTED)
+ ndl_ctrl |= NAN_NDL_CTRL_NDC_ATTR_PRESENT;
+ break;
+ case NAN_NDL_STATE_RES_RECV:
+ type = NAN_NDL_TYPE_CONFIRM;
+ if (ndl->sched.ndc.len &&
+ ndl->status != NAN_NDL_STATUS_REJECTED)
+ ndl_ctrl |= NAN_NDL_CTRL_NDC_ATTR_PRESENT;
+ break;
+ case NAN_NDL_STATE_DONE:
+ wpa_printf(MSG_DEBUG,
+ "NAN: NDL: done. Not adding NDL attribute");
+ return 0;
+ }
+
+ /* QoS attribute is going to be added */
+ if (ndl->local_qos.max_latency != NAN_QOS_MAX_LATENCY_NO_PREF ||
+ ndl->local_qos.min_slots != NAN_QOS_MIN_SLOTS_NO_PREF)
+ ndl_ctrl |= NAN_NDL_CTRL_NDL_QOS_ATTR_PRESENT;
+
+ wpabuf_put_u8(buf, NAN_ATTR_NDL);
+ wpabuf_put_le16(buf, sizeof(struct ieee80211_ndl));
+
+ wpabuf_put_u8(buf, ndl->dialog_token);
+ wpabuf_put_u8(buf, type |
+ (ndl->status << NAN_NDL_STATUS_POS));
+ wpabuf_put_u8(buf, ndl->reason);
+ wpabuf_put_u8(buf, ndl_ctrl);
+
+ return 0;
+}
+
+
+/*
+ * nan_ndl_add_ndc_attr - Add NDC attribute to frame
+ *
+ * @nan: NAN module context from nan_init()
+ * @peer: NAN peer for NDL establishment
+ * @buf: Frame buffer to which the attribute would be added
+ * Returns: 0 on success, negative on failure.
+ */
+int nan_ndl_add_ndc_attr(struct nan_data *nan,
+ const struct nan_peer *peer,
+ struct wpabuf *buf)
+{
+ struct nan_ndl *ndl;
+ u8 ndc_ctrl = NAN_NDC_CTRL_SELECTED;
+ u16 sched_entry_ctrl = 0;
+
+ if (!peer || !peer->ndl)
+ return -1;
+
+ ndl = peer->ndl;
+
+ if (ndl->state != NAN_NDL_STATE_START &&
+ ndl->state != NAN_NDL_STATE_REQ_RECV &&
+ ndl->state != NAN_NDL_STATE_RES_RECV)
+ return 0;
+
+ wpa_printf(MSG_DEBUG, "NAN: Add NDC attribute. state=%s, status=%u",
+ nan_ndl_state_str(ndl->state), ndl->status);
+
+ /* NDC attribute is optional in case of reject */
+ if (ndl->status == NAN_NDL_STATUS_REJECTED)
+ return 0;
+
+ /*
+ * NDC attribute for NDP Request is optional. In all other cases it is
+ * mandatory
+ */
+ if (!ndl->sched.ndc.len) {
+ if (ndl->state != NAN_NDL_STATE_START) {
+ wpa_printf(MSG_DEBUG, "NAN: NDL: no NDC to add");
+ return -1;
+ }
+
+ return 0;
+ }
+
+ wpabuf_put_u8(buf, NAN_ATTR_NDC);
+ wpabuf_put_le16(buf, (sizeof(struct ieee80211_ndc) +
+ sizeof(struct nan_sched_entry) +
+ ndl->sched.ndc.len));
+
+ wpabuf_put_data(buf, ndl->ndc_id, sizeof(ndl->ndc_id));
+ wpabuf_put_u8(buf, ndc_ctrl);
+
+ /* add the schedule entry */
+ wpabuf_put_u8(buf, ndl->sched.ndc_map_id);
+
+ sched_entry_ctrl |= ndl->sched.ndc.duration <<
+ NAN_TIME_BM_CTRL_BIT_DURATION_POS;
+ sched_entry_ctrl |= ndl->sched.ndc.period <<
+ NAN_TIME_BM_CTRL_PERIOD_POS;
+ sched_entry_ctrl |= ndl->sched.ndc.offset <<
+ NAN_TIME_BM_CTRL_START_OFFSET_POS;
+
+ wpabuf_put_le16(buf, sched_entry_ctrl);
+ wpabuf_put_u8(buf, ndl->sched.ndc.len);
+
+ /* add the bitmap */
+ wpabuf_put_data(buf, ndl->sched.ndc.bitmap, ndl->sched.ndc.len);
+
+ return 0;
+}
+
+
+/*
+ * nan_ndl_add_qos_attr - Add QOS attribute to frame
+ *
+ * @nan: NAN module context from nan_init()
+ * @peer: NAN peer for NDL establishment
+ * @buf: Frame buffer to which the attribute would be added
+ * Returns: 0 on success, negative on failure.
+ */
+int nan_ndl_add_qos_attr(struct nan_data *nan,
+ const struct nan_peer *peer,
+ struct wpabuf *buf)
+{
+ struct nan_ndl *ndl;
+
+ if (!peer || !peer->ndl)
+ return -1;
+
+ ndl = peer->ndl;
+
+ wpa_printf(MSG_DEBUG, "NAN: Add QoS attribute. state=%s, status=%u",
+ nan_ndl_state_str(ndl->state), ndl->status);
+
+ switch (ndl->state) {
+ case NAN_NDL_STATE_START:
+ case NAN_NDL_STATE_REQ_RECV:
+ case NAN_NDL_STATE_RES_RECV:
+ break;
+ case NAN_NDL_STATE_NONE:
+ case NAN_NDL_STATE_REQ_SENT:
+ case NAN_NDL_STATE_RES_SENT:
+ case NAN_NDL_STATE_CON_SENT:
+ case NAN_NDL_STATE_CON_RECV:
+ case NAN_NDL_STATE_DONE:
+ default:
+ return 0;
+ }
+
+ if (ndl->local_qos.max_latency == NAN_QOS_MAX_LATENCY_NO_PREF &&
+ ndl->local_qos.min_slots == NAN_QOS_MIN_SLOTS_NO_PREF)
+ return 0;
+
+ wpabuf_put_u8(buf, NAN_ATTR_NDL_QOS);
+ wpabuf_put_le16(buf, sizeof(struct ieee80211_nan_qos));
+ wpabuf_put_u8(buf, ndl->local_qos.min_slots);
+ wpabuf_put_le16(buf, ndl->local_qos.max_latency);
+
+ return 0;
+}
--
2.49.0
More information about the Hostap
mailing list