aboutsummaryrefslogtreecommitdiffstats
path: root/hostapd/beacon.c
diff options
context:
space:
mode:
Diffstat (limited to 'hostapd/beacon.c')
-rw-r--r--hostapd/beacon.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/hostapd/beacon.c b/hostapd/beacon.c
index b53bc76..4e7f93d 100644
--- a/hostapd/beacon.c
+++ b/hostapd/beacon.c
@@ -26,6 +26,7 @@
#include "hw_features.h"
#include "driver.h"
#include "sta_info.h"
+#include "ieee802_11h.h"
static u8 ieee802_11_erp_info(struct hostapd_data *hapd)
@@ -94,6 +95,74 @@ static u8 * hostapd_eid_erp_info(struct hostapd_data *hapd, u8 *eid)
}
+static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid,
+ int max_len)
+{
+ int left;
+ u8 *pos = eid;
+
+ if ((!hapd->iconf->ieee80211d && !hapd->iface->dfs_enable) ||
+ max_len < 6)
+ return eid;
+
+ *pos++ = WLAN_EID_COUNTRY;
+ pos++; /* length will be set later */
+ memcpy(pos, hapd->iconf->country, 3); /* e.g., 'US ' */
+ pos += 3;
+ left = max_len - 3;
+
+ if ((pos - eid) & 1) {
+ if (left < 1)
+ return eid;
+ *pos++ = 0; /* pad for 16-bit alignment */
+ left--;
+ }
+
+ eid[1] = (pos - eid) - 2;
+
+ return pos;
+}
+
+
+static u8 * hostapd_eid_power_constraint(struct hostapd_data *hapd, u8 *eid)
+
+{
+ if (!hapd->iface->dfs_enable)
+ return eid;
+ *eid++ = WLAN_EID_PWR_CONSTRAINT;
+ *eid++ = 1;
+ *eid++ = hapd->iface->pwr_const;
+ return eid;
+}
+
+
+static u8 * hostapd_eid_tpc_report(struct hostapd_data *hapd, u8 *eid)
+
+{
+ if (!hapd->iface->dfs_enable)
+ return eid;
+ *eid++ = WLAN_EID_TPC_REPORT;
+ *eid++ = 2;
+ *eid++ = hapd->iface->tx_power; /* TX POWER */
+ *eid++ = 0; /* Link Margin */
+ return eid;
+}
+
+static u8 * hostapd_eid_channel_switch(struct hostapd_data *hapd, u8 *eid)
+
+{
+ if (!hapd->iface->dfs_enable || !hapd->iface->channel_switch)
+ return eid;
+ *eid++ = WLAN_EID_CHANNEL_SWITCH;
+ *eid++ = 3;
+ *eid++ = CHAN_SWITCH_MODE_QUIET;
+ *eid++ = hapd->iface->channel_switch; /* New channel */
+ /* 0 - very soon; 1 - before next TBTT; num - after num beacons */
+ *eid++ = 0;
+ return eid;
+}
+
+
static u8 * hostapd_eid_wpa(struct hostapd_data *hapd, u8 *eid, size_t len,
struct sta_info *sta)
{
@@ -203,6 +272,11 @@ void handle_probe_req(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
/* DS Params */
pos = hostapd_eid_ds_params(hapd, pos);
+ pos = hostapd_eid_country(hapd, pos, epos - pos);
+
+ pos = hostapd_eid_power_constraint(hapd, pos);
+ pos = hostapd_eid_tpc_report(hapd, pos);
+
/* ERP Information element */
pos = hostapd_eid_erp_info(hapd, pos);
@@ -286,6 +360,13 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
head_len = pos - (u8 *) head;
+ tailpos = hostapd_eid_country(hapd, tailpos,
+ tail + BEACON_TAIL_BUF_SIZE - tailpos);
+
+ tailpos = hostapd_eid_power_constraint(hapd, tailpos);
+ tailpos = hostapd_eid_channel_switch(hapd, tailpos);
+ tailpos = hostapd_eid_tpc_report(hapd, tailpos);
+
/* ERP Information element */
tailpos = hostapd_eid_erp_info(hapd, tailpos);