diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 9d808c55d..f034e5040 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1921,7 +1921,7 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, if (wnm_scan_process(wpa_s, 1) > 0) goto scan_work_done; - if (sme_proc_obss_scan(wpa_s) > 0) + if (sme_proc_obss_scan(wpa_s, scan_res) > 0) goto scan_work_done; if (own_request && data && diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 749802496..08d7e3ece 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -13,6 +13,7 @@ #include "common/ieee802_11_defs.h" #include "common/ieee802_11_common.h" #include "common/ocv.h" +#include "common/hw_features_common.h" #include "eapol_supp/eapol_supp_sm.h" #include "common/wpa_common.h" #include "common/sae.h" @@ -2214,13 +2215,14 @@ static void sme_send_2040_bss_coex(struct wpa_supplicant *wpa_s, } -int sme_proc_obss_scan(struct wpa_supplicant *wpa_s) +int sme_proc_obss_scan(struct wpa_supplicant *wpa_s, + struct wpa_scan_results *scan_res) { - struct wpa_bss *bss; const u8 *ie; - u16 ht_cap; u8 chan_list[P2P_MAX_CHANNELS], channel; u8 num_channels = 0, num_intol = 0, i; + size_t j; + int pri_freq, sec_freq; if (!wpa_s->sme.sched_obss_scan) return 0; @@ -2248,22 +2250,36 @@ int sme_proc_obss_scan(struct wpa_supplicant *wpa_s) os_memset(chan_list, 0, sizeof(chan_list)); - dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { - /* Skip other band bss */ + pri_freq = wpa_s->assoc_freq; + + switch (wpa_s->sme.ht_sec_chan) { + case HT_SEC_CHAN_ABOVE: + sec_freq = pri_freq + 20; + break; + case HT_SEC_CHAN_BELOW: + sec_freq = pri_freq - 20; + break; + case HT_SEC_CHAN_UNKNOWN: + default: + wpa_msg(wpa_s, MSG_WARNING, + "Undefined secondary channel: drop OBSS scan results"); + return 1; + } + + for (j = 0; j < scan_res->num; j++) { + struct wpa_scan_res *bss = scan_res->res[j]; enum hostapd_hw_mode mode; + int res; + + /* Skip other band bss */ mode = ieee80211_freq_to_chan(bss->freq, &channel); if (mode != HOSTAPD_MODE_IEEE80211G && mode != HOSTAPD_MODE_IEEE80211B) continue; - ie = wpa_bss_get_ie(bss, WLAN_EID_HT_CAP); - ht_cap = (ie && (ie[1] == 26)) ? WPA_GET_LE16(ie + 2) : 0; - wpa_printf(MSG_DEBUG, "SME OBSS scan BSS " MACSTR - " freq=%u chan=%u ht_cap=0x%x", - MAC2STR(bss->bssid), bss->freq, channel, ht_cap); - - if (!ht_cap || (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT)) { - if (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT) + res = check_bss_coex_40mhz(bss, pri_freq, sec_freq); + if (res) { + if (res == 2) num_intol++; /* Check whether the channel is already considered */ diff --git a/wpa_supplicant/sme.h b/wpa_supplicant/sme.h index 1a7f9e832..42d5a8317 100644 --- a/wpa_supplicant/sme.h +++ b/wpa_supplicant/sme.h @@ -37,7 +37,8 @@ void sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s, void sme_clear_on_disassoc(struct wpa_supplicant *wpa_s); void sme_deinit(struct wpa_supplicant *wpa_s); -int sme_proc_obss_scan(struct wpa_supplicant *wpa_s); +int sme_proc_obss_scan(struct wpa_supplicant *wpa_s, + struct wpa_scan_results *scan_res); void sme_sched_obss_scan(struct wpa_supplicant *wpa_s, int enable); void sme_external_auth_trigger(struct wpa_supplicant *wpa_s, union wpa_event_data *data); @@ -112,7 +113,8 @@ static inline void sme_deinit(struct wpa_supplicant *wpa_s) { } -static inline int sme_proc_obss_scan(struct wpa_supplicant *wpa_s) +static inline int sme_proc_obss_scan(struct wpa_supplicant *wpa_s, + struct wpa_scan_results *scan_res) { return 0; }