Accumulative patch from commit 17b8995cf5813d7c027cd7a6884700e791d72392
17b8995 Interworking: Try to use same BSS entry for storing GAS results
3db5439 Optimize Extended Capabilities element to be of minimal length
8cd6b7b hostapd/wpa_s: Use driver's extended capabilities
acb5464 Add ctrl_iface command FLUSH for clearing wpa_supplicant state
97236ce WPS: Skip rescanning after provisioning if AP was configured
4342326 Add ignore_old_scan_res configuration parameter
9599ccc WPS: Clear after_wps on new WPS connection
702621e WPS: Use latest updated BSS entry if multiple BSSID matches found
ab547b5 WPS: Add more helpful debug for invalid WPS_REG command parsing
a679c0f WPS: Allow hostapd process to control independent WPS interfaces
ccdff94 WPS AP: Add support for reconfiguration with in-memory config
8970bae nl80211: Use nla_nest_start/end instead of nla_put_nested
558d69e P2P: Omit P2P Group Info in case of no connected peers
65a32cd AP: Fix infinite loop in WPA state machine when out of random bytes
a5f61b2 Fix OLBC non-HT AP detection to check channel
69554d7 ap_list: Remove unused functions
08c99ca ap_list: Remove unused iteration list pointers
6b16917 ap_list: Remove unused fields
66f1f75 P2P: Fix provision discovery response handling in some cases
2f9b66d Extend ROAM command to handle multiple SSIDs per BSS
Change-Id: I46002b1d3bbf6e376c2ae09bcb2c824c54805bbd
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 6fb1cae..a6478b6 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1184,30 +1184,67 @@
}
+static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
+{
+ *pos = 0x00;
+
+ switch (idx) {
+ case 0: /* Bits 0-7 */
+ break;
+ case 1: /* Bits 8-15 */
+ break;
+ case 2: /* Bits 16-23 */
+#ifdef CONFIG_WNM
+ *pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */
+ *pos |= 0x08; /* Bit 19 - BSS Transition */
+#endif /* CONFIG_WNM */
+ break;
+ case 3: /* Bits 24-31 */
+#ifdef CONFIG_WNM
+ *pos |= 0x02; /* Bit 25 - SSID List */
+#endif /* CONFIG_WNM */
+#ifdef CONFIG_INTERWORKING
+ if (wpa_s->conf->interworking)
+ *pos |= 0x80; /* Bit 31 - Interworking */
+#endif /* CONFIG_INTERWORKING */
+ break;
+ case 4: /* Bits 32-39 */
+ break;
+ case 5: /* Bits 40-47 */
+ break;
+ case 6: /* Bits 48-55 */
+ break;
+ }
+}
+
+
int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf)
{
- u32 ext_capab = 0;
u8 *pos = buf;
+ u8 len = 4, i;
-#ifdef CONFIG_INTERWORKING
- if (wpa_s->conf->interworking)
- ext_capab |= BIT(31); /* Interworking */
-#endif /* CONFIG_INTERWORKING */
-
-#ifdef CONFIG_WNM
- ext_capab |= BIT(17); /* WNM-Sleep Mode */
- ext_capab |= BIT(19); /* BSS Transition */
-#endif /* CONFIG_WNM */
-
- if (!ext_capab)
- return 0;
+ if (len < wpa_s->extended_capa_len)
+ len = wpa_s->extended_capa_len;
*pos++ = WLAN_EID_EXT_CAPAB;
- *pos++ = 4;
- WPA_PUT_LE32(pos, ext_capab);
- pos += 4;
+ *pos++ = len;
+ for (i = 0; i < len; i++, pos++) {
+ wpas_ext_capab_byte(wpa_s, pos, i);
- return pos - buf;
+ if (i < wpa_s->extended_capa_len) {
+ *pos &= ~wpa_s->extended_capa_mask[i];
+ *pos |= wpa_s->extended_capa[i];
+ }
+ }
+
+ while (len > 0 && buf[1 + len] == 0) {
+ len--;
+ buf[1] = len;
+ }
+ if (len == 0)
+ return 0;
+
+ return 2 + len;
}
@@ -2925,6 +2962,9 @@
wpa_s->max_match_sets = capa.max_match_sets;
wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
wpa_s->max_stations = capa.max_stations;
+ wpa_s->extended_capa = capa.extended_capa;
+ wpa_s->extended_capa_mask = capa.extended_capa_mask;
+ wpa_s->extended_capa_len = capa.extended_capa_len;
}
if (wpa_s->max_remain_on_chan == 0)
wpa_s->max_remain_on_chan = 1000;