From edfca280cbe85d0364f4d039bd6394b1bb57c496 Mon Sep 17 00:00:00 2001 From: Purushottam Kushwaha Date: Tue, 18 Apr 2023 19:34:19 +0530 Subject: [PATCH] SCS: Add support for optional QoS Charateristics parameters Per IEEE P802.11be/D4.0, 9.4.2.316 (QoS Characteristics element), enable support for the following optional QoS Characteristics parameters: - Maximum MSDU Size - Service Start Time - Service Start Time LinkID - Mean Data Rate - Delayed Bounded Burst Size - MSDU Lifetime - MSDU Delivery Info - Medium Time Signed-off-by: Purushottam Kushwaha --- src/common/ieee802_11_defs.h | 13 ++++++ wpa_supplicant/ctrl_iface.c | 58 ++++++++++++++++++++++++++- wpa_supplicant/robust_av.c | 66 +++++++++++++++++++++++++++++++ wpa_supplicant/wpa_supplicant_i.h | 16 ++++++++ 4 files changed, 151 insertions(+), 2 deletions(-) diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index a5ec42c74..f7123acc1 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -2789,6 +2789,19 @@ enum scs_direction { #define EHT_QOS_CONTROL_INFO_PRESENCE_MASK_OFFSET 9 #define EHT_QOS_CONTROL_INFO_LINK_ID_OFFSET 25 +/* + * IEEE P802.11be/D4.0, 9.4.2.316 QoS Characteristics element, + * Presence Bitmap Of Additional Parameters + */ +#define SCS_QOS_BIT_MAX_MSDU_SIZE ((u16) BIT(0)) +#define SCS_QOS_BIT_SERVICE_START_TIME ((u16) BIT(1)) +#define SCS_QOS_BIT_SERVICE_START_TIME_LINKID ((u16) BIT(2)) +#define SCS_QOS_BIT_MEAN_DATA_RATE ((u16) BIT(3)) +#define SCS_QOS_BIT_DELAYED_BOUNDED_BURST_SIZE ((u16) BIT(4)) +#define SCS_QOS_BIT_MSDU_LIFETIME ((u16) BIT(5)) +#define SCS_QOS_BIT_MSDU_DELIVERY_INFO ((u16) BIT(6)) +#define SCS_QOS_BIT_MEDIUM_TIME ((u16) BIT(7)) + /* Optional subelement IDs for MSCS Descriptor element */ enum mscs_description_subelem { MCSC_SUBELEM_STATUS = 1, diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 4f81175ff..4363dde1f 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -11531,7 +11531,12 @@ static int wpas_ctrl_iface_configure_scs(struct wpa_supplicant *wpa_s, * [tclas_processing=<0|1>] * [qos_characteristics] [min_si=] * [max_si=] [min_data_rate=] - * [delay_bound=] + * [delay_bound=] [max_msdu=] + * [service_start_time=] + * [service_start_time_link_id=] + * [mean_data_rate=] [burst_size=] + * [msdu_lifetime=] + * [msdu_delivery_info=] [medium_time=] * [scs_id=] ... */ pos1 = os_strstr(cmd, "scs_id="); @@ -11545,7 +11550,7 @@ static int wpas_ctrl_iface_configure_scs(struct wpa_supplicant *wpa_s, while (pos1) { struct scs_desc_elem *n1; struct active_scs_elem *active_scs_desc; - char *next_scs_desc; + char *next_scs_desc, *pos2; unsigned int num_tclas_elem = 0; bool scsid_active = false, tclas_present = false; struct qos_characteristics *qos_elem = &desc_elem.qos_char_elem; @@ -11752,6 +11757,55 @@ static int wpas_ctrl_iface_configure_scs(struct wpa_supplicant *wpa_s, goto free_scs_desc; } + pos2 = os_strstr(pos1, "max_msdu="); + if (pos2) { + qos_elem->max_msdu_size = atoi(pos2 + 9); + qos_elem->mask |= SCS_QOS_BIT_MAX_MSDU_SIZE; + } + + pos2 = os_strstr(pos1, "service_start_time="); + if (pos2) { + qos_elem->service_start_time = atoi(pos2 + 19); + qos_elem->mask |= SCS_QOS_BIT_SERVICE_START_TIME; + } + + pos2 = os_strstr(pos1, "service_start_time_link_id="); + if (pos2) { + qos_elem->service_start_time_link_id = atoi(pos2 + 27); + qos_elem->mask |= SCS_QOS_BIT_SERVICE_START_TIME_LINKID; + } + + pos2 = os_strstr(pos1, "mean_data_rate="); + if (pos2) { + qos_elem->mean_data_rate = atoi(pos2 + 15); + qos_elem->mask |= SCS_QOS_BIT_MEAN_DATA_RATE; + } + + pos2 = os_strstr(pos1, "burst_size="); + if (pos2) { + qos_elem->burst_size = atoi(pos2 + 11); + qos_elem->mask |= + SCS_QOS_BIT_DELAYED_BOUNDED_BURST_SIZE; + } + + pos2 = os_strstr(pos1, "msdu_lifetime="); + if (pos2) { + qos_elem->msdu_lifetime = atoi(pos2 + 14); + qos_elem->mask |= SCS_QOS_BIT_MSDU_LIFETIME; + } + + pos2 = os_strstr(pos1, "msdu_delivery_info="); + if (pos2) { + qos_elem->msdu_delivery_info = atoi(pos2 + 19); + qos_elem->mask |= SCS_QOS_BIT_MSDU_DELIVERY_INFO; + } + + pos2 = os_strstr(pos1, "medium_time="); + if (pos2) { + qos_elem->medium_time = atoi(pos2 + 12); + qos_elem->mask |= SCS_QOS_BIT_MEDIUM_TIME; + } + scs_desc_end: n1 = os_realloc(scs_data->scs_desc_elems, (num_scs_desc + 1) * sizeof(struct scs_desc_elem)); diff --git a/wpa_supplicant/robust_av.c b/wpa_supplicant/robust_av.c index 6794e99ff..3a095603e 100644 --- a/wpa_supplicant/robust_av.c +++ b/wpa_supplicant/robust_av.c @@ -190,6 +190,21 @@ skip_tclas_elem: len1 = wpabuf_put(buf, 1); wpabuf_put_u8(buf, WLAN_EID_EXT_QOS_CHARACTERISTICS); + /* Remove invalid mask bits */ + + /* Medium Time is applicable only for direct link */ + if ((qos_elem->mask & SCS_QOS_BIT_MEDIUM_TIME) && + qos_elem->direction != SCS_DIRECTION_DIRECT) + qos_elem->mask &= ~SCS_QOS_BIT_MEDIUM_TIME; + + /* Service Start Time LinkID is valid only when Service Start + * Time is present. + */ + if ((qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME_LINKID) && + !(qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME)) + qos_elem->mask &= + ~SCS_QOS_BIT_SERVICE_START_TIME_LINKID; + /* IEEE P802.11be/D4.0, 9.4.2.316 QoS Characteristics element, * Figure 9-1001av (Control Info field format) */ @@ -213,6 +228,32 @@ skip_tclas_elem: /* Delay Bound */ wpabuf_put_le24(buf, qos_elem->delay_bound); + /* Maximum MSDU Size */ + if (qos_elem->mask & SCS_QOS_BIT_MAX_MSDU_SIZE) + wpabuf_put_le16(buf, qos_elem->max_msdu_size); + /* Start Service Time */ + if (qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME) + wpabuf_put_le32(buf, qos_elem->service_start_time); + /* Service Start Time LinkID */ + if (qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME_LINKID) + wpabuf_put_u8(buf, + qos_elem->service_start_time_link_id); + /* Mean Data Rate */ + if (qos_elem->mask & SCS_QOS_BIT_MEAN_DATA_RATE) + wpabuf_put_le24(buf, qos_elem->mean_data_rate); + /* Delayed Bounded Burst Size */ + if (qos_elem->mask & SCS_QOS_BIT_DELAYED_BOUNDED_BURST_SIZE) + wpabuf_put_le32(buf, qos_elem->burst_size); + /* MSDU Lifetime */ + if (qos_elem->mask & SCS_QOS_BIT_MSDU_LIFETIME) + wpabuf_put_le16(buf, qos_elem->msdu_lifetime); + /* MSDU Delivery Info */ + if (qos_elem->mask & SCS_QOS_BIT_MSDU_DELIVERY_INFO) + wpabuf_put_u8(buf, qos_elem->msdu_delivery_info); + /* Medium Time */ + if (qos_elem->mask & SCS_QOS_BIT_MEDIUM_TIME) + wpabuf_put_le16(buf, qos_elem->medium_time); + *len1 = (u8 *) wpabuf_put(buf, 0) - len1 - 1; } @@ -338,6 +379,31 @@ static size_t qos_char_len(const struct qos_characteristics *qos_elem) 3 + /* Minimum Data Rate */ 3; /* Delay Bound */ + if (qos_elem->mask & SCS_QOS_BIT_MAX_MSDU_SIZE) + buf_len += 2; /* Maximum MSDU Size */ + + if (qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME) { + buf_len += 4; /* Service Start Time */ + if (qos_elem->mask & SCS_QOS_BIT_SERVICE_START_TIME_LINKID) + buf_len++; /* Service Start Time LinkID */ + } + + if (qos_elem->mask & SCS_QOS_BIT_MEAN_DATA_RATE) + buf_len += 3; /* Mean Data Rate */ + + if (qos_elem->mask & SCS_QOS_BIT_DELAYED_BOUNDED_BURST_SIZE) + buf_len += 4; /* Delayed Bounded Burst Size */ + + if (qos_elem->mask & SCS_QOS_BIT_MSDU_LIFETIME) + buf_len += 2; /* MSDU Lifetime */ + + if (qos_elem->mask & SCS_QOS_BIT_MSDU_DELIVERY_INFO) + buf_len++; /* MSDU Delivery Info */ + + if (qos_elem->mask & SCS_QOS_BIT_MEDIUM_TIME && + qos_elem->direction == SCS_DIRECTION_DIRECT) + buf_len += 2; /* Medium Time */ + return buf_len; } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index d655595cf..c44413e4e 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -611,6 +611,22 @@ struct qos_characteristics { u32 min_data_rate; /* Delay Bound */ u32 delay_bound; + /* Maximum MSDU Size */ + u16 max_msdu_size; + /* Service Start Time */ + u32 service_start_time; + /* Service Start Time LinkID */ + u8 service_start_time_link_id; + /* Mean Data Rate */ + u32 mean_data_rate; + /* Delayed Bounded Burst Size */ + u32 burst_size; + /* MSDU Lifetime */ + u16 msdu_lifetime; + /* MSDU Delivery Info */ + u8 msdu_delivery_info; + /* Medium Time */ + u16 medium_time; };