}
+bool is_80plus_op_class(u8 op_class)
+{
+ /* Operating classes with "80+" behavior indication in Table E-4 */
+ return op_class == 130 || op_class == 135;
+}
+
+
static int is_11b(u8 rate)
{
return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
* channel center frequency index value, but it happens to be a 20 MHz
* channel and the channel number in the channel set would match the
* value in for the frequency center.
+ *
+ * Operating class value pair 128 and 130 is used to describe a 80+80
+ * MHz channel on the 5 GHz band. 130 is identified with "80+", so this
+ * is encoded with two octets 130 and 128. Similarly, operating class
+ * value pair 133 and 135 is used to describe a 80+80 MHz channel on
+ * the 6 GHz band (135 being the one with "80+" indication). All other
+ * operating classes listed here are used as 1-octet values.
*/
{ HOSTAPD_MODE_IEEE80211A, 128, 36, 177, 4, BW80, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 129, 36, 177, 4, BW160, P2P_SUPP },
+ { HOSTAPD_MODE_IEEE80211A, 130, 36, 177, 4, BW80P80, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 131, 1, 233, 4, BW20, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 132, 1, 233, 8, BW40, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 133, 1, 233, 16, BW80, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211AD, 182, 17, 20, 1, BW6480, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211AD, 183, 25, 27, 1, BW8640, P2P_SUPP },
- /* Keep the operating class 130 as the last entry as a workaround for
- * the OneHundredAndThirty Delimiter value used in the Supported
- * Operating Classes element to indicate the end of the Operating
- * Classes field. */
- { HOSTAPD_MODE_IEEE80211A, 130, 36, 177, 4, BW80P80, P2P_SUPP },
{ -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
};
u8 op, current, chan;
u8 *ie_len;
size_t res;
+ bool op128 = false, op130 = false, op133 = false, op135 = false;
/*
* Determine the current operating class correct mode based on
wpabuf_put_u8(buf, current);
for (op = 0; global_op_class[op].op_class; op++) {
- if (wpas_op_class_supported(wpa_s, ssid, &global_op_class[op]))
- wpabuf_put_u8(buf, global_op_class[op].op_class);
+ bool supp;
+ u8 op_class = global_op_class[op].op_class;
+
+ supp = wpas_op_class_supported(wpa_s, ssid,
+ &global_op_class[op]);
+ if (!supp)
+ continue;
+ switch (op_class) {
+ case 128:
+ op128 = true;
+ break;
+ case 130:
+ op130 = true;
+ break;
+ case 133:
+ op133 = true;
+ break;
+ case 135:
+ op135 = true;
+ break;
+ }
+ if (is_80plus_op_class(op_class))
+ continue;
+
+ /* Add a 1-octet operating class to the Operating Class field */
+ wpabuf_put_u8(buf, global_op_class[op].op_class);
+ }
+
+ /* Add the 2-octet operating classes (i.e., 80+80 MHz cases), if any */
+ if ((op128 && op130) || (op133 && op135)) {
+ /* Operating Class Duple Sequence field */
+
+ /* Zero Delimiter */
+ wpabuf_put_u8(buf, 0);
+
+ /* Operating Class Duple List */
+ if (op128 && op130) {
+ wpabuf_put_u8(buf, 130);
+ wpabuf_put_u8(buf, 128);
+ }
+ if (op133 && op135) {
+ wpabuf_put_u8(buf, 135);
+ wpabuf_put_u8(buf, 133);
+ }
}
*ie_len = wpabuf_len(buf) - 2;