[PATCH] Add Support for TPC and VHT-TPE IE's

chaitanya.mgit at gmail.com chaitanya.mgit
Wed Jul 24 11:58:53 PDT 2013


Add Support TPC as per 802.11-2012
and TPE(VHT) IE's as per 802.11ac-draft-5.0.

Signed-hostap: Srinivasan <srinivasanb at posedge.com>
Signed-hostap: Chaitanya T K <chaitanyatk at posedge.com>
---
Fixed the signoffs.

TPC Support from the RFC submitted by Srinivasan.
Clubbed these two as they belong to the same category.

For TPE, for input of power constraints
currently only user support is added,  regulatory support
can be added later.
---
hostapd/config_file.c        |   12 ++++++++++
 hostapd/hostapd.conf         |   10 ++++++++
 src/ap/ap_config.c           |    9 +++++++
 src/ap/ap_config.h           |   17 ++++++++++++++
 src/ap/beacon.c              |   32 +++++++++++++++++++++++++++
 src/ap/ieee802_11.c          |    6 +++++
 src/ap/ieee802_11.h          |    1 +
 src/ap/ieee802_11_vht.c      |   49
++++++++++++++++++++++++++++++++++++++++++
 src/common/ieee802_11_defs.h |    8 ++++++
 9 files changed, 144 insertions(+), 0 deletions(-)

diff --git a/hostapd/config_file.c b/hostapd/config_file.c index
8e6f35a..06b57f0 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -2508,6 +2508,18 @@ static int hostapd_config_fill(struct hostapd_config
*conf,
 		} else if (os_strcmp(buf, "vht_oper_centr_freq_seg1_idx") ==
0)
 		{
 			conf->vht_oper_centr_freq_seg1_idx = atoi(pos);
+		}
+		else if (os_strcmp(buf, "vht_tpe_lpc_20") == 0) {
+			conf->vht_tpe_lpc_20 = atoi(pos);
+		}
+		else if (os_strcmp(buf, "vht_tpe_lpc_40") == 0) {
+			conf->vht_tpe_lpc_40 = atoi(pos);
+		}
+		else if (os_strcmp(buf, "vht_tpe_lpc_80") == 0) {
+			conf->vht_tpe_lpc_80 = atoi(pos);
+		}
+		else if (os_strcmp(buf, "vht_tpe_lpc_160") == 0) {
+			conf->vht_tpe_lpc_160 = atoi(pos);
 #endif /* CONFIG_IEEE80211AC */
 		} else if (os_strcmp(buf, "max_listen_interval") == 0) {
 			bss->max_listen_interval = atoi(pos); diff --git
a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 68c4069..054dad9 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -589,6 +589,16 @@ wmm_ac_vo_acm=0
 # which is channel 159 in 5G band
 #
 #vht_oper_centr_freq_seg1_idx=159
+#
+#IEEE802.11-ac-5.0: 8.4.2.164
+#VHT Transmit Power Envelope Requires 802.11h support #Local Maximum 
+Power Constraints/Channel.
+#Valid Range: -64dBm to 53 dBm in 0.5 dB steps (63.5 dBM disables the 
+Power Constraint) #Encoded Range: -128 to 126 (8-bit 2's Compliment) 
+(127 disabled the Power Constraint)
+#vht_tpe_lpc_20=0
+#vht_tpe_lpc_40=0
+#vht_tpe_lpc_80=0
+#vht_tpe_lpc_160=0
 
 ##### IEEE 802.1X-2004 related configuration
##################################
 
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index fbc1ee0..3f53583
100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -163,6 +163,15 @@ struct hostapd_config * hostapd_config_defaults(void)
 	conf->ap_table_max_size = 255;
 	conf->ap_table_expiration_time = 60;
 
+#ifdef CONFIG_IEEE80211AC
+	/* This will help us identify whether user has configured
+	 * for a band or not */
+	conf->vht_tpe_lpc_20  = VHT_TPE_PWR_CONSTRAINT_DISABLE;
+	conf->vht_tpe_lpc_40  = VHT_TPE_PWR_CONSTRAINT_DISABLE;
+	conf->vht_tpe_lpc_80  = VHT_TPE_PWR_CONSTRAINT_DISABLE;
+	conf->vht_tpe_lpc_160 = VHT_TPE_PWR_CONSTRAINT_DISABLE; #endif
+
 #ifdef CONFIG_TESTING_OPTIONS
 	conf->ignore_probe_probability = 0.0d;
 	conf->ignore_auth_probability = 0.0d;
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index a744ba6..e9360ce
100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -174,6 +174,14 @@ struct hostapd_nai_realm_data {
 	} eap_method[MAX_NAI_EAP_METHODS];
 };
 
+/* 127 Means 63.5 dBm, meaning no local max power constraint
+ * So either User has not entered the power constraint for that BW
+ * (or) He configured to use no power constraint, in both cases
+ * For Mandaotry (20MHZ): We will use 127 values
+ * For Optional(40/80/160 MHz): we will skip those fields.
+ */
+#define VHT_TPE_PWR_CONSTRAINT_DISABLE 127
+
 /**
  * struct hostapd_bss_config - Per-BSS configuration
  */
@@ -465,6 +473,8 @@ struct hostapd_bss_config {
 	int *sae_groups;
 };
 
+/* Default value for pwr constraint */
+#define DEFAULT_PWR_CONSTRAINT 0
 
 /**
  * struct hostapd_config - Per-radio interface configuration @@ -526,6
+536,13 @@ struct hostapd_config {
 	u8 vht_oper_centr_freq_seg0_idx;
 	u8 vht_oper_centr_freq_seg1_idx;
 
+#ifdef CONFIG_IEEE80211AC
+	s8 vht_tpe_lpc_20;
+	s8 vht_tpe_lpc_40;
+	s8 vht_tpe_lpc_80;
+	s8 vht_tpe_lpc_160;
+#endif
+
 #ifdef CONFIG_TESTING_OPTIONS
 	double ignore_probe_probability;
 	double ignore_auth_probability;
diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 2f4ba23..26c036b 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -92,6 +92,30 @@ static u8 * hostapd_eid_erp_info(struct hostapd_data
*hapd, u8 *eid)
 	return eid;
 }
 
+static u8 * hostapd_eid_pwr_constraint(struct hostapd_data *hapd, u8 
+*eid) {
+	u8 *pos = eid;
+
+	if (!hapd->iconf->ieee80211h ||
+		hapd->iface->current_mode == NULL ||
+		hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211A)
+			return eid;
+
+	/* CRDA provides reduced TX power than actual regulatory max TX
power.
+	*      * Value of 0 to the Local Power constraint provides an
opportunity
+	*      * for the client devices to operate at Power Limit provided
by CRDA
+	*      * (for client devices
+	*      * "Local max TX pwr" = regul max TX pwr - Local pwr
constraint)*/
+
+	/* Element ID */
+	*pos++ = WLAN_EID_PWR_CONSTRAINT;
+	/* Length */
+	*pos++ = 1;
+	/* Local Power Constraint */
+	*pos++ = DEFAULT_PWR_CONSTRAINT;
+
+	return pos;
+}
 
 static u8 * hostapd_eid_country_add(u8 *pos, u8 *end, int chan_spacing,
 				    struct hostapd_channel_data *start, @@
-245,6 +269,9 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data
*hapd,
 	/* ERP Information element */
 	pos = hostapd_eid_erp_info(hapd, pos);
 
+	/* Power Constraint element */
+	pos = hostapd_eid_pwr_constraint(hapd, pos);
+
 	/* Extended supported rates */
 	pos = hostapd_eid_ext_supp_rates(hapd, pos);
 
@@ -268,6 +295,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data
*hapd,  #ifdef CONFIG_IEEE80211AC
 	pos = hostapd_eid_vht_capabilities(hapd, pos);
 	pos = hostapd_eid_vht_operation(hapd, pos);
+	pos = hostapd_eid_vht_tpe(hapd, pos);
 #endif /* CONFIG_IEEE80211AC */
 
 	/* Wi-Fi Alliance WMM */
@@ -655,6 +683,9 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
 	/* ERP Information element */
 	tailpos = hostapd_eid_erp_info(hapd, tailpos);
 
+	/* Power Constraint element */
+	pos = hostapd_eid_pwr_constraint(hapd, pos);
+
 	/* Extended supported rates */
 	tailpos = hostapd_eid_ext_supp_rates(hapd, tailpos);
 
@@ -682,6 +713,7 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
#ifdef CONFIG_IEEE80211AC
 	tailpos = hostapd_eid_vht_capabilities(hapd, tailpos);
 	tailpos = hostapd_eid_vht_operation(hapd, tailpos);
+	tailpos = hostapd_eid_vht_tpe(hapd, tailpos);
 #endif /* CONFIG_IEEE80211AC */
 
 	/* Wi-Fi Alliance WMM */
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index
5503af1..e72b3e7 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -175,6 +175,12 @@ 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;
 
+	/* To Do: Also consider driver support for DFS to set Spectrum
Mgmt*/
+	if (hapd->iface->current_mode &&
+	    hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
+	    hapd->iconf->ieee80211h)
+		capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
+
 	return capab;
 }
 
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h index
2aab56d..e1b3b2d 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -47,6 +47,7 @@ u8 * hostapd_eid_ht_capabilities(struct hostapd_data
*hapd, u8 *eid);
 u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid);
 u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid);
 u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid);
+u8 * hostapd_eid_vht_tpe(struct hostapd_data *hapd, u8 *eid);
 int hostapd_ht_operation_update(struct hostapd_iface *iface);  void
ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
 				  const u8 *addr, const u8 *trans_id); diff
--git a/src/ap/ieee802_11_vht.c b/src/ap/ieee802_11_vht.c index
0012c0f..0241fbd 100644
--- a/src/ap/ieee802_11_vht.c
+++ b/src/ap/ieee802_11_vht.c
@@ -81,6 +81,55 @@ u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd,
u8 *eid)
 	return pos;
 }
 
+u8 * hostapd_eid_vht_tpe(struct hostapd_data *hapd, u8 *eid) {
+	#define PWR_IE_CNT_MASK 0x3
+	struct ieee80211_vht_tx_pwr_env *txenv;
+	u8 *pos = eid;
+	u8 pwr_ie_cnt = 0; /* Only 20MHZ info*/
+	u8 size = 0 ;
+
+	if (!hapd->iconf->ieee80211h || !hapd->iconf->ieee80211ac ||
hapd->conf->disable_11ac)
+		return eid;
+		
+	size = sizeof(*txenv) +
+		  ((hapd->iconf->vht_tpe_lpc_40  !=
VHT_TPE_PWR_CONSTRAINT_DISABLE) ? 1 : 0)
+		+ ((hapd->iconf->vht_tpe_lpc_80  !=
VHT_TPE_PWR_CONSTRAINT_DISABLE) ? 1 : 0)
+		+ ((hapd->iconf->vht_tpe_lpc_160 !=
VHT_TPE_PWR_CONSTRAINT_DISABLE) ? 
+1 : 0);
+
+	*pos++ = WLAN_EID_VHT_TRANSMIT_POWER_ENVELOPE;
+	/* Variable Length Structure*/
+	*pos++ = size;
+
+	txenv = (struct ieee80211_vht_tx_pwr_env *) pos;
+	os_memset(txenv, 0 , size);
+
+	/* Mandatory Field*/
+	txenv->vht_local_max_tx_pwr_20 = hapd->iconf->vht_tpe_lpc_20;
+
+	/* Indent ignored to maintain readability and <80 chars */
+	if (hapd->iconf->vht_tpe_lpc_160 != VHT_TPE_PWR_CONSTRAINT_DISABLE)
{
+	txenv->vht_local_max_tx_pwr_opts[0]  = hapd->iconf->vht_tpe_lpc_40;
+	txenv->vht_local_max_tx_pwr_opts[1]  = hapd->iconf->vht_tpe_lpc_80;
+	txenv->vht_local_max_tx_pwr_opts[2]  = hapd->iconf->vht_tpe_lpc_160;
+	pwr_ie_cnt = 3;
+	} else if (hapd->iconf->vht_tpe_lpc_80 !=
VHT_TPE_PWR_CONSTRAINT_DISABLE) {
+	txenv->vht_local_max_tx_pwr_opts[0]  = hapd->iconf->vht_tpe_lpc_40;
+	txenv->vht_local_max_tx_pwr_opts[1]  = hapd->iconf->vht_tpe_lpc_80;
+	pwr_ie_cnt = 2;
+	} else if (hapd->iconf->vht_tpe_lpc_40 !=
VHT_TPE_PWR_CONSTRAINT_DISABLE) {
+	txenv->vht_local_max_tx_pwr_opts[0]  = hapd->iconf->vht_tpe_lpc_40;
+	pwr_ie_cnt = 1;
+	}
+
+	/* Ignore remaining like EIRP as they are by default reserved/0*/
+	txenv->vht_tx_pwr_info = (PWR_IE_CNT_MASK & pwr_ie_cnt);
+
+	pos += size;
+
+	return pos;
+
+}
 
 u16 copy_sta_vht_capab(struct hostapd_data *hapd, struct sta_info *sta,
 		       const u8 *vht_capab, size_t vht_capab_len) diff --git
a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index
137c309..04fd195 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -602,6 +602,14 @@ struct ieee80211_vht_operation {
 	le16 vht_basic_mcs_set;
 } STRUCT_PACKED;
 
+
+struct ieee80211_vht_tx_pwr_env {
+	u8 vht_tx_pwr_info;
+	/* Valid Range -64 dBM to +63 dBm */
+	s8 vht_local_max_tx_pwr_20;
+	s8 vht_local_max_tx_pwr_opts[0];
+} STRUCT_PACKED;
+
 #ifdef _MSC_VER
 #pragma pack(pop)
 #endif /* _MSC_VER */




More information about the Hostap mailing list