[PATCH v2 2/5] PR: Handle PASN Authentication frame TX status with retransmission
Peddolla Harshavardhan Reddy
peddolla.reddy at oss.qualcomm.com
Fri Jul 31 02:52:24 PDT 2026
Proximity ranging can be triggered out-of-band, in which case the
PASN responder may not yet be on channel when the initiator sends
Authentication frame 1 and may miss it. On each unacked TX status,
schedule a retransmission after a short delay to allow the responder
time to come on channel between attempts. The retry timer is
cancelled on PASN timeout or auth work completion.
Extend the initiator auth work timeout from 2 seconds to 10 seconds
via a new PR_PASN_AUTH_TIMEOUT constant to allow sufficient retries
before giving up on the session.
Add pr_pasn_auth_retransmit() to perform the retransmission from the
stored frame buffer, and return early from pr_pasn_auth_tx_status()
on TX failure to preserve pasn->frame for subsequent retransmits.
Signed-off-by: Peddolla Harshavardhan Reddy <peddolla.reddy at oss.qualcomm.com>
---
src/common/proximity_ranging.c | 25 ++++++++++++++++++++++
src/common/proximity_ranging.h | 1 +
wpa_supplicant/pr_supplicant.c | 38 ++++++++++++++++++++++++++++++++--
3 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/src/common/proximity_ranging.c b/src/common/proximity_ranging.c
index fd2776787..5e39bfaf0 100644
--- a/src/common/proximity_ranging.c
+++ b/src/common/proximity_ranging.c
@@ -2119,6 +2119,14 @@ int pr_pasn_auth_tx_status(struct pr_data *pr, const u8 *data, size_t data_len,
MAC2STR(mgmt->da), acked);
ret = wpa_pasn_auth_tx_status(pasn, data, data_len, acked);
+
+ /*
+ * Auth frame 1 was not acked; return to caller to schedule a
+ * retransmission. Preserve pasn->frame for the retry.
+ */
+ if (ret == 2)
+ return ret;
+
if (ret == 1 && acked && pr->cfg->pasn_result)
pr->cfg->pasn_result(pr->cfg->cb_ctx, dev->ranging_role,
dev->protocol_type, dev->final_op_class,
@@ -2161,6 +2169,23 @@ out:
}
+int pr_pasn_auth_retransmit(struct pr_data *pr, const u8 *addr)
+{
+ struct pr_device *dev;
+ struct pasn_data *pasn;
+
+ dev = pr_get_device(pr, addr);
+ if (!dev || !dev->pasn || !dev->pasn->frame)
+ return -1;
+
+ pasn = dev->pasn;
+ wpa_printf(MSG_DEBUG, "PR PASN: retransmit auth frame 1 to " MACSTR,
+ MAC2STR(addr));
+ return pasn->send_mgmt(pasn->cb_ctx, wpabuf_head(pasn->frame),
+ wpabuf_len(pasn->frame), 0, pasn->freq, 1000);
+}
+
+
static int pr_process_pasn_ranging_wrapper(struct pr_data *pr,
struct pr_device *dev,
const struct ieee80211_mgmt *mgmt,
diff --git a/src/common/proximity_ranging.h b/src/common/proximity_ranging.h
index 920eb297a..6ce9f6922 100644
--- a/src/common/proximity_ranging.h
+++ b/src/common/proximity_ranging.h
@@ -676,6 +676,7 @@ int pr_initiate_pasn_auth(struct pr_data *pr, const u8 *addr, int freq,
int forced_pr_freq);
int pr_pasn_auth_tx_status(struct pr_data *pr, const u8 *data, size_t data_len,
bool acked);
+int pr_pasn_auth_retransmit(struct pr_data *pr, const u8 *addr);
int pr_pasn_auth_rx(struct pr_data *pr, const struct ieee80211_mgmt *mgmt,
size_t len, int freq);
diff --git a/wpa_supplicant/pr_supplicant.c b/wpa_supplicant/pr_supplicant.c
index d4bc7035e..c9750233d 100644
--- a/wpa_supplicant/pr_supplicant.c
+++ b/wpa_supplicant/pr_supplicant.c
@@ -24,9 +24,15 @@
static void wpas_pr_pasn_timeout(void *eloop_ctx, void *timeout_ctx);
static void wpas_pr_pasn_roc_total_timeout(void *eloop_ctx, void *timeout_ctx);
static void wpas_pr_pasn_auth_work_done(struct wpa_supplicant *wpa_s);
+static void wpas_pr_pasn_auth_retry_timeout(void *eloop_ctx,
+ void *timeout_ctx);
/* Total listen window (ms) for the PASN responder ROC */
#define PR_PASN_RESPONDER_ROC_DURATION 5000
+/* Initiator PASN auth timeout (s) */
+#define PR_PASN_AUTH_TIMEOUT 10
+/* Retry interval (ms) for unacked PASN auth frame 1 */
+#define PR_PASN_AUTH1_RETRY_INTERVAL_MS 100
#endif /* CONFIG_PASN */
@@ -1012,6 +1018,7 @@ static void wpas_pr_pasn_auth_work_done(struct wpa_supplicant *wpa_s)
wpa_s->pr_pasn_auth_work->ctx = NULL;
radio_work_done(wpa_s->pr_pasn_auth_work);
wpa_s->pr_pasn_auth_work = NULL;
+ eloop_cancel_timeout(wpas_pr_pasn_auth_retry_timeout, wpa_s, NULL);
}
@@ -1200,6 +1207,8 @@ static void wpas_pr_pasn_timeout(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
+ eloop_cancel_timeout(wpas_pr_pasn_auth_retry_timeout, wpa_s, NULL);
+
if (wpa_s->pr_pasn_auth_work) {
wpas_pr_pasn_cancel_auth_work(wpa_s);
wpa_s->pr_pasn_auth_work = NULL;
@@ -1250,7 +1259,8 @@ static void wpas_pr_pasn_auth_start_cb(struct wpa_radio_work *work, int deinit)
}
eloop_cancel_timeout(wpas_pr_pasn_timeout, wpa_s, NULL);
- eloop_register_timeout(2, 0, wpas_pr_pasn_timeout, wpa_s, NULL);
+ eloop_register_timeout(PR_PASN_AUTH_TIMEOUT, 0, wpas_pr_pasn_timeout,
+ wpa_s, NULL);
wpa_s->pr_pasn_auth_work = work;
return;
@@ -1628,11 +1638,34 @@ int wpas_pr_pasn_auth_tx_status(struct wpa_supplicant *wpa_s, const u8 *data,
size_t data_len, bool acked)
{
struct pr_data *pr = wpa_s->global->pr;
+ int ret;
if (!wpa_s->pr_pasn_auth_work && is_zero_ether_addr(wpa_s->pd_addr))
return -1;
- return pr_pasn_auth_tx_status(pr, data, data_len, acked);
+ ret = pr_pasn_auth_tx_status(pr, data, data_len, acked);
+ if (ret == 2) {
+ eloop_cancel_timeout(wpas_pr_pasn_auth_retry_timeout, wpa_s,
+ NULL);
+ eloop_register_timeout(0, PR_PASN_AUTH1_RETRY_INTERVAL_MS * 1000,
+ wpas_pr_pasn_auth_retry_timeout, wpa_s,
+ NULL);
+ return 0;
+ }
+
+ return ret;
+}
+
+
+static void wpas_pr_pasn_auth_retry_timeout(void *eloop_ctx, void *timeout_ctx)
+{
+ struct wpa_supplicant *wpa_s = eloop_ctx;
+ struct pr_data *pr = wpa_s->global->pr;
+
+ if (!pr || !pr->pr_pasn_params)
+ return;
+
+ pr_pasn_auth_retransmit(pr, pr->pr_pasn_params->peer_addr);
}
@@ -1757,6 +1790,7 @@ void wpas_pr_abort_ranging(struct wpa_supplicant *wpa_s)
/* Stop PD wdev and cleanup all ranging resources */
wpas_pr_pd_stop(wpa_s);
+ eloop_cancel_timeout(wpas_pr_pasn_auth_retry_timeout, wpa_s, NULL);
/* Free ranging params so a new session can be started */
wpas_pr_clear_ranging_params(pr);
wpas_notify_pr_ranging_terminated(wpa_s, PR_SESSION_END_USER_ABORT);
--
2.34.1
More information about the Hostap
mailing list