[PATCH 2/2] hostapd: Configure spectrum management capability
Marek Puzyniak
marek.puzyniak
Fri Feb 21 05:42:18 PST 2014
From: Chaitanya T K <chaitanyatk at posedge.com>
Add configuration of Spectrum Managment subfield in
the Capability Information of Beacon, Probe Response and
Association Response. 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 future also TPC
shall require this bit to be set.
Signed-hostap: Srinivasan <srinivasanb at posedge.com>
Signed-hostap: Chaitanya T K <chaitanyatk at posedge.com>
Signed-hostap: Marek Puzyniak <marek.puzyniak at tieto.com>
---
hostapd/config_file.c | 2 ++
hostapd/hostapd.conf | 7 +++++++
src/ap/ap_config.c | 6 ++++++
src/ap/ap_config.h | 3 +++
src/ap/beacon.c | 43 +++++++++++++++++++++++++++++++++++++++----
src/ap/dfs.c | 19 +++++++++++++++++++
src/ap/dfs.h | 2 ++
src/ap/ieee802_11.c | 21 +++++++++++++++++++++
8 files changed, 99 insertions(+), 4 deletions(-)
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index ef4958a..cde78f1 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -2916,6 +2916,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
errors++;
} else
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);
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index 15cd364..5ae1ab9 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -116,6 +116,13 @@ ssid=test
# Valid values are 0..255.
#local_pwr_constraint=3
+# Set Spectrum Managment subfield in the Capability Information field.
+# This config option forces Spectrum Management bit to be set. When this
+# option is not set then value of Spectrum Management bit depends on whether
+# DFS or TPC is reuired 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)
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 6c80e48..cc64f92 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -838,6 +838,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;
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index c641a83..c8ba441 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -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];
/*
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 36b0074..5da68f1 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -27,6 +27,7 @@
#include "ap_drv_ops.h"
#include "beacon.h"
#include "hs20.h"
+#include "dfs.h"
#ifdef NEED_AP_MLME
@@ -105,13 +106,44 @@ 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;
+ int local_pwr_constraint = 0;
+ int dfs;
- if (hapd->iconf->local_pwr_constraint == -1 ||
- hapd->iface->current_mode == NULL ||
- hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211A)
+ 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 direcly
+ * 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 3dB 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.
* The local maximum transmit power can be calculated from the formula:
@@ -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;
}
diff --git a/src/ap/dfs.c b/src/ap/dfs.c
index ec691db..cd8742e 100644
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -801,3 +801,22 @@ 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;
+ int res = 0;
+
+ /* 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 */
+ res = dfs_check_chans_radar(iface, start_chan_idx, n_chans);
+
+ return res;
+}
diff --git a/src/ap/dfs.h b/src/ap/dfs.h
index 859ff79..2710021 100644
--- a/src/ap/dfs.h
+++ b/src/ap/dfs.h
@@ -21,5 +21,7 @@ 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 */
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 9251ac3..342ef8d 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -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;
}
--
1.8.1.2
More information about the Hostap
mailing list