From d512f406fc733f53d57c494b4751f9af4c6f9957 Mon Sep 17 00:00:00 2001 From: Peng Xu Date: Tue, 25 Oct 2016 10:23:24 -0700 Subject: [PATCH] hostapd: Add IEEE 802.11ax HE IEs into Beacon/Probe Response frames IEEE 802.11ax HE changes to include HE IEs in Beacon and Probe Response frames. These elements are using vendor specific forms for now since the IEEE 802.11ax draft is not yet finalized and the element contents is subject to change. Signed-off-by: Jouni Malinen --- hostapd/Android.mk | 4 ++ hostapd/Makefile | 1 + src/ap/beacon.c | 28 +++++++++++ src/ap/ieee802_11.h | 2 + src/ap/ieee802_11_he.c | 101 ++++++++++++++++++++++++++++++++++++++ wpa_supplicant/Android.mk | 3 ++ wpa_supplicant/Makefile | 3 ++ 7 files changed, 142 insertions(+) create mode 100644 src/ap/ieee802_11_he.c diff --git a/hostapd/Android.mk b/hostapd/Android.mk index 102172c8a..17cc39114 100644 --- a/hostapd/Android.mk +++ b/hostapd/Android.mk @@ -917,6 +917,10 @@ ifdef CONFIG_IEEE80211AC OBJS += src/ap/ieee802_11_vht.c endif +ifdef CONFIG_IEEE80211AX +OBJS += src/ap/ieee802_11_he.c +endif + ifdef CONFIG_P2P_MANAGER L_CFLAGS += -DCONFIG_P2P_MANAGER OBJS += src/ap/p2p_hostapd.c diff --git a/hostapd/Makefile b/hostapd/Makefile index ca17c8484..3160d0deb 100644 --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -327,6 +327,7 @@ endif ifdef CONFIG_IEEE80211AX CFLAGS += -DCONFIG_IEEE80211AX +OBJS += ../src/ap/ieee802_11_he.o endif ifdef CONFIG_MBO diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 3788a9764..c6bbda3cc 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -392,6 +392,13 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, 2 + sizeof(struct ieee80211_vht_operation); } +#ifdef CONFIG_IEEE80211AX + if (hapd->iconf->ieee80211ax) { + buflen += 4 + sizeof (struct ieee80211_he_capabilities) + + 4 + sizeof (struct ieee80211_he_operation); + } +#endif + buflen += hostapd_mbo_ie_len(hapd); resp = os_zalloc(buflen); @@ -500,6 +507,13 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, pos = hostapd_eid_vendor_vht(hapd, pos); #endif /* CONFIG_IEEE80211AC */ +#ifdef CONFIG_IEEE80211AX + if (hapd->iconf->ieee80211ax) { + pos = hostapd_eid_vendor_he_capab(hapd, pos); + pos = hostapd_eid_vendor_he_operation(hapd, pos); + } +#endif /* CONFIG_IEEE80211AX */ + /* Wi-Fi Alliance WMM */ pos = hostapd_eid_wmm(hapd, pos); @@ -1040,6 +1054,13 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, } #endif /* CONFIG_IEEE80211AC */ +#ifdef CONFIG_IEEE80211AX + if (hapd->iconf->ieee80211ax) { + tail_len += 4 + sizeof (struct ieee80211_he_capabilities) + + 4 + sizeof (struct ieee80211_he_operation); + } +#endif + tail_len += hostapd_mbo_ie_len(hapd); tailpos = tail = os_malloc(tail_len); @@ -1171,6 +1192,13 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, tailpos = hostapd_eid_vendor_vht(hapd, tailpos); #endif /* CONFIG_IEEE80211AC */ +#ifdef CONFIG_IEEE80211AX + if (hapd->iconf->ieee80211ax) { + tailpos = hostapd_eid_vendor_he_capab(hapd, tailpos); + tailpos = hostapd_eid_vendor_he_operation(hapd, tailpos); + } +#endif /* CONFIG_IEEE80211AX */ + /* Wi-Fi Alliance WMM */ tailpos = hostapd_eid_wmm(hapd, tailpos); diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h index 74ed69013..ce3abcbb0 100644 --- a/src/ap/ieee802_11.h +++ b/src/ap/ieee802_11.h @@ -55,6 +55,8 @@ u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_vendor_vht(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid); +u8 * hostapd_eid_vendor_he_capab(struct hostapd_data *hapd, u8 *eid); +u8 * hostapd_eid_vendor_he_operation(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, diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c new file mode 100644 index 000000000..7d6a84fcc --- /dev/null +++ b/src/ap/ieee802_11_he.c @@ -0,0 +1,101 @@ +/* + * hostapd / IEEE 802.11ax HE + * Copyright (c) 2016-2017, Qualcomm Atheros, Inc. + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "utils/includes.h" + +#include "utils/common.h" +#include "common/ieee802_11_defs.h" +#include "common/qca-vendor.h" +#include "hostapd.h" +#include "ap_config.h" +#include "beacon.h" +#include "ieee802_11.h" +#include "dfs.h" + +u8 * hostapd_eid_vendor_he_capab(struct hostapd_data *hapd, u8 *eid) +{ + struct ieee80211_he_capabilities *cap; + u8 *pos = eid; + + if (!hapd->iface->current_mode) + return eid; + + /* For now, use a vendor specific element since the P802.11ax draft is + * still subject to changes and the contents of this element may change. + * This can be replaced with the actual element once P802.11ax is + * finalized. */ + /* Vendor HE Capabilities element */ + *pos++ = WLAN_EID_VENDOR_SPECIFIC; + *pos++ = 4 /* The Vendor OUI, subtype */ + + sizeof(struct ieee80211_he_capabilities); + + WPA_PUT_BE32(pos, (OUI_QCA << 8) | QCA_VENDOR_ELEM_HE_CAPAB); + pos += 4; + cap = (struct ieee80211_he_capabilities *) pos; + os_memset(cap, 0, sizeof(*cap)); + + if (hapd->iface->conf->he_phy_capab.he_su_beamformer) + cap->he_phy_capab_info[HE_PHYCAP_SU_BEAMFORMER_CAPAB_IDX] |= + HE_PHYCAP_SU_BEAMFORMER_CAPAB; + + if (hapd->iface->conf->he_phy_capab.he_su_beamformee) + cap->he_phy_capab_info[HE_PHYCAP_SU_BEAMFORMEE_CAPAB_IDX] |= + HE_PHYCAP_SU_BEAMFORMEE_CAPAB; + + if (hapd->iface->conf->he_phy_capab.he_mu_beamformer) + cap->he_phy_capab_info[HE_PHYCAP_MU_BEAMFORMER_CAPAB_IDX] |= + HE_PHYCAP_MU_BEAMFORMER_CAPAB; + + pos += sizeof(*cap); + + return pos; +} + + +u8 * hostapd_eid_vendor_he_operation(struct hostapd_data *hapd, u8 *eid) +{ + struct ieee80211_he_operation *oper; + u8 *pos = eid; + + if (!hapd->iface->current_mode) + return eid; + + /* For now, use a vendor specific element since the P802.11ax draft is + * still subject to changes and the contents of this element may change. + * This can be replaced with the actual element once P802.11ax is + * finalized. */ + /* Vendor HE Operation element */ + *pos++ = WLAN_EID_VENDOR_SPECIFIC; + *pos++ = 4 /* The Vendor OUI, subtype */ + + sizeof(struct ieee80211_he_operation); + + WPA_PUT_BE32(pos, (OUI_QCA << 8) | QCA_VENDOR_ELEM_HE_OPER); + pos += 4; + oper = (struct ieee80211_he_operation *) pos; + os_memset(oper, 0, sizeof(*oper)); + + if (hapd->iface->conf->he_op.he_bss_color) + oper->he_oper_params |= hapd->iface->conf->he_op.he_bss_color; + + if (hapd->iface->conf->he_op.he_default_pe_duration) + oper->he_oper_params |= + (hapd->iface->conf->he_op.he_default_pe_duration << + HE_OPERATION_DFLT_PE_DURATION_OFFSET); + + if (hapd->iface->conf->he_op.he_twt_required) + oper->he_oper_params |= HE_OPERATION_TWT_REQUIRED; + + if (hapd->iface->conf->he_op.he_rts_threshold) + oper->he_oper_params |= + (hapd->iface->conf->he_op.he_rts_threshold << + HE_OPERATION_RTS_THRESHOLD_OFFSET); + + pos += sizeof(*oper); + + return pos; +} diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk index 448f954a2..dd8af4d62 100644 --- a/wpa_supplicant/Android.mk +++ b/wpa_supplicant/Android.mk @@ -827,6 +827,9 @@ OBJS += src/ap/ieee802_11_ht.c ifdef CONFIG_IEEE80211AC OBJS += src/ap/ieee802_11_vht.c endif +ifdef CONFIG_IEEE80211AX +OBJS += src/ap/ieee802_11_he.c +endif endif ifdef CONFIG_WNM OBJS += src/ap/wnm_ap.c diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index 65b55c208..7bcb7e431 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -868,6 +868,9 @@ OBJS += ../src/ap/ieee802_11_ht.o ifdef CONFIG_IEEE80211AC OBJS += ../src/ap/ieee802_11_vht.o endif +ifdef CONFIG_IEEE80211AX +OBJS += ../src/ap/ieee802_11_he.o +endif endif ifdef CONFIG_WNM OBJS += ../src/ap/wnm_ap.o