From f8361e3d681e55efead2aac79fedf4b232d533fb Mon Sep 17 00:00:00 2001 From: Sunil Dutt Date: Mon, 25 Feb 2013 10:31:50 +0200 Subject: [PATCH] TDLS: Pass peer's VHT Capability information during sta_add The information of the peer's VHT capability is required for the driver to establish a TDLS link in VHT mode with a compatible peer. Pass this information to the driver when the peer station is getting added. Signed-hostap: Jouni Malinen --- src/rsn_supp/tdls.c | 46 ++++++++++++++++++++++++++++++++++---- src/rsn_supp/wpa.h | 1 + src/rsn_supp/wpa_i.h | 5 +++-- src/rsn_supp/wpa_ie.c | 3 +++ src/rsn_supp/wpa_ie.h | 2 ++ wpa_supplicant/wpas_glue.c | 2 ++ 6 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c index 09adc194d..09abdbbc0 100644 --- a/src/rsn_supp/tdls.c +++ b/src/rsn_supp/tdls.c @@ -122,6 +122,7 @@ struct wpa_tdls_peer { size_t supp_rates_len; struct ieee80211_ht_capabilities *ht_capabilities; + struct ieee80211_vht_capabilities *vht_capabilities; u8 qos_info; @@ -620,6 +621,8 @@ static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer) peer->sm_tmr.buf = NULL; os_free(peer->ht_capabilities); peer->ht_capabilities = NULL; + os_free(peer->vht_capabilities); + peer->vht_capabilities = NULL; os_free(peer->ext_capab); peer->ext_capab = NULL; peer->rsnie_i_len = peer->rsnie_p_len = 0; @@ -1370,6 +1373,34 @@ static int copy_peer_ht_capab(const struct wpa_eapol_ie_parse *kde, } +static int copy_peer_vht_capab(const struct wpa_eapol_ie_parse *kde, + struct wpa_tdls_peer *peer) +{ + if (!kde->vht_capabilities || + kde->vht_capabilities_len < + sizeof(struct ieee80211_vht_capabilities) ) { + wpa_printf(MSG_DEBUG, "TDLS: No supported vht capabilities " + "received"); + return 0; + } + + if (!peer->vht_capabilities) { + peer->vht_capabilities = + os_zalloc(sizeof(struct ieee80211_vht_capabilities)); + if (peer->vht_capabilities == NULL) + return -1; + } + + os_memcpy(peer->vht_capabilities, kde->vht_capabilities, + sizeof(struct ieee80211_vht_capabilities)); + wpa_hexdump(MSG_DEBUG, "TDLS: Peer VHT capabilities", + (u8 *) peer->vht_capabilities, + sizeof(struct ieee80211_vht_capabilities)); + + return 0; +} + + static int copy_peer_ext_capab(const struct wpa_eapol_ie_parse *kde, struct wpa_tdls_peer *peer) { @@ -1466,6 +1497,9 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr, if (copy_peer_ht_capab(&kde, peer) < 0) goto error; + if (copy_peer_vht_capab(&kde, peer) < 0) + goto error; + if (copy_peer_ext_capab(&kde, peer) < 0) goto error; @@ -1694,7 +1728,7 @@ skip_rsn: skip_rsn_check: /* add the peer to the driver as a "setup in progress" peer */ - wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, 0, + wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, NULL, 0, NULL, 0); wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Response / TPK M2"); @@ -1738,8 +1772,9 @@ static void wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer) /* add supported rates, capabilities, and qos_info to the TDLS peer */ wpa_sm_tdls_peer_addset(sm, peer->addr, 0, peer->capability, peer->supp_rates, peer->supp_rates_len, - peer->ht_capabilities, peer->qos_info, - peer->ext_capab, peer->ext_capab_len); + peer->ht_capabilities, peer->vht_capabilities, + peer->qos_info, peer->ext_capab, + peer->ext_capab_len); wpa_sm_tdls_oper(sm, TDLS_ENABLE_LINK, peer->addr); } @@ -1838,6 +1873,9 @@ static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr, if (copy_peer_ht_capab(&kde, peer) < 0) goto error; + if (copy_peer_vht_capab(&kde, peer) < 0) + goto error; + if (copy_peer_ext_capab(&kde, peer) < 0) goto error; @@ -2146,7 +2184,7 @@ int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr) peer->initiator = 1; /* add the peer to the driver as a "setup in progress" peer */ - wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, 0, + wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, NULL, 0, NULL, 0); if (wpa_tdls_send_tpk_m1(sm, peer) < 0) { diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index 6679dda54..dbb493e4e 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -60,6 +60,7 @@ struct wpa_sm_ctx { u16 capability, const u8 *supp_rates, size_t supp_rates_len, const struct ieee80211_ht_capabilities *ht_capab, + const struct ieee80211_vht_capabilities *vht_capab, u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len); #endif /* CONFIG_TDLS */ diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 5dae5de8e..877e6de11 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -285,14 +285,15 @@ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add, u16 capability, const u8 *supp_rates, size_t supp_rates_len, const struct ieee80211_ht_capabilities *ht_capab, + const struct ieee80211_vht_capabilities *vht_capab, u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len) { if (sm->ctx->tdls_peer_addset) return sm->ctx->tdls_peer_addset(sm->ctx->ctx, addr, add, capability, supp_rates, supp_rates_len, ht_capab, - qosinfo, ext_capab, - ext_capab_len); + vht_capab, qosinfo, + ext_capab, ext_capab_len); return -1; } #endif /* CONFIG_TDLS */ diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c index 252737f21..652197ffd 100644 --- a/src/rsn_supp/wpa_ie.c +++ b/src/rsn_supp/wpa_ie.c @@ -430,6 +430,9 @@ int wpa_supplicant_parse_ies(const u8 *buf, size_t len, } else if (*pos == WLAN_EID_HT_CAP) { ie->ht_capabilities = pos + 2; ie->ht_capabilities_len = pos[1]; + } else if (*pos == WLAN_EID_VHT_CAP) { + ie->vht_capabilities = pos + 2; + ie->vht_capabilities_len = pos[1]; } else if (*pos == WLAN_EID_QOS && pos[1] >= 1) { ie->qosinfo = pos[2]; } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) { diff --git a/src/rsn_supp/wpa_ie.h b/src/rsn_supp/wpa_ie.h index b212711f2..82a5c08ce 100644 --- a/src/rsn_supp/wpa_ie.h +++ b/src/rsn_supp/wpa_ie.h @@ -51,6 +51,8 @@ struct wpa_eapol_ie_parse { size_t ext_supp_rates_len; const u8 *ht_capabilities; size_t ht_capabilities_len; + const u8 *vht_capabilities; + size_t vht_capabilities_len; u8 qosinfo; }; diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c index dfc3b7692..7585b867e 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -554,6 +554,7 @@ static int wpa_supplicant_tdls_peer_addset( void *ctx, const u8 *peer, int add, u16 capability, const u8 *supp_rates, size_t supp_rates_len, const struct ieee80211_ht_capabilities *ht_capab, + const struct ieee80211_vht_capabilities *vht_capab, u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len) { struct wpa_supplicant *wpa_s = ctx; @@ -574,6 +575,7 @@ static int wpa_supplicant_tdls_peer_addset( params.flags |= WPA_STA_WMM; params.ht_capabilities = ht_capab; + params.vht_capabilities = vht_capab; params.qosinfo = qosinfo; params.listen_interval = 0; params.supp_rates = supp_rates;