[FIX 1] Correct op class and chan for HE PHY
Trevor North
trevor at freedisc.co.uk
Mon Jan 26 02:27:39 PST 2026
This leverages the more recently added get_operation_channel_width
to maintain return of the correct operating class and channel when a HE
PHY type is determined.
Signed-off-by: Trevor North <trevor at freedisc.co.uk>
---
wpa_supplicant/rrm.c | 66 ++++++++++++++--------------------------
wpa_supplicant/wnm_sta.c | 48 ++++++++++++++---------------
2 files changed, 45 insertions(+), 69 deletions(-)
diff --git a/wpa_supplicant/rrm.c b/wpa_supplicant/rrm.c
index dabbf8cfa..dc8374350 100644
--- a/wpa_supplicant/rrm.c
+++ b/wpa_supplicant/rrm.c
@@ -751,18 +751,24 @@ static int * wpas_beacon_request_freqs(struct wpa_supplicant *wpa_s,
int wpas_get_op_chan_phy(int freq, const u8 *ies, size_t ies_len,
u8 *op_class, u8 *chan, u8 *phy_type)
{
- const u8 *ie;
- int sec_chan = 0, vht = 0;
- struct ieee80211_ht_operation *ht_oper = NULL;
- struct ieee80211_vht_operation *vht_oper = NULL;
- u8 seg0, seg1;
-
- ie = get_ie(ies, ies_len, WLAN_EID_HT_OPERATION);
- if (ie && ie[1] >= sizeof(struct ieee80211_ht_operation)) {
- u8 sec_chan_offset;
-
- ht_oper = (struct ieee80211_ht_operation *) (ie + 2);
- sec_chan_offset = ht_oper->ht_param &
+ int sec_chan = 0, chanwidth = 0;
+ struct ieee802_11_elems elems;
+ struct ieee80211_ht_operation *ht_oper;
+
+ if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) {
+ return -1;
+ }
+
+ chanwidth = get_operation_channel_width(&elems);
+ if (chanwidth == CHAN_WIDTH_UNKNOWN) {
+ wpa_printf(MSG_DEBUG,
+ "Cannot determine channel width");
+ return -1;
+ }
+
+ ht_oper = (struct ieee80211_ht_operation *) elems.ht_operation;
+ if (ht_oper) {
+ u8 sec_chan_offset = ht_oper->ht_param &
HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
if (sec_chan_offset == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE)
sec_chan = 1;
@@ -771,44 +777,16 @@ int wpas_get_op_chan_phy(int freq, const u8 *ies, size_t ies_len,
sec_chan = -1;
}
- ie = get_ie(ies, ies_len, WLAN_EID_VHT_OPERATION);
- if (ie && ie[1] >= sizeof(struct ieee80211_vht_operation)) {
- vht_oper = (struct ieee80211_vht_operation *) (ie + 2);
-
- switch (vht_oper->vht_op_info_chwidth) {
- case CHANWIDTH_80MHZ:
- seg0 = vht_oper->vht_op_info_chan_center_freq_seg0_idx;
- seg1 = vht_oper->vht_op_info_chan_center_freq_seg1_idx;
- if (seg1 && abs(seg1 - seg0) == 8)
- vht = CONF_OPER_CHWIDTH_160MHZ;
- else if (seg1)
- vht = CONF_OPER_CHWIDTH_80P80MHZ;
- else
- vht = CONF_OPER_CHWIDTH_80MHZ;
- break;
- case CHANWIDTH_160MHZ:
- vht = CONF_OPER_CHWIDTH_160MHZ;
- break;
- case CHANWIDTH_80P80MHZ:
- vht = CONF_OPER_CHWIDTH_80P80MHZ;
- break;
- default:
- vht = CONF_OPER_CHWIDTH_USE_HT;
- break;
- }
- }
-
- if (ieee80211_freq_to_channel_ext(freq, sec_chan, vht, op_class,
+ if (ieee80211_chaninfo_to_channel(freq, chanwidth, sec_chan, op_class,
chan) == NUM_HOSTAPD_MODES) {
wpa_printf(MSG_DEBUG,
"Cannot determine operating class and channel");
return -1;
}
- int he = get_ie_ext(ies, ies_len, WLAN_EID_EXT_HE_OPERATION) != NULL;
-
- *phy_type = ieee80211_get_phy_type(freq, ht_oper != NULL,
- vht_oper != NULL, he);
+ *phy_type = ieee80211_get_phy_type(freq, elems.ht_operation != NULL,
+ elems.vht_operation != NULL,
+ elems.he_operation != NULL);
if (*phy_type == PHY_TYPE_UNSPECIFIED) {
wpa_printf(MSG_DEBUG, "Cannot determine phy type");
return -1;
diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
index 07b59b198..3eefd72ed 100644
--- a/wpa_supplicant/wnm_sta.c
+++ b/wpa_supplicant/wnm_sta.c
@@ -889,47 +889,45 @@ static int wnm_nei_rep_add_bss(struct wpa_supplicant *wpa_s,
struct wpa_bss *bss, struct wpabuf **buf,
u8 pref)
{
- const u8 *ie;
u8 op_class, chan;
- int sec_chan = 0;
- enum oper_chan_width vht = CONF_OPER_CHWIDTH_USE_HT;
+ int sec_chan = 0, chanwidth = 0;
+ struct ieee802_11_elems elems;
+ struct ieee80211_ht_operation *ht_oper;
enum phy_type phy_type;
u32 info;
- struct ieee80211_ht_operation *ht_oper = NULL;
- struct ieee80211_vht_operation *vht_oper = NULL;
- ie = wpa_bss_get_ie(bss, WLAN_EID_HT_OPERATION);
- if (ie && ie[1] >= 2) {
- ht_oper = (struct ieee80211_ht_operation *) (ie + 2);
+ if (ieee802_11_parse_elems(wpa_bss_ie_ptr(bss), bss->ie_len, &elems, 1) == ParseFailed) {
+ return -2;
+ }
+
+ chanwidth = get_operation_channel_width(&elems);
+ if (chanwidth == CHAN_WIDTH_UNKNOWN) {
+ wpa_printf(MSG_DEBUG,
+ "Cannot determine channel width");
+ return -2;
+ }
- if (ht_oper->ht_param & HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE)
+ ht_oper = (struct ieee80211_ht_operation *) elems.ht_operation;
+ if (ht_oper) {
+ u8 sec_chan_offset = ht_oper->ht_param &
+ HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
+ if (sec_chan_offset == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE)
sec_chan = 1;
- else if (ht_oper->ht_param &
+ else if (sec_chan_offset ==
HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW)
sec_chan = -1;
}
- ie = wpa_bss_get_ie(bss, WLAN_EID_VHT_OPERATION);
- if (ie && ie[1] >= 1) {
- vht_oper = (struct ieee80211_vht_operation *) (ie + 2);
-
- if (vht_oper->vht_op_info_chwidth == CHANWIDTH_80MHZ ||
- vht_oper->vht_op_info_chwidth == CHANWIDTH_160MHZ ||
- vht_oper->vht_op_info_chwidth == CHANWIDTH_80P80MHZ)
- vht = vht_oper->vht_op_info_chwidth;
- }
-
- if (ieee80211_freq_to_channel_ext(bss->freq, sec_chan, vht, &op_class,
+ if (ieee80211_freq_to_channel_ext(bss->freq, sec_chan, chanwidth, &op_class,
&chan) == NUM_HOSTAPD_MODES) {
wpa_printf(MSG_DEBUG,
"WNM: Cannot determine operating class and channel");
return -2;
}
- int he = wpa_bss_get_ie_ext(bss, WLAN_EID_EXT_HE_OPERATION) != NULL;
-
- phy_type = ieee80211_get_phy_type(bss->freq, (ht_oper != NULL),
- (vht_oper != NULL), he);
+ phy_type = ieee80211_get_phy_type(bss->freq, elems.ht_operation != NULL,
+ elems.vht_operation != NULL,
+ elems.he_operation != NULL);
if (phy_type == PHY_TYPE_UNSPECIFIED) {
wpa_printf(MSG_DEBUG,
"WNM: Cannot determine BSS phy type for Neighbor Report");
--
2.52.0
More information about the Hostap
mailing list