From 2974dde2aa3273451b6a51c33a30fc98cee10b25 Mon Sep 17 00:00:00 2001 From: Pradeep Kumar Chitrapu Date: Sat, 30 Jan 2021 10:15:52 -0800 Subject: [PATCH 1/4] hostapd: Add country Information element support for 6Ghz Signed-off-by: Pradeep Kumar Chitrapu --- src/ap/beacon.c | 66 +++++++++++++++++++++++++----------- src/common/ieee802_11_defs.h | 10 ++++++ 2 files changed, 56 insertions(+), 20 deletions(-) --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -187,7 +187,8 @@ static u8 * hostapd_eid_pwr_constraint(s } -static u8 * hostapd_eid_country_add(u8 *pos, u8 *end, int chan_spacing, +static u8 * hostapd_eid_country_add(struct hostapd_data *hapd, u8 *pos, + u8 *end, int chan_spacing, struct hostapd_channel_data *start, struct hostapd_channel_data *prev) { @@ -199,30 +200,20 @@ static u8 * hostapd_eid_country_add(u8 * /* number of channels */ *pos++ = (prev->chan - start->chan) / chan_spacing + 1; /* maximum transmit power level */ - *pos++ = start->max_tx_power; + if (!is_6ghz_op_class(hapd->iconf->op_class)) + *pos++ = start->max_tx_power; + else + *pos++ = 0; /* Reserved for 6GHz Band */ return pos; } - -static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid, - int max_len) +static u8 * hostapd_fill_triplets(struct hostapd_data *hapd, u8 *pos, + u8 *end) { - u8 *pos = eid; - u8 *end = eid + max_len; - int i; struct hostapd_hw_modes *mode; struct hostapd_channel_data *start, *prev; - int chan_spacing = 1; - - if (!hapd->iconf->ieee80211d || max_len < 6 || - hapd->iface->current_mode == NULL) - return eid; - - *pos++ = WLAN_EID_COUNTRY; - pos++; /* length will be set later */ - os_memcpy(pos, hapd->iconf->country, 3); /* e.g., 'US ' */ - pos += 3; + int i, chan_spacing = 1; mode = hapd->iface->current_mode; if (mode->mode == HOSTAPD_MODE_IEEE80211A) @@ -233,6 +224,7 @@ static u8 * hostapd_eid_country(struct h struct hostapd_channel_data *chan = &mode->channels[i]; if (chan->flag & HOSTAPD_CHAN_DISABLED) continue; + if (start && prev && prev->chan + chan_spacing == chan->chan && start->max_tx_power == chan->max_tx_power) { @@ -241,7 +233,8 @@ static u8 * hostapd_eid_country(struct h } if (start && prev) { - pos = hostapd_eid_country_add(pos, end, chan_spacing, + pos = hostapd_eid_country_add(hapd, pos, end, + chan_spacing, start, prev); start = NULL; } @@ -251,10 +244,48 @@ static u8 * hostapd_eid_country(struct h } if (start) { - pos = hostapd_eid_country_add(pos, end, chan_spacing, + pos = hostapd_eid_country_add(hapd, pos, end, + chan_spacing, start, prev); } + return pos; +} + +static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid, + int max_len) +{ + u8 *pos = eid; + u8 *end = eid + max_len; + + if (!hapd->iconf->ieee80211d || max_len < 6 || + hapd->iface->current_mode == NULL) + return eid; + + *pos++ = WLAN_EID_COUNTRY; + pos++; /* length will be set later */ + os_memcpy(pos, hapd->iconf->country, 3); /* e.g., 'US ' */ + pos += 3; + + if (is_6ghz_op_class(hapd->iconf->op_class)) { + /* Third octet of the country string to indicate + * Global Operating Class + */ + eid[4] = 0x4; + + *pos++ = WLAN_EID_EXT_OPERATING_TRIPLET; + /* Operating class*/ + *pos++ = hapd->iconf->op_class; + /* Coverage Class */ + *pos++ = 0; + /* Subband Triplets are required only for 20MHz case */ + if (hapd->iconf->op_class == 131 || + hapd->iconf->op_class == 136) + pos = hostapd_fill_triplets(hapd, pos, end); + } else { + pos = hostapd_fill_triplets(hapd, pos, end); + } + if ((pos - eid) & 1) { if (end - pos < 1) return eid; --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -494,6 +494,16 @@ #define WLAN_EID_EXT_ANTI_CLOGGING_TOKEN 93 #define WLAN_EID_EXT_PASN_PARAMS 100 +/* Operating Triplet can be any integer >= 201 + * From IEEE P802.11-REVmd/D4.0: The first octet in each Subband + * Triplet field or Operating Triplet field contains an unsigned + * integer and identifies the type of field. If the integer has + * a value less than or equal to 200, then the field is a + * Subband Triplet field. If the integer has a value of 201 or + * greater, then the field is an Operating Triplet field. + */ +#define WLAN_EID_EXT_OPERATING_TRIPLET 201 + /* Extended Capabilities field */ #define WLAN_EXT_CAPAB_20_40_COEX 0 #define WLAN_EXT_CAPAB_GLK 1