blob: 5c7f2e0b807759183b3b3ca51355e55b5346e5ba [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2022 The Fuchsia Authors
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# See the License for the specific language governing permissions and
# limitations under the License.
from enum import IntEnum, unique
class ApReachability(IntEnum):
"""Neighbor Report AP Reachability values.
See IEEE 802.11-2020 Figure 9-172.
class BssidInformationCapabilities:
"""Representation of Neighbor Report BSSID Information Capabilities.
See IEEE 802.11-2020 Figure 9-338 and
def __init__(
spectrum_management: bool = False,
qos: bool = False,
apsd: bool = False,
radio_measurement: bool = False,
"""Create a capabilities object.
spectrum_management: whether spectrum management is required.
qos: whether QoS is implemented.
apsd: whether APSD is implemented.
radio_measurement: whether radio measurement is activated.
self._spectrum_management = spectrum_management
self._qos = qos
self._apsd = apsd
self._radio_measurement = radio_measurement
def __index__(self) -> int:
"""Convert to numeric representation of the field's bits."""
return (
self.spectrum_management << 5
| self.qos << 4
| self.apsd << 3
| self.radio_measurement << 2
def spectrum_management(self) -> bool:
return self._spectrum_management
def qos(self) -> bool:
return self._qos
def apsd(self) -> bool:
return self._apsd
def radio_measurement(self) -> bool:
return self._radio_measurement
class BssidInformation:
"""Representation of Neighbor Report BSSID Information field.
BssidInformation contains info about a neighboring AP, to be included in a
neighbor report element. See IEEE 802.11-2020 Figure 9-337.
def __init__(
ap_reachability: ApReachability = ApReachability.UNKNOWN,
security: bool = False,
key_scope: bool = False,
capabilities: BssidInformationCapabilities = BssidInformationCapabilities(),
mobility_domain: bool = False,
high_throughput: bool = False,
very_high_throughput: bool = False,
ftm: bool = False,
"""Create a BSSID Information object for a neighboring AP.
ap_reachability: whether this AP is reachable by the STA that
requested the neighbor report.
security: whether this AP is known to support the same security
provisioning as used by the STA in its current association.
key_scope: whether this AP is known to have the same
authenticator as the AP sending the report.
capabilities: selected capabilities of this AP.
mobility_domain: whether the AP is including an MDE in its beacon
frames and the contents of that MDE are identical to the MDE
advertised by the AP sending the report.
high_throughput: whether the AP is an HT AP including the HT
Capabilities element in its Beacons, and that the contents of
that HT capabilities element are identical to the HT
capabilities element advertised by the AP sending the report.
very_high_throughput: whether the AP is a VHT AP and the VHT
capabilities element, if included as a subelement, is
identical in content to the VHT capabilities element included
in the AP’s beacon.
ftm: whether the AP is known to have the Fine Timing Measurement
Responder extended capability.
self._ap_reachability = ap_reachability
self._security = security
self._key_scope = key_scope
self._capabilities = capabilities
self._mobility_domain = mobility_domain
self._high_throughput = high_throughput
self._very_high_throughput = very_high_throughput
self._ftm = ftm
def __index__(self) -> int:
"""Convert to numeric representation of the field's bits."""
return (
self._ap_reachability << 30
| << 29
| self.key_scope << 28
| int(self.capabilities) << 22
| self.mobility_domain << 21
| self.high_throughput << 20
| self.very_high_throughput << 19
| self.ftm << 18
def security(self) -> bool:
return self._security
def key_scope(self) -> bool:
return self._key_scope
def capabilities(self) -> BssidInformationCapabilities:
return self._capabilities
def mobility_domain(self) -> bool:
return self._mobility_domain
def high_throughput(self) -> bool:
return self._high_throughput
def very_high_throughput(self) -> bool:
return self._very_high_throughput
def ftm(self) -> bool:
return self._ftm
class PhyType(IntEnum):
"""PHY type values, see dot11PhyType in 802.11-2020 Annex C."""
DSSS = 2
OFDM = 4
ERP = 6
HT = 7
DMG = 8
VHT = 9
TVHT = 10
S1G = 11
CDMG = 12
CMMG = 13
class NeighborReportElement:
"""Representation of Neighbor Report element.
See IEEE 802.11-2020
def __init__(
bssid: str,
bssid_information: BssidInformation,
operating_class: int,
channel_number: int,
phy_type: PhyType,
"""Create a neighbor report element.
bssid: MAC address of the neighbor.
bssid_information: BSSID Information of the neigbor.
operating_class: operating class of the neighbor.
channel_number: channel number of the neighbor.
phy_type: dot11PhyType of the neighbor.
self._bssid = bssid
self._bssid_information = bssid_information
# Operating Class, IEEE 802.11-2020 Annex E.
self._operating_class = operating_class
self._channel_number = channel_number
# PHY Type, IEEE 802.11-2020 Annex C.
self._phy_type = phy_type
def bssid(self) -> str:
return self._bssid
def bssid_information(self) -> BssidInformation:
return self._bssid_information
def operating_class(self) -> int:
return self._operating_class
def channel_number(self) -> int:
return self._channel_number
def phy_type(self) -> PhyType:
return self._phy_type