From ec27b04e606873952956563fff99b6ed0bd93fd0 Mon Sep 17 00:00:00 2001 From: Peng Xu Date: Thu, 20 Apr 2017 17:05:25 -0700 Subject: [PATCH] hostapd: Select a valid secondary channel if both enabled When starting AP in HT40 mode and both HT40+ and HT40- options are specified in hostapd.conf, select a valid secondary channel for the AP automatically. Signed-off-by: Jouni Malinen --- hostapd/config_file.c | 4 ++++ src/ap/ap_config.h | 1 + src/ap/hw_features.c | 23 +++++++++++++++++++++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 7b4380605..d4d0c92c9 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -1106,6 +1106,10 @@ static int hostapd_config_ht_capab(struct hostapd_config *conf, conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET; conf->secondary_channel = 1; } + if (os_strstr(capab, "[HT40+]") && os_strstr(capab, "[HT40-]")) { + conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET; + conf->ht40_plus_minus_allowed = 1; + } if (os_strstr(capab, "[SMPS-STATIC]")) { conf->ht_capab &= ~HT_CAP_INFO_SMPS_MASK; conf->ht_capab |= HT_CAP_INFO_SMPS_STATIC; diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 989b07107..498891c54 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -724,6 +724,7 @@ struct hostapd_config { u8 vht_oper_chwidth; u8 vht_oper_centr_freq_seg0_idx; u8 vht_oper_centr_freq_seg1_idx; + u8 ht40_plus_minus_allowed; /* Use driver-generated interface addresses when adding multiple BSSs */ u8 use_driver_iface_addr; diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c index 93d923af5..c677d30f4 100644 --- a/src/ap/hw_features.c +++ b/src/ap/hw_features.c @@ -722,14 +722,33 @@ static int hostapd_is_usable_chan(struct hostapd_iface *iface, static int hostapd_is_usable_chans(struct hostapd_iface *iface) { + int secondary_chan; + if (!hostapd_is_usable_chan(iface, iface->conf->channel, 1)) return 0; if (!iface->conf->secondary_channel) return 1; - return hostapd_is_usable_chan(iface, iface->conf->channel + - iface->conf->secondary_channel * 4, 0); + if (!iface->conf->ht40_plus_minus_allowed) + return hostapd_is_usable_chan( + iface, iface->conf->channel + + iface->conf->secondary_channel * 4, 0); + + /* Both HT40+ and HT40- are set, pick a valid secondary channel */ + secondary_chan = iface->conf->channel + 4; + if (hostapd_is_usable_chan(iface, secondary_chan, 0)) { + iface->conf->secondary_channel = 1; + return 1; + } + + secondary_chan = iface->conf->channel - 4; + if (hostapd_is_usable_chan(iface, secondary_chan, 0)) { + iface->conf->secondary_channel = -1; + return 1; + } + + return 0; }