Cumulative patch from commit fcd85d9a3f2d9d63d0fa57e93446ad467db75b23
fcd85d9 Add QCA vendor commands/attributes for indoor location
d1723c5 wpa_supplicant: Allow FTM functionality to be published
faecb39 hostapd: Allow FTM functionality to be published
fc72a48 hostapd: Use stations nsts capability in (Re)Association Response frame
22950d0 QCA vendor subcommand for LL_STATS extension
b44d9c7 D-Bus: Add ConfigFile parameter into the interface properties
7dcec24 mka: Clean up key allocation
95e9460 mka: Get rid of struct ieee802_1x_cp_conf
07a6bfe mka: Store cipher suite ID in a u64 instead of u8 pointer
535a8b8 mka: Make csindex unsigned
343eb3b mka: Reorganize live peer creation and key server election
34dbe90 mka: Share a single delete mka implementation
0dabf79 mka: Introduce compare_priorities()
53080f7 mka: Clean up ieee802_1x_kay_mkpdu_sanity_check()
05283e7 mka: Simplify ieee802_1x_mka_dist_sak_body_present()
87b19c8 mka: Replace participant->kay with a local kay variable
f9ea083 mka: Fix typos in grammar in variable names and comments
921171f mka: Use named initializers for mka_body_handler[]
86bef17 mka: Remove unused enum mka_created_mode values
ec958ae mka: Remove cs_len argument from the set_current_cipher_suite functions
46bbda2 mka: Clean up ieee802_1x_mka_decode_potential_peer_body()
cf375eb mka: Simplify ieee802_1x_mka_encode_icv_body() memory copying
8b4a148 mka: Simplify ieee802_1x_mka_sak_use_body_present()
b3df783 mka: Reorganize loops in number of KaY functions
de7f533 mka: Remove unused body_peer incrementation
2b13bca mka: Add reset_participant_mi() helper
3ceb458 mka: Clean up printf formats
8fab9e1 mka: Use named initializers for static structs
d4f668f mka: Add MKA_ALIGN_LENGTH macro
1de7a9f mka: Add helper functions for dumping and creating peer
d9639d1 mka: Clean up ieee802_1x_kay_get_cipher_suite() lookup function
7c547cf mka: Refactor the get_*_peer() functions
515bc1a mka: Fix a typo in mka_body_handler (mak to mka)
a33e3c3 mka: Add a helper function, sci_equal(), for sci comparison
cefeb8e mka: Use less bitfields in the IEEE 802.1X-2010 structs
2e94489 mka: Fix a typo in macsec_capbility
f2f8616 Initialize hapd->nr_db in hostapd_alloc_bss_data()
30e0745 Fix TRACK_STA_LIST before BSS enabled
1f3b8b4 Check for driver initialization before doing driver operations
833d0d4 radius: Sanity check for NULL pointer segfault
Change-Id: I500fe4f62e1a0010ea82c277f73becd2ac2dfa43
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 64daf4c..8c8f7e2 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -582,6 +582,7 @@
u8 radio_measurements[RRM_CAPABILITIES_IE_LEN];
int vendor_vht;
+ int use_sta_nsts;
char *no_probe_resp_if_seen_on;
char *no_auth_if_seen_on;
@@ -591,6 +592,9 @@
#ifdef CONFIG_MBO
int mbo_enabled;
#endif /* CONFIG_MBO */
+
+ int ftm_responder;
+ int ftm_initiator;
};
diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index 532b72f..f139465 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -623,7 +623,7 @@
int hostapd_drv_send_mlme(struct hostapd_data *hapd,
const void *msg, size_t len, int noack)
{
- if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
+ if (!hapd->driver || !hapd->driver->send_mlme || !hapd->drv_priv)
return 0;
return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0,
NULL, 0);
@@ -644,7 +644,7 @@
int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
const u8 *addr, int reason)
{
- if (hapd->driver == NULL || hapd->driver->sta_deauth == NULL)
+ if (!hapd->driver || !hapd->driver->sta_deauth || !hapd->drv_priv)
return 0;
return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr,
reason);
@@ -654,7 +654,7 @@
int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
const u8 *addr, int reason)
{
- if (hapd->driver == NULL || hapd->driver->sta_disassoc == NULL)
+ if (!hapd->driver || !hapd->driver->sta_disassoc || !hapd->drv_priv)
return 0;
return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr,
reason);
@@ -680,7 +680,7 @@
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
- if (hapd->driver == NULL || hapd->driver->send_action == NULL)
+ if (!hapd->driver || !hapd->driver->send_action || !hapd->drv_priv)
return 0;
bssid = hapd->own_addr;
if (!is_multicast_ether_addr(dst) &&
@@ -754,7 +754,7 @@
int hostapd_drv_set_qos_map(struct hostapd_data *hapd,
const u8 *qos_map_set, u8 qos_map_set_len)
{
- if (hapd->driver == NULL || hapd->driver->set_qos_map == NULL)
+ if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv)
return 0;
return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set,
qos_map_set_len);
diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
index 6406d13..0bb7954 100644
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -160,7 +160,7 @@
static inline int hostapd_drv_sta_remove(struct hostapd_data *hapd,
const u8 *addr)
{
- if (hapd->driver == NULL || hapd->driver->sta_remove == NULL)
+ if (!hapd->driver || !hapd->driver->sta_remove || !hapd->drv_priv)
return 0;
return hapd->driver->sta_remove(hapd->drv_priv, addr);
}
@@ -283,7 +283,7 @@
static inline int hostapd_drv_status(struct hostapd_data *hapd, char *buf,
size_t buflen)
{
- if (hapd->driver == NULL || hapd->driver->status == NULL)
+ if (!hapd->driver || !hapd->driver->status || !hapd->drv_priv)
return -1;
return hapd->driver->status(hapd->drv_priv, buf, buflen);
}
@@ -342,7 +342,7 @@
static inline int hostapd_drv_stop_ap(struct hostapd_data *hapd)
{
- if (hapd->driver == NULL || hapd->driver->stop_ap == NULL)
+ if (!hapd->driver || !hapd->driver->stop_ap || !hapd->drv_priv)
return 0;
return hapd->driver->stop_ap(hapd->drv_priv);
}
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 0570ab7..202abe6 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -485,7 +485,7 @@
#ifdef CONFIG_IEEE80211AC
if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
- pos = hostapd_eid_vht_capabilities(hapd, pos);
+ pos = hostapd_eid_vht_capabilities(hapd, pos, 0);
pos = hostapd_eid_vht_operation(hapd, pos);
pos = hostapd_eid_txpower_envelope(hapd, pos);
pos = hostapd_eid_wb_chsw_wrapper(hapd, pos);
@@ -1105,7 +1105,7 @@
#ifdef CONFIG_IEEE80211AC
if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
- tailpos = hostapd_eid_vht_capabilities(hapd, tailpos);
+ tailpos = hostapd_eid_vht_capabilities(hapd, tailpos, 0);
tailpos = hostapd_eid_vht_operation(hapd, tailpos);
tailpos = hostapd_eid_txpower_envelope(hapd, tailpos);
tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos);
diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
index 17a3ea4..23c8c60 100644
--- a/src/ap/ctrl_iface_ap.c
+++ b/src/ap/ctrl_iface_ap.c
@@ -258,7 +258,7 @@
int ret;
u8 *pos;
- if (hapd->driver->send_frame == NULL)
+ if (!hapd->drv_priv || !hapd->driver->send_frame)
return -1;
mgmt = os_zalloc(sizeof(*mgmt) + 100);
@@ -325,7 +325,7 @@
if (pos) {
struct ieee80211_mgmt mgmt;
int encrypt;
- if (hapd->driver->send_frame == NULL)
+ if (!hapd->drv_priv || !hapd->driver->send_frame)
return -1;
pos += 6;
encrypt = atoi(pos);
@@ -388,7 +388,7 @@
if (pos) {
struct ieee80211_mgmt mgmt;
int encrypt;
- if (hapd->driver->send_frame == NULL)
+ if (!hapd->drv_priv || !hapd->driver->send_frame)
return -1;
pos += 6;
encrypt = atoi(pos);
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 65f513d..a09d423 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -912,7 +912,6 @@
return -1;
}
hapd->started = 1;
- dl_list_init(&hapd->nr_db);
if (!first || first == -1) {
u8 *addr = hapd->own_addr;
@@ -2002,6 +2001,7 @@
hapd->driver = hapd->iconf->driver;
hapd->ctrl_sock = -1;
dl_list_init(&hapd->ctrl_dst);
+ dl_list_init(&hapd->nr_db);
return hapd;
}
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index eed5483..2ecd78f 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -1944,7 +1944,23 @@
#ifdef CONFIG_IEEE80211AC
if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
- p = hostapd_eid_vht_capabilities(hapd, p);
+ u32 nsts = 0, sta_nsts;
+
+ if (hapd->conf->use_sta_nsts && sta->vht_capabilities) {
+ struct ieee80211_vht_capabilities *capa;
+
+ nsts = (hapd->iface->conf->vht_capab >>
+ VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
+ capa = sta->vht_capabilities;
+ sta_nsts = (le_to_host32(capa->vht_capabilities_info) >>
+ VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
+
+ if (nsts < sta_nsts)
+ nsts = 0;
+ else
+ nsts = sta_nsts;
+ }
+ p = hostapd_eid_vht_capabilities(hapd, p, nsts);
p = hostapd_eid_vht_operation(hapd, p);
}
#endif /* CONFIG_IEEE80211AC */
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h
index 71b3b49..0327dec 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -50,7 +50,7 @@
u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid);
u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid);
u8 * hostapd_eid_secondary_channel(struct hostapd_data *hapd, u8 *eid);
-u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid);
+u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid, u32 nsts);
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);
diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c
index af858f0..259413b 100644
--- a/src/ap/ieee802_11_shared.c
+++ b/src/ap/ieee802_11_shared.c
@@ -218,6 +218,12 @@
if (hapd->conf->ssid.utf8_ssid)
*pos |= 0x01; /* Bit 48 - UTF-8 SSID */
break;
+ case 8: /* Bits 64-71 */
+ if (hapd->conf->ftm_responder)
+ *pos |= 0x40; /* Bit 70 - FTM responder */
+ if (hapd->conf->ftm_initiator)
+ *pos |= 0x80; /* Bit 71 - FTM initiator */
+ break;
}
}
@@ -237,6 +243,9 @@
len = 1;
if (len < 7 && hapd->conf->ssid.utf8_ssid)
len = 7;
+ if (len < 9 &&
+ (hapd->conf->ftm_initiator || hapd->conf->ftm_responder))
+ len = 9;
#ifdef CONFIG_WNM
if (len < 4)
len = 4;
diff --git a/src/ap/ieee802_11_vht.c b/src/ap/ieee802_11_vht.c
index 0841898..f30f63b 100644
--- a/src/ap/ieee802_11_vht.c
+++ b/src/ap/ieee802_11_vht.c
@@ -20,7 +20,7 @@
#include "dfs.h"
-u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid)
+u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid, u32 nsts)
{
struct ieee80211_vht_capabilities *cap;
struct hostapd_hw_modes *mode = hapd->iface->current_mode;
@@ -50,6 +50,18 @@
cap->vht_capabilities_info = host_to_le32(
hapd->iface->conf->vht_capab);
+ if (nsts != 0) {
+ u32 hapd_nsts;
+
+ hapd_nsts = le_to_host32(cap->vht_capabilities_info);
+ hapd_nsts = (hapd_nsts >> VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
+ cap->vht_capabilities_info &=
+ ~(host_to_le32(hapd_nsts <<
+ VHT_CAP_BEAMFORMEE_STS_OFFSET));
+ cap->vht_capabilities_info |=
+ host_to_le32(nsts << VHT_CAP_BEAMFORMEE_STS_OFFSET);
+ }
+
/* Supported MCS set comes from hw */
os_memcpy(&cap->vht_supported_mcs_set, mode->vht_mcs_set, 8);
@@ -398,7 +410,7 @@
WPA_PUT_BE32(pos, (OUI_BROADCOM << 8) | VENDOR_VHT_TYPE);
pos += 4;
*pos++ = VENDOR_VHT_SUBTYPE;
- pos = hostapd_eid_vht_capabilities(hapd, pos);
+ pos = hostapd_eid_vht_capabilities(hapd, pos, 0);
pos = hostapd_eid_vht_operation(hapd, pos);
return pos;