]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
PR: Pass PR elements in USD frames for processing
authorPeddolla Harshavardhan Reddy <peddolla@qti.qualcomm.com>
Mon, 28 Apr 2025 09:14:36 +0000 (14:44 +0530)
committerJouni Malinen <j@w1.fi>
Fri, 17 Oct 2025 10:22:50 +0000 (13:22 +0300)
Add changes needed 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.

This commit includes only the base framework for getting the information
into appropriate places. Actual processing of the elements will be added
in separate commits.

Signed-off-by: Peddolla Harshavardhan Reddy <peddolla@qti.qualcomm.com>
src/common/nan_de.c
src/common/nan_de.h
src/common/proximity_ranging.c
src/common/proximity_ranging.h
wpa_supplicant/nan_usd.c
wpa_supplicant/pr_supplicant.c
wpa_supplicant/pr_supplicant.h

index 110fba8a1ef29b4a72d41958598699b58543d34b..8ea925aace930b31c4fb3bb290ea7387e2c5312f 100644 (file)
@@ -850,7 +850,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;
@@ -873,6 +873,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);
 }
 
 
@@ -1212,7 +1215,8 @@ 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) {
index ceb13c1a82b04c5173d8ce295d62d1ada44d64fc..b423544649db4f81a94a175a428e28237c2e0e09 100644 (file)
@@ -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);
index 5c566f606baed8f87e1f98aa43dff04dbe89d7e6..d6a41e5ac6d145d63cf3c9f8cbf9d2cd03245b3e 100644 (file)
 #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,
+                          "PR: 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 " MACSTR
+                  " added to list", MAC2STR(addr));
+
+       return dev;
+}
+
+
 struct pr_data * pr_init(const struct pr_config *cfg)
 {
        struct pr_data *pr;
@@ -43,8 +97,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");
@@ -99,3 +155,19 @@ struct wpabuf * pr_prepare_usd_elems(struct pr_data *pr)
 
        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_INFO, "PR: Failed to create a device");
+               return;
+       }
+
+       os_get_reltime(&dev->last_seen);
+       dev->listen_freq = freq;
+}
index 04336e0185e45eb7a0052795aa915a5a8a3f0773..52871947d6e08621ccbedd8ac78d9d7d986068ed 100644 (file)
@@ -96,6 +96,7 @@ enum ntb_format_and_bw_value {
 struct pr_device {
        struct dl_list list;
        struct os_reltime last_seen;
+       int listen_freq;
 
        /**
         * pr_device_addr - PR Device Address of the peer
@@ -179,5 +180,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);
+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 */
index 52eee206ef74dc02bcf40f031d812e2d5eb8932a..b8eb4c41b7738b78c066bfffbaa925a66615c005 100644 (file)
@@ -339,6 +339,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;
@@ -358,6 +370,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);
index 7028af9132e9d827eec7904b4386d81280953c1f..f32d9a45ed90e1f72a400ea889512e64cf493dc1 100644 (file)
@@ -244,6 +244,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,
                 const struct wpa_driver_capa *capa)
 {
index ec68cae03dc89faae62a50542ded1fdce9d8c91f..6877fa84277e58dcf872f78d76b9b2c1eb3e57b1 100644 (file)
@@ -15,6 +15,9 @@ int wpas_pr_init(struct wpa_global *global, struct wpa_supplicant *wpa_s,
                 const struct wpa_driver_capa *capa);
 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 */