RRM: Move neighbor report functions
Move functions corresponding to neighbor report elements to src/ap/neighbor_db.[c,h] in preparation to using them after channel switch from src/ap/drv_callbacks.c. Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
This commit is contained in:
parent
dc67982381
commit
0998d9bd41
3 changed files with 123 additions and 122 deletions
123
src/ap/hostapd.c
123
src/ap/hostapd.c
|
@ -1668,127 +1668,6 @@ void fst_hostapd_fill_iface_obj(struct hostapd_data *hapd,
|
||||||
|
|
||||||
#endif /* CONFIG_FST */
|
#endif /* CONFIG_FST */
|
||||||
|
|
||||||
|
|
||||||
#ifdef NEED_AP_MLME
|
|
||||||
static enum nr_chan_width hostapd_get_nr_chan_width(struct hostapd_data *hapd,
|
|
||||||
int ht, int vht)
|
|
||||||
{
|
|
||||||
if (!ht && !vht)
|
|
||||||
return NR_CHAN_WIDTH_20;
|
|
||||||
if (!hapd->iconf->secondary_channel)
|
|
||||||
return NR_CHAN_WIDTH_20;
|
|
||||||
if (!vht || hapd->iconf->vht_oper_chwidth == VHT_CHANWIDTH_USE_HT)
|
|
||||||
return NR_CHAN_WIDTH_40;
|
|
||||||
if (hapd->iconf->vht_oper_chwidth == VHT_CHANWIDTH_80MHZ)
|
|
||||||
return NR_CHAN_WIDTH_80;
|
|
||||||
if (hapd->iconf->vht_oper_chwidth == VHT_CHANWIDTH_160MHZ)
|
|
||||||
return NR_CHAN_WIDTH_160;
|
|
||||||
if (hapd->iconf->vht_oper_chwidth == VHT_CHANWIDTH_80P80MHZ)
|
|
||||||
return NR_CHAN_WIDTH_80P80;
|
|
||||||
return NR_CHAN_WIDTH_20;
|
|
||||||
}
|
|
||||||
#endif /* NEED_AP_MLME */
|
|
||||||
|
|
||||||
|
|
||||||
static void hostapd_set_own_neighbor_report(struct hostapd_data *hapd)
|
|
||||||
{
|
|
||||||
#ifdef NEED_AP_MLME
|
|
||||||
u16 capab = hostapd_own_capab_info(hapd);
|
|
||||||
int ht = hapd->iconf->ieee80211n && !hapd->conf->disable_11n;
|
|
||||||
int vht = hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac;
|
|
||||||
struct wpa_ssid_value ssid;
|
|
||||||
u8 channel, op_class;
|
|
||||||
u8 center_freq1_idx = 0, center_freq2_idx = 0;
|
|
||||||
enum nr_chan_width width;
|
|
||||||
u32 bssid_info;
|
|
||||||
struct wpabuf *nr;
|
|
||||||
|
|
||||||
if (!(hapd->conf->radio_measurements[0] &
|
|
||||||
WLAN_RRM_CAPS_NEIGHBOR_REPORT))
|
|
||||||
return;
|
|
||||||
|
|
||||||
bssid_info = 3; /* AP is reachable */
|
|
||||||
bssid_info |= NEI_REP_BSSID_INFO_SECURITY; /* "same as the AP" */
|
|
||||||
bssid_info |= NEI_REP_BSSID_INFO_KEY_SCOPE; /* "same as the AP" */
|
|
||||||
|
|
||||||
if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT)
|
|
||||||
bssid_info |= NEI_REP_BSSID_INFO_SPECTRUM_MGMT;
|
|
||||||
|
|
||||||
bssid_info |= NEI_REP_BSSID_INFO_RM; /* RRM is supported */
|
|
||||||
|
|
||||||
if (hapd->conf->wmm_enabled) {
|
|
||||||
bssid_info |= NEI_REP_BSSID_INFO_QOS;
|
|
||||||
|
|
||||||
if (hapd->conf->wmm_uapsd &&
|
|
||||||
(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_UAPSD))
|
|
||||||
bssid_info |= NEI_REP_BSSID_INFO_APSD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ht) {
|
|
||||||
bssid_info |= NEI_REP_BSSID_INFO_HT |
|
|
||||||
NEI_REP_BSSID_INFO_DELAYED_BA;
|
|
||||||
|
|
||||||
/* VHT bit added in IEEE P802.11-REVmc/D4.3 */
|
|
||||||
if (vht)
|
|
||||||
bssid_info |= NEI_REP_BSSID_INFO_VHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Set NEI_REP_BSSID_INFO_MOBILITY_DOMAIN if MDE is set */
|
|
||||||
|
|
||||||
if (ieee80211_freq_to_channel_ext(hapd->iface->freq,
|
|
||||||
hapd->iconf->secondary_channel,
|
|
||||||
hapd->iconf->vht_oper_chwidth,
|
|
||||||
&op_class, &channel) ==
|
|
||||||
NUM_HOSTAPD_MODES)
|
|
||||||
return;
|
|
||||||
width = hostapd_get_nr_chan_width(hapd, ht, vht);
|
|
||||||
if (vht) {
|
|
||||||
center_freq1_idx = hapd->iconf->vht_oper_centr_freq_seg0_idx;
|
|
||||||
if (width == NR_CHAN_WIDTH_80P80)
|
|
||||||
center_freq2_idx =
|
|
||||||
hapd->iconf->vht_oper_centr_freq_seg1_idx;
|
|
||||||
} else if (ht) {
|
|
||||||
ieee80211_freq_to_chan(hapd->iface->freq +
|
|
||||||
10 * hapd->iconf->secondary_channel,
|
|
||||||
¢er_freq1_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
ssid.ssid_len = hapd->conf->ssid.ssid_len;
|
|
||||||
os_memcpy(ssid.ssid, hapd->conf->ssid.ssid, ssid.ssid_len);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Neighbor Report element size = BSSID + BSSID info + op_class + chan +
|
|
||||||
* phy type + wide bandwidth channel subelement.
|
|
||||||
*/
|
|
||||||
nr = wpabuf_alloc(ETH_ALEN + 4 + 1 + 1 + 1 + 5);
|
|
||||||
if (!nr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
wpabuf_put_data(nr, hapd->own_addr, ETH_ALEN);
|
|
||||||
wpabuf_put_le32(nr, bssid_info);
|
|
||||||
wpabuf_put_u8(nr, op_class);
|
|
||||||
wpabuf_put_u8(nr, channel);
|
|
||||||
wpabuf_put_u8(nr, ieee80211_get_phy_type(hapd->iface->freq, ht, vht));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Wide Bandwidth Channel subelement may be needed to allow the
|
|
||||||
* receiving STA to send packets to the AP. See IEEE P802.11-REVmc/D5.0
|
|
||||||
* Figure 9-301.
|
|
||||||
*/
|
|
||||||
wpabuf_put_u8(nr, WNM_NEIGHBOR_WIDE_BW_CHAN);
|
|
||||||
wpabuf_put_u8(nr, 3);
|
|
||||||
wpabuf_put_u8(nr, width);
|
|
||||||
wpabuf_put_u8(nr, center_freq1_idx);
|
|
||||||
wpabuf_put_u8(nr, center_freq2_idx);
|
|
||||||
|
|
||||||
hostapd_neighbor_set(hapd, hapd->own_addr, &ssid, nr, hapd->iconf->lci,
|
|
||||||
hapd->iconf->civic, hapd->iconf->stationary_ap);
|
|
||||||
|
|
||||||
wpabuf_free(nr);
|
|
||||||
#endif /* NEED_AP_MLME */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_OWE
|
#ifdef CONFIG_OWE
|
||||||
|
|
||||||
static int hostapd_owe_iface_iter(struct hostapd_iface *iface, void *ctx)
|
static int hostapd_owe_iface_iter(struct hostapd_iface *iface, void *ctx)
|
||||||
|
@ -2085,7 +1964,7 @@ dfs_offload:
|
||||||
iface->interfaces->terminate_on_error--;
|
iface->interfaces->terminate_on_error--;
|
||||||
|
|
||||||
for (j = 0; j < iface->num_bss; j++)
|
for (j = 0; j < iface->num_bss; j++)
|
||||||
hostapd_set_own_neighbor_report(iface->bss[j]);
|
hostapd_neighbor_set_own_report(iface->bss[j]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include "utils/common.h"
|
#include "utils/common.h"
|
||||||
#include "hostapd.h"
|
#include "hostapd.h"
|
||||||
|
#include "ieee802_11.h"
|
||||||
#include "neighbor_db.h"
|
#include "neighbor_db.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -134,3 +135,123 @@ void hostapd_free_neighbor_db(struct hostapd_data *hapd)
|
||||||
os_free(nr);
|
os_free(nr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef NEED_AP_MLME
|
||||||
|
static enum nr_chan_width hostapd_get_nr_chan_width(struct hostapd_data *hapd,
|
||||||
|
int ht, int vht)
|
||||||
|
{
|
||||||
|
if (!ht && !vht)
|
||||||
|
return NR_CHAN_WIDTH_20;
|
||||||
|
if (!hapd->iconf->secondary_channel)
|
||||||
|
return NR_CHAN_WIDTH_20;
|
||||||
|
if (!vht || hapd->iconf->vht_oper_chwidth == VHT_CHANWIDTH_USE_HT)
|
||||||
|
return NR_CHAN_WIDTH_40;
|
||||||
|
if (hapd->iconf->vht_oper_chwidth == VHT_CHANWIDTH_80MHZ)
|
||||||
|
return NR_CHAN_WIDTH_80;
|
||||||
|
if (hapd->iconf->vht_oper_chwidth == VHT_CHANWIDTH_160MHZ)
|
||||||
|
return NR_CHAN_WIDTH_160;
|
||||||
|
if (hapd->iconf->vht_oper_chwidth == VHT_CHANWIDTH_80P80MHZ)
|
||||||
|
return NR_CHAN_WIDTH_80P80;
|
||||||
|
return NR_CHAN_WIDTH_20;
|
||||||
|
}
|
||||||
|
#endif /* NEED_AP_MLME */
|
||||||
|
|
||||||
|
|
||||||
|
void hostapd_neighbor_set_own_report(struct hostapd_data *hapd)
|
||||||
|
{
|
||||||
|
#ifdef NEED_AP_MLME
|
||||||
|
u16 capab = hostapd_own_capab_info(hapd);
|
||||||
|
int ht = hapd->iconf->ieee80211n && !hapd->conf->disable_11n;
|
||||||
|
int vht = hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac;
|
||||||
|
struct wpa_ssid_value ssid;
|
||||||
|
u8 channel, op_class;
|
||||||
|
u8 center_freq1_idx = 0, center_freq2_idx = 0;
|
||||||
|
enum nr_chan_width width;
|
||||||
|
u32 bssid_info;
|
||||||
|
struct wpabuf *nr;
|
||||||
|
|
||||||
|
if (!(hapd->conf->radio_measurements[0] &
|
||||||
|
WLAN_RRM_CAPS_NEIGHBOR_REPORT))
|
||||||
|
return;
|
||||||
|
|
||||||
|
bssid_info = 3; /* AP is reachable */
|
||||||
|
bssid_info |= NEI_REP_BSSID_INFO_SECURITY; /* "same as the AP" */
|
||||||
|
bssid_info |= NEI_REP_BSSID_INFO_KEY_SCOPE; /* "same as the AP" */
|
||||||
|
|
||||||
|
if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT)
|
||||||
|
bssid_info |= NEI_REP_BSSID_INFO_SPECTRUM_MGMT;
|
||||||
|
|
||||||
|
bssid_info |= NEI_REP_BSSID_INFO_RM; /* RRM is supported */
|
||||||
|
|
||||||
|
if (hapd->conf->wmm_enabled) {
|
||||||
|
bssid_info |= NEI_REP_BSSID_INFO_QOS;
|
||||||
|
|
||||||
|
if (hapd->conf->wmm_uapsd &&
|
||||||
|
(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_UAPSD))
|
||||||
|
bssid_info |= NEI_REP_BSSID_INFO_APSD;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ht) {
|
||||||
|
bssid_info |= NEI_REP_BSSID_INFO_HT |
|
||||||
|
NEI_REP_BSSID_INFO_DELAYED_BA;
|
||||||
|
|
||||||
|
/* VHT bit added in IEEE P802.11-REVmc/D4.3 */
|
||||||
|
if (vht)
|
||||||
|
bssid_info |= NEI_REP_BSSID_INFO_VHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Set NEI_REP_BSSID_INFO_MOBILITY_DOMAIN if MDE is set */
|
||||||
|
|
||||||
|
if (ieee80211_freq_to_channel_ext(hapd->iface->freq,
|
||||||
|
hapd->iconf->secondary_channel,
|
||||||
|
hapd->iconf->vht_oper_chwidth,
|
||||||
|
&op_class, &channel) ==
|
||||||
|
NUM_HOSTAPD_MODES)
|
||||||
|
return;
|
||||||
|
width = hostapd_get_nr_chan_width(hapd, ht, vht);
|
||||||
|
if (vht) {
|
||||||
|
center_freq1_idx = hapd->iconf->vht_oper_centr_freq_seg0_idx;
|
||||||
|
if (width == NR_CHAN_WIDTH_80P80)
|
||||||
|
center_freq2_idx =
|
||||||
|
hapd->iconf->vht_oper_centr_freq_seg1_idx;
|
||||||
|
} else if (ht) {
|
||||||
|
ieee80211_freq_to_chan(hapd->iface->freq +
|
||||||
|
10 * hapd->iconf->secondary_channel,
|
||||||
|
¢er_freq1_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssid.ssid_len = hapd->conf->ssid.ssid_len;
|
||||||
|
os_memcpy(ssid.ssid, hapd->conf->ssid.ssid, ssid.ssid_len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Neighbor Report element size = BSSID + BSSID info + op_class + chan +
|
||||||
|
* phy type + wide bandwidth channel subelement.
|
||||||
|
*/
|
||||||
|
nr = wpabuf_alloc(ETH_ALEN + 4 + 1 + 1 + 1 + 5);
|
||||||
|
if (!nr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wpabuf_put_data(nr, hapd->own_addr, ETH_ALEN);
|
||||||
|
wpabuf_put_le32(nr, bssid_info);
|
||||||
|
wpabuf_put_u8(nr, op_class);
|
||||||
|
wpabuf_put_u8(nr, channel);
|
||||||
|
wpabuf_put_u8(nr, ieee80211_get_phy_type(hapd->iface->freq, ht, vht));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wide Bandwidth Channel subelement may be needed to allow the
|
||||||
|
* receiving STA to send packets to the AP. See IEEE P802.11-REVmc/D5.0
|
||||||
|
* Figure 9-301.
|
||||||
|
*/
|
||||||
|
wpabuf_put_u8(nr, WNM_NEIGHBOR_WIDE_BW_CHAN);
|
||||||
|
wpabuf_put_u8(nr, 3);
|
||||||
|
wpabuf_put_u8(nr, width);
|
||||||
|
wpabuf_put_u8(nr, center_freq1_idx);
|
||||||
|
wpabuf_put_u8(nr, center_freq2_idx);
|
||||||
|
|
||||||
|
hostapd_neighbor_set(hapd, hapd->own_addr, &ssid, nr, hapd->iconf->lci,
|
||||||
|
hapd->iconf->civic, hapd->iconf->stationary_ap);
|
||||||
|
|
||||||
|
wpabuf_free(nr);
|
||||||
|
#endif /* NEED_AP_MLME */
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid,
|
||||||
const struct wpa_ssid_value *ssid,
|
const struct wpa_ssid_value *ssid,
|
||||||
const struct wpabuf *nr, const struct wpabuf *lci,
|
const struct wpabuf *nr, const struct wpabuf *lci,
|
||||||
const struct wpabuf *civic, int stationary);
|
const struct wpabuf *civic, int stationary);
|
||||||
|
void hostapd_neighbor_set_own_report(struct hostapd_data *hapd);
|
||||||
int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
|
int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
|
||||||
const struct wpa_ssid_value *ssid);
|
const struct wpa_ssid_value *ssid);
|
||||||
void hostapd_free_neighbor_db(struct hostapd_data *hapd);
|
void hostapd_free_neighbor_db(struct hostapd_data *hapd);
|
||||||
|
|
Loading…
Add table
Reference in a new issue