[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