Do not store dynamic HT IEs in configuration structures
authorJouni Malinen <jouni.malinen@atheros.com>
Fri, 22 Aug 2008 17:55:52 +0000 (20:55 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 22 Aug 2008 17:55:52 +0000 (20:55 +0300)
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
hostapd/config.c
hostapd/config.h
hostapd/driver.h
hostapd/hostapd.c
hostapd/hostapd.h
hostapd/ieee802_11.c

index 1235275..05dcbb5 100644 (file)
@@ -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");
        }
index 8c1ac2d..16f2a8e 100644 (file)
@@ -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;
index eb27d81..977f815 100644 (file)
@@ -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 */
 };
 
index 3ec87a1..6746c8c 100644 (file)
@@ -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 */
index e9d9647..d9f39e6 100644 (file)
@@ -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) {
index 4f5fcd4..6f4832e 100644 (file)
@@ -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,
index c1071a7..bdade7a 100644 (file)
@@ -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;
 }