Do not store dynamic HT IEs in configuration structures
The configuration data should only store the static configuration data and not dynamic data. In addition, storing HT configuration and state in IEs is not the easiest way of doing this, so use more convenient data types for storing configuration and dynamic state. The HT IEs are then generated based on the static configuration and dynamic state whenever needed.
This commit is contained in:
parent
71b6ae1425
commit
edd360e170
7 changed files with 87 additions and 98 deletions
|
@ -386,18 +386,19 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
|
|||
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
if (hapd->conf->ieee80211n) {
|
||||
u8 *start;
|
||||
start = tailpos;
|
||||
tailpos = hostapd_eid_ht_capabilities_info(hapd, tailpos);
|
||||
tailpos = hostapd_eid_ht_operation(hapd, tailpos);
|
||||
|
||||
if (hostapd_set_ht_capability(
|
||||
hapd->conf->iface, hapd,
|
||||
&hapd->conf->ht_capabilities.data)) {
|
||||
if (hostapd_set_ht_capability(hapd->conf->iface, hapd,
|
||||
start + 2)) {
|
||||
wpa_printf(MSG_ERROR, "Could not set HT capabilities "
|
||||
"for kernel driver");
|
||||
}
|
||||
if (hostapd_set_ht_operation(
|
||||
hapd->conf->iface, hapd,
|
||||
&hapd->conf->ht_operation.data))
|
||||
|
||||
start = tailpos;
|
||||
tailpos = hostapd_eid_ht_operation(hapd, tailpos);
|
||||
if (hostapd_set_ht_operation(hapd->conf->iface, hapd,
|
||||
start + 2))
|
||||
wpa_printf(MSG_ERROR, "Could not set HT operation for "
|
||||
"kernel driver");
|
||||
}
|
||||
|
|
|
@ -184,54 +184,6 @@ static void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
|
|||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
static int hostapd_config_defaults_bss_80211n(struct hostapd_bss_config *bss)
|
||||
{
|
||||
u16 capabilities_info = 0;
|
||||
u16 operation_mode = 0;
|
||||
|
||||
if (bss == NULL)
|
||||
return -1;
|
||||
|
||||
/* add default values to HT capabilities parameters */
|
||||
os_memset(&bss->ht_capabilities, 0, sizeof(struct ht_cap_ie));
|
||||
bss->ht_capabilities.id = WLAN_EID_HT_CAP;
|
||||
bss->ht_capabilities.length = HT_CAPABILITIES_LEN;
|
||||
|
||||
#if 0 /* FIX: remove? was commented out */
|
||||
bss->ht_capabilities.mac_ht_param_info.max_rx_ampdu_factor =
|
||||
MAX_RX_AMPDU_FACTOR_64KB;
|
||||
#endif
|
||||
SET_2BIT_U8(&bss->ht_capabilities.data.mac_ht_params_info,
|
||||
MAC_HT_PARAM_INFO_MAX_RX_AMPDU_FACTOR_OFFSET,
|
||||
MAX_RX_AMPDU_FACTOR_64KB);
|
||||
|
||||
SET_2BIT_LE16(&capabilities_info,
|
||||
HT_CAP_INFO_MIMO_PWR_SAVE_OFFSET,
|
||||
MIMO_PWR_NO_LIMIT_ON_MIMO_SEQS);
|
||||
|
||||
capabilities_info |= HT_CAP_INFO_GREEN_FIELD;
|
||||
|
||||
bss->ht_capabilities.data.capabilities_info =
|
||||
host_to_le16(capabilities_info);
|
||||
|
||||
bss->ht_capabilities.data.supported_mcs_set[0] = 0xff;
|
||||
bss->ht_capabilities.data.supported_mcs_set[1] = 0xff;
|
||||
|
||||
/* add default values to HT operation parameters */
|
||||
os_memset(&bss->ht_operation, 0, sizeof(struct ht_operation_ie));
|
||||
bss->ht_operation.id = WLAN_EID_HT_OPERATION;
|
||||
bss->ht_operation.length = HT_OPERATION_LEN;
|
||||
SET_2BIT_LE16(&operation_mode,
|
||||
HT_INFO_OPERATION_MODE_OP_MODE_OFFSET,
|
||||
OP_MODE_PURE);
|
||||
bss->ht_operation.data.operation_mode = host_to_le16(operation_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
|
||||
|
||||
static struct hostapd_config * hostapd_config_defaults(void)
|
||||
{
|
||||
struct hostapd_config *conf;
|
||||
|
@ -294,7 +246,11 @@ static struct hostapd_config * hostapd_config_defaults(void)
|
|||
conf->wme_ac_params[3] = ac_vo;
|
||||
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
hostapd_config_defaults_bss_80211n(bss);
|
||||
SET_2BIT_LE16(&bss->ht_capab,
|
||||
HT_CAP_INFO_MIMO_PWR_SAVE_OFFSET,
|
||||
MIMO_PWR_NO_LIMIT_ON_MIMO_SEQS);
|
||||
|
||||
bss->ht_capab |= HT_CAP_INFO_GREEN_FIELD;
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
|
||||
return conf;
|
||||
|
|
|
@ -19,9 +19,6 @@
|
|||
#include "defs.h"
|
||||
#include "ip_addr.h"
|
||||
#include "wpa_common.h"
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
#include "ieee802_11_defs.h"
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
|
||||
#ifndef IFNAMSIZ
|
||||
#define IFNAMSIZ 16
|
||||
|
@ -279,12 +276,8 @@ struct hostapd_bss_config {
|
|||
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
int ieee80211n;
|
||||
/* TODO: these structures should not really be used here; move to
|
||||
* struct hostapd_data or struct hostapd_iface and just include the
|
||||
* needed values here for generating IEs elsewhere */
|
||||
struct ht_cap_ie ht_capabilities;
|
||||
struct ht_operation_ie ht_operation;
|
||||
int ht_op_mode_fixed;
|
||||
u16 ht_capab;
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
};
|
||||
|
||||
|
|
|
@ -743,25 +743,25 @@ hostapd_set_radius_acl_expire(struct hostapd_data *hapd, const u8 *mac)
|
|||
#ifdef CONFIG_IEEE80211N
|
||||
static inline int
|
||||
hostapd_set_ht_capability(const char *ifname, struct hostapd_data *hapd,
|
||||
const struct ieee80211_ht_capability *ht_cap)
|
||||
const u8 *ht_cap)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_ht_capability == NULL ||
|
||||
ht_cap == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_ht_capability(
|
||||
ifname, hapd->drv_priv, (const u8 *) ht_cap,
|
||||
ifname, hapd->drv_priv, ht_cap,
|
||||
sizeof(struct ieee80211_ht_capability));
|
||||
}
|
||||
|
||||
static inline int
|
||||
hostapd_set_ht_operation(const char *ifname, struct hostapd_data *hapd,
|
||||
const struct ieee80211_ht_operation *ht_operation)
|
||||
const u8 *ht_operation)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_ht_operation == NULL ||
|
||||
ht_operation == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_ht_operation(
|
||||
ifname, hapd->drv_priv, (const u8 *) ht_operation,
|
||||
ifname, hapd->drv_priv, ht_operation,
|
||||
sizeof(struct ieee80211_ht_operation));
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
|
|
|
@ -1563,6 +1563,12 @@ static int setup_interface1(struct hostapd_iface *iface)
|
|||
if (hostapd_validate_bssid_configuration(iface))
|
||||
return -1;
|
||||
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
SET_2BIT_LE16(&iface->ht_op_mode,
|
||||
HT_INFO_OPERATION_MODE_OP_MODE_OFFSET,
|
||||
OP_MODE_PURE);
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
|
||||
os_memcpy(country, hapd->iconf->country, 3);
|
||||
country[3] = '\0';
|
||||
if (hostapd_set_country(hapd, country) < 0) {
|
||||
|
|
|
@ -244,6 +244,10 @@ struct hostapd_iface {
|
|||
struct hostapd_config_change *change;
|
||||
hostapd_iface_cb reload_iface_cb;
|
||||
hostapd_iface_cb config_reload_cb;
|
||||
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
u16 ht_op_mode;
|
||||
#endif /* CONFIG_IEEE80211N */
|
||||
};
|
||||
|
||||
void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
|
|
|
@ -105,19 +105,50 @@ u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid)
|
|||
|
||||
u8 * hostapd_eid_ht_capabilities_info(struct hostapd_data *hapd, u8 *eid)
|
||||
{
|
||||
struct ieee80211_ht_capability *cap;
|
||||
u8 *pos = eid;
|
||||
os_memcpy(pos, &hapd->conf->ht_capabilities, sizeof(struct ht_cap_ie));
|
||||
pos += sizeof(struct ht_cap_ie);
|
||||
|
||||
if (!hapd->conf->ieee80211n)
|
||||
return eid;
|
||||
|
||||
*pos++ = WLAN_EID_HT_CAP;
|
||||
*pos++ = sizeof(*cap);
|
||||
|
||||
cap = (struct ieee80211_ht_capability *) pos;
|
||||
os_memset(cap, 0, sizeof(*cap));
|
||||
SET_2BIT_U8(&cap->mac_ht_params_info,
|
||||
MAC_HT_PARAM_INFO_MAX_RX_AMPDU_FACTOR_OFFSET,
|
||||
MAX_RX_AMPDU_FACTOR_64KB);
|
||||
|
||||
cap->capabilities_info = host_to_le16(hapd->conf->ht_capab);
|
||||
|
||||
cap->supported_mcs_set[0] = 0xff;
|
||||
cap->supported_mcs_set[1] = 0xff;
|
||||
|
||||
pos += sizeof(*cap);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid)
|
||||
{
|
||||
struct ieee80211_ht_operation *oper;
|
||||
u8 *pos = eid;
|
||||
os_memcpy(pos, &hapd->conf->ht_operation,
|
||||
sizeof(struct ht_operation_ie));
|
||||
pos += sizeof(struct ht_operation_ie);
|
||||
|
||||
if (!hapd->conf->ieee80211n)
|
||||
return eid;
|
||||
|
||||
*pos++ = WLAN_EID_HT_OPERATION;
|
||||
*pos++ = sizeof(*oper);
|
||||
|
||||
oper = (struct ieee80211_ht_operation *) pos;
|
||||
os_memset(oper, 0, sizeof(*oper));
|
||||
|
||||
oper->operation_mode = host_to_le16(hapd->iface->ht_op_mode);
|
||||
|
||||
pos += sizeof(*oper);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
@ -136,8 +167,6 @@ Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
|
|||
*/
|
||||
int hostapd_ht_operation_update(struct hostapd_iface *iface)
|
||||
{
|
||||
struct ht_operation_ie *ht_operation;
|
||||
u16 operation_mode = 0;
|
||||
u16 cur_op_mode, new_op_mode;
|
||||
int op_mode_changes = 0;
|
||||
struct hostapd_data *hapd = iface->bss[0];
|
||||
|
@ -148,29 +177,31 @@ int hostapd_ht_operation_update(struct hostapd_iface *iface)
|
|||
if (!hapd->conf->ieee80211n || hapd->conf->ht_op_mode_fixed)
|
||||
return 0;
|
||||
|
||||
ht_operation = &hapd->conf->ht_operation;
|
||||
operation_mode = le_to_host16(ht_operation->data.operation_mode);
|
||||
wpa_printf(MSG_DEBUG, "%s current operation mode=0x%X",
|
||||
__func__, operation_mode);
|
||||
__func__, iface->ht_op_mode);
|
||||
|
||||
if ((operation_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) == 0
|
||||
if (!(iface->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)
|
||||
&& iface->num_sta_ht_no_gf) {
|
||||
operation_mode |= HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
|
||||
iface->ht_op_mode |=
|
||||
HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
|
||||
op_mode_changes++;
|
||||
} else if ((operation_mode &
|
||||
} else if ((iface->ht_op_mode &
|
||||
HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
|
||||
iface->num_sta_ht_no_gf == 0) {
|
||||
operation_mode &= ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
|
||||
iface->ht_op_mode &=
|
||||
~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
|
||||
op_mode_changes++;
|
||||
}
|
||||
|
||||
if ((operation_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) == 0
|
||||
&& (iface->num_sta_no_ht || iface->olbc_ht)) {
|
||||
operation_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
|
||||
if (!(iface->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
|
||||
(iface->num_sta_no_ht || iface->olbc_ht)) {
|
||||
iface->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
|
||||
op_mode_changes++;
|
||||
} else if ((operation_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT)
|
||||
&& (iface->num_sta_no_ht == 0 && iface->olbc_ht == 0)) {
|
||||
operation_mode &= ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
|
||||
} else if ((iface->ht_op_mode &
|
||||
HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
|
||||
(iface->num_sta_no_ht == 0 && !iface->olbc_ht)) {
|
||||
iface->ht_op_mode &=
|
||||
~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
|
||||
op_mode_changes++;
|
||||
}
|
||||
|
||||
|
@ -180,27 +211,25 @@ int hostapd_ht_operation_update(struct hostapd_iface *iface)
|
|||
*/
|
||||
new_op_mode = 0;
|
||||
if (iface->num_sta_no_ht ||
|
||||
(operation_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
|
||||
(iface->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
|
||||
new_op_mode = OP_MODE_MIXED;
|
||||
else if ((hapd->conf->ht_capabilities.data.capabilities_info &
|
||||
HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
|
||||
iface->num_sta_ht_20mhz)
|
||||
else if ((hapd->conf->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
|
||||
iface->num_sta_ht_20mhz)
|
||||
new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
|
||||
else if (iface->olbc_ht)
|
||||
new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
|
||||
else
|
||||
new_op_mode = OP_MODE_PURE;
|
||||
|
||||
cur_op_mode = operation_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
|
||||
cur_op_mode = iface->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
|
||||
if (cur_op_mode != new_op_mode) {
|
||||
operation_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
|
||||
operation_mode |= new_op_mode;
|
||||
iface->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
|
||||
iface->ht_op_mode |= new_op_mode;
|
||||
op_mode_changes++;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s new operation mode=0x%X changes=%d",
|
||||
__func__, operation_mode, op_mode_changes);
|
||||
ht_operation->data.operation_mode = host_to_le16(operation_mode);
|
||||
__func__, iface->ht_op_mode, op_mode_changes);
|
||||
|
||||
return op_mode_changes;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue