From 5a5b20f44da130406699759ec67b84ec5041777c Mon Sep 17 00:00:00 2001 From: "tarun.kumar" Date: Fri, 2 May 2025 17:54:52 +0530 Subject: [PATCH] fix(wifi): Get operating class in dual band --- components/esp_wifi/lib | 2 +- .../esp_supplicant/src/esp_common.c | 60 ++++++++++++++----- .../esp_supplicant/src/esp_wifi_driver.h | 5 +- .../src/common/ieee802_11_common.c | 24 ++++++++ .../src/common/ieee802_11_common.h | 14 +++++ 5 files changed, 89 insertions(+), 16 deletions(-) diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 10dca7affa..09b6a047b0 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 10dca7affa0ef6e50130a9bb8b2e1beb95bd4eb7 +Subproject commit 09b6a047b069ddf1ec42e09818a1ea7b74fb3118 diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_common.c b/components/wpa_supplicant/esp_supplicant/src/esp_common.c index d4dc0d3e4f..04a9a9a27a 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_common.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_common.c @@ -23,6 +23,7 @@ #include "rsn_supp/wpa_i.h" #include "rsn_supp/wpa.h" #include "esp_private/wifi.h" +#include "esp_wifi_types_generic.h" /* Utility Functions */ 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; } -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}; - uint8_t op_class_ie_len = 2; - uint8_t *pos = op_class_ie; + size_t res = 0; + struct wpabuf *buf; + 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; - *pos++ = op_class_ie_len; -#define OPER_CLASS 0x51 - /* Current Operating Class */ - *pos++ = OPER_CLASS; -#undef OPER_CLASS - *pos = 0; - os_memcpy(ie, op_class_ie, sizeof(op_class_ie)); + if (!bss) { + wpa_printf(MSG_ERROR, "bss not found"); + return 0; + } - 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 */ @@ -819,7 +851,7 @@ void esp_set_assoc_ie(uint8_t *bssid, const u8 *ies, size_t ies_len, bool mdie) len -= ie_len; #endif /* defined(CONFIG_RRM) */ #ifdef CONFIG_MBO - ie_len = get_operating_class_ie(pos, len); + ie_len = get_operating_class_ie(bssid, pos, len); pos += ie_len; len -= ie_len; ie_len = get_mbo_oce_assoc_ie(pos, len); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h index e4ca4879ed..e99fd88dab 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h @@ -9,6 +9,7 @@ #include "esp_err.h" #include "esp_wifi.h" +#include "esp_wifi_types_generic.h" #if CONFIG_NEWLIB_NANO_FORMAT #define TASK_STACK_SIZE_ADD 0 @@ -217,6 +218,8 @@ enum key_flag { KEY_FLAG_PMK = BIT(6), }; +typedef wifi_scan_channel_bitmap_t channel_bitmap_t; + uint8_t *esp_wifi_ap_get_prof_pmk_internal(void); struct wifi_ssid *esp_wifi_ap_get_prof_ap_ssid_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); void esp_wifi_set_sigma_internal(bool flag); 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_ */ diff --git a/components/wpa_supplicant/src/common/ieee802_11_common.c b/components/wpa_supplicant/src/common/ieee802_11_common.c index 58997d0e26..e4c1f4a52d 100644 --- a/components/wpa_supplicant/src/common/ieee802_11_common.c +++ b/components/wpa_supplicant/src/common/ieee802_11_common.c @@ -355,6 +355,30 @@ int ieee802_11_ext_capab(const u8 *ie, unsigned int capab) 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 op_class = 0; diff --git a/components/wpa_supplicant/src/common/ieee802_11_common.h b/components/wpa_supplicant/src/common/ieee802_11_common.h index aa150fbf6a..90cae7814d 100644 --- a/components/wpa_supplicant/src/common/ieee802_11_common.h +++ b/components/wpa_supplicant/src/common/ieee802_11_common.h @@ -34,6 +34,20 @@ struct element { 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, size_t nei_rep_len); const u8 * get_ie(const u8 *ies, size_t len, u8 eid);