diff mbox series

[1/3] MSCS: Extend MSCS response handling

Message ID 20231226094525.502618-1-andrei.otcheretianski@intel.com
State Accepted
Headers show
Series [1/3] MSCS: Extend MSCS response handling | expand

Commit Message

Andrei Otcheretianski Dec. 26, 2023, 9:45 a.m. UTC
From: Daniel Gabay <daniel.gabay@intel.com>

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@intel.com>
---
 wpa_supplicant/robust_av.c | 87 +++++++++++++++++++++++++++++++++-----
 1 file changed, 77 insertions(+), 10 deletions(-)

Comments

Jouni Malinen Jan. 14, 2024, 10:46 a.m. UTC | #1
On Tue, Dec 26, 2023 at 11:45:23AM +0200, Andrei Otcheretianski wrote:
> 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.

Thanks, all three patches applied.
diff mbox series

Patch

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);
 }