Signed-off-by: Peddolla Harshavardhan Reddy <peddolla@xxxxxxxxxxxxxxxx> --- 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 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap