WNM: Event report handling for BSS color collision and in-use
Add support for WNM event report handling for the BSS color collision and in use events. Co-developed-by: Ryder Lee <ryder.lee@mediatek.com> Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com> Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
This commit is contained in:
parent
97405be969
commit
faa4102926
2 changed files with 167 additions and 0 deletions
131
src/ap/wnm_ap.c
131
src/ap/wnm_ap.c
|
@ -643,6 +643,133 @@ static void ieee802_11_rx_wnm_coloc_intf_report(struct hostapd_data *hapd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const char * wnm_event_type2str(enum wnm_event_report_type wtype)
|
||||||
|
{
|
||||||
|
#define W2S(wtype) case WNM_EVENT_TYPE_ ## wtype: return #wtype;
|
||||||
|
switch (wtype) {
|
||||||
|
W2S(TRANSITION)
|
||||||
|
W2S(RSNA)
|
||||||
|
W2S(P2P_LINK)
|
||||||
|
W2S(WNM_LOG)
|
||||||
|
W2S(BSS_COLOR_COLLISION)
|
||||||
|
W2S(BSS_COLOR_IN_USE)
|
||||||
|
}
|
||||||
|
return "UNKNOWN";
|
||||||
|
#undef W2S
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ieee802_11_rx_wnm_event_report(struct hostapd_data *hapd,
|
||||||
|
const u8 *addr, const u8 *buf,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
struct sta_info *sta;
|
||||||
|
u8 dialog_token;
|
||||||
|
struct wnm_event_report_element *report_ie;
|
||||||
|
const u8 *pos = buf, *end = buf + len;
|
||||||
|
const size_t fixed_field_len = 3; /* Event Token/Type/Report Status */
|
||||||
|
#ifdef CONFIG_IEEE80211AX
|
||||||
|
const size_t tsf_len = 8;
|
||||||
|
u8 color;
|
||||||
|
u64 bitmap;
|
||||||
|
#endif /* CONFIG_IEEE80211AX */
|
||||||
|
|
||||||
|
if (end - pos < 1 + 2) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"WNM: Ignore too short WNM Event Report frame from "
|
||||||
|
MACSTR, MAC2STR(addr));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog_token = *pos++;
|
||||||
|
report_ie = (struct wnm_event_report_element *) pos;
|
||||||
|
|
||||||
|
if (end - pos < 2 + report_ie->len ||
|
||||||
|
report_ie->len < fixed_field_len) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"WNM: Ignore truncated WNM Event Report frame from "
|
||||||
|
MACSTR, MAC2STR(addr));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (report_ie->eid != WLAN_EID_EVENT_REPORT ||
|
||||||
|
report_ie->status != WNM_STATUS_SUCCESSFUL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "WNM: Received WNM Event Report frame from "
|
||||||
|
MACSTR " dialog_token=%u event_token=%u type=%d (%s)",
|
||||||
|
MAC2STR(addr), dialog_token, report_ie->token,
|
||||||
|
report_ie->type, wnm_event_type2str(report_ie->type));
|
||||||
|
|
||||||
|
pos += 2 + fixed_field_len;
|
||||||
|
wpa_hexdump(MSG_MSGDUMP, "WNM: Event Report", pos, end - pos);
|
||||||
|
|
||||||
|
sta = ap_get_sta(hapd, addr);
|
||||||
|
if (!sta || !(sta->flags & WLAN_STA_ASSOC)) {
|
||||||
|
wpa_printf(MSG_DEBUG, "Station " MACSTR
|
||||||
|
" not found for received WNM Event Report",
|
||||||
|
MAC2STR(addr));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (report_ie->type) {
|
||||||
|
#ifdef CONFIG_IEEE80211AX
|
||||||
|
case WNM_EVENT_TYPE_BSS_COLOR_COLLISION:
|
||||||
|
if (!hapd->iconf->ieee80211ax || hapd->conf->disable_11ax)
|
||||||
|
return;
|
||||||
|
if (report_ie->len <
|
||||||
|
fixed_field_len + tsf_len + 8) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"WNM: Too short BSS color collision event report from "
|
||||||
|
MACSTR, MAC2STR(addr));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bitmap = WPA_GET_LE64(report_ie->u.bss_color_collision.color_bitmap);
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"WNM: BSS color collision bitmap 0x%llx reported by "
|
||||||
|
MACSTR, (unsigned long long) bitmap, MAC2STR(addr));
|
||||||
|
hostapd_switch_color(hapd->iface->bss[0], bitmap);
|
||||||
|
break;
|
||||||
|
case WNM_EVENT_TYPE_BSS_COLOR_IN_USE:
|
||||||
|
if (!hapd->iconf->ieee80211ax || hapd->conf->disable_11ax)
|
||||||
|
return;
|
||||||
|
if (report_ie->len < fixed_field_len + tsf_len + 1) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"WNM: Too short BSS color in use event report from "
|
||||||
|
MACSTR, MAC2STR(addr));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
color = report_ie->u.bss_color_in_use.color;
|
||||||
|
if (color > 63) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"WNM: Invalid BSS color %u report from "
|
||||||
|
MACSTR, color, MAC2STR(addr));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (color == 0) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"WNM: BSS color use report canceled by "
|
||||||
|
MACSTR, MAC2STR(addr));
|
||||||
|
/* TODO: Clear stored color from the collision bitmap
|
||||||
|
* if there are no other users for it. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wpa_printf(MSG_DEBUG, "WNM: BSS color %u use report by "
|
||||||
|
MACSTR, color, MAC2STR(addr));
|
||||||
|
hapd->color_collision_bitmap |= 1ULL << color;
|
||||||
|
break;
|
||||||
|
#endif /* CONFIG_IEEE80211AX */
|
||||||
|
default:
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"WNM Event Report type=%d (%s) not supported",
|
||||||
|
report_ie->type,
|
||||||
|
wnm_event_type2str(report_ie->type));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int ieee802_11_rx_wnm_action_ap(struct hostapd_data *hapd,
|
int ieee802_11_rx_wnm_action_ap(struct hostapd_data *hapd,
|
||||||
const struct ieee80211_mgmt *mgmt, size_t len)
|
const struct ieee80211_mgmt *mgmt, size_t len)
|
||||||
{
|
{
|
||||||
|
@ -658,6 +785,10 @@ int ieee802_11_rx_wnm_action_ap(struct hostapd_data *hapd,
|
||||||
plen = len - IEEE80211_HDRLEN - 2;
|
plen = len - IEEE80211_HDRLEN - 2;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
|
case WNM_EVENT_REPORT:
|
||||||
|
ieee802_11_rx_wnm_event_report(hapd, mgmt->sa, payload,
|
||||||
|
plen);
|
||||||
|
return 0;
|
||||||
case WNM_BSS_TRANS_MGMT_QUERY:
|
case WNM_BSS_TRANS_MGMT_QUERY:
|
||||||
ieee802_11_rx_bss_trans_mgmt_query(hapd, mgmt->sa, payload,
|
ieee802_11_rx_bss_trans_mgmt_query(hapd, mgmt->sa, payload,
|
||||||
plen);
|
plen);
|
||||||
|
|
|
@ -1959,6 +1959,42 @@ enum wnm_notification_Type {
|
||||||
WNM_NOTIF_TYPE_VENDOR_SPECIFIC = 221,
|
WNM_NOTIF_TYPE_VENDOR_SPECIFIC = 221,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wnm_event_report_element {
|
||||||
|
u8 eid; /* WLAN_EID_EVENT_REPORT */
|
||||||
|
u8 len;
|
||||||
|
u8 token;
|
||||||
|
u8 type;
|
||||||
|
u8 status;
|
||||||
|
/* Followed by conditional fields */
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
u8 tsf[8]; /* Event TSF */
|
||||||
|
u8 color_bitmap[8]; /* Event Report field */
|
||||||
|
} STRUCT_PACKED bss_color_collision;
|
||||||
|
struct {
|
||||||
|
u8 tsf[8]; /* Event TSF */
|
||||||
|
u8 color; /* Event Report field */
|
||||||
|
} STRUCT_PACKED bss_color_in_use;
|
||||||
|
} u;
|
||||||
|
} STRUCT_PACKED;
|
||||||
|
|
||||||
|
enum wnm_event_report_status {
|
||||||
|
WNM_STATUS_SUCCESSFUL = 0,
|
||||||
|
WNM_STATUS_REQ_FAILED = 1,
|
||||||
|
WNM_STATUS_REQ_REFUSED = 2,
|
||||||
|
WNM_STATUS_REQ_INCAPABLE = 3,
|
||||||
|
WNM_STATUS_FREQUENT_TRANSITION = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum wnm_event_report_type {
|
||||||
|
WNM_EVENT_TYPE_TRANSITION = 0,
|
||||||
|
WNM_EVENT_TYPE_RSNA = 1,
|
||||||
|
WNM_EVENT_TYPE_P2P_LINK = 2,
|
||||||
|
WNM_EVENT_TYPE_WNM_LOG = 3,
|
||||||
|
WNM_EVENT_TYPE_BSS_COLOR_COLLISION = 4,
|
||||||
|
WNM_EVENT_TYPE_BSS_COLOR_IN_USE = 5,
|
||||||
|
};
|
||||||
|
|
||||||
/* Channel Switch modes (802.11h) */
|
/* Channel Switch modes (802.11h) */
|
||||||
#define CHAN_SWITCH_MODE_ALLOW_TX 0
|
#define CHAN_SWITCH_MODE_ALLOW_TX 0
|
||||||
#define CHAN_SWITCH_MODE_BLOCK_TX 1
|
#define CHAN_SWITCH_MODE_BLOCK_TX 1
|
||||||
|
|
Loading…
Reference in a new issue