Merge branch 'fix/chip_esp32c5_eco2_supp' into 'master'

Get operating class in dual band

Closes IDF-10613

See merge request espressif/esp-idf!38892
This commit is contained in:
Jiang Jiang Jian
2025-08-01 10:27:34 +08:00
5 changed files with 89 additions and 16 deletions

View File

@@ -23,6 +23,7 @@
#include "rsn_supp/wpa_i.h" #include "rsn_supp/wpa_i.h"
#include "rsn_supp/wpa.h" #include "rsn_supp/wpa.h"
#include "esp_private/wifi.h" #include "esp_private/wifi.h"
#include "esp_wifi_types_generic.h"
/* Utility Functions */ /* Utility Functions */
esp_err_t esp_supplicant_str_to_mac(const char *str, uint8_t dest[6]) esp_err_t esp_supplicant_str_to_mac(const char *str, uint8_t dest[6])
@@ -592,22 +593,53 @@ static size_t get_mbo_oce_assoc_ie(uint8_t *ie, size_t len)
return mbo_ie_len; return mbo_ie_len;
} }
static uint8_t get_operating_class_ie(uint8_t *ie, size_t len) static uint8_t get_operating_class_ie(uint8_t *bssid, uint8_t *ie, size_t len)
{ {
uint8_t op_class_ie[4] = {0}; size_t res = 0;
uint8_t op_class_ie_len = 2; struct wpabuf *buf;
uint8_t *pos = op_class_ie; u8 *ie_len;
u8 op;
channel_bitmap_t non_pref_channels[1] = { 0 };
struct wpa_bss *bss = wpa_bss_get_bssid(&g_wpa_supp, bssid);
*pos++ = WLAN_EID_SUPPORTED_OPERATING_CLASSES; if (!bss) {
*pos++ = op_class_ie_len; wpa_printf(MSG_ERROR, "bss not found");
#define OPER_CLASS 0x51 return 0;
/* Current Operating Class */ }
*pos++ = OPER_CLASS;
#undef OPER_CLASS
*pos = 0;
os_memcpy(ie, op_class_ie, sizeof(op_class_ie));
return op_class_ie_len + 2; /*
* Need 3 bytes for EID, length, and current operating class, plus
* 1 byte for every other supported operating class.
*/
buf = wpabuf_alloc(global_op_class_size + 3);
if (!buf) {
return 0;
}
wpabuf_put_u8(buf, WLAN_EID_SUPPORTED_OPERATING_CLASSES);
/* Will set the length later, putting a placeholder */
ie_len = wpabuf_put(buf, 1);
wpabuf_put_u8(buf, get_operating_class(bss->channel, 0));
for (op = 0; op < global_op_class_size; op++) {
bool supp;
u8 op_class = global_op_class[op].op_class;
supp = esp_wifi_op_class_supported_internal(op_class, global_op_class[op].min_chan, global_op_class[op].max_chan,
global_op_class[op].inc, global_op_class[op].bw, non_pref_channels);
if (!supp) {
continue;
}
/* Add a 1-octet operating class to the Operating Class field */
wpabuf_put_u8(buf, op_class);
}
if (non_pref_channels[0].ghz_2_channels != 0 || non_pref_channels[0].ghz_5_channels != 0) {
wpa_printf(MSG_WARNING,
"It is recommended to forbid channels by operating class instead of channels for better compatibility.\n"
"Non-preferred channels: 2Ghz=0x%04x, 5Ghz=0x%08x", non_pref_channels[0].ghz_2_channels, non_pref_channels[0].ghz_5_channels);
}
*ie_len = wpabuf_len(buf) - 2;
os_memcpy(ie, wpabuf_head(buf), wpabuf_len(buf));
res = wpabuf_len(buf);
wpabuf_free(buf);
return res;
} }
#endif /* CONFIG_MBO */ #endif /* CONFIG_MBO */
@@ -819,7 +851,7 @@ void esp_set_assoc_ie(uint8_t *bssid, const u8 *ies, size_t ies_len, bool mdie)
len -= ie_len; len -= ie_len;
#endif /* defined(CONFIG_RRM) */ #endif /* defined(CONFIG_RRM) */
#ifdef CONFIG_MBO #ifdef CONFIG_MBO
ie_len = get_operating_class_ie(pos, len); ie_len = get_operating_class_ie(bssid, pos, len);
pos += ie_len; pos += ie_len;
len -= ie_len; len -= ie_len;
ie_len = get_mbo_oce_assoc_ie(pos, len); ie_len = get_mbo_oce_assoc_ie(pos, len);

View File

@@ -9,6 +9,7 @@
#include "esp_err.h" #include "esp_err.h"
#include "esp_wifi.h" #include "esp_wifi.h"
#include "esp_wifi_types_generic.h"
#if CONFIG_NEWLIB_NANO_FORMAT #if CONFIG_NEWLIB_NANO_FORMAT
#define TASK_STACK_SIZE_ADD 0 #define TASK_STACK_SIZE_ADD 0
@@ -217,6 +218,8 @@ enum key_flag {
KEY_FLAG_PMK = BIT(6), KEY_FLAG_PMK = BIT(6),
}; };
typedef wifi_scan_channel_bitmap_t channel_bitmap_t;
uint8_t *esp_wifi_ap_get_prof_pmk_internal(void); uint8_t *esp_wifi_ap_get_prof_pmk_internal(void);
struct wifi_ssid *esp_wifi_ap_get_prof_ap_ssid_internal(void); struct wifi_ssid *esp_wifi_ap_get_prof_ap_ssid_internal(void);
uint8_t esp_wifi_ap_get_prof_authmode_internal(void); uint8_t esp_wifi_ap_get_prof_authmode_internal(void);
@@ -306,5 +309,5 @@ uint8_t esp_wifi_ap_get_transition_disable_internal(void);
int esp_wifi_softap_set_obss_overlap(bool overlap); int esp_wifi_softap_set_obss_overlap(bool overlap);
void esp_wifi_set_sigma_internal(bool flag); void esp_wifi_set_sigma_internal(bool flag);
void esp_wifi_ap_set_group_mgmt_cipher_internal(wifi_cipher_type_t cipher); void esp_wifi_ap_set_group_mgmt_cipher_internal(wifi_cipher_type_t cipher);
uint8_t esp_wifi_op_class_supported_internal(uint8_t op_class, uint8_t min_chan, uint8_t max_chan, uint8_t inc, uint8_t bw, channel_bitmap_t *non_pref_channels);
#endif /* _ESP_WIFI_DRIVER_H_ */ #endif /* _ESP_WIFI_DRIVER_H_ */

View File

@@ -355,6 +355,30 @@ int ieee802_11_ext_capab(const u8 *ie, unsigned int capab)
return !!(ie[2 + capab / 8] & BIT(capab % 8)); return !!(ie[2 + capab / 8] & BIT(capab % 8));
} }
const struct oper_class_map global_op_class[] = {
{ HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 121, 100, 144, 4, BW20, NO_P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 122, 100, 140, 8, BW40PLUS, NO_P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 123, 104, 144, 8, BW40MINUS, NO_P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 125, 149, 177, 4, BW20, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 126, 149, 173, 8, BW40PLUS, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 127, 153, 177, 8, BW40MINUS, P2P_SUPP }
};
size_t global_op_class_size = ARRAY_SIZE(global_op_class);
u8 get_operating_class(u8 chan, int sec_channel) u8 get_operating_class(u8 chan, int sec_channel)
{ {
u8 op_class = 0; u8 op_class = 0;

View File

@@ -34,6 +34,20 @@ struct element {
struct wpa_supplicant; struct wpa_supplicant;
struct oper_class_map {
enum hostapd_hw_mode mode;
u8 op_class;
u8 min_chan;
u8 max_chan;
u8 inc;
enum { BW20, BW40PLUS, BW40MINUS, BW40, BW80, BW2160, BW160, BW80P80,
BW320, BW4320, BW6480, BW8640} bw;
enum { P2P_SUPP, NO_P2P_SUPP } p2p;
};
extern const struct oper_class_map global_op_class[];
extern size_t global_op_class_size;
int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
size_t nei_rep_len); size_t nei_rep_len);
const u8 * get_ie(const u8 *ies, size_t len, u8 eid); const u8 * get_ie(const u8 *ies, size_t len, u8 eid);