MSCS: Add support to send MSCS Request frames
Add support to send MSCS add/change/remove types of Action frames to the connected AP. Signed-off-by: Vinita S. Maloo <vmaloo@codeaurora.org>
This commit is contained in:
parent
1733e356e4
commit
a118047245
7 changed files with 215 additions and 1 deletions
|
@ -478,6 +478,8 @@
|
|||
#define WLAN_EID_EXT_HE_6GHZ_BAND_CAP 59
|
||||
#define WLAN_EID_EXT_EDMG_CAPABILITIES 61
|
||||
#define WLAN_EID_EXT_EDMG_OPERATION 62
|
||||
#define WLAN_EID_EXT_MSCS_DESCRIPTOR 88
|
||||
#define WLAN_EID_EXT_TCLAS_MASK 89
|
||||
#define WLAN_EID_EXT_REJECTED_GROUPS 92
|
||||
#define WLAN_EID_EXT_ANTI_CLOGGING_TOKEN 93
|
||||
|
||||
|
@ -562,6 +564,7 @@
|
|||
#define WLAN_EXT_CAPAB_SAE_PW_ID 81
|
||||
#define WLAN_EXT_CAPAB_SAE_PW_ID_EXCLUSIVELY 82
|
||||
#define WLAN_EXT_CAPAB_BEACON_PROTECTION 84
|
||||
#define WLAN_EXT_CAPAB_MSCS 85
|
||||
#define WLAN_EXT_CAPAB_SAE_PK_EXCLUSIVELY 88
|
||||
|
||||
/* Extended RSN Capabilities */
|
||||
|
@ -2340,4 +2343,20 @@ enum edmg_bw_config {
|
|||
/* DPP Public Action frame identifiers - OUI_WFA */
|
||||
#define DPP_OUI_TYPE 0x1A
|
||||
|
||||
/* Robust AV streaming Action field values */
|
||||
enum robust_av_streaming_action {
|
||||
ROBUST_AV_SCS_REQ = 0,
|
||||
ROBUST_AV_SCS_RESP = 1,
|
||||
ROBUST_AV_GROUP_MEMBERSHIP_REQ = 2,
|
||||
ROBUST_AV_GROUP_MEMBERSHIP_RESP = 3,
|
||||
ROBUST_AV_MSCS_REQ = 4,
|
||||
ROBUST_AV_MSCS_RESP = 5,
|
||||
};
|
||||
|
||||
enum scs_request_type {
|
||||
SCS_REQ_ADD = 0,
|
||||
SCS_REQ_REMOVE = 1,
|
||||
SCS_REQ_CHANGE = 2,
|
||||
};
|
||||
|
||||
#endif /* IEEE802_11_DEFS_H */
|
||||
|
|
|
@ -98,6 +98,7 @@ OBJS += src/utils/crc32.c
|
|||
OBJS += wmm_ac.c
|
||||
OBJS += op_classes.c
|
||||
OBJS += rrm.c
|
||||
OBJS += robust_av.c
|
||||
OBJS_p = wpa_passphrase.c
|
||||
OBJS_p += src/utils/common.c
|
||||
OBJS_p += src/utils/wpa_debug.c
|
||||
|
|
|
@ -107,6 +107,7 @@ OBJS += ../src/utils/ip_addr.o
|
|||
OBJS += ../src/utils/crc32.o
|
||||
OBJS += op_classes.o
|
||||
OBJS += rrm.o
|
||||
OBJS += robust_av.o
|
||||
OBJS_p = wpa_passphrase.o
|
||||
OBJS_p += ../src/utils/common.o
|
||||
OBJS_p += ../src/utils/wpa_debug.o
|
||||
|
|
|
@ -8483,6 +8483,7 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
|
|||
wpa_s->next_scan_bssid_wildcard_ssid = 0;
|
||||
os_free(wpa_s->select_network_scan_freqs);
|
||||
wpa_s->select_network_scan_freqs = NULL;
|
||||
os_memset(&wpa_s->robust_av, 0, sizeof(struct robust_av_data));
|
||||
|
||||
wpa_bss_flush(wpa_s);
|
||||
if (!dl_list_empty(&wpa_s->bss)) {
|
||||
|
@ -8508,6 +8509,8 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
|
|||
wpa_supplicant_update_channel_list(wpa_s, NULL);
|
||||
|
||||
free_bss_tmp_disallowed(wpa_s);
|
||||
|
||||
os_memset(&wpa_s->robust_av, 0, sizeof(struct robust_av_data));
|
||||
}
|
||||
|
||||
|
||||
|
@ -10342,6 +10345,76 @@ static int wpas_ctrl_cmd_debug_level(const char *cmd)
|
|||
}
|
||||
|
||||
|
||||
static int wpas_ctrl_iface_configure_mscs(struct wpa_supplicant *wpa_s,
|
||||
const char *cmd)
|
||||
{
|
||||
size_t frame_classifier_len;
|
||||
const char *pos, *end;
|
||||
struct robust_av_data *robust_av = &wpa_s->robust_av;
|
||||
int val;
|
||||
|
||||
/*
|
||||
* format:
|
||||
* <add|remove|change> [up_bitmap=<hex byte>] [up_limit=<integer>]
|
||||
* [stream_timeout=<in TUs>] [frame_classifier=<hex bytes>]
|
||||
*/
|
||||
os_memset(robust_av, 0, sizeof(struct robust_av_data));
|
||||
if (os_strncmp(cmd, "add ", 4) == 0) {
|
||||
robust_av->request_type = SCS_REQ_ADD;
|
||||
} else if (os_strcmp(cmd, "remove") == 0) {
|
||||
robust_av->request_type = SCS_REQ_REMOVE;
|
||||
robust_av->valid_config = false;
|
||||
return wpas_send_mscs_req(wpa_s);
|
||||
} else if (os_strncmp(cmd, "change ", 7) == 0) {
|
||||
robust_av->request_type = SCS_REQ_CHANGE;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pos = os_strstr(cmd, "up_bitmap=");
|
||||
if (!pos)
|
||||
return -1;
|
||||
|
||||
val = hex2byte(pos + 10);
|
||||
if (val < 0)
|
||||
return -1;
|
||||
robust_av->up_bitmap = val;
|
||||
|
||||
pos = os_strstr(cmd, "up_limit=");
|
||||
if (!pos)
|
||||
return -1;
|
||||
|
||||
robust_av->up_limit = atoi(pos + 9);
|
||||
|
||||
pos = os_strstr(cmd, "stream_timeout=");
|
||||
if (!pos)
|
||||
return -1;
|
||||
|
||||
robust_av->stream_timeout = atoi(pos + 15);
|
||||
if (robust_av->stream_timeout == 0)
|
||||
return -1;
|
||||
|
||||
pos = os_strstr(cmd, "frame_classifier=");
|
||||
if (!pos)
|
||||
return -1;
|
||||
|
||||
pos += 17;
|
||||
end = os_strchr(pos, ' ');
|
||||
if (!end)
|
||||
end = pos + os_strlen(pos);
|
||||
|
||||
frame_classifier_len = (end - pos) / 2;
|
||||
if (frame_classifier_len > sizeof(robust_av->frame_classifier) ||
|
||||
hexstr2bin(pos, robust_av->frame_classifier, frame_classifier_len))
|
||||
return -1;
|
||||
|
||||
robust_av->frame_classifier_len = frame_classifier_len;
|
||||
robust_av->valid_config = true;
|
||||
|
||||
return wpas_send_mscs_req(wpa_s);
|
||||
}
|
||||
|
||||
|
||||
char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
||||
char *buf, size_t *resp_len)
|
||||
{
|
||||
|
@ -11233,6 +11306,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
|||
reply_len = -1;
|
||||
#endif /* CONFIG_DPP2 */
|
||||
#endif /* CONFIG_DPP */
|
||||
} else if (os_strncmp(buf, "MSCS ", 5) == 0) {
|
||||
if (wpas_ctrl_iface_configure_mscs(wpa_s, buf + 5))
|
||||
reply_len = -1;
|
||||
} else {
|
||||
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
|
||||
reply_len = 16;
|
||||
|
|
98
wpa_supplicant/robust_av.c
Normal file
98
wpa_supplicant/robust_av.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* wpa_supplicant - Robust AV procedures
|
||||
* Copyright (c) 2020, The Linux Foundation
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
#include "common/wpa_ctrl.h"
|
||||
#include "wpa_supplicant_i.h"
|
||||
#include "driver_i.h"
|
||||
#include "bss.h"
|
||||
|
||||
|
||||
void wpas_populate_mscs_descriptor_ie(struct robust_av_data *robust_av,
|
||||
struct wpabuf *buf)
|
||||
{
|
||||
u8 *len, *len1;
|
||||
|
||||
/* MSCS descriptor element */
|
||||
wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
|
||||
len = wpabuf_put(buf, 1);
|
||||
wpabuf_put_u8(buf, WLAN_EID_EXT_MSCS_DESCRIPTOR);
|
||||
wpabuf_put_u8(buf, robust_av->request_type);
|
||||
wpabuf_put_u8(buf, robust_av->up_bitmap);
|
||||
wpabuf_put_u8(buf, robust_av->up_limit);
|
||||
wpabuf_put_le32(buf, robust_av->stream_timeout);
|
||||
|
||||
if (robust_av->request_type != SCS_REQ_REMOVE) {
|
||||
/* TCLAS mask element */
|
||||
wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
|
||||
len1 = wpabuf_put(buf, 1);
|
||||
wpabuf_put_u8(buf, WLAN_EID_EXT_TCLAS_MASK);
|
||||
|
||||
/* Frame classifier */
|
||||
wpabuf_put_data(buf, robust_av->frame_classifier,
|
||||
robust_av->frame_classifier_len);
|
||||
*len1 = (u8 *) wpabuf_put(buf, 0) - len1 - 1;
|
||||
}
|
||||
|
||||
*len = (u8 *) wpabuf_put(buf, 0) - len - 1;
|
||||
}
|
||||
|
||||
|
||||
int wpas_send_mscs_req(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
struct wpabuf *buf;
|
||||
const u8 *ext_capab = NULL;
|
||||
size_t buf_len;
|
||||
int ret;
|
||||
|
||||
if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid)
|
||||
return 0;
|
||||
|
||||
if (wpa_s->current_bss)
|
||||
ext_capab = wpa_bss_get_ie(wpa_s->current_bss,
|
||||
WLAN_EID_EXT_CAPAB);
|
||||
|
||||
if (!ext_capab || ext_capab[1] < 11 || !(ext_capab[12] & 0x20)) {
|
||||
wpa_dbg(wpa_s, MSG_INFO,
|
||||
"AP does not support MSCS - could not send MSCS Req");
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf_len = 3 + /* Action frame header */
|
||||
3 + /* MSCS descriptor IE header */
|
||||
1 + /* Request type */
|
||||
2 + /* User priority control */
|
||||
4 + /* Stream timeout */
|
||||
3 + /* TCLAS Mask IE header */
|
||||
wpa_s->robust_av.frame_classifier_len;
|
||||
|
||||
buf = wpabuf_alloc(buf_len);
|
||||
if (!buf) {
|
||||
wpa_printf(MSG_ERROR, "Failed to allocate MSCS req");
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpabuf_put_u8(buf, WLAN_ACTION_ROBUST_AV_STREAMING);
|
||||
wpabuf_put_u8(buf, ROBUST_AV_MSCS_REQ);
|
||||
wpa_s->robust_av.dialog_token++;
|
||||
wpabuf_put_u8(buf, wpa_s->robust_av.dialog_token);
|
||||
|
||||
/* MSCS descriptor element */
|
||||
wpas_populate_mscs_descriptor_ie(&wpa_s->robust_av, buf);
|
||||
|
||||
wpa_hexdump_buf(MSG_MSGDUMP, "MSCS Request", wpabuf_head(buf));
|
||||
ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
|
||||
wpa_s->own_addr, wpa_s->bssid,
|
||||
wpabuf_head(buf), wpabuf_len(buf), 0);
|
||||
if (ret < 0)
|
||||
wpa_dbg(wpa_s, MSG_INFO, "MSCS: Failed to send MSCS Request");
|
||||
|
||||
wpabuf_free(buf);
|
||||
return ret;
|
||||
}
|
|
@ -1899,6 +1899,9 @@ static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
|
|||
*pos |= 0x01;
|
||||
#endif /* CONFIG_FILS */
|
||||
break;
|
||||
case 10: /* Bits 80-87 */
|
||||
*pos |= 0x20; /* Bit 85 - Mirrored SCS */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1906,7 +1909,7 @@ static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
|
|||
int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen)
|
||||
{
|
||||
u8 *pos = buf;
|
||||
u8 len = 10, i;
|
||||
u8 len = 11, i;
|
||||
|
||||
if (len < wpa_s->extended_capa_len)
|
||||
len = wpa_s->extended_capa_len;
|
||||
|
|
|
@ -491,6 +491,17 @@ struct driver_signal_override {
|
|||
int scan_level;
|
||||
};
|
||||
|
||||
struct robust_av_data {
|
||||
u8 dialog_token;
|
||||
enum scs_request_type request_type;
|
||||
u8 up_bitmap;
|
||||
u8 up_limit;
|
||||
u32 stream_timeout;
|
||||
u8 frame_classifier[48];
|
||||
size_t frame_classifier_len;
|
||||
bool valid_config;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wpa_supplicant - Internal data for wpa_supplicant interface
|
||||
*
|
||||
|
@ -1315,6 +1326,7 @@ struct wpa_supplicant {
|
|||
unsigned int multi_ap_ie:1;
|
||||
unsigned int multi_ap_backhaul:1;
|
||||
unsigned int multi_ap_fronthaul:1;
|
||||
struct robust_av_data robust_av;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1623,4 +1635,8 @@ int wpa_is_fils_sk_pfs_supported(struct wpa_supplicant *wpa_s);
|
|||
|
||||
void wpas_clear_driver_signal_override(struct wpa_supplicant *wpa_s);
|
||||
|
||||
int wpas_send_mscs_req(struct wpa_supplicant *wpa_s);
|
||||
void wpas_populate_mscs_descriptor_ie(struct robust_av_data *robust_av,
|
||||
struct wpabuf *buf);
|
||||
|
||||
#endif /* WPA_SUPPLICANT_I_H */
|
||||
|
|
Loading…
Reference in a new issue