wpa_drv_get_ext_capa(wpa_s, type);
ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
- sizeof(ext_capab));
+ sizeof(ext_capab), NULL);
if (ext_capab_len > 0 &&
wpabuf_resize(&default_ies, ext_capab_len) == 0)
wpabuf_put_data(default_ies, ext_capab, ext_capab_len);
wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
- sizeof(ext_capab));
+ sizeof(ext_capab), NULL);
if (ext_capab_len > 0 &&
wpabuf_resize(&extra_ie, ext_capab_len) == 0)
wpabuf_put_data(extra_ie, ext_capab, ext_capab_len);
}
-static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
+static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx,
+ struct wpa_bss *bss)
{
bool scs = true, mscs = true;
if (wpa_s->disable_scs_support)
scs = false;
#endif /* CONFIG_TESTING_OPTIONS */
+ if (bss && !wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_SCS)) {
+ /* Drop own SCS capability indication since the AP does
+ * not support it. This is needed to avoid
+ * interoperability issues with APs that get confused
+ * with Extended Capabilities element. */
+ scs = false;
+ }
if (scs)
*pos |= 0x40; /* Bit 54 - SCS */
break;
if (wpa_s->disable_mscs_support)
mscs = false;
#endif /* CONFIG_TESTING_OPTIONS */
+ if (bss && !wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_MSCS)) {
+ /* Drop own MSCS capability indication since the AP does
+ * not support it. This is needed to avoid
+ * interoperability issues with APs that get confused
+ * with Extended Capabilities element. */
+ mscs = false;
+ }
if (mscs)
*pos |= 0x20; /* Bit 85 - Mirrored SCS */
break;
}
-int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen)
+int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf,
+ size_t buflen, struct wpa_bss *bss)
{
u8 *pos = buf;
u8 len = 11, i;
*pos++ = WLAN_EID_EXT_CAPAB;
*pos++ = len;
for (i = 0; i < len; i++, pos++) {
- wpas_ext_capab_byte(wpa_s, pos, i);
+ wpas_ext_capab_byte(wpa_s, pos, i, bss);
if (i < wpa_s->extended_capa_len) {
*pos &= ~wpa_s->extended_capa_mask[i];
u8 ext_capab[18];
int ext_capab_len;
ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
- sizeof(ext_capab));
+ sizeof(ext_capab), bss);
if (ext_capab_len > 0 &&
wpa_ie_len + ext_capab_len <= max_wpa_ie_len) {
u8 *pos = wpa_ie;
size_t ssid_len);
void wpas_request_connection(struct wpa_supplicant *wpa_s);
void wpas_request_disconnection(struct wpa_supplicant *wpa_s);
-int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen);
+int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen,
+ struct wpa_bss *bss);
int wpas_update_random_addr(struct wpa_supplicant *wpa_s,
enum wpas_mac_addr_style style,
struct wpa_ssid *ssid);