From edd360e170f15caa614bf4bb3847f5937b0517e5 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 22 Aug 2008 20:55:52 +0300 Subject: [PATCH] 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. --- hostapd/beacon.c | 17 +++++---- hostapd/config.c | 54 +++------------------------ hostapd/config.h | 9 +---- hostapd/driver.h | 8 ++-- hostapd/hostapd.c | 6 +++ hostapd/hostapd.h | 4 ++ hostapd/ieee802_11.c | 87 +++++++++++++++++++++++++++++--------------- 7 files changed, 87 insertions(+), 98 deletions(-) diff --git a/hostapd/beacon.c b/hostapd/beacon.c index 1235275b3..05dcbb53e 100644 --- a/hostapd/beacon.c +++ b/hostapd/beacon.c @@ -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"); } diff --git a/hostapd/config.c b/hostapd/config.c index 8c1ac2d90..16f2a8e12 100644 --- a/hostapd/config.c +++ b/hostapd/config.c @@ -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; diff --git a/hostapd/config.h b/hostapd/config.h index eb27d8144..977f815fd 100644 --- a/hostapd/config.h +++ b/hostapd/config.h @@ -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 */ }; diff --git a/hostapd/driver.h b/hostapd/driver.h index 3ec87a10b..6746c8c71 100644 --- a/hostapd/driver.h +++ b/hostapd/driver.h @@ -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 */ diff --git a/hostapd/hostapd.c b/hostapd/hostapd.c index e9d964760..d9f39e62f 100644 --- a/hostapd/hostapd.c +++ b/hostapd/hostapd.c @@ -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) { diff --git a/hostapd/hostapd.h b/hostapd/hostapd.h index 4f5fcd466..6f4832e1b 100644 --- a/hostapd/hostapd.h +++ b/hostapd/hostapd.h @@ -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, diff --git a/hostapd/ieee802_11.c b/hostapd/ieee802_11.c index c1071a7d1..bdade7a77 100644 --- a/hostapd/ieee802_11.c +++ b/hostapd/ieee802_11.c @@ -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; }