Add changes to the Proximity Ranging Information Element (PR IE) required for the PASN Auth1 frame. This frame includes ranging capabilities, capabilities specific to ranging type (EDCA/NTB), and the proposed operation mode. The operation mode contains the proposed ranging role, ranging type, and channel list. These parameters will be negotiated through subsequent PASN frames. Signed-off-by: Peddolla Harshavardhan Reddy <peddolla@xxxxxxxxxxxxxxxx> --- src/common/proximity_ranging.c | 138 +++++++++++++++++++++++++++++++++ src/common/proximity_ranging.h | 12 +++ 2 files changed, 150 insertions(+) diff --git a/src/common/proximity_ranging.c b/src/common/proximity_ranging.c index 7fb64d47a..f2e7dbf60 100644 --- a/src/common/proximity_ranging.c +++ b/src/common/proximity_ranging.c @@ -427,6 +427,30 @@ static int pr_validate_dira(struct pr_data *pr, struct pr_device *dev, } +#ifdef CONFIG_PASN + +static void pr_copy_channels(struct pr_channels *dst, + const struct pr_channels *src, bool allow_6ghz) +{ + size_t i, j; + + if (allow_6ghz) { + os_memcpy(dst, src, sizeof(struct pr_channels)); + return; + } + + for (i = 0, j = 0; i < src->op_classes; i++) { + if (is_6ghz_op_class(src->op_class[i].op_class)) + continue; + os_memcpy(&dst->op_class[j], &src->op_class[i], + sizeof(struct pr_op_class)); + j++; + } + dst->op_classes = j; +} + +#endif /* CONFIG_PASN */ + static void pr_buf_add_channel_list(struct wpabuf *buf, const char *country, struct pr_channels *chan) { @@ -993,6 +1017,103 @@ void pr_process_usd_elems(struct pr_data *pr, const u8 *ies, u16 ies_len, #ifdef CONFIG_PASN +static void pr_buf_add_operation_mode(struct wpabuf *buf, + struct operation_mode *mode) +{ + u8 *len; + + wpabuf_put_u8(buf, PR_ATTR_OPERATION_MODE); + /* Length to be filled */ + len = wpabuf_put(buf, 2); + + wpabuf_put_u8(buf, mode->protocol_type); + wpabuf_put_u8(buf, mode->role); + pr_buf_add_channel_list(buf, mode->country, &mode->channels); + + /* Update attribute length */ + WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2); + wpa_hexdump(MSG_DEBUG, "PR: * Operation Mode", + len + 2, (u8 *) wpabuf_put(buf, 0) - len - 2); +} + + +static int pr_prepare_pasn_pr_ie(struct pr_data *pr, struct wpabuf *extra_ies, + bool add_dira, u8 ranging_role, + u8 ranging_type, int forced_pr_freq) +{ + u32 ie_type; + struct wpabuf *buf, *buf2; + struct pr_dira dira; + struct pr_capabilities pr_caps; + struct edca_capabilities edca_caps; + struct ntb_capabilities ntb_caps; + struct operation_mode op_mode; + struct pr_channels op_channels; + u8 forced_op_class = 0, forced_op_channel = 0; + enum hostapd_hw_mode hw_mode; + + buf = wpabuf_alloc(1000); + if (!buf) + return -1; + + pr_get_ranging_capabilities(pr, &pr_caps); + pr_buf_add_ranging_capa_info(buf, &pr_caps); + + if (ranging_type & PR_EDCA_BASED_RANGING) { + pr_get_edca_capabilities(pr, &edca_caps); + pr_buf_add_edca_capa_info(buf, &edca_caps); + pr_copy_channels(&op_channels, &edca_caps.channels, false); + } else if (ranging_type & PR_NTB_OPEN_BASED_RANGING || + ranging_type & PR_NTB_SECURE_LTF_BASED_RANGING) { + pr_get_ntb_capabilities(pr, &ntb_caps); + pr_buf_add_ntb_capa_info(buf, &ntb_caps); + pr_copy_channels(&op_channels, &ntb_caps.channels, false); + } + + os_memset(&op_mode, 0, sizeof(struct operation_mode)); + op_mode.role = ranging_role; + op_mode.protocol_type = ranging_type; + os_memcpy(op_mode.country, pr->cfg->country, 3); + + if (forced_pr_freq) { + hw_mode = ieee80211_freq_to_channel_ext(forced_pr_freq, 0, 0, + &forced_op_class, + &forced_op_channel); + if (hw_mode == NUM_HOSTAPD_MODES) { + wpa_printf(MSG_DEBUG, "PR: Invalid PR freq received"); + wpabuf_free(buf); + return -1; + } + + op_mode.channels.op_classes = 1; + op_mode.channels.op_class[0].channels = 1; + op_mode.channels.op_class[0].channel[0] = forced_op_channel; + op_mode.channels.op_class[0].op_class = forced_op_class; + } else { + pr_copy_channels(&op_mode.channels, &op_channels, false); + } + + pr_buf_add_operation_mode(buf, &op_mode); + + /* PR Device Identity Resolution attribute */ + if (!pr_derive_dira(pr, &dira)) + pr_buf_add_dira(buf, &dira); + + ie_type = (OUI_WFA << 8) | PR_OUI_TYPE; + buf2 = pr_encaps_ie(buf, ie_type); + wpabuf_free(buf); + + if (wpabuf_tailroom(extra_ies) < wpabuf_len(buf2)) { + wpa_printf(MSG_ERROR, + "Not enough room for PR IE in PASN Frame"); + wpabuf_free(buf2); + return -1; + } + wpabuf_put_buf(extra_ies, buf2); + wpabuf_free(buf2); + + return 0; +} static struct wpabuf * pr_pasn_generate_rsnxe(struct pr_data *pr, int akmp) @@ -1186,6 +1307,7 @@ int pr_initiate_pasn_auth(struct pr_data *pr, const u8 *addr, int freq, struct pasn_data *pasn; struct pr_device *dev; u8 pmkid[PMKID_LEN]; + struct wpabuf *extra_ies; if (!addr) { wpa_printf(MSG_DEBUG, "Peer address NULL"); @@ -1213,6 +1335,20 @@ int pr_initiate_pasn_auth(struct pr_data *pr, const u8 *addr, int freq, } pasn = dev->pasn; + extra_ies = wpabuf_alloc(1500); + if (!extra_ies) + return -1; + + if (pr_prepare_pasn_pr_ie(pr, extra_ies, false, ranging_role, + ranging_type, forced_pr_freq)) { + wpa_printf(MSG_ERROR, "Failed to prepare PASN extra elements"); + ret = -1; + goto out; + } + + pasn_set_extra_ies(dev->pasn, wpabuf_head_u8(extra_ies), + wpabuf_len(extra_ies)); + if (auth_mode == PR_PASN_AUTH_MODE_PMK) { ret = wpa_pasn_verify(pasn, pasn->own_addr, pasn->peer_addr, pasn->bssid, pasn->akmp, pasn->cipher, @@ -1227,6 +1363,8 @@ int pr_initiate_pasn_auth(struct pr_data *pr, const u8 *addr, int freq, if (ret) wpa_printf(MSG_ERROR, "PR: Failed to start PASN"); +out: + wpabuf_free(extra_ies); return ret; } diff --git a/src/common/proximity_ranging.h b/src/common/proximity_ranging.h index 9a898d2bb..498697828 100644 --- a/src/common/proximity_ranging.h +++ b/src/common/proximity_ranging.h @@ -406,6 +406,18 @@ struct pr_dira { size_t tag_len; }; +struct operation_mode { + /* Bit map for Ranging Protocol type */ + u8 protocol_type; + + /* Bit map for Role-ISTA/RSTA */ + u8 role; + + char country[3]; + + struct pr_channels channels; +}; + struct pr_data * pr_init(const struct pr_config *cfg); void pr_deinit(struct pr_data *pr); void pr_clear_dev_iks(struct pr_data *pr); -- 2.34.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap