wpa_supplicant: Handle HT40 and mode downgrade in AP mode

Add some missing pieces to the interface configuration of AP/mesh mode
in wpa_supplicant.
 - check for secondary channel and HT40 capability
 - try to downgrade to IEEE 802.11b if 802.11g is not available
Especially with the HT40 check, this code now performs all settings,
which the deleted/duplicated mesh code did.

Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
This commit is contained in:
Markus Theil 2020-06-30 13:53:19 +02:00 committed by Jouni Malinen
parent 93da12fd9f
commit df6745e8c8

View File

@ -134,6 +134,24 @@ no_vht:
} }
static struct hostapd_hw_modes *
wpa_supplicant_find_hw_mode(struct wpa_supplicant *wpa_s,
enum hostapd_hw_mode hw_mode)
{
struct hostapd_hw_modes *mode = NULL;
int i;
for (i = 0; i < wpa_s->hw.num_modes; i++) {
if (wpa_s->hw.modes[i].mode == hw_mode) {
mode = &wpa_s->hw.modes[i];
break;
}
}
return mode;
}
int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s, int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid, struct wpa_ssid *ssid,
struct hostapd_config *conf) struct hostapd_config *conf)
@ -147,9 +165,6 @@ int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
return -1; return -1;
} }
/* TODO: enable HT40 if driver supports it;
* drop to 11b if driver does not support 11g */
/* /*
* Enable HT20 if the driver supports it, by setting conf->ieee80211n * Enable HT20 if the driver supports it, by setting conf->ieee80211n
* and a mask of allowed capabilities within conf->ht_capab. * and a mask of allowed capabilities within conf->ht_capab.
@ -158,17 +173,28 @@ int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
*/ */
if (wpa_s->hw.modes) { if (wpa_s->hw.modes) {
struct hostapd_hw_modes *mode = NULL; struct hostapd_hw_modes *mode = NULL;
int i, no_ht = 0; int no_ht = 0;
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"Determining HT/VHT options based on driver capabilities (freq=%u chan=%u)", "Determining HT/VHT options based on driver capabilities (freq=%u chan=%u)",
ssid->frequency, conf->channel); ssid->frequency, conf->channel);
for (i = 0; i < wpa_s->hw.num_modes; i++) { mode = wpa_supplicant_find_hw_mode(wpa_s, conf->hw_mode);
if (wpa_s->hw.modes[i].mode == conf->hw_mode) {
mode = &wpa_s->hw.modes[i]; /* May drop to IEEE 802.11b if the driver does not support IEEE
break; * 802.11g */
} if (!mode && conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
conf->hw_mode = HOSTAPD_MODE_IEEE80211B;
wpa_printf(MSG_INFO,
"Try downgrade to IEEE 802.11b as 802.11g is not supported by the current hardware");
mode = wpa_supplicant_find_hw_mode(wpa_s,
conf->hw_mode);
}
if (!mode) {
wpa_printf(MSG_ERROR,
"No match between requested and supported hw modes found");
return -1;
} }
#ifdef CONFIG_HT_OVERRIDES #ifdef CONFIG_HT_OVERRIDES
@ -193,6 +219,14 @@ int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET), HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET),
ssid->ht40); ssid->ht40);
conf->ieee80211n = 1; conf->ieee80211n = 1;
if (ssid->ht40 &&
(mode->ht_capab &
HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
conf->secondary_channel = ssid->ht40;
else
conf->secondary_channel = 0;
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
if (ssid->p2p_group && if (ssid->p2p_group &&
conf->hw_mode == HOSTAPD_MODE_IEEE80211A && conf->hw_mode == HOSTAPD_MODE_IEEE80211A &&