[PATCH 04/34] PR: Add support to process PR elements in USD frames
Peddolla Harshavardhan Reddy
peddolla at qti.qualcomm.com
Thu Jun 19 08:36:57 PDT 2025
Add changes to process Proximity Ranging attributes present in USD
frames. USD is performed with the PR attribute to exchange
capabilities specific to proximity ranging.
The discovered device capabilities along with the other details such
as address and name are stored in a list present within the proximity
ranging global context.
Signed-off-by: Peddolla Harshavardhan Reddy <peddolla at qti.qualcomm.com>
---
src/common/ieee802_11_common.c | 5 +++
src/common/ieee802_11_common.h | 2 +
src/common/nan_de.c | 7 +++-
src/common/nan_de.h | 4 ++
src/common/proximity_ranging.c | 73 +++++++++++++++++++++++++++++++++-
src/common/proximity_ranging.h | 3 ++
wpa_supplicant/nan_usd.c | 15 +++++++
wpa_supplicant/pr_supplicant.c | 12 ++++++
wpa_supplicant/pr_supplicant.h | 3 ++
9 files changed, 121 insertions(+), 3 deletions(-)
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index ae7a7647a..7974e4d17 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -165,6 +165,11 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
elems->p2p2_ie = pos;
elems->p2p2_ie_len = elen;
break;
+ case PR_OUI_TYPE:
+ /* Wi-Fi Alliance - PR IE */
+ elems->proximity_ranging = pos;
+ elems->proximity_ranging_len = elen;
+ break;
default:
wpa_printf(MSG_MSGDUMP, "Unknown WFA "
"information element ignored "
diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h
index 5f52b573c..906c13854 100644
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -122,6 +122,7 @@ struct ieee802_11_elems {
const u8 *rsnxe_override;
const u8 *rsn_selection;
const u8 *wfa_capab;
+ const u8 *proximity_ranging;
u8 ssid_len;
u8 supp_rates_len;
@@ -191,6 +192,7 @@ struct ieee802_11_elems {
size_t rsnxe_override_len;
size_t rsn_selection_len;
u8 wfa_capab_len;
+ size_t proximity_ranging_len;
struct mb_ies_info mb_ies;
diff --git a/src/common/nan_de.c b/src/common/nan_de.c
index ba038094b..2247af895 100644
--- a/src/common/nan_de.c
+++ b/src/common/nan_de.c
@@ -843,7 +843,7 @@ static void nan_de_get_sdea(const u8 *buf, size_t len, u8 instance_id,
static void nan_de_process_elem_container(struct nan_de *de, const u8 *buf,
size_t len, const u8 *peer_addr,
- unsigned int freq, bool p2p)
+ unsigned int freq, bool p2p, bool pr)
{
const u8 *elem;
u16 elem_len;
@@ -866,6 +866,9 @@ static void nan_de_process_elem_container(struct nan_de *de, const u8 *buf,
if (p2p && de->cb.process_p2p_usd_elems)
de->cb.process_p2p_usd_elems(de->cb.ctx, elem, elem_len,
peer_addr, freq);
+ if (pr && de->cb.process_pr_usd_elems)
+ de->cb.process_pr_usd_elems(de->cb.ctx, elem, elem_len,
+ peer_addr, freq);
}
@@ -1205,7 +1208,7 @@ static void nan_de_rx_sda(struct nan_de *de, const u8 *peer_addr, const u8 *a3,
ssi, ssi_len);
}
nan_de_process_elem_container(de, buf, len, peer_addr,
- freq, srv->is_p2p);
+ freq, srv->is_p2p, srv->is_pr);
}
switch (type) {
diff --git a/src/common/nan_de.h b/src/common/nan_de.h
index 7f0836332..29999b31f 100644
--- a/src/common/nan_de.h
+++ b/src/common/nan_de.h
@@ -60,6 +60,10 @@ struct nan_callbacks {
void (*process_p2p_usd_elems)(void *ctx, const u8 *buf,
u16 buf_len, const u8 *peer_addr,
unsigned int freq);
+
+ void (*process_pr_usd_elems)(void *ctx, const u8 *buf,
+ u16 buf_len, const u8 *peer_addr,
+ unsigned int freq);
};
bool nan_de_is_nan_network_id(const u8 *addr);
diff --git a/src/common/proximity_ranging.c b/src/common/proximity_ranging.c
index 9d2cf6135..a3f640bce 100644
--- a/src/common/proximity_ranging.c
+++ b/src/common/proximity_ranging.c
@@ -15,6 +15,59 @@
#include "wps/wps_i.h"
#include "proximity_ranging.h"
+static void pr_device_free(struct pr_data *pr, struct pr_device *dev)
+{
+ os_free(dev);
+}
+
+
+static struct pr_device * pr_get_device(struct pr_data *pr, const u8 *addr)
+{
+ struct pr_device *dev;
+
+ dl_list_for_each(dev, &pr->devices, struct pr_device, list) {
+ if (ether_addr_equal(dev->pr_device_addr, addr))
+ return dev;
+ }
+ return NULL;
+}
+
+
+static struct pr_device * pr_create_device(struct pr_data *pr, const u8 *addr)
+{
+ struct pr_device *dev, *oldest = NULL;
+ size_t count = 0;
+
+ dev = pr_get_device(pr, addr);
+ if (dev)
+ return dev;
+
+ dl_list_for_each(dev, &pr->devices, struct pr_device, list) {
+ count++;
+ if (!oldest ||
+ os_reltime_before(&dev->last_seen, &oldest->last_seen))
+ oldest = dev;
+ }
+ if (count + 1 > PR_MAX_PEER && oldest) {
+ wpa_printf(MSG_DEBUG,
+ "Remove oldest peer entry to make room for a new peer " MACSTR,
+ MAC2STR(oldest->pr_device_addr));
+ dl_list_del(&oldest->list);
+ pr_device_free(pr, oldest);
+ }
+
+ dev = os_zalloc(sizeof(*dev));
+ if (!dev)
+ return NULL;
+
+ dl_list_add(&pr->devices, &dev->list);
+ os_memcpy(dev->pr_device_addr, addr, ETH_ALEN);
+ wpa_printf(MSG_DEBUG, "PR: New Proximity Ranging device add to list");
+
+ return dev;
+}
+
+
struct pr_data * pr_init(const struct pr_config *cfg)
{
struct pr_data *pr;
@@ -45,8 +98,10 @@ void pr_deinit(struct pr_data *pr)
os_free(pr->cfg->dev_name);
- dl_list_for_each_safe(dev, prev, &pr->devices, struct pr_device, list)
+ dl_list_for_each_safe(dev, prev, &pr->devices, struct pr_device, list) {
dl_list_del(&dev->list);
+ pr_device_free(pr, dev);
+ }
os_free(pr);
wpa_printf(MSG_DEBUG, "PR: Deinit done");
@@ -102,3 +157,19 @@ struct wpabuf * pr_prepare_usd_elems(struct pr_data *pr, const char *country)
return buf2;
}
+
+
+void pr_process_usd_elems(struct pr_data *pr, const u8 *ies, u16 ies_len,
+ const u8 *peer_addr, unsigned int freq)
+{
+ struct pr_device *dev;
+
+ dev = pr_create_device(pr, peer_addr);
+ if (!dev) {
+ wpa_printf(MSG_ERROR, "PR: Failed to create a device");
+ return;
+ }
+
+ os_get_reltime(&dev->last_seen);
+ dev->listen_freq = freq;
+}
diff --git a/src/common/proximity_ranging.h b/src/common/proximity_ranging.h
index 12387e434..ec6539eac 100644
--- a/src/common/proximity_ranging.h
+++ b/src/common/proximity_ranging.h
@@ -64,6 +64,7 @@ struct pr_channels {
struct pr_device {
struct dl_list list;
struct os_reltime last_seen;
+ int listen_freq;
/**
* pr_device_addr - PR Device Address of the peer
@@ -148,5 +149,7 @@ struct pr_data {
struct pr_data * pr_init(const struct pr_config *cfg);
void pr_deinit(struct pr_data *pr);
struct wpabuf * pr_prepare_usd_elems(struct pr_data *pr, const char *country);
+void pr_process_usd_elems(struct pr_data *pr, const u8 *ies, u16 ies_len,
+ const u8 *peer_addr, unsigned int freq);
#endif /* PROXIMITY_RANGING_H */
diff --git a/wpa_supplicant/nan_usd.c b/wpa_supplicant/nan_usd.c
index 68b2e6521..cb8c6d6aa 100644
--- a/wpa_supplicant/nan_usd.c
+++ b/wpa_supplicant/nan_usd.c
@@ -322,6 +322,18 @@ static void wpas_nan_process_p2p_usd_elems(void *ctx, const u8 *buf,
#endif /* CONFIG_P2P */
+#ifdef CONFIG_PR
+static void wpas_nan_process_pr_usd_elems(void *ctx, const u8 *buf, u16 buf_len,
+ const u8 *peer_addr,
+ unsigned int freq)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+
+ wpas_pr_process_usd_elems(wpa_s, buf, buf_len, peer_addr, freq);
+}
+#endif /* CONFIG_PR */
+
+
int wpas_nan_usd_init(struct wpa_supplicant *wpa_s)
{
struct nan_callbacks cb;
@@ -341,6 +353,9 @@ int wpas_nan_usd_init(struct wpa_supplicant *wpa_s)
#ifdef CONFIG_P2P
cb.process_p2p_usd_elems = wpas_nan_process_p2p_usd_elems;
#endif /* CONFIG_P2P */
+#ifdef CONFIG_PR
+ cb.process_pr_usd_elems = wpas_nan_process_pr_usd_elems;
+#endif /* CONFIG_PR */
wpa_s->nan_de = nan_de_init(wpa_s->own_addr, offload, false,
wpa_s->max_remain_on_chan, &cb);
diff --git a/wpa_supplicant/pr_supplicant.c b/wpa_supplicant/pr_supplicant.c
index 1610dfe49..df416bd0a 100644
--- a/wpa_supplicant/pr_supplicant.c
+++ b/wpa_supplicant/pr_supplicant.c
@@ -80,6 +80,18 @@ struct wpabuf * wpas_pr_usd_elems(struct wpa_supplicant *wpa_s)
}
+void wpas_pr_process_usd_elems(struct wpa_supplicant *wpa_s, const u8 *buf,
+ u16 buf_len, const u8 *peer_addr,
+ unsigned int freq)
+{
+ struct pr_data *pr = wpa_s->global->pr;
+
+ if (!pr)
+ return;
+ pr_process_usd_elems(pr, buf, buf_len, peer_addr, freq);
+}
+
+
int wpas_pr_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
{
struct pr_config pr;
diff --git a/wpa_supplicant/pr_supplicant.h b/wpa_supplicant/pr_supplicant.h
index 92f6087e8..6abe59331 100644
--- a/wpa_supplicant/pr_supplicant.h
+++ b/wpa_supplicant/pr_supplicant.h
@@ -16,6 +16,9 @@
int wpas_pr_init(struct wpa_global *global, struct wpa_supplicant *wpa_s);
void wpas_pr_deinit(struct wpa_supplicant *wpa_s);
struct wpabuf * wpas_pr_usd_elems(struct wpa_supplicant *wpa_s);
+void wpas_pr_process_usd_elems(struct wpa_supplicant *wpa_s, const u8 *buf,
+ u16 buf_len, const u8 *peer_addr,
+ unsigned int freq);
#else /* CONFIG_PR */
static inline int wpas_pr_init(struct wpa_global *global,
struct wpa_supplicant *wpa_s)
--
2.34.1
More information about the Hostap
mailing list