From 8b3b803ab9fe69650da7e3b2ee9e44f0f054ee0a Mon Sep 17 00:00:00 2001 From: Arif Hussain Date: Wed, 2 Oct 2013 07:38:35 -0700 Subject: [PATCH] Include Extended Capabilities element based on scan results Add Extended Capabilities element to association request only if the AP included this element in Beacon/Probe Response frames. This is a workaround to address interoperability issues with some older APs that do not seem to be able to handle Extended Capabilities element in (Re)Association Request frames. Signed-hostap: Jouni Malinen --- wpa_supplicant/wpa_supplicant.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index eab1c39a4..99e48eb6b 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1278,8 +1278,6 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, int wep_keys_set = 0; int assoc_failed = 0; struct wpa_ssid *old_ssid; - u8 ext_capab[10]; - int ext_capab_len; #ifdef CONFIG_HT_OVERRIDES struct ieee80211_ht_capabilities htcaps; struct ieee80211_ht_capabilities htcaps_mask; @@ -1491,15 +1489,27 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, } #endif /* CONFIG_HS20 */ - ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab); - if (ext_capab_len > 0) { - u8 *pos = wpa_ie; - if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN) - pos += 2 + pos[1]; - os_memmove(pos + ext_capab_len, pos, - wpa_ie_len - (pos - wpa_ie)); - wpa_ie_len += ext_capab_len; - os_memcpy(pos, ext_capab, ext_capab_len); + /* + * Workaround: Add Extended Capabilities element only if the AP + * included this element in Beacon/Probe Response frames. Some older + * APs seem to have interoperability issues if this element is + * included, so while the standard may require us to include the + * element in all cases, it is justifiable to skip it to avoid + * interoperability issues. + */ + if (!bss || wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB)) { + u8 ext_capab[10]; + int ext_capab_len; + ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab); + if (ext_capab_len > 0) { + u8 *pos = wpa_ie; + if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN) + pos += 2 + pos[1]; + os_memmove(pos + ext_capab_len, pos, + wpa_ie_len - (pos - wpa_ie)); + wpa_ie_len += ext_capab_len; + os_memcpy(pos, ext_capab, ext_capab_len); + } } wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);