[PATCH v4 14/20] PR: Handle peer measurement complete event
Kavita Kavita
kavita.kavita at oss.qualcomm.com
Fri May 22 18:23:46 PDT 2026
From: Peddolla Harshavardhan Reddy <peddolla.reddy at oss.qualcomm.com>
Add support for NL80211_CMD_PEER_MEASUREMENT_COMPLETE which signals
the entire ranging session has ended.
Add EVENT_PEER_MEASUREMENT_COMPLETE event and peer_measurement_complete
struct. wpas_pr_measurement_complete() validates the cookie, emits
PR-RANGING-COMPLETE ctrl event, frees pr_pasn_params, resets
ranging_final_received, and stops the PD wdev.
Signed-off-by: Peddolla Harshavardhan Reddy <peddolla.reddy at oss.qualcomm.com>
---
src/common/wpa_ctrl.h | 3 +++
src/drivers/driver.h | 15 +++++++++++++
src/drivers/driver_common.c | 1 +
src/drivers/driver_nl80211_event.c | 26 +++++++++++++++++++++
wpa_supplicant/events.c | 7 ++++++
wpa_supplicant/notify.c | 7 ++++++
wpa_supplicant/notify.h | 2 ++
wpa_supplicant/pr_supplicant.c | 36 ++++++++++++++++++++++++++++++
wpa_supplicant/pr_supplicant.h | 8 +++++++
9 files changed, 105 insertions(+)
diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index e136a61bf..69f710185 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -512,6 +512,9 @@ extern "C" {
/* Proximity Ranging measurement result */
#define PR_EVENT_PEER_MEASUREMENT "PR-PEER-MEASUREMENT "
+/* Proximity Ranging measurement session complete */
+#define PR_EVENT_RANGING_COMPLETE "PR-RANGING-COMPLETE "
+
/* BSS command information masks */
#define WPA_BSS_MASK_ALL 0xFFFDFFFF
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 55d71a7e4..c95d3767e 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -6657,6 +6657,14 @@ enum wpa_event_type {
* This event is used to indicate a ranging measurement result.
*/
EVENT_PEER_MEASUREMENT_RESULT,
+
+ /**
+ * EVENT_PEER_MEASUREMENT_COMPLETE - Ranging session fully done
+ *
+ * This event is used to notify that the entire peer
+ * measurement session identified by the cookie has ended.
+ */
+ EVENT_PEER_MEASUREMENT_COMPLETE,
};
@@ -7764,6 +7772,13 @@ union wpa_event_data {
} ftm;
} peer_measurement_result;
+
+ /**
+ * struct peer_measurement_complete - Ranging session complete
+ */
+ struct peer_measurement_complete {
+ u64 cookie;
+ } peer_measurement_complete;
};
/**
diff --git a/src/drivers/driver_common.c b/src/drivers/driver_common.c
index 170821423..812305cae 100644
--- a/src/drivers/driver_common.c
+++ b/src/drivers/driver_common.c
@@ -109,6 +109,7 @@ const char * event_to_string(enum wpa_event_type event)
E2S(NAN_ULW_UPDATE);
E2S(NAN_CHAN_EVACUATION);
E2S(PEER_MEASUREMENT_RESULT);
+ E2S(PEER_MEASUREMENT_COMPLETE);
}
return "UNKNOWN";
diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
index 8023ec6e2..55076e16f 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -4407,6 +4407,29 @@ nl80211_parse_peer_ftm_result(struct peer_measurement_ftm_result *ftm,
}
+static void nl80211_peer_measurement_complete_event(struct i802_bss *bss,
+ struct nlattr **tb)
+{
+ union wpa_event_data data;
+ u64 cookie = 0;
+
+ os_memset(&data, 0, sizeof(data));
+
+ if (tb[NL80211_ATTR_COOKIE]) {
+ cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
+ wpa_printf(MSG_DEBUG,
+ "nl80211: PR: Peer measurement complete cookie: %llu",
+ (unsigned long long) cookie);
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: PR: Peer measurement complete (no cookie)");
+ }
+
+ data.peer_measurement_complete.cookie = cookie;
+ wpa_supplicant_event(bss->ctx, EVENT_PEER_MEASUREMENT_COMPLETE, &data);
+}
+
+
static void nl80211_peer_measurement_result_event(struct i802_bss *bss,
struct nlattr **tb)
{
@@ -5089,6 +5112,9 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
case NL80211_CMD_PEER_MEASUREMENT_RESULT:
nl80211_peer_measurement_result_event(bss, tb);
break;
+ case NL80211_CMD_PEER_MEASUREMENT_COMPLETE:
+ nl80211_peer_measurement_complete_event(bss, tb);
+ break;
#endif /* CONFIG_PR */
default:
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 64808c19f..44ee15744 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -7677,6 +7677,13 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
if (data)
wpas_pr_measurement_result(wpa_s,
&data->peer_measurement_result);
+#endif /* CONFIG_PR */
+ break;
+ case EVENT_PEER_MEASUREMENT_COMPLETE:
+#ifdef CONFIG_PR
+ if (data)
+ wpas_pr_measurement_complete(wpa_s,
+ &data->peer_measurement_complete);
#endif /* CONFIG_PR */
break;
#ifdef CONFIG_NAN
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 876b2c151..f7d0fef3d 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -1604,4 +1604,11 @@ void wpas_notify_pr_measurement_result(struct wpa_supplicant *wpa_s,
result->ftm.burst_index, rtt, dist);
}
+
+void wpas_notify_pr_ranging_complete(struct wpa_supplicant *wpa_s, u64 cookie)
+{
+ wpa_msg_global(wpa_s, MSG_INFO, PR_EVENT_RANGING_COMPLETE
+ "cookie=%llu", (unsigned long long) cookie);
+}
+
#endif /* CONFIG_PR */
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index f2014f3cb..c16b5e163 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -220,6 +220,8 @@ void wpas_notify_pr_ranging_params(struct wpa_supplicant *wpa_s,
int bw, int format_bw);
void wpas_notify_pr_measurement_result(struct wpa_supplicant *wpa_s,
const struct peer_measurement_result *result);
+void wpas_notify_pr_ranging_complete(struct wpa_supplicant *wpa_s,
+ u64 cookie);
void wpas_notify_nan_bootstrap_request(struct wpa_supplicant *wpa_s,
const u8 *peer_addr, u16 pbm,
int handle, u8 requestor_instance_id);
diff --git a/wpa_supplicant/pr_supplicant.c b/wpa_supplicant/pr_supplicant.c
index 5085df977..b9171362d 100644
--- a/wpa_supplicant/pr_supplicant.c
+++ b/wpa_supplicant/pr_supplicant.c
@@ -765,6 +765,42 @@ void wpas_pr_set_dev_ik(struct wpa_supplicant *wpa_s, const u8 *dik,
}
+void wpas_pr_measurement_complete(struct wpa_supplicant *wpa_s,
+ struct peer_measurement_complete *complete)
+{
+ struct pr_data *pr = wpa_s->global->pr;
+
+ if (!complete) {
+ wpa_printf(MSG_ERROR,
+ "PR: Invalid measurement complete event");
+ return;
+ }
+
+ wpa_printf(MSG_DEBUG,
+ "PR: Peer measurement complete cookie=%llu",
+ (unsigned long long) complete->cookie);
+
+ /* Validate cookie if we have a pending ranging request */
+ if (pr && pr->pr_pasn_params && complete->cookie != 0) {
+ if (pr->pr_pasn_params->cookie != complete->cookie) {
+ wpa_printf(MSG_WARNING,
+ "PR: Complete cookie mismatch - expected %llu, got %llu. Ignoring.",
+ (unsigned long long) pr->pr_pasn_params->cookie,
+ (unsigned long long) complete->cookie);
+ return;
+ }
+ }
+
+ wpas_notify_pr_ranging_complete(wpa_s, complete->cookie);
+ if (pr) {
+ os_free(pr->pr_pasn_params);
+ pr->pr_pasn_params = NULL;
+ pr->ranging_final_received = false;
+ }
+ wpas_pr_pd_stop(wpa_s);
+}
+
+
void wpas_pr_measurement_result(struct wpa_supplicant *wpa_s,
struct peer_measurement_result *result)
{
diff --git a/wpa_supplicant/pr_supplicant.h b/wpa_supplicant/pr_supplicant.h
index 991a8dd5e..962cd446c 100644
--- a/wpa_supplicant/pr_supplicant.h
+++ b/wpa_supplicant/pr_supplicant.h
@@ -41,6 +41,8 @@ void wpas_pr_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
unsigned int freq);
void wpas_pr_pasn_trigger(struct wpa_supplicant *wpa_s,
struct pr_pasn_ranging_params *pr_pasn_params);
+void wpas_pr_measurement_complete(struct wpa_supplicant *wpa_s,
+ struct peer_measurement_complete *complete);
void wpas_pr_measurement_result(struct wpa_supplicant *wpa_s,
struct peer_measurement_result *result);
@@ -121,6 +123,12 @@ wpas_pr_pasn_trigger(struct wpa_supplicant *wpa_s,
{
}
+static inline void
+wpas_pr_measurement_complete(struct wpa_supplicant *wpa_s,
+ struct peer_measurement_complete *complete)
+{
+}
+
static inline void
wpas_pr_measurement_result(struct wpa_supplicant *wpa_s,
struct peer_measurement_result *result)
--
2.34.1
More information about the Hostap
mailing list