[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