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);
# 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)
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;
*/
int local_pwr_constraint;
+ /* Control Spectrum Management bit */
+ int spectrum_mgmt_required;
+
struct hostapd_tx_queue_params tx_queue[NUM_TX_QUEUES];
/*
#include "ap_drv_ops.h"
#include "beacon.h"
#include "hs20.h"
+#include "dfs.h"
#ifdef NEED_AP_MLME
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.
/* 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;
}
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);
+}
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 */
#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)
{
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)
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;
}