TDLS: Pass peer's VHT Capability information during sta_add
authorSunil Dutt <duttus@codeaurora.org>
Mon, 25 Feb 2013 08:31:50 +0000 (10:31 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 25 Feb 2013 08:31:50 +0000 (10:31 +0200)
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 <jouni@qca.qualcomm.com>

src/rsn_supp/tdls.c
src/rsn_supp/wpa.h
src/rsn_supp/wpa_i.h
src/rsn_supp/wpa_ie.c
src/rsn_supp/wpa_ie.h
wpa_supplicant/wpas_glue.c

index 09adc19..09abdbb 100644 (file)
@@ -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) {
index 6679dda..dbb493e 100644 (file)
@@ -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 */
index 5dae5de..877e6de 100644 (file)
@@ -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 */
index 252737f..652197f 100644 (file)
@@ -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) {
index b212711..82a5c08 100644 (file)
@@ -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;
 };
 
index dfc3b76..7585b86 100644 (file)
@@ -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;