hostapd: Configure spectrum management capability

Add configuration of Spectrum Management subfield in the Capability
Information of Beacon, Probe Response, and Association Response frames.
Spectrum Management bit is set when directly requested by new
configuration option spectrum_mgmt_required=1 or when AP is running on
DFS channels. In the future, also TPC shall require this bit to be set.

Signed-hostap: Srinivasan <srinivasanb@posedge.com>
Signed-hostap: Chaitanya T K <chaitanyatk@posedge.com>
Signed-hostap: Marek Puzyniak <marek.puzyniak@tieto.com>
This commit is contained in:
Chaitanya T K 2014-02-21 14:42:18 +01:00 committed by Jouni Malinen
parent e0392f825d
commit 3d7ad2f681
8 changed files with 98 additions and 3 deletions

View file

@ -2915,6 +2915,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
return 1;
}
conf->local_pwr_constraint = val;
} else if (os_strcmp(buf, "spectrum_mgmt_required") == 0) {
conf->spectrum_mgmt_required = atoi(pos);
} else {
wpa_printf(MSG_ERROR, "Line %d: unknown configuration "
"item '%s'", line, buf);

View file

@ -115,6 +115,13 @@ ssid=test
# Valid values are 0..255.
#local_pwr_constraint=3
# Set Spectrum Management subfield in the Capability Information field.
# This config option forces the Spectrum Management bit to be set. When this
# option is not set, the value of the Spectrum Management bit depends on whether
# DFS or TPC is required by regulatory authorities. This can be used only with
# ieee80211d=1 and local_pwr_constraint configured.
#spectrum_mgmt_required=1
# Operation mode (a = IEEE 802.11a, b = IEEE 802.11b, g = IEEE 802.11g,
# ad = IEEE 802.11ad (60 GHz); a/g options are used with IEEE 802.11n, too, to
# specify band)

View file

@ -837,6 +837,12 @@ int hostapd_config_check(struct hostapd_config *conf, int full_config)
return -1;
}
if (full_config && conf->spectrum_mgmt_required &&
conf->local_pwr_constraint == -1) {
wpa_printf(MSG_ERROR, "Cannot set Spectrum Management bit without Country and Power Constraint elements");
return -1;
}
for (i = 0; i < conf->num_bss; i++) {
if (hostapd_config_check_bss(conf->bss[i], conf, full_config))
return -1;

View file

@ -526,6 +526,9 @@ struct hostapd_config {
*/
int local_pwr_constraint;
/* Control Spectrum Management bit */
int spectrum_mgmt_required;
struct hostapd_tx_queue_params tx_queue[NUM_TX_QUEUES];
/*

View file

@ -27,6 +27,7 @@
#include "ap_drv_ops.h"
#include "beacon.h"
#include "hs20.h"
#include "dfs.h"
#ifdef NEED_AP_MLME
@ -105,12 +106,43 @@ static u8 * hostapd_eid_erp_info(struct hostapd_data *hapd, u8 *eid)
static u8 * hostapd_eid_pwr_constraint(struct hostapd_data *hapd, u8 *eid)
{
u8 *pos = eid;
u8 local_pwr_constraint = 0;
int dfs;
if (hapd->iconf->local_pwr_constraint == -1 ||
hapd->iface->current_mode == NULL ||
if (hapd->iface->current_mode == NULL ||
hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211A)
return eid;
/*
* There is no DFS support and power constraint was not directly
* requested by config option.
*/
if (!hapd->iconf->ieee80211h &&
hapd->iconf->local_pwr_constraint == -1)
return eid;
/* Check if DFS is required by regulatory. */
dfs = hostapd_is_dfs_required(hapd->iface);
if (dfs < 0) {
wpa_printf(MSG_WARNING, "Failed to check if DFS is required; ret=%d",
dfs);
dfs = 0;
}
if (dfs == 0 && hapd->iconf->local_pwr_constraint == -1)
return eid;
/*
* ieee80211h (DFS) is enabled so Power Constraint element shall
* be added when running on DFS channel whenever local_pwr_constraint
* is configured or not. In order to meet regulations when TPC is not
* implemented using a transmit power that is below the legal maximum
* (including any mitigation factor) should help. In this case,
* indicate 3 dB below maximum allowed transmit power.
*/
if (hapd->iconf->local_pwr_constraint == -1)
local_pwr_constraint = 3;
/*
* A STA that is not an AP shall use a transmit power less than or
* equal to the local maximum transmit power level for the channel.
@ -126,7 +158,10 @@ static u8 * hostapd_eid_pwr_constraint(struct hostapd_data *hapd, u8 *eid)
/* Length */
*pos++ = 1;
/* Local Power Constraint */
*pos++ = hapd->iconf->local_pwr_constraint;
if (local_pwr_constraint)
*pos++ = local_pwr_constraint;
else
*pos++ = hapd->iconf->local_pwr_constraint;
return pos;
}

View file

@ -801,3 +801,23 @@ int hostapd_dfs_nop_finished(struct hostapd_iface *iface, int freq,
cf1, cf2, HOSTAPD_CHAN_DFS_USABLE);
return 0;
}
int hostapd_is_dfs_required(struct hostapd_iface *iface)
{
int n_chans, start_chan_idx;
if (!iface->current_mode)
return -1;
/* Get start (first) channel for current configuration */
start_chan_idx = dfs_get_start_chan_idx(iface);
if (start_chan_idx == -1)
return -1;
/* Get number of used channels, depend on width */
n_chans = dfs_get_used_n_chans(iface);
/* Check if any of configured channels require DFS */
return dfs_check_chans_radar(iface, start_chan_idx, n_chans);
}

View file

@ -21,5 +21,6 @@ int hostapd_dfs_radar_detected(struct hostapd_iface *iface, int freq,
int hostapd_dfs_nop_finished(struct hostapd_iface *iface, int freq,
int ht_enabled,
int chan_offset, int chan_width, int cf1, int cf2);
int hostapd_is_dfs_required(struct hostapd_iface *iface);
#endif /* DFS_H */

View file

@ -38,6 +38,7 @@
#include "ap_drv_ops.h"
#include "wnm_ap.h"
#include "ieee802_11.h"
#include "dfs.h"
u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
@ -137,6 +138,15 @@ u16 hostapd_own_capab_info(struct hostapd_data *hapd, struct sta_info *sta,
{
int capab = WLAN_CAPABILITY_ESS;
int privacy;
int dfs;
/* Check if any of configured channels require DFS */
dfs = hostapd_is_dfs_required(hapd->iface);
if (dfs < 0) {
wpa_printf(MSG_WARNING, "Failed to check if DFS is required; ret=%d",
dfs);
dfs = 0;
}
if (hapd->iface->num_sta_no_short_preamble == 0 &&
hapd->iconf->preamble == SHORT_PREAMBLE)
@ -174,6 +184,17 @@ u16 hostapd_own_capab_info(struct hostapd_data *hapd, struct sta_info *sta,
hapd->iface->num_sta_no_short_slot_time == 0)
capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
/*
* Currently, Spectrum Management capability bit is set when directly
* requested in configuration by spectrum_mgmt_required or when AP is
* running on DFS channel.
* TODO: Also consider driver support for TPC to set Spectrum Mgmt bit
*/
if (hapd->iface->current_mode &&
hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
(hapd->iconf->spectrum_mgmt_required || dfs))
capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
return capab;
}