[RFC PATCH 04/34] Add support to process PR elements in USD frames
Peddolla Harshavardhan Reddy
peddolla at qti.qualcomm.com
Thu May 15 00:17:27 PDT 2025
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 838869a03..7bf255fbc 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 abd17f062..428531c9b 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 ab61f6e3a..d87856b12 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 8ebc363c1..4f5c59f9b 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
@@ -146,5 +147,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 59955d6dc..1e151581a 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 b2469781a..2bad595bb 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