[PATCH v3 34/46] nl80211: Add dedicated PR ranging socket and stop op
Kavita Kavita
kavita.kavita at oss.qualcomm.com
Wed May 13 02:59:58 PDT 2026
From: Veerendranath Jakkam <vjakkam at qti.qualcomm.com>
Create a dedicated netlink socket (nl_pr) in nl80211_global for PR
peer measurements. The socket is created when start_peer_measurement()
is called, used to send NL80211_CMD_PEER_MEASUREMENT_START, and
registered with eloop to receive RESULT and COMPLETE events.
Add stop_peer_measurement() driver op implemented by
nl80211_stop_peer_measurement() which destroys the nl_pr socket and
unregisters it from eloop. Also add cleanup in nl80211_global_deinit()
for the case where stop was never called.
Signed-off-by: Veerendranath Jakkam <vjakkam at qti.qualcomm.com>
---
src/drivers/driver.h | 9 +++++++
src/drivers/driver_nl80211.c | 46 +++++++++++++++++++++++++++++++++++-
src/drivers/driver_nl80211.h | 4 ++++
3 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index ee710fad8..4689bc5b0 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -5863,6 +5863,15 @@ struct wpa_driver_ops {
int (*start_peer_measurement)(void *priv, const u8 *peer_addr,
int freq, u8 channel, int bw,
struct pr_pasn_ranging_params *params);
+
+ /**
+ * stop_peer_measurement - Stop peer measurement and destroy ranging socket
+ * @priv: Private driver interface data
+ *
+ * Unregisters the ranging socket from eloop and frees all associated
+ * resources. Safe to call when no ranging session is active (no-op).
+ */
+ void (*stop_peer_measurement)(void *priv);
#endif /* CONFIG_PR */
#ifdef CONFIG_NAN
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 8af3efe98..4435b915d 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -9330,6 +9330,20 @@ static int nl80211_start_peer_measurement(void *priv, const u8 *peer_addr,
return -1;
}
+ /* Create dedicated ranging socket if not already created */
+ if (drv->global->nl_pr) {
+ wpa_printf(MSG_ERROR,
+ "nl80211: PR ranging socket already in use");
+ return -1;
+ }
+
+ drv->global->nl_pr = nl_create_handle(drv->global->nl_cb, "pr");
+ if (!drv->global->nl_pr) {
+ wpa_printf(MSG_ERROR,
+ "nl80211: Failed to create PR ranging socket");
+ return -1;
+ }
+
/* Route via PD wdev if src_addr matches */
if (drv->pd_bss && !is_zero_ether_addr(params->src_addr) &&
ether_addr_equal(params->src_addr, drv->pd_bss->addr)) {
@@ -9553,19 +9567,29 @@ static int nl80211_start_peer_measurement(void *priv, const u8 *peer_addr,
cookie = 0;
os_memset(&ack_arg, 0, sizeof(struct nl80211_ack_ext_arg));
ack_arg.ext_data = &cookie;
- ret = send_and_recv(drv, drv->global->nl, msg, NULL, NULL,
+ ret = send_and_recv(drv, drv->global->nl_pr, msg, NULL, NULL,
ack_handler_cookie, &ack_arg, NULL);
if (ret < 0) {
wpa_printf(MSG_ERROR,
"nl80211: Peer measurement start failed: ret=%d (%s)",
ret, strerror(-ret));
+ nl_destroy_handles(&drv->global->nl_pr);
} else {
wpa_printf(MSG_DEBUG,
"nl80211: Peer measurement started successfully addr=" MACSTR
" cookie=%llu", MAC2STR(peer_addr),
(unsigned long long) cookie);
params->cookie = cookie;
+ /*
+ * Register the PR socket with eloop so that
+ * NL80211_CMD_PEER_MEASUREMENT_RESULT and
+ * NL80211_CMD_PEER_MEASUREMENT_COMPLETE events are delivered
+ * to the existing nl80211 event handler.
+ */
+ nl80211_register_eloop_read(&drv->global->nl_pr,
+ wpa_driver_nl80211_event_receive,
+ drv->global->nl_cb, 1);
}
return ret;
@@ -9573,9 +9597,23 @@ static int nl80211_start_peer_measurement(void *priv, const u8 *peer_addr,
fail:
wpa_printf(MSG_ERROR, "nl80211: Failed to build peer measurement message");
nlmsg_free(msg);
+ nl_destroy_handles(&drv->global->nl_pr);
return -1;
}
+
+static void nl80211_stop_peer_measurement(void *priv)
+{
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+
+ if (!drv->global->nl_pr)
+ return;
+
+ wpa_printf(MSG_DEBUG, "nl80211: Stopping PR ranging socket");
+ nl80211_destroy_eloop_handle(&drv->global->nl_pr, 1);
+}
+
#endif /* CONFIG_PR */
static void dump_ifidx(struct wpa_driver_nl80211_data *drv)
@@ -11354,6 +11392,11 @@ static void nl80211_global_deinit(void *priv)
nl_cb_put(global->nl_cb);
+#ifdef CONFIG_PR
+ if (global->nl_pr)
+ nl80211_destroy_eloop_handle(&global->nl_pr, 1);
+#endif /* CONFIG_PR */
+
if (global->ioctl_sock >= 0)
close(global->ioctl_sock);
@@ -16722,5 +16765,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.pd_start = nl80211_pd_start,
.pd_stop = nl80211_pd_stop,
.start_peer_measurement = nl80211_start_peer_measurement,
+ .stop_peer_measurement = nl80211_stop_peer_measurement,
#endif /* CONFIG_PR */
};
diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
index d1133a1fe..9c871ce18 100644
--- a/src/drivers/driver_nl80211.h
+++ b/src/drivers/driver_nl80211.h
@@ -52,6 +52,10 @@ struct nl80211_global {
/* Dedicated socket for NAN interface creation and events */
struct nl_sock *nl_nan;
#endif /* CONFIG_NAN */
+#ifdef CONFIG_PR
+ /* Dedicated socket for PR peer measurement commands and events */
+ struct nl_sock *nl_pr;
+#endif /* CONFIG_PR */
};
struct nl80211_wiphy_data {
--
2.34.1
More information about the Hostap
mailing list