1#!/usr/bin/env python3 2# 3# Copyright 2021 - The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17from enum import IntEnum, unique 18from typing import Tuple 19 20 21@unique 22class ExtendedCapability(IntEnum): 23 """All extended capabilities present in IEEE 802.11-2020 Table 9-153. 24 25 Each name has a value corresponding to that extended capability's bit offset 26 in the specification's extended capabilities field. 27 28 Note that most extended capabilities are represented by a single bit, which 29 indicates whether the extended capability is advertised by the STA; but 30 some are represented by multiple bits. In the enum, each extended capability 31 has the value of its offset; comments indicate capabilities that use 32 multiple bits. 33 """ 34 TWENTY_FORTY_BSS_COEXISTENCE_MANAGEMENT_SUPPORT = 0 35 GLK = 1 36 EXTENDED_CHANNEL_SWITCHING = 2 37 GLK_GCR = 3 38 PSMP_CAPABILITY = 4 39 # 5 reserved 40 S_PSMP_SUPPORT = 6 41 EVENT = 7 42 DIAGNOSTICS = 8 43 MULTICAST_DIAGNOSTICS = 9 44 LOCATION_TRACKING = 10 45 FMS = 11 46 PROXY_ARP_SERVICE = 12 47 COLLOCATED_INTERFERENCE_REPORTING = 13 48 CIVIC_LOCATION = 14 49 GEOSPATIAL_LOCATION = 15 50 TFS = 16 51 WNM_SLEEP_MODE = 17 52 TIM_BROADCAST = 18 53 BSS_TRANSITION = 19 54 QOS_TRAFFIC_CAPABILITY = 20 55 AC_STATION_COUNT = 21 56 MULTIPLE_BSSID = 22 57 TIMING_MEASUREMENT = 23 58 CHANNEL_USAGE = 24 59 SSID_LIST = 25 60 DMS = 26 61 UTC_TSF_OFFSET = 27 62 TPU_BUFFER_STA_SUPPORT = 28 63 TDLS_PEER_PSM_SUPPORT = 29 64 TDLS_CHANNEL_SWITCHING = 30 65 INTERWORKING = 31 66 QOS_MAP = 32 67 EBR = 33 68 SSPN_INTERFACE = 34 69 # 35 reserved 70 MSGCF_CAPABILITY = 36 71 TDLS_SUPPORT = 37 72 TDLS_PROHIBITED = 38 73 TDLS_CHANNEL_SWITCHING_PROHIBITED = 39 74 REJECT_UNADMITTED_FRAME = 40 75 SERVICE_INTERVAL_GRANULARITY = 41 76 # Bits 41-43 contain SERVICE_INTERVAL_GRANULARITY value 77 IDENTIFIER_LOCATION = 44 78 U_APSD_COEXISTENCE = 45 79 WNM_NOTIFICATION = 46 80 QAB_CAPABILITY = 47 81 UTF_8_SSID = 48 82 QMF_ACTIVATED = 49 83 QMF_RECONFIGURATION_ACTIVATED = 50 84 ROBUST_AV_STREAMING = 51 85 ADVANCED_GCR = 52 86 MESH_GCR = 53 87 SCS = 54 88 QLOAD_REPORT = 55 89 ALTERNATE_EDCA = 56 90 UNPROTECTED_TXOP_NEGOTIATION = 57 91 PROTECTED_TXOP_NEGOTIATION = 58 92 # 59 reserved 93 PROTECTED_QLOAD_REPORT = 60 94 TDLS_WIDER_BANDWIDTH = 61 95 OPERATING_MODE_NOTIFICATION = 62 96 MAX_NUMBER_OF_MSDUS_IN_A_MSDU = 63 97 # 63-64 contain MAX_NUMBER_OF_MSDUS_IN_A_MSDU value 98 CHANNEL_SCHEDULE_MANAGEMENT = 65 99 GEODATABASE_INBAND_ENABLING_SIGNAL = 66 100 NETWORK_CHANNEL_CONTROL = 67 101 WHITE_SPACE_MAP = 68 102 CHANNEL_AVAILABILITY_QUERY = 69 103 FINE_TIMING_MEASUREMENT_RESPONDER = 70 104 FINE_TIMING_MEASUREMENT_INITIATOR = 71 105 FILS_CAPABILITY = 72 106 EXTENDED_SPECTRUM_MANAGEMENT_CAPABLE = 73 107 FUTURE_CHANNEL_GUIDANCE = 74 108 PAD = 75 109 # 76-79 reserved 110 COMPLETE_LIST_OF_NON_TX_BSSID_PROFILES = 80 111 SAE_PASSWORD_IDENTIFIERS_IN_USE = 81 112 SAE_PASSWORD_IDENTIFIERS_USED_EXCLUSIVELY = 82 113 # 83 reserved 114 BEACON_PROTECTION_ENABLED = 84 115 MIRRORED_SCS = 85 116 # 86 reserved 117 LOCAL_MAC_ADDRESS_POLICY = 87 118 # 88-n reserved 119 120 121def _offsets(ext_cap_offset: ExtendedCapability) -> Tuple[int, int]: 122 """For given capability, return the byte and bit offsets within the field. 123 124 802.11 divides the extended capability field into bytes, as does the 125 ExtendedCapabilities class below. This function returns the index of the 126 byte that contains the given extended capability, as well as the bit offset 127 inside that byte (all offsets zero-indexed). For example, 128 MULTICAST_DIAGNOSTICS is bit 9, which is within byte 1 at bit offset 1. 129 """ 130 byte_offset = ext_cap_offset // 8 131 bit_offset = ext_cap_offset % 8 132 return byte_offset, bit_offset 133 134 135class ExtendedCapabilities: 136 """Extended capability parsing and representation. 137 138 See IEEE 802.11-2020 9.4.2.26. 139 """ 140 141 def __init__(self, ext_cap: bytearray = bytearray()): 142 """Represent the given extended capabilities field. 143 144 Args: 145 ext_cap: IEEE 802.11-2020 9.4.2.26 extended capabilities field. 146 Default is an empty field, meaning no extended capabilities are 147 advertised. 148 """ 149 self._ext_cap = ext_cap 150 151 def _capability_advertised(self, ext_cap: ExtendedCapability) -> bool: 152 """Whether an extended capability is advertised. 153 154 Args: 155 ext_cap: an extended capability. 156 Returns: 157 True if the bit is present and its value is 1, otherwise False. 158 Raises: 159 NotImplementedError: for extended capabilities that span more than 160 a single bit. These could be supported, but no callers need them 161 at this time. 162 """ 163 if ext_cap in [ 164 ExtendedCapability.SERVICE_INTERVAL_GRANULARITY, 165 ExtendedCapability.MAX_NUMBER_OF_MSDUS_IN_A_MSDU 166 ]: 167 raise NotImplementedError( 168 f'{ext_cap.name} not implemented yet by {__class__}') 169 byte_offset, bit_offset = _offsets(ext_cap) 170 if len(self._ext_cap) > byte_offset: 171 # Use bit_offset to derive a mask that will check the correct bit. 172 if self._ext_cap[byte_offset] & 2**bit_offset > 0: 173 return True 174 return False 175 176 @property 177 def bss_transition(self) -> bool: 178 return self._capability_advertised(ExtendedCapability.BSS_TRANSITION) 179 180 @property 181 def proxy_arp_service(self) -> bool: 182 return self._capability_advertised( 183 ExtendedCapability.PROXY_ARP_SERVICE) 184 185 @property 186 def utc_tsf_offset(self) -> bool: 187 return self._capability_advertised(ExtendedCapability.UTC_TSF_OFFSET) 188 189 @property 190 def wnm_sleep_mode(self) -> bool: 191 return self._capability_advertised(ExtendedCapability.WNM_SLEEP_MODE) 192 193 # Other extended capability property methods can be added as needed by callers. 194