From: Ilan Peer <ilan.peer@xxxxxxxxx> Add the required ML and RNR definitions and report the information in BSS command. Signed-off-by: Ilan Peer <ilan.peer@xxxxxxxxx> Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@xxxxxxxxx> --- src/common/ieee802_11_defs.h | 104 ++++++++++++++ src/common/wpa_ctrl.h | 2 + wpa_supplicant/ctrl_iface.c | 269 +++++++++++++++++++++++++++++++++-- 3 files changed, 367 insertions(+), 8 deletions(-) diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 427b284b85..d4c292d376 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -2562,6 +2562,100 @@ struct ieee80211_eht_capabilities { #define BASIC_MLE_STA_PROF_STA_MAC_IDX 3 +struct eht_ml_basic_common_info { + u8 len; + u8 mld_addr[ETH_ALEN]; + + /* + * Followed by optional fields based on the multi link basic presence + * bitmap + * + * link info: 1 octet + * BSS parameters change count: 1 octet + * Medium synchronization delay: 2 octets + * EML capabilities: 2 octets + * MLD capabilities: 2 octets + * MLD ID: 1 octet + */ + u8 variable[]; +} STRUCT_PACKED; + +#define EHT_ML_LINK_ID_MSK 0x0f + +#define EHT_ML_MEDIUM_SYNC_DELAY_DURATION 0x00ff +#define EHT_ML_MEDIUM_SYNC_DELAY_OFDM_ED_TH 0x0f00 +#define EHT_ML_MEDIUM_SYNC_DELAY_MAX_TXOP 0xf000 + +#define EHT_ML_EML_CAPA_EMLSR_SUPP_MSK 0x0001 +#define EHT_ML_EML_CAPA_EMLSR_PADDING_DELAY_MSK 0x000e +#define EHT_ML_EML_CAPA_EMLSR_TRANS_DELAY_MSK 0x0070 +#define EHT_ML_EML_CAPA_EMLMR_SUPP_MSK 0x0080 +#define EHT_ML_EML_CAPA_EMLMR_DELAY_MSK 0x0700 +#define EHT_ML_EML_CAPA_TRANSITION_TIMEOUT_MSK 0x7800 + +#define EHT_ML_MLD_CAPA_MAX_NUM_SIM_LINKS_MSK 0x000f +#define EHT_ML_MLD_CAPA_SRS_SUPP_MSK 0x0010 +#define EHT_ML_MLD_CAPA_TID_TO_LINK_MAP_ALL_TO_ALL 0x0020 +#define EHT_ML_MLD_CAPA_TID_TO_LINK_MAP_ALL_TO_ONE 0x0040 +#define EHT_ML_MLD_CAPA_TID_TO_LINK_MAP_NEG_SUPP_MSK 0x0060 +#define EHT_ML_MLD_CAPA_FREQ_SEP_FOR_STR_MSK 0x0f80 +#define EHT_ML_MLD_CAPA_AAR_SUPP_MSK 0x1000 + +/** + * + * This structure is the "eht per sta subelement" fixed fields as described in + * P802.11be_D2.0 section 9.4.2.312.2 + */ +struct ieee80211_eht_per_sta_profile { + le16 sta_control; + + /* Followed by sta info and sta profile fields */ + u8 variable[]; +} STRUCT_PACKED; + +/* + * EHT probe request Multi link presence bitmap as defined in P802.11be_D2.0 + * section 9.4.2.312.3 + */ +#define EHT_ML_PRES_BM_PROB_REQ_MLD_ID 0x0010 + +struct eht_ml_probe_req_common_info { + u8 len; + + /* + * Followed by optional fields based on the multi link basic presence + * bitmap + * + * MLD ID: 1 octet + */ + u8 variable[]; +} STRUCT_PACKED; + +/* + * EHT Reconfiguration Multi-Link presence bitmap as defined in P802.11be_D2.0 + * section 9.4.2.312.4 + */ +#define EHT_ML_PRES_BM_RECONFIGURE_MLD_ADDRESS 0x0001 + +/** + * struct ieee80211_eht_ml - eht multi link element + * + * This structure is the "eht multi link element" fixed fields as described in + * P802.11be_D2.0 section 9.4.2.312.1 + */ +struct ieee80211_eht_ml { + le16 ml_control; + + /* Followed by common info and link info fields */ + u8 variable[]; +} STRUCT_PACKED; + +enum ieee80211_eht_ml_sub_elem { + EHT_ML_SUB_ELEM_PER_STA_PROFILE = 0, + EHT_ML_SUB_ELEM_VENDOR = 221, + EHT_ML_SUB_ELEM_FRAGMENT = 254, +}; + /* IEEE P802.11ay/D4.0, 9.4.2.251 - EDMG Operation element */ #define EDMG_BSS_OPERATING_CHANNELS_OFFSET 6 #define EDMG_OPERATING_CHANNEL_WIDTH_OFFSET 7 @@ -2703,4 +2797,14 @@ enum dscp_policy_request_type { #define WFA_CAPA_QM_DSCP_POLICY BIT(0) #define WFA_CAPA_QM_UNSOLIC_DSCP BIT(1) +struct ieee80211_neighbor_ap_info { + u8 tbtt_info_hdr; + u8 tbtt_info_len; + u8 op_class; + u8 channel; + + /* Followed by the rest of the TBTT Information field contents */ + u8 data[0]; +} STRUCT_PACKED; + #endif /* IEEE802_11_DEFS_H */ diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h index ba54da544f..4ab2a1b634 100644 --- a/src/common/wpa_ctrl.h +++ b/src/common/wpa_ctrl.h @@ -466,6 +466,8 @@ extern "C" { #define WPA_BSS_MASK_UPDATE_IDX BIT(22) #define WPA_BSS_MASK_BEACON_IE BIT(23) #define WPA_BSS_MASK_FILS_INDICATION BIT(24) +#define WPA_BSS_MASK_RNR BIT(25) +#define WPA_BSS_MASK_ML BIT(26) /* VENDOR_ELEM_* frame id values */ diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index e91bf4ebe8..785575fbf1 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -5001,6 +5001,262 @@ static int print_fils_indication(struct wpa_bss *bss, char *pos, char *end) #endif /* CONFIG_FILS */ +static int print_rnr(struct wpa_bss *bss, char *pos, char *end) +{ + char *start = pos; + const u8 *ie, *ie_end; + u32 n = 0; + int ret; + + ie = wpa_bss_get_ie(bss, WLAN_EID_REDUCED_NEIGHBOR_REPORT); + if (!ie) + return 0; + + ie_end = ie + 2 + ie[1]; + ie += 2; + + while (ie < ie_end) { + struct ieee80211_neighbor_ap_info *info = + (struct ieee80211_neighbor_ap_info *)ie; + const u8 *tbtt_start; + + if (ie + sizeof(struct ieee80211_neighbor_ap_info) >= ie_end) + return 0; + + if (ie + sizeof(struct ieee80211_neighbor_ap_info) + + info->tbtt_info_len > ie_end) + return 0; + + ret = os_snprintf(pos, end - pos, + "ap_info[%u]: tbtt_info: hdr=0x%x, len=%u, ", + n, *ie, info->tbtt_info_len); + if (os_snprintf_error(end - pos, ret)) + return 0; + pos += ret; + + ret = os_snprintf(pos, end - pos, + "op_c=%u, channel=%u, ", + info->op_class, info->channel); + if (os_snprintf_error(end - pos, ret)) + return 0; + pos += ret; + + ie += 4; + tbtt_start = ie; + if (info->tbtt_info_len >= 1) { + ret = os_snprintf(pos, end - pos, + "tbtt_offset=%u, ", *ie); + if (os_snprintf_error(end - pos, ret)) + return 0; + + ie++; + pos += ret; + } + + if (info->tbtt_info_len >= 7) { + ret = os_snprintf(pos, end - pos, + "bssid=" MACSTR ", ", + MAC2STR(ie)); + if (os_snprintf_error(end - pos, ret)) + return 0; + + ie += 6; + pos += ret; + } + + if (info->tbtt_info_len >= 11) { + ret = os_snprintf(pos, end - pos, + "short SSID=0x%x, ", + WPA_GET_LE32(ie)); + if (os_snprintf_error(end - pos, ret)) + return 0; + + ie += 4; + pos += ret; + } + + if (info->tbtt_info_len >= 12) { + ret = os_snprintf(pos, end - pos, + "bss_params=0x%x, ", *ie); + if (os_snprintf_error(end - pos, ret)) + return 0; + + ie++; + pos += ret; + } + + if (info->tbtt_info_len >= 13) { + ret = os_snprintf(pos, end - pos, + "PSD=0x%x, ", *ie); + if (os_snprintf_error(end - pos, ret)) + return 0; + + ie++; + pos += ret; + } + + if (info->tbtt_info_len >= 16) { + ret = os_snprintf(pos, end - pos, + "mld ID=%u, link ID=%u", + *ie, *(ie + 1) & 0xF); + if (os_snprintf_error(end - pos, ret)) + return 0; + + ie += 3; + pos += ret; + } + + ie = tbtt_start + info->tbtt_info_len; + + ret = os_snprintf(pos, end - pos, "\n"); + if (os_snprintf_error(end - pos, ret)) + return 0; + pos += ret; + + n++; + } + + return pos - start; +} + + +static int print_ml(struct wpa_bss *bss, char *pos, char *end) +{ + struct ieee80211_eht_ml *ml; + char *start = pos; + const u8 *ie, *ie_end; + u16 ml_control; + u8 common_info_length; + int ret; + + ie = get_ml_ie(wpa_bss_ie_ptr(bss), bss->ie_len, + MULTI_LINK_CONTROL_TYPE_BASIC); + if (!ie) + return 0; + + ie_end = ie + 2 + ie[1]; + ie += 3; + ml = (struct ieee80211_eht_ml *)ie; + + /* control + common info length + MLD MAC Address */ + if (ie_end - ie < 2 + 1 + 6) + return 0; + + ml_control = le_to_host16(ml->ml_control); + + common_info_length = *(ie + 2); + ret = os_snprintf(pos, end - pos, + "multi-link: control=0x%x, common info len=%u", + ml_control, common_info_length); + if (os_snprintf_error(end - pos, ret)) + return 0; + + pos += ret; + ie += 2; + + if (ie_end - ie < common_info_length) + return 0; + + ie++; + common_info_length--; + + if (common_info_length < ETH_ALEN) + return 0; + + ret = os_snprintf(pos, end - pos, ", MLD addr=" MACSTR, MAC2STR(ie)); + if (os_snprintf_error(end - pos, ret)) + return 0; + + pos += ret; + ie += ETH_ALEN; + common_info_length -= ETH_ALEN; + + if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_LINK_ID) { + if (common_info_length < 1) + return 0; + + ret = os_snprintf(pos, end - pos, ", link ID=%u", *ie); + if (os_snprintf_error(end - pos, ret)) + return 0; + + pos += ret; + ie++; + common_info_length--; + } + + if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_BSS_PARAM_CH_COUNT) { + if (common_info_length < 1) + return 0; + + ret = os_snprintf(pos, end - pos, + ", BSS change parameters=0x%x", *ie); + if (os_snprintf_error(end - pos, ret)) + return 0; + + pos += ret; + ie++; + common_info_length--; + } + + if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_MSD_INFO) { + if (common_info_length < 2) + return 0; + + ret = os_snprintf(pos, end - pos, ", MSD Info=0x%x", + WPA_GET_LE16(ie)); + if (os_snprintf_error(end - pos, ret)) + return 0; + + pos += ret; + ie += 2; + common_info_length -= 2; + } + + if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_EML_CAPA) { + if (common_info_length < 2) + return 0; + + ret = os_snprintf(pos, end - pos, ", EML capabilities=0x%x", + WPA_GET_LE16(ie)); + if (os_snprintf_error(end - pos, ret)) + return 0; + + pos += ret; + ie += 2; + common_info_length -= 2; + } + + if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_MLD_CAPA) { + if (common_info_length < 2) + return 0; + + ret = os_snprintf(pos, end - pos, ", MLD capabilities=0x%x", + WPA_GET_LE16(ie)); + if (os_snprintf_error(end - pos, ret)) + return 0; + + pos += ret; + ie += 2; + common_info_length -= 2; + } + + if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_AP_MLD_ID) { + if (common_info_length < 1) + return 0; + + ret = os_snprintf(pos, end - pos, ", MLD ID=0x%x\n", *ie); + if (os_snprintf_error(end - pos, ret)) + return 0; + + pos += ret; + ie += 1; + common_info_length--; + } + + return pos - start; +} + + static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, unsigned long mask, char *buf, size_t buflen) { @@ -5442,14 +5698,11 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, } #endif /* CONFIG_FILS */ - if (!is_zero_ether_addr(bss->mld_addr)) { - ret = os_snprintf(pos, end - pos, - "ap_mld_addr=" MACSTR "\n", - MAC2STR(bss->mld_addr)); - if (os_snprintf_error(end - pos, ret)) - return 0; - pos += ret; - } + if (mask & WPA_BSS_MASK_RNR) + pos += print_rnr(bss, pos, end); + + if (mask & WPA_BSS_MASK_ML) + pos += print_ml(bss, pos, end); if (mask & WPA_BSS_MASK_DELIM) { ret = os_snprintf(pos, end - pos, "====\n"); -- 2.25.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap