[RFC PATCH 03/34] Add API to initiate USD for Proximity Ranging
Peddolla Harshavardhan Reddy
peddolla at qti.qualcomm.com
Thu May 15 00:17:26 PDT 2025
Signed-off-by: Peddolla Harshavardhan Reddy <peddolla at qti.qualcomm.com>
---
src/common/ieee802_11_defs.h | 13 +++++++++
src/common/nan_de.c | 53 ++++++++++++++++++++++++++--------
src/common/nan_de.h | 6 ++++
src/common/proximity_ranging.c | 51 ++++++++++++++++++++++++++++++++
src/common/proximity_ranging.h | 1 +
wpa_supplicant/nan_usd.c | 25 +++++++++++++---
wpa_supplicant/pr_supplicant.c | 6 ++++
wpa_supplicant/pr_supplicant.h | 6 ++++
8 files changed, 145 insertions(+), 16 deletions(-)
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index c5341d3b0..2c094ef25 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -1477,6 +1477,12 @@ struct ieee80211_ampe_ie {
#define RSNXE_OVERRIDE_IE_VENDOR_TYPE 0x506f9a2b
#define RSN_SELECTION_IE_VENDOR_TYPE 0x506f9a2c
+/* TODO: The PR_IE_VENDOR_TYPE has not been finalized yet.
+ * Please update the type once it is confirmed.
+ */
+#define PR_IE_VENDOR_TYPE 0x506f9afe
+
+
#define MULTI_AP_SUB_ELEM_TYPE 0x06
#define MULTI_AP_PROFILE_SUB_ELEM_TYPE 0x07
#define MULTI_AP_VLAN_SUB_ELEM_TYPE 0x08
@@ -3165,6 +3171,13 @@ struct ieee80211_s1g_beacon_compat {
le32 tsf_completion;
} STRUCT_PACKED;
+/* Proximity Ranging (PR) */
+
+/* TODO: The PR_OUI_TYPE has not been finalized yet.
+ * Please update the OUI type once it is confirmed.
+ */
+#define PR_OUI_TYPE 0xFE
+
#ifdef _MSC_VER
#pragma pack(pop)
#endif /* _MSC_VER */
diff --git a/src/common/nan_de.c b/src/common/nan_de.c
index 2833211f9..ba038094b 100644
--- a/src/common/nan_de.c
+++ b/src/common/nan_de.c
@@ -64,6 +64,7 @@ struct nan_de_service {
struct os_reltime next_publish_chan;
unsigned int next_publish_duration;
bool is_p2p;
+ bool is_pr;
};
struct nan_de {
@@ -1328,7 +1329,7 @@ int nan_de_publish(struct nan_de *de, const char *service_name,
int publish_id;
struct nan_de_service *srv;
- if (!service_name) {
+ if (!service_name && !params->proximity_ranging) {
wpa_printf(MSG_DEBUG, "NAN: Publish() - no service_name");
return -1;
}
@@ -1339,6 +1340,12 @@ int nan_de_publish(struct nan_de *de, const char *service_name,
return -1;
}
+ if (params->proximity_ranging && params->solicited && !elems) {
+ wpa_printf(MSG_ERROR,
+ "NAN: Unable to fetch proximity ranging params");
+ return -1;
+ }
+
publish_id = nan_de_get_handle(de);
if (publish_id < 1)
return -1;
@@ -1348,11 +1355,18 @@ int nan_de_publish(struct nan_de *de, const char *service_name,
return -1;
srv->type = NAN_DE_PUBLISH;
srv->freq = srv->default_freq = params->freq;
- srv->service_name = os_strdup(service_name);
- if (!srv->service_name)
- goto fail;
- if (nan_de_derive_service_id(srv) < 0)
+
+ if (service_name) {
+ srv->service_name = os_strdup(service_name);
+ if (!srv->service_name)
+ goto fail;
+ }
+
+ if (params->proximity_ranging && !service_name)
+ os_memset(srv->service_id, 0, NAN_SERVICE_ID_LEN);
+ else if (nan_de_derive_service_id(srv) < 0)
goto fail;
+
os_memcpy(&srv->publish, params, sizeof(*params));
if (params->freq_list) {
@@ -1383,9 +1397,10 @@ int nan_de_publish(struct nan_de *de, const char *service_name,
nan_de_start_new_publish_state(srv, true);
wpa_printf(MSG_DEBUG, "NAN: Assigned new publish handle %d for %s",
- publish_id, service_name);
+ publish_id, service_name ? service_name : "Ranging");
srv->id = publish_id;
srv->is_p2p = p2p;
+ srv->is_pr = params->proximity_ranging && params->solicited;
nan_de_add_srv(de, srv);
nan_de_run_timer(de);
return publish_id;
@@ -1468,11 +1483,17 @@ int nan_de_subscribe(struct nan_de *de, const char *service_name,
int subscribe_id;
struct nan_de_service *srv;
- if (!service_name) {
+ if (!service_name && !params->proximity_ranging) {
wpa_printf(MSG_DEBUG, "NAN: Subscribe() - no service_name");
return -1;
}
+ if (params->proximity_ranging && params->active && !elems) {
+ wpa_printf(MSG_ERROR,
+ "NAN: Unable to fetch proximity ranging params");
+ return -1;
+ }
+
subscribe_id = nan_de_get_handle(de);
if (subscribe_id < 1)
return -1;
@@ -1482,11 +1503,18 @@ int nan_de_subscribe(struct nan_de *de, const char *service_name,
return -1;
srv->type = NAN_DE_SUBSCRIBE;
srv->freq = params->freq;
- srv->service_name = os_strdup(service_name);
- if (!srv->service_name)
- goto fail;
- if (nan_de_derive_service_id(srv) < 0)
+
+ if (service_name) {
+ srv->service_name = os_strdup(service_name);
+ if (!srv->service_name)
+ goto fail;
+ }
+
+ if (params->proximity_ranging && !service_name)
+ os_memset(srv->service_id, 0, NAN_SERVICE_ID_LEN);
+ else if (nan_de_derive_service_id(srv) < 0)
goto fail;
+
os_memcpy(&srv->subscribe, params, sizeof(*params));
if (params->freq_list) {
@@ -1512,9 +1540,10 @@ int nan_de_subscribe(struct nan_de *de, const char *service_name,
}
wpa_printf(MSG_DEBUG, "NAN: Assigned new subscribe handle %d for %s",
- subscribe_id, service_name);
+ subscribe_id, service_name ? service_name : "Ranging");
srv->id = subscribe_id;
srv->is_p2p = p2p;
+ srv->is_pr = params->proximity_ranging && params->active;
nan_de_add_srv(de, srv);
nan_de_run_timer(de);
return subscribe_id;
diff --git a/src/common/nan_de.h b/src/common/nan_de.h
index 2900bab5c..7f0836332 100644
--- a/src/common/nan_de.h
+++ b/src/common/nan_de.h
@@ -110,6 +110,9 @@ struct nan_publish_params {
/* Announcement period in ms; 0 = use default */
unsigned int announcement_period;
+
+ /* Proximity ranging flag */
+ bool proximity_ranging;
};
/* Returns -1 on failure or >0 publish_id */
@@ -143,6 +146,9 @@ struct nan_subscribe_params {
/* Query period in ms; 0 = use default */
unsigned int query_period;
+
+ /* Proximity ranging flag */
+ bool proximity_ranging;
};
/* Returns -1 on failure or >0 subscribe_id */
diff --git a/src/common/proximity_ranging.c b/src/common/proximity_ranging.c
index 287bff2f7..ab61f6e3a 100644
--- a/src/common/proximity_ranging.c
+++ b/src/common/proximity_ranging.c
@@ -51,3 +51,54 @@ void pr_deinit(struct pr_data *pr)
os_free(pr);
wpa_printf(MSG_DEBUG, "PR: Deinit done");
}
+
+
+static struct wpabuf * pr_encaps_ie(const struct wpabuf *subelems, u32 ie_type)
+{
+ struct wpabuf *ie = NULL;
+ const u8 *pos, *end;
+ size_t len = 0;
+
+ if (!subelems)
+ return NULL;
+
+ len = wpabuf_len(subelems) + 1000;
+
+ ie = wpabuf_alloc(len);
+
+ if (!ie)
+ return NULL;
+
+ pos = wpabuf_head(subelems);
+ end = pos + wpabuf_len(subelems);
+
+ while (end > pos) {
+ size_t frag_len = end - pos;
+
+ if (frag_len > 251)
+ frag_len = 251;
+ wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
+ wpabuf_put_u8(ie, 4 + frag_len);
+ wpabuf_put_be32(ie, ie_type);
+ wpabuf_put_data(ie, pos, frag_len);
+ pos += frag_len;
+ }
+ return ie;
+}
+
+
+struct wpabuf * pr_prepare_usd_elems(struct pr_data *pr, const char *country)
+{
+ u32 ie_type;
+ struct wpabuf *buf, *buf2;
+
+ buf = wpabuf_alloc(1000);
+ if (!buf)
+ return NULL;
+
+ ie_type = (OUI_WFA << 8) | PR_OUI_TYPE;
+ buf2 = pr_encaps_ie(buf, ie_type);
+ wpabuf_free(buf);
+
+ return buf2;
+}
diff --git a/src/common/proximity_ranging.h b/src/common/proximity_ranging.h
index 9992c005c..8ebc363c1 100644
--- a/src/common/proximity_ranging.h
+++ b/src/common/proximity_ranging.h
@@ -145,5 +145,6 @@ 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);
#endif /* PROXIMITY_RANGING_H */
diff --git a/wpa_supplicant/nan_usd.c b/wpa_supplicant/nan_usd.c
index b2d195ca7..68b2e6521 100644
--- a/wpa_supplicant/nan_usd.c
+++ b/wpa_supplicant/nan_usd.c
@@ -16,6 +16,7 @@
#include "notify.h"
#include "p2p_supplicant.h"
#include "nan_usd.h"
+#include "pr_supplicant.h"
static const char *
@@ -388,11 +389,19 @@ int wpas_nan_usd_publish(struct wpa_supplicant *wpa_s, const char *service_name,
if (!wpa_s->nan_de)
return -1;
+ if (params->proximity_ranging && !params->solicited) {
+ wpa_printf(MSG_ERROR,
+ "PR unsolicited publish service discovery not allowed");
+ return -1;
+ }
+
+ addr = wpa_s->own_addr;
+
if (p2p) {
elems = wpas_p2p_usd_elems(wpa_s, service_name);
addr = wpa_s->global->p2p_dev_addr;
- } else {
- addr = wpa_s->own_addr;
+ } else if (params->proximity_ranging) {
+ elems = wpas_pr_usd_elems(wpa_s);
}
publish_id = nan_de_publish(wpa_s->nan_de, service_name, srv_proto_type,
@@ -460,11 +469,19 @@ int wpas_nan_usd_subscribe(struct wpa_supplicant *wpa_s,
if (!wpa_s->nan_de)
return -1;
+ if (params->proximity_ranging && !params->active) {
+ wpa_printf(MSG_ERROR,
+ "PR passive subscriber service discovery not allowed");
+ return -1;
+ }
+
+ addr = wpa_s->own_addr;
+
if (p2p) {
elems = wpas_p2p_usd_elems(wpa_s, service_name);
addr = wpa_s->global->p2p_dev_addr;
- } else {
- addr = wpa_s->own_addr;
+ } else if (params->proximity_ranging) {
+ elems = wpas_pr_usd_elems(wpa_s);
}
subscribe_id = nan_de_subscribe(wpa_s->nan_de, service_name,
diff --git a/wpa_supplicant/pr_supplicant.c b/wpa_supplicant/pr_supplicant.c
index 308eac9b1..59955d6dc 100644
--- a/wpa_supplicant/pr_supplicant.c
+++ b/wpa_supplicant/pr_supplicant.c
@@ -74,6 +74,12 @@ static int wpas_pr_setup_channels(struct wpa_supplicant *wpa_s,
return 0;
}
+struct wpabuf * wpas_pr_usd_elems(struct wpa_supplicant *wpa_s)
+{
+ return pr_prepare_usd_elems(wpa_s->global->pr, wpa_s->conf->country);
+}
+
+
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 fc8019dda..b2469781a 100644
--- a/wpa_supplicant/pr_supplicant.h
+++ b/wpa_supplicant/pr_supplicant.h
@@ -15,6 +15,7 @@
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);
#else /* CONFIG_PR */
static inline int wpas_pr_init(struct wpa_global *global,
struct wpa_supplicant *wpa_s)
@@ -26,6 +27,11 @@ static inline void wpas_pr_deinit(struct wpa_supplicant *wpa_s)
{
}
+static inline struct wpabuf * wpas_pr_usd_elems(struct wpa_supplicant *wpa_s)
+{
+ return NULL;
+}
+
#endif /* CONFIG_PR */
#endif /*PR_SUPPLICANT_H */
--
2.34.1
More information about the Hostap
mailing list