[PATCH 22/34] PR: Add support to handle PR IE in Auth M1 and prepare M2

Peddolla Harshavardhan Reddy peddolla at qti.qualcomm.com
Thu Jun 19 08:37:15 PDT 2025


Add changes to validate the PR IE received in Auth M1. For Auth M1
attributes such as capabilities and ranging capabilities are
validated. In case where validation of PR IE's fail or processing of
M1 frame fails or operation mode could not be derived then status is
set as failure and M2 is sent. In case a PR IE's could be validated
and operation mode could be derived then capabilities and preferred
ranging type capabilities and operation mode and status as success are
added to the PR IE for M2 and sent.

Signed-off-by: Peddolla Harshavardhan Reddy <peddolla at qti.qualcomm.com>
---
 src/common/proximity_ranging.c | 497 ++++++++++++++++++++++++++++++++-
 src/common/proximity_ranging.h |  15 +
 2 files changed, 510 insertions(+), 2 deletions(-)

diff --git a/src/common/proximity_ranging.c b/src/common/proximity_ranging.c
index 98ede4ac9..99b481799 100644
--- a/src/common/proximity_ranging.c
+++ b/src/common/proximity_ranging.c
@@ -23,6 +23,7 @@
 
 static void pr_device_free(struct pr_data *pr, struct pr_device *dev)
 {
+	wpabuf_free(dev->ranging_wrapper);
 #ifdef CONFIG_PASN
 	if (dev->pasn) {
 		wpa_pasn_reset(dev->pasn);
@@ -449,6 +450,65 @@ static void pr_copy_channels(struct pr_channels *dst,
 	dst->op_classes = j;
 }
 
+
+static void pr_op_class_intersect(const struct pr_op_class *a,
+				   const struct pr_op_class *b,
+				   struct pr_op_class *res)
+{
+	size_t i, j;
+
+	res->op_class = a->op_class;
+	for (i = 0; i < a->channels; i++) {
+		for (j = 0; j < b->channels; j++) {
+			if (a->channel[i] != b->channel[j])
+				continue;
+			res->channel[res->channels] = a->channel[i];
+			res->channels++;
+			if (res->channels == PR_MAX_OP_CLASS_CHANNELS)
+				return;
+		}
+	}
+}
+
+
+/**
+ * pr_channels_intersect - Intersection of supported channel lists
+ * @a: First set of supported channels
+ * @b: Second set of supported channels
+ * @res: Data structure for returning the intersection of support channels
+ *
+ * This function can be used to find a common set of supported channels. Both
+ * input channels sets are assumed to use the same country code. If different
+ * country codes are used, the operating class numbers may not be matched
+ * correctly and results are undefined.
+ */
+static void pr_channels_intersect(const struct pr_channels *a,
+				  const struct pr_channels *b,
+				  struct pr_channels *res)
+{
+	size_t i, j;
+	const struct pr_op_class *a_op;
+	const struct pr_op_class *b_op;
+
+	os_memset(res, 0, sizeof(*res));
+
+	for (i = 0; i < a->op_classes; i++) {
+		a_op = &a->op_class[i];
+		for (j = 0; j < b->op_classes; j++) {
+			b_op = &b->op_class[j];
+			if (a_op->op_class != b_op->op_class)
+				continue;
+			pr_op_class_intersect(a_op, b_op,
+					&res->op_class[res->op_classes]);
+			if (res->op_class[res->op_classes].channels) {
+				res->op_classes++;
+				if (res->op_classes == PR_MAX_OP_CLASSES)
+					return;
+			}
+		}
+	}
+}
+
 #endif /* CONFIG_PASN */
 
 static void pr_buf_add_channel_list(struct wpabuf *buf, const char *country,
@@ -1037,6 +1097,229 @@ static void pr_buf_add_operation_mode(struct wpabuf *buf,
 }
 
 
+static void pr_buf_add_ranging_neg_status(struct wpabuf *buf, u8 status)
+{
+	u8 *len;
+
+	wpabuf_put_u8(buf, PR_ATTR_STATUS);
+	len = wpabuf_put(buf, 2);
+
+	wpabuf_put_u8(buf, status);
+
+	WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
+	wpa_hexdump(MSG_DEBUG, "PR: * Role negotiation status",
+		    len + 2, (u8 *) wpabuf_put(buf, 0) - len - 2);
+}
+
+
+static void pr_process_op_mode(const u8 *caps, size_t caps_len,
+			       struct operation_mode *op_mode)
+{
+	const u8 *pos, *end;
+
+	if (!caps)
+		return;
+
+	pos = caps;
+	end = caps + caps_len;
+
+	op_mode->protocol_type = *pos;
+
+	pos++;
+	op_mode->role = *pos;
+
+	pos++;
+	os_memcpy(op_mode->country, pos, 3);
+
+	pos += 3;
+	pr_process_channels(pos, end - pos, &op_mode->channels);
+
+	wpa_printf(MSG_INFO, "protocol type=%u, role type=%u, "
+		   "country=%c%c, channel size=%lu",
+		   op_mode->protocol_type, op_mode->role,
+		   op_mode->country[0] ? op_mode->country[0] : '_',
+		   op_mode->country[1] ? op_mode->country[1] : '_',
+		   op_mode->channels.op_classes);
+}
+
+
+static u8 pr_pasn_get_best_op_mode(struct pr_data *pr, u8 supp_roles,
+				    struct operation_mode *op_mode,
+				    struct operation_mode *res_op_mode)
+{
+	int status = PR_NEGOTIATION_FAIL;
+	struct pr_channels common_chan;
+
+	if (op_mode->protocol_type & PR_NTB_SECURE_LTF_BASED_RANGING ||
+	    op_mode->protocol_type & PR_NTB_OPEN_BASED_RANGING) {
+		if ((!pr->cfg->ntb_ista_support &&
+		     !pr->cfg->ntb_rsta_support) ||
+		    (op_mode->protocol_type & PR_NTB_SECURE_LTF_BASED_RANGING &&
+				 !pr->cfg->secure_he_ltf)) {
+			wpa_printf(MSG_DEBUG,
+				   "PR: Device can't fulfill requested NTB role");
+			return PR_NEGOTIATION_FAIL;
+		}
+
+		if (op_mode->protocol_type & PR_NTB_SECURE_LTF_BASED_RANGING &&
+		    !pr->cfg->secure_he_ltf) {
+			wpa_printf(MSG_DEBUG, "PR: Secure HE-LTF not supported");
+			return PR_NEGOTIATION_FAIL;
+		}
+
+		pr_channels_intersect(&pr->cfg->ntb_channels,
+				      &op_mode->channels, &common_chan);
+		if (!common_chan.op_classes) {
+			wpa_printf(MSG_DEBUG,
+				   "PR: No common channels found to do ranging");
+			return PR_NEGOTIATION_FAIL;
+		}
+
+		if (op_mode->role == PR_ISTA_SUPPORT &&
+		    !pr->cfg->ntb_rsta_support &&
+		    !(supp_roles & PR_RSTA_SUPPORT)) {
+			wpa_printf(MSG_DEBUG, "PR: Device cannot act as NTB RSTA");
+			return PR_NEGOTIATION_FAIL;
+		} else if (op_mode->role == PR_RSTA_SUPPORT &&
+			   !pr->cfg->ntb_ista_support &&
+			   !(supp_roles & PR_ISTA_SUPPORT)) {
+			wpa_printf(MSG_DEBUG, "PR: Device cannot act as NTB ISTA");
+			return PR_NEGOTIATION_FAIL;
+		}
+
+		if (op_mode->role == PR_ISTA_SUPPORT &&
+		    pr->cfg->ntb_rsta_support) {
+			res_op_mode->role = PR_RSTA_SUPPORT;
+			status = PR_NEGOTIATION_SUCCESS;
+		} else if (op_mode->role == PR_RSTA_SUPPORT &&
+			   pr->cfg->ntb_ista_support) {
+			res_op_mode->role = PR_ISTA_SUPPORT;
+			status = PR_NEGOTIATION_SUCCESS;
+		} else if (op_mode->role == PR_ISTA_SUPPORT &&
+			   !pr->cfg->ntb_rsta_support &&
+			   supp_roles & PR_RSTA_SUPPORT &&
+			   pr->cfg->ntb_ista_support) {
+			res_op_mode->role = PR_ISTA_SUPPORT;
+			status = PR_NEGOTIATION_UPDATE;
+		} else if (op_mode->role == PR_RSTA_SUPPORT &&
+			   !pr->cfg->ntb_ista_support &&
+			   (supp_roles & PR_ISTA_SUPPORT) &&
+			   pr->cfg->ntb_rsta_support) {
+			res_op_mode->role = PR_RSTA_SUPPORT;
+			status = PR_NEGOTIATION_UPDATE;
+		} else if (op_mode->role == (PR_RSTA_SUPPORT |
+					     PR_ISTA_SUPPORT)) {
+			if (pr->cfg->ntb_rsta_support &&
+			    (pr->cfg->preferred_ranging_role ||
+			    !pr->cfg->ntb_ista_support)) {
+				res_op_mode->role = PR_RSTA_SUPPORT;
+				status = PR_NEGOTIATION_SUCCESS;
+				wpa_printf(MSG_DEBUG, "PR: Device choosing RSTA role");
+			} else if (pr->cfg->ntb_ista_support &&
+				   (!pr->cfg->preferred_ranging_role ||
+				   !pr->cfg->ntb_rsta_support)) {
+				res_op_mode->role = PR_ISTA_SUPPORT;
+				status = PR_NEGOTIATION_SUCCESS;
+				wpa_printf(MSG_DEBUG, "PR: Device choosing ISTA role");
+			}
+		}
+
+		res_op_mode->protocol_type = op_mode->protocol_type;
+		os_memcpy(res_op_mode->country, pr->cfg->country, 3);
+		pr_copy_channels(&res_op_mode->channels, &common_chan, false);
+
+		wpa_printf(MSG_DEBUG,
+			   "NTB attr Ranging Protocol=%u, Role=%u, country=%c%c,"
+			   " status=%d, op class size= %lu",
+			   res_op_mode->protocol_type, res_op_mode->role,
+			   res_op_mode->country[0] ? res_op_mode->country[0] : '_',
+			   res_op_mode->country[1] ? res_op_mode->country[1] : '_',
+			   status, res_op_mode->channels.op_classes);
+
+		return status;
+	} else if (op_mode->protocol_type & PR_EDCA_BASED_RANGING) {
+		if (!pr->cfg->edca_ista_support &&
+		    !pr->cfg->edca_rsta_support) {
+			wpa_printf(MSG_DEBUG,
+				   "PR: Device can't fulfill requested EDCA role");
+			return PR_NEGOTIATION_FAIL;
+		}
+		pr_channels_intersect(&pr->cfg->edca_channels,
+				      &op_mode->channels, &common_chan);
+		if (!common_chan.op_classes) {
+			wpa_printf(MSG_DEBUG,
+				   "PR: No common channels to perform ranging");
+			return PR_NEGOTIATION_FAIL;
+		}
+
+		if (op_mode->role == PR_ISTA_SUPPORT &&
+		    !pr->cfg->edca_rsta_support &&
+		    !(supp_roles & PR_RSTA_SUPPORT)) {
+			wpa_printf(MSG_DEBUG, "PR: Device cannot act as NTB RSTA");
+			return PR_NEGOTIATION_FAIL;
+		} else if (op_mode->role == PR_RSTA_SUPPORT &&
+			   !pr->cfg->edca_ista_support &&
+			   !(supp_roles & PR_ISTA_SUPPORT)) {
+			wpa_printf(MSG_DEBUG, "PR: Device cannot act as NTB ISTA");
+			return PR_NEGOTIATION_FAIL;
+		}
+
+		if (op_mode->role == PR_ISTA_SUPPORT &&
+		    pr->cfg->edca_rsta_support) {
+			res_op_mode->role = PR_RSTA_SUPPORT;
+			status = PR_NEGOTIATION_SUCCESS;
+		} else if (op_mode->role == PR_RSTA_SUPPORT &&
+			   pr->cfg->edca_ista_support) {
+			res_op_mode->role = PR_ISTA_SUPPORT;
+			status = PR_NEGOTIATION_SUCCESS;
+		} else if (op_mode->role == PR_ISTA_SUPPORT &&
+			   !pr->cfg->edca_rsta_support &&
+			   (supp_roles & PR_RSTA_SUPPORT) &&
+			   pr->cfg->edca_ista_support) {
+			res_op_mode->role = PR_ISTA_SUPPORT;
+			status = PR_NEGOTIATION_UPDATE;
+		} else if (op_mode->role == PR_RSTA_SUPPORT &&
+			   !pr->cfg->edca_ista_support &&
+			   (supp_roles & PR_ISTA_SUPPORT) &&
+			   pr->cfg->edca_rsta_support) {
+			res_op_mode->role = PR_RSTA_SUPPORT;
+			status = PR_NEGOTIATION_UPDATE;
+		} else if (op_mode->role == (PR_RSTA_SUPPORT |
+					     PR_ISTA_SUPPORT)) {
+			if (pr->cfg->edca_rsta_support &&
+			    (pr->cfg->preferred_ranging_role ||
+			    !pr->cfg->edca_ista_support)) {
+				res_op_mode->role = PR_RSTA_SUPPORT;
+				status = PR_NEGOTIATION_SUCCESS;
+				wpa_printf(MSG_DEBUG, "PR: Device choosing RSTA role");
+			} else if (pr->cfg->edca_ista_support &&
+				   (!pr->cfg->preferred_ranging_role ||
+				   !pr->cfg->edca_rsta_support)) {
+				res_op_mode->role = PR_ISTA_SUPPORT;
+				status = PR_NEGOTIATION_SUCCESS;
+				wpa_printf(MSG_DEBUG, "PR: Device choosing ISTA role");
+			}
+		}
+
+		res_op_mode->protocol_type = op_mode->protocol_type;
+		os_memcpy(res_op_mode->country, pr->cfg->country, 3);
+		pr_copy_channels(&res_op_mode->channels, &common_chan, false);
+
+		wpa_printf(MSG_DEBUG,
+			   "EDCA attr Ranging Protocol=%u, Role=%u, country=%c%c,"
+			   " status=%d, op class size=%lu",
+			   res_op_mode->protocol_type, res_op_mode->role,
+			   res_op_mode->country[0] ? res_op_mode->country[0] : '_',
+			   res_op_mode->country[1] ? res_op_mode->country[1] : '_',
+			   status, res_op_mode->channels.op_classes);
+
+		return status;
+	}
+
+	return status;
+}
+
+
 static int pr_prepare_pasn_pr_ie(struct pr_data *pr, struct wpabuf *extra_ies,
 				 bool add_dira, u8 ranging_role,
 				 u8 ranging_type, int forced_pr_freq)
@@ -1496,11 +1779,217 @@ int pr_pasn_auth_tx_status(struct pr_data *pr, const u8 *data, size_t data_len,
 }
 
 
+static int pr_process_pasn_ranging_wrapper(struct pr_data *pr,
+					   struct pr_device *dev,
+					   const struct ieee80211_mgmt *mgmt,
+					   size_t len, int trans_seq)
+{
+	u32 ie_type;
+	const u8 *ies;
+	size_t ies_len;
+	u8 status = PR_NEGOTIATION_FAIL;
+	bool success = false;
+	struct wpabuf *buf, *buf2;
+	struct pr_message msg;
+	struct pr_capabilities caps;
+	struct edca_capabilities edca;
+	struct ntb_capabilities ntb;
+	struct operation_mode op_mode;
+	u8 supp_ranging_role = 0;
+	struct operation_mode res_op_mode;
+	bool ntb_caps_valid = false, edca_caps_valid = false;
+
+	buf = wpabuf_alloc(1000);
+	if (!buf) {
+		wpa_printf(MSG_DEBUG, "PR: Memory allocation failed");
+		return -1;
+	}
+
+	os_memset(&msg, 0, sizeof(msg));
+	ies = mgmt->u.auth.variable;
+	ies_len = len - offsetof(struct ieee80211_mgmt, u.auth.variable);
+
+	if (pr_parse_ies(ies, ies_len, &msg) || !msg.op_mode) {
+		wpa_printf(MSG_DEBUG,
+			   "PR PASN: Failed to parse PR IE in Auth1");
+		goto end;
+	}
+
+	if (msg.dira && msg.dira_len)
+		pr_validate_dira(pr, dev, msg.dira, msg.dira_len);
+
+	if (!msg.op_mode || !msg.op_mode_len ||
+	    !msg.pr_capability || !msg.pr_capability_len ||
+	    ((!msg.edca_capability || !msg.edca_capability_len) &&
+	     (!msg.ntb_capability || !msg.ntb_capability_len))) {
+		goto end;
+	}
+
+	pr_process_op_mode(msg.op_mode, msg.op_mode_len, &op_mode);
+	if (!op_mode.channels.op_classes) {
+		wpa_printf(MSG_DEBUG, "PR: Received empty channel list");
+		goto end;
+	}
+
+	os_memset(&caps, 0, sizeof(struct pr_capabilities));
+	pr_process_ranging_capabilities(msg.pr_capability,
+					msg.pr_capability_len, &caps);
+
+	pr_get_ranging_capabilities(pr, &caps);
+
+	if ((op_mode.protocol_type & PR_EDCA_BASED_RANGING) &&
+	    (!msg.edca_capability || !msg.edca_capability_len)) {
+		goto end;
+	} else if ((op_mode.protocol_type & PR_NTB_OPEN_BASED_RANGING) &&
+		   (!msg.ntb_capability || !msg.ntb_capability_len)) {
+		goto end;
+	} else if ((op_mode.protocol_type & PR_NTB_SECURE_LTF_BASED_RANGING) &&
+		   (!msg.ntb_capability || !msg.ntb_capability_len)) {
+		goto end;
+	}
+
+	if (op_mode.protocol_type & PR_NTB_SECURE_LTF_BASED_RANGING ||
+	    op_mode.protocol_type & PR_NTB_OPEN_BASED_RANGING) {
+		pr_process_ntb_capabilities(msg.ntb_capability,
+					    msg.ntb_capability_len, &ntb,
+					    caps.secure_he_ltf);
+
+		if (dev->ntb_caps.ista_support)
+			supp_ranging_role |= PR_ISTA_SUPPORT;
+		if (dev->ntb_caps.rsta_support)
+			supp_ranging_role |= PR_RSTA_SUPPORT;
+
+		pr_get_ntb_capabilities(pr, &ntb);
+		ntb_caps_valid = true;
+
+	} else if (op_mode.protocol_type & PR_EDCA_BASED_RANGING) {
+		pr_process_edca_capabilities(msg.edca_capability,
+					     msg.edca_capability_len, &edca);
+
+		if (dev->edca_caps.ista_support)
+			supp_ranging_role |= PR_ISTA_SUPPORT;
+		if (dev->edca_caps.rsta_support)
+			supp_ranging_role |= PR_RSTA_SUPPORT;
+
+		pr_get_edca_capabilities(pr, &edca);
+		edca_caps_valid = true;
+	}
+
+	if (trans_seq == 1)
+		status = pr_pasn_get_best_op_mode(pr, supp_ranging_role,
+						  &op_mode, &res_op_mode);
+
+	if (status != PR_NEGOTIATION_SUCCESS &&
+	    status != PR_NEGOTIATION_UPDATE) {
+		wpa_printf(MSG_DEBUG, "PR: Couldn't derive suitable operation mode");
+		goto end;
+	}
+
+	pr_buf_add_ranging_capa_info(buf, &caps);
+	if (edca_caps_valid)
+		pr_buf_add_edca_capa_info(buf, &edca);
+	if (ntb_caps_valid)
+		pr_buf_add_ntb_capa_info(buf, &ntb);
+
+	pr_buf_add_ranging_neg_status(buf, status);
+	pr_buf_add_operation_mode(buf, &res_op_mode);
+
+	if (trans_seq == 2) {
+		dev->ranging_role = res_op_mode.role;
+		dev->protocol_type = res_op_mode.protocol_type;
+		dev->final_op_channel = res_op_mode.channels.op_class[0].channel[0];
+		dev->final_op_class = res_op_mode.channels.op_class[0].op_class;
+	}
+	success = true;
+end:
+	if (!success)
+		pr_buf_add_ranging_neg_status(buf, PR_NEGOTIATION_FAIL);
+
+	ie_type = (OUI_WFA << 8) | PR_OUI_TYPE;
+	buf2 = pr_encaps_ie(buf, ie_type);
+	wpabuf_free(buf);
+
+	dev->ranging_wrapper = buf2;
+	pr_parse_free(&msg);
+	return 0;
+}
+
+
+static int pr_pasn_handle_auth_1(struct pr_data *pr, struct pr_device *dev,
+				 const struct ieee80211_mgmt *mgmt, size_t len,
+				 int freq)
+{
+	int ret = -1;
+	u8 pasn_type;
+	u8 auth_mode = 0;
+	int pasn_groups[4] = { 0 };
+	struct wpa_ie_data rsn_data;
+	struct ieee802_11_elems elems;
+
+	pasn_type = pr->cfg->pasn_type;
+	if (pasn_type & 0xc && pasn_type & 0x3) {
+		pasn_groups[0] = 20;
+		pasn_groups[1] = 19;
+	} else if (pasn_type & 0xc) {
+		pasn_groups[0] = 20;
+	} else {
+		pasn_groups[0] = 19;
+	}
+
+	if (pr_process_pasn_ranging_wrapper(pr, dev, mgmt, len, 1)) {
+		wpa_printf(MSG_ERROR,
+			   "PR PASN: Handle Auth1 action wrapper failed");
+		return -1;
+	}
+
+	if (ieee802_11_parse_elems(mgmt->u.auth.variable,
+				   len - offsetof(struct ieee80211_mgmt,
+				   u.auth.variable),
+				   &elems, 0) == ParseFailed) {
+		wpa_printf(MSG_DEBUG,
+			   "PR PASN: Failed parsing elements in Auth1 frame");
+		goto fail;
+	}
+
+	if (wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
+				 &rsn_data) == 0) {
+		if (rsn_data.key_mgmt == WPA_KEY_MGMT_SAE && rsn_data.num_pmkid)
+			auth_mode = PR_PASN_AUTH_MODE_PMK;
+		else if (rsn_data.key_mgmt == WPA_KEY_MGMT_SAE)
+			auth_mode = PR_PASN_AUTH_MODE_SAE;
+		else
+			auth_mode = PR_PASN_AUTH_MODE_PASN;
+	}
+
+	dev->pasn_role = PR_ROLE_PASN_RESPONDER;
+	if (pr_pasn_initialize(pr, dev, mgmt->sa, auth_mode, freq,
+			       rsn_data.pmkid)) {
+		wpa_printf(MSG_ERROR, "PR PASN: Initialize failed");
+		goto fail;
+	}
+	pasn_set_extra_ies(dev->pasn, wpabuf_head_u8(dev->ranging_wrapper),
+			   wpabuf_len(dev->ranging_wrapper));
+	dev->pasn->pasn_groups = pasn_groups;
+	if (handle_auth_pasn_1(dev->pasn, pr->cfg->dev_addr, mgmt->sa, mgmt,
+			       len, false) < 0) {
+		wpa_printf(MSG_ERROR, "PR PASN: Handle Auth1 failed");
+		goto fail;
+	}
+
+	ret = 0;
+
+fail:
+	wpabuf_free(dev->ranging_wrapper);
+	dev->ranging_wrapper = NULL;
+	return ret;
+}
+
+
 int pr_pasn_auth_rx(struct pr_data *pr, const struct ieee80211_mgmt *mgmt,
 		    size_t len, int freq)
 {
 	struct pr_device *dev;
-	u16 auth_alg;
+	u16 auth_alg, auth_transaction;
 
 	dev = pr_get_device(pr, mgmt->sa);
 	if (!dev) {
@@ -1524,7 +2013,11 @@ int pr_pasn_auth_rx(struct pr_data *pr, const struct ieee80211_mgmt *mgmt,
 		return -1;
 	}
 
-	return 0;
+	auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
+
+	if (auth_transaction == 1)
+		return pr_pasn_handle_auth_1(pr, dev, mgmt, len, freq);
+	return -1;
 }
 
 #endif /* CONFIG_PASN */
diff --git a/src/common/proximity_ranging.h b/src/common/proximity_ranging.h
index fe9deb6e6..d8468e580 100644
--- a/src/common/proximity_ranging.h
+++ b/src/common/proximity_ranging.h
@@ -38,6 +38,15 @@
 #define PR_MAX_PEER 100
 
 
+/**
+ * Proximity Ranging negotiation status
+ * Proximity Ranging Implementation Considerations for P2P Operation 2025,
+ * 3.3.6, Table 11.
+ */
+#define PR_NEGOTIATION_SUCCESS 0
+#define PR_NEGOTIATION_UPDATE 1
+#define PR_NEGOTIATION_FAIL 2
+
 enum pr_pasn_role {
 	PR_ROLE_IDLE = 0,
 	PR_ROLE_PASN_INITIATOR,
@@ -250,7 +259,13 @@ struct pr_device {
 
 	/* PASN data structure */
 	struct pasn_data *pasn;
+	struct wpabuf *ranging_wrapper;
+
 	enum pr_pasn_role pasn_role;
+	u8 ranging_role;
+	u8 protocol_type;
+	u8 final_op_class;
+	u8 final_op_channel;
 };
 
 
-- 
2.34.1




More information about the Hostap mailing list