From: Daniel Gabay <daniel.gabay@xxxxxxxxx> Align MSCS response hanlding as described in section 11.25.3 of Draft P802.11REVme_D4.0: 1. AP may send unsolicited MSCS response using dialog_token == 0. Instead of dropping the frame due to dialog_token mismatch, accept it and set the status accordingly. 2. If an MSCS descriptor element is present in a MSCS response frame that does not indicate a status of "SUCCESS", the request type field is set to "change" - the element indicates a suggested set of parameters that could be accepted by the AP in response to a subsequent request by the non-AP STA. Handle both action frame and (Re)Association response with change request by extending WPA_EVENT_MSCS_RESULT with the change values. Note: since we extend MSCS_RESULT event, move the original event from both action frame / assoc response handlers to a common function that handles now both 'change' and other response. Signed-off-by: Daniel Gabay <daniel.gabay@xxxxxxxxx> --- wpa_supplicant/robust_av.c | 87 +++++++++++++++++++++++++++++++++----- 1 file changed, 77 insertions(+), 10 deletions(-) diff --git a/wpa_supplicant/robust_av.c b/wpa_supplicant/robust_av.c index 3a095603eb..b421143aee 100644 --- a/wpa_supplicant/robust_av.c +++ b/wpa_supplicant/robust_av.c @@ -664,27 +664,95 @@ void free_up_scs_desc(struct scs_robust_av_data *data) } +static void wpas_parse_mscs_resp(struct wpa_supplicant *wpa_s, + u16 status, const u8 *bssid, + const u8 *mscs_desc_ie) +{ + struct robust_av_data robust_av; + const u8 *pos; + + /* it is optional in robust av action frame */ + if (!mscs_desc_ie) + goto event_mscs_result; + + /* ext_id(1) + request type(1) + upc(2) + stream timeout(4) */ + if (mscs_desc_ie[1] < 8) { + wpa_printf(MSG_INFO, + "MSCS: Drop received frame: invalid descriptor IE len: %d", + mscs_desc_ie[1]); + return; + } + + os_memset(&robust_av, 0, sizeof(struct robust_av_data)); + + pos = &mscs_desc_ie[3]; + robust_av.request_type = *pos++; + + switch (robust_av.request_type) { + case SCS_REQ_CHANGE: + /* + * inform the suggested set of parameters that could be accepted + * by the AP in response to a subsequent request by the station + */ + robust_av.up_bitmap = *pos++; + robust_av.up_limit = *pos++; + robust_av.stream_timeout = WPA_GET_LE32(pos); + wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_MSCS_RESULT "bssid=" MACSTR + " status_code=%u change up_bitmap=%u up_limit=%u stream_timeout=%u", + MAC2STR(bssid), status, robust_av.up_bitmap, + robust_av.up_limit, robust_av.stream_timeout); + wpa_s->mscs_setup_done = false; + return; + case SCS_REQ_ADD: + /* + * this type is used in assoc response MSCS descriptor element + * if no change required. + */ + break; + default: + wpa_printf(MSG_INFO, + "MSCS: Drop received frame with invalid type: %u", + robust_av.request_type); + return; + } + +event_mscs_result: + wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_MSCS_RESULT "bssid=" MACSTR + " status_code=%u", MAC2STR(bssid), status); + wpa_s->mscs_setup_done = status == WLAN_STATUS_SUCCESS; +} + void wpas_handle_robust_av_recv_action(struct wpa_supplicant *wpa_s, const u8 *src, const u8 *buf, size_t len) { u8 dialog_token; u16 status_code; + const u8 *pos = buf; + const u8 *mscs_desc_ie; if (len < 3) return; - dialog_token = *buf++; - if (dialog_token != wpa_s->robust_av.dialog_token) { + dialog_token = *pos++; + /* AP sets dialog token to 0 for unsolicited response */ + if (!dialog_token && !wpa_s->mscs_setup_done) { wpa_printf(MSG_INFO, - "MSCS: Drop received frame due to dialog token mismatch: received:%u expected:%u", + "MSCS: Drop unsolicited received frame: inactive"); + return; + } else if (dialog_token && + dialog_token != wpa_s->robust_av.dialog_token) { + wpa_printf(MSG_INFO, + "MSCS: Drop frame: dialog token mismatch (got:%u expected:%u", dialog_token, wpa_s->robust_av.dialog_token); return; } - status_code = WPA_GET_LE16(buf); - wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_MSCS_RESULT "bssid=" MACSTR - " status_code=%u", MAC2STR(src), status_code); - wpa_s->mscs_setup_done = status_code == WLAN_STATUS_SUCCESS; + status_code = WPA_GET_LE16(pos); + + /* skip 3 bytes of dialog token(1) + status code(2) */ + mscs_desc_ie = get_ie_ext(buf + 3, len - 3, + WLAN_EID_EXT_MSCS_DESCRIPTOR); + wpas_parse_mscs_resp(wpa_s, status_code, src, mscs_desc_ie); } @@ -712,9 +780,8 @@ void wpas_handle_assoc_resp_mscs(struct wpa_supplicant *wpa_s, const u8 *bssid, return; status = WPA_GET_LE16(mscs_status + 2); - wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_MSCS_RESULT "bssid=" MACSTR - " status_code=%u", MAC2STR(bssid), status); - wpa_s->mscs_setup_done = status == WLAN_STATUS_SUCCESS; + + wpas_parse_mscs_resp(wpa_s, status, bssid, mscs_desc_ie); } -- 2.43.0 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap