[RFC PATCH v2 18/23] PR: Add extended ranging parameters to PASN peer structure
Peddolla Harshavardhan Reddy
peddolla.reddy at oss.qualcomm.com
Thu Apr 2 05:24:23 PDT 2026
Add EDCA, NTB, and continuous ranging parameters to the single-peer
pr_pasn_ranging_params structure. This enables comprehensive ranging
configuration for proximity ranging operations.
EDCA parameters:
- burst_period, num_bursts_exp, ftms_per_burst
- ftmr_retries, burst_duration
NTB parameters:
- min_time_between_measurements, max_time_between_measurements
- availability_window, nominal_time, measurements_per_aw
Continuous ranging and location parameters:
- request_lci, request_civicloc
- trigger_continuous_ranging
- continuous_ranging_interval, continuous_ranging_session_time
Enhanced wpas_pr_pasn_trigger() with debug logging for all parameter
categories to aid in debugging and verification of ranging operations.
Signed-off-by: Peddolla Harshavardhan Reddy <peddolla.reddy at oss.qualcomm.com>
---
src/common/proximity_ranging.h | 78 +++++++++++++
wpa_supplicant/pr_supplicant.c | 203 ++++++++++++++++++++++++++++++++-
2 files changed, 280 insertions(+), 1 deletion(-)
diff --git a/src/common/proximity_ranging.h b/src/common/proximity_ranging.h
index b7e9da303..cd12aaa50 100644
--- a/src/common/proximity_ranging.h
+++ b/src/common/proximity_ranging.h
@@ -275,6 +275,84 @@ 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.
+ * @measurements_per_aw: Number of measurement attempts per Availability
+ * Window.
+ */
+ u32 min_time_between_measurements;
+ u32 max_time_between_measurements;
+ u8 availability_window;
+ u32 nominal_time;
+ u8 measurements_per_aw;
+
+ /**
+ * @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 496334021..3ccc659ee 100644
--- a/wpa_supplicant/pr_supplicant.c
+++ b/wpa_supplicant/pr_supplicant.c
@@ -920,6 +920,136 @@ int wpas_pr_initiate_pasn_auth(struct wpa_supplicant *wpa_s,
}
+/**
+ * wpas_pr_validate_ranging_request - Validate PR ranging request parameters
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @pr_pasn_params: Pointer to PR PASN ranging parameters to validate
+ * Returns: 0 on success, -1 on validation failure
+ *
+ * This function validates the ranging request against device capabilities,
+ * driver support, and parameter compatibility before triggering PASN.
+ */
+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;
+ }
+
+ /* measurements_per_aw max value is 4 per spec */
+ if (pr_pasn_params->measurements_per_aw > 4) {
+ wpa_printf(MSG_DEBUG,
+ "PR: measurements_per_aw=%u exceeds max (4)",
+ pr_pasn_params->measurements_per_aw);
+ 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) {
+ wpa_printf(MSG_DEBUG,
+ "PR: min_time_between_measurements=%u > max=%u",
+ 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 - Trigger PASN authentication for a single peer
* @wpa_s: Pointer to wpa_supplicant data
@@ -952,6 +1082,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
@@ -983,12 +1120,76 @@ void wpas_pr_pasn_trigger(struct wpa_supplicant *wpa_s,
os_memcpy(dst->src_addr, pr_pasn_params->src_addr, ETH_ALEN);
dst->pasn_role = pr_pasn_params->pasn_role;
+ /* Copy EDCA parameters */
+ dst->burst_period = pr_pasn_params->burst_period;
+ dst->num_bursts_exp = pr_pasn_params->num_bursts_exp;
+ dst->ftms_per_burst = pr_pasn_params->ftms_per_burst;
+ dst->ftmr_retries = pr_pasn_params->ftmr_retries;
+ dst->burst_duration = pr_pasn_params->burst_duration;
+
+ /* Copy NTB parameters */
+ dst->min_time_between_measurements =
+ pr_pasn_params->min_time_between_measurements;
+ dst->max_time_between_measurements =
+ pr_pasn_params->max_time_between_measurements;
+ dst->availability_window = pr_pasn_params->availability_window;
+ dst->nominal_time = pr_pasn_params->nominal_time;
+ dst->measurements_per_aw = pr_pasn_params->measurements_per_aw;
+
+ /* Copy continuous ranging and location parameters */
+ dst->request_lci = pr_pasn_params->request_lci;
+ dst->request_civicloc = pr_pasn_params->request_civicloc;
+ dst->continuous_ranging_session_time =
+ pr_pasn_params->continuous_ranging_session_time;
+
+ /* Copy PD-specific parameters */
+ dst->lmr_feedback = pr_pasn_params->lmr_feedback;
+ dst->ingress_threshold = pr_pasn_params->ingress_threshold;
+ dst->egress_threshold = pr_pasn_params->egress_threshold;
+ dst->pr_suppress_results = pr_pasn_params->pr_suppress_results;
+ dst->forced_pr_freq = pr_pasn_params->forced_pr_freq;
+
+ /* 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 meas_per_aw=%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,
+ pr_pasn_params->measurements_per_aw);
+ }
+
+ /* 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,
+ dst->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