aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPeng Xu <pxu@qca.qualcomm.com>2016-10-25 17:23:24 (GMT)
committerJouni Malinen <j@w1.fi>2017-02-19 15:37:55 (GMT)
commitd512f406fc733f53d57c494b4751f9af4c6f9957 (patch)
tree1a0a7985a15bcbeb8acb77b3f238ab3255d895c3 /src
parent94380cb40a64094bdaac0122a0123743c569b0b3 (diff)
downloadhostap-d512f406fc733f53d57c494b4751f9af4c6f9957.zip
hostap-d512f406fc733f53d57c494b4751f9af4c6f9957.tar.gz
hostap-d512f406fc733f53d57c494b4751f9af4c6f9957.tar.bz2
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 <jouni@qca.qualcomm.com>
Diffstat (limited to 'src')
-rw-r--r--src/ap/beacon.c28
-rw-r--r--src/ap/ieee802_11.h2
-rw-r--r--src/ap/ieee802_11_he.c101
3 files changed, 131 insertions, 0 deletions
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 3788a97..c6bbda3 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 74ed690..ce3abcb 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 0000000..7d6a84f
--- /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;
+}