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;
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);
}
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) {
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);
#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;
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");
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;
+}
struct pr_device {
struct dl_list list;
struct os_reltime last_seen;
+ int listen_freq;
/**
* pr_device_addr - PR Device Address of the peer
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 */
#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;
#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);
}
+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)
{
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 */