[PATCH v3 28/46] PR: Add extended ranging parameters to PASN peer structure
Kavita Kavita
kavita.kavita at oss.qualcomm.com
Wed May 13 02:59:52 PDT 2026
From: Peddolla Harshavardhan Reddy <peddolla.reddy at oss.qualcomm.com>
Extend pr_pasn_ranging_params with EDCA, NTB, continuous ranging, and
PD-specific parameters:
- EDCA: burst_period, num_bursts_exp, ftms_per_burst, ftmr_retries,
burst_duration
- NTB: min_time_between_measurements, max_time_between_measurements,
availability_window, nominal_time
- PD-specific: lmr_feedback, ingress_threshold, egress_threshold,
pr_suppress_results, continuous_ranging_session_time, forced_pr_freq
Location: request_lci, request_civicloc
Add wpas_pr_validate_ranging_request() to validate the request against
device capabilities and parameter constraints before triggering PASN.
Pass forced_pr_freq from params to wpas_pr_initiate_pasn_auth().
Signed-off-by: Peddolla Harshavardhan Reddy <peddolla.reddy at oss.qualcomm.com>
---
src/common/proximity_ranging.h | 75 ++++++++++++++++
wpa_supplicant/pr_supplicant.c | 159 ++++++++++++++++++++++++++++++++-
2 files changed, 233 insertions(+), 1 deletion(-)
diff --git a/src/common/proximity_ranging.h b/src/common/proximity_ranging.h
index a9d7ed16a..3cee96133 100644
--- a/src/common/proximity_ranging.h
+++ b/src/common/proximity_ranging.h
@@ -275,6 +275,81 @@ struct pr_pasn_ranging_params {
int freq;
u8 src_addr[ETH_ALEN];
enum pr_pasn_role pasn_role;
+
+ /**
+ * EDCA based ranging specific parameters
+ *
+ * @burst_period: Burst period in units of 100 ms
+ * @num_bursts_exp: Number of bursts exponent
+ * @ftms_per_burst: Number of FTM frames per burst
+ * @ftmr_retries: Number of retries for FTM Request frame
+ * @burst_duration: Burst duration as defined in IEEE 2024 std
+ * Table 9-322—Burst Duration subfield encoding.
+ */
+ u16 burst_period;
+ u8 num_bursts_exp;
+ u8 ftms_per_burst;
+ u8 ftmr_retries;
+ u8 burst_duration;
+
+ /**
+ * NTB ranging specific parameters
+ *
+ * @min_time_between_measurements: Minimum time between two consecutive
+ * range measurements in units of 100 micro seconds.
+ * @max_time_between_measurements: Maximum time between two consecutive
+ * range measurements in units of 10 milli seconds, to avoid FTM
+ * negotiation.
+ * @availability_window: Duration of the Availability Window (AW) in
+ * units of 1 millisecond (0-255 ms).
+ * @nominal_time: Nominal duration between adjacent Availability Windows
+ * in units of milliseconds.
+ */
+ u32 min_time_between_measurements;
+ u32 max_time_between_measurements;
+ u8 availability_window;
+ u32 nominal_time;
+
+ /**
+ * @request_lci: Whether to request LCI
+ * @request_civicloc: Whether to request civic location
+ */
+ bool request_lci;
+ bool request_civicloc;
+
+ /**
+ * @lmr_feedback: Negotiate LMR feedback for NTB ranging.
+ * Only valid when NTB ranging type is set. Required for RSTA
+ * to report measurement results back to the initiator.
+ */
+ bool lmr_feedback;
+
+ /**
+ * @ingress_threshold: Ingress range threshold in millimeters.
+ * Only valid when NL80211_PMSR_PEER_ATTR_PD_REQUEST is set.
+ * The kernel reports a measurement result when the device
+ * moves INTO this range.
+ */
+ u64 ingress_threshold;
+
+ /**
+ * @egress_threshold: Egress range threshold in millimeters.
+ * Only valid when NL80211_PMSR_PEER_ATTR_PD_REQUEST is set.
+ * The kernel reports a measurement result when the device
+ * moves OUT OF this range.
+ */
+ u64 egress_threshold;
+
+ /**
+ * @pr_suppress_results: Suppress ranging results for PD requests.
+ * Only valid when NL80211_PMSR_PEER_ATTR_PD_REQUEST is set.
+ * Cannot be used with range_report or lmr_feedback.
+ */
+ bool pr_suppress_results;
+
+ u32 continuous_ranging_session_time;
+
+ int forced_pr_freq;
};
struct pr_dev_ik {
diff --git a/wpa_supplicant/pr_supplicant.c b/wpa_supplicant/pr_supplicant.c
index 77e35aa1a..f3f3ad11d 100644
--- a/wpa_supplicant/pr_supplicant.c
+++ b/wpa_supplicant/pr_supplicant.c
@@ -976,6 +976,122 @@ int wpas_pr_initiate_pasn_auth(struct wpa_supplicant *wpa_s,
}
+/**
+ * wpas_pr_validate_ranging_request - Validate PR ranging request parameters
+ */
+static int wpas_pr_validate_ranging_request(struct wpa_supplicant *wpa_s,
+ struct pr_pasn_ranging_params *pr_pasn_params)
+{
+ struct pr_data *pr = wpa_s->global->pr;
+ struct pr_config *cfg;
+ bool is_edca, is_ntb, is_ista;
+
+ if (!pr || !pr->cfg) {
+ wpa_printf(MSG_DEBUG, "PR: PR not initialized");
+ return -1;
+ }
+
+ cfg = pr->cfg;
+
+ /* Peer address must not be all-zeros */
+ if (is_zero_ether_addr(pr_pasn_params->peer_addr)) {
+ wpa_printf(MSG_DEBUG, "PR: Invalid peer address (all zeros)");
+ return -1;
+ }
+
+ /* Frequency must be set */
+ if (!pr_pasn_params->freq) {
+ wpa_printf(MSG_DEBUG, "PR: Invalid frequency (zero)");
+ return -1;
+ }
+
+ /* ranging_type must have at least one valid bit and no unknown bits */
+ if (!pr_pasn_params->ranging_type ||
+ (pr_pasn_params->ranging_type &
+ ~(PR_EDCA_BASED_RANGING | PR_NTB_SECURE_LTF_BASED_RANGING |
+ PR_NTB_OPEN_BASED_RANGING))) {
+ wpa_printf(MSG_DEBUG,
+ "PR: Invalid ranging_type=0x%x",
+ pr_pasn_params->ranging_type);
+ return -1;
+ }
+
+ /* ranging_role must have at least one valid bit and no unknown bits */
+ if (!pr_pasn_params->ranging_role ||
+ (pr_pasn_params->ranging_role &
+ ~(PR_ISTA_SUPPORT | PR_RSTA_SUPPORT))) {
+ wpa_printf(MSG_DEBUG,
+ "PR: Invalid ranging_role=0x%x",
+ pr_pasn_params->ranging_role);
+ return -1;
+ }
+
+ is_edca = !!(pr_pasn_params->ranging_type & PR_EDCA_BASED_RANGING);
+ is_ntb = !!(pr_pasn_params->ranging_type &
+ (PR_NTB_SECURE_LTF_BASED_RANGING |
+ PR_NTB_OPEN_BASED_RANGING));
+ is_ista = !!(pr_pasn_params->ranging_role & PR_ISTA_SUPPORT);
+
+ /* Validate ranging type against device capabilities */
+ if (is_edca) {
+ if (is_ista && !cfg->edca_ista_support) {
+ wpa_printf(MSG_DEBUG,
+ "PR: EDCA ISTA ranging not supported by device");
+ return -1;
+ }
+ if (!is_ista && !cfg->edca_rsta_support) {
+ wpa_printf(MSG_DEBUG,
+ "PR: EDCA RSTA ranging not supported by device");
+ return -1;
+ }
+ }
+
+ if (is_ntb) {
+ if (is_ista && !cfg->ntb_ista_support) {
+ wpa_printf(MSG_DEBUG,
+ "PR: NTB ISTA ranging not supported by device");
+ return -1;
+ }
+ if (!is_ista && !cfg->ntb_rsta_support) {
+ wpa_printf(MSG_DEBUG,
+ "PR: NTB RSTA ranging not supported by device");
+ return -1;
+ }
+
+ /* Secure LTF requires explicit device support */
+ if ((pr_pasn_params->ranging_type &
+ PR_NTB_SECURE_LTF_BASED_RANGING) &&
+ !cfg->secure_he_ltf) {
+ wpa_printf(MSG_DEBUG,
+ "PR: Secure HE-LTF NTB ranging not supported by device");
+ return -1;
+ }
+
+ /* min must not exceed max time between measurements */
+ if (pr_pasn_params->min_time_between_measurements &&
+ pr_pasn_params->max_time_between_measurements &&
+ pr_pasn_params->min_time_between_measurements >
+ pr_pasn_params->max_time_between_measurements * 100) {
+ wpa_printf(MSG_DEBUG,
+ "PR: min_time_between_measurements=%u > max=%u (units: 100us vs 10ms)",
+ pr_pasn_params->min_time_between_measurements,
+ pr_pasn_params->max_time_between_measurements);
+ return -1;
+ }
+ }
+
+ /* lmr_feedback is only valid for NTB ranging */
+ if (pr_pasn_params->lmr_feedback && !is_ntb) {
+ wpa_printf(MSG_DEBUG,
+ "PR: lmr_feedback is only valid for NTB ranging");
+ return -1;
+ }
+
+ wpa_printf(MSG_DEBUG, "PR: Ranging request validation successful");
+ return 0;
+}
+
+
/**
* wpas_pr_pasn_trigger - Entry point to trigger PASN authentication for PR
*/
@@ -1001,6 +1117,13 @@ void wpas_pr_pasn_trigger(struct wpa_supplicant *wpa_s,
return;
}
+ /* Validate request before proceeding */
+ if (wpas_pr_validate_ranging_request(wpa_s, pr_pasn_params) < 0) {
+ wpa_printf(MSG_DEBUG, "PR PASN: Request validation failed");
+ pr_pasn_params->pr_pasn_status = PASN_STATUS_FAILURE;
+ return;
+ }
+
if (pr_pasn_params->action == PR_PASN_AND_RANGING) {
wpa_printf(MSG_DEBUG,
"PR PASN: Triggering PASN authentication for " MACSTR
@@ -1023,12 +1146,46 @@ void wpas_pr_pasn_trigger(struct wpa_supplicant *wpa_s,
os_memcpy(pr->pr_pasn_params, pr_pasn_params,
sizeof(*pr->pr_pasn_params));
+ /* Log EDCA parameters if applicable */
+ if (pr_pasn_params->ranging_type & PR_EDCA_BASED_RANGING) {
+ wpa_printf(MSG_DEBUG,
+ "PR PASN: EDCA params - burst_period=%u num_bursts_exp=%u "
+ "ftms_per_burst=%u ftmr_retries=%u burst_duration=%u",
+ pr_pasn_params->burst_period,
+ pr_pasn_params->num_bursts_exp,
+ pr_pasn_params->ftms_per_burst,
+ pr_pasn_params->ftmr_retries,
+ pr_pasn_params->burst_duration);
+ }
+
+ /* Log NTB parameters if applicable */
+ if (pr_pasn_params->ranging_type & (PR_NTB_SECURE_LTF_BASED_RANGING |
+ PR_NTB_OPEN_BASED_RANGING)) {
+ wpa_printf(MSG_DEBUG,
+ "PR PASN: NTB params - min_time=%u max_time=%u "
+ "aw=%u nominal_time=%u",
+ pr_pasn_params->min_time_between_measurements,
+ pr_pasn_params->max_time_between_measurements,
+ pr_pasn_params->availability_window,
+ pr_pasn_params->nominal_time);
+ }
+
+ /* Log location request parameters */
+ if (pr_pasn_params->request_lci ||
+ pr_pasn_params->request_civicloc) {
+ wpa_printf(MSG_DEBUG,
+ "PR PASN: Location requests - LCI=%d CivicLoc=%d",
+ pr_pasn_params->request_lci,
+ pr_pasn_params->request_civicloc);
+ }
+
/* Initiate PASN authentication for the peer */
if (wpas_pr_initiate_pasn_auth(wpa_s, pr_pasn_params->peer_addr,
pr_pasn_params->freq,
pr_pasn_params->auth_mode,
pr_pasn_params->ranging_role,
- pr_pasn_params->ranging_type, 0,
+ pr_pasn_params->ranging_type,
+ pr_pasn_params->forced_pr_freq,
pr_pasn_params->src_addr,
pr_pasn_params->pasn_role)) {
wpa_printf(MSG_DEBUG,
--
2.34.1
More information about the Hostap
mailing list