1#!/usr/bin/env python3 2# 3# Copyright 2022 - 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 typing import List, NewType, Optional 18 19from acts.controllers.ap_lib.radio_measurement import NeighborReportElement 20 21BssTransitionCandidateList = NewType('BssTransitionCandidateList', 22 List[NeighborReportElement]) 23 24 25class BssTerminationDuration: 26 """Representation of BSS Termination Duration subelement. 27 28 See IEEE 802.11-2020 Figure 9-341. 29 """ 30 31 def __init__(self, duration: int): 32 """Create a BSS Termination Duration subelement. 33 34 Args: 35 duration: number of minutes the BSS will be offline. 36 """ 37 # Note: hostapd does not currently support setting BSS Termination TSF, 38 # which is the other value held in this subelement. 39 self._duration = duration 40 41 @property 42 def duration(self) -> int: 43 return self._duration 44 45 46class BssTransitionManagementRequest: 47 """Representation of BSS Transition Management request. 48 49 See IEEE 802.11-2020 9.6.13.9. 50 """ 51 52 def __init__( 53 self, 54 preferred_candidate_list_included: bool = False, 55 abridged: bool = False, 56 disassociation_imminent: bool = False, 57 ess_disassociation_imminent: bool = False, 58 disassociation_timer: int = 0, 59 validity_interval: int = 1, 60 bss_termination_duration: Optional[BssTerminationDuration] = None, 61 session_information_url: Optional[str] = None, 62 candidate_list: Optional[BssTransitionCandidateList] = None): 63 """Create a BSS Transition Management request. 64 65 Args: 66 preferred_candidate_list_included: whether the candidate list is a 67 preferred candidate list, or (if False) a list of known 68 candidates. 69 abridged: whether a preference value of 0 is assigned to all BSSIDs 70 that do not appear in the candidate list, or (if False) AP has 71 no recommendation for/against anything not in the candidate 72 list. 73 disassociation_imminent: whether the STA is about to be 74 disassociated by the AP. 75 ess_disassociation_imminent: whether the STA will be disassociated 76 from the ESS. 77 disassociation_timer: the number of beacon transmission times 78 (TBTTs) until the AP disassociates this STA (default 0, meaning 79 AP has not determined when it will disassociate this STA). 80 validity_interval: number of TBTTs until the candidate list is no 81 longer valid (default 1). 82 bss_termination_duration: BSS Termination Duration subelement. 83 session_information_url: this URL is included if ESS disassociation 84 is immiment. 85 candidate_list: zero or more neighbor report elements. 86 """ 87 # Request mode field, see IEEE 802.11-2020 Figure 9-924. 88 self._preferred_candidate_list_included = preferred_candidate_list_included 89 self._abridged = abridged 90 self._disassociation_imminent = disassociation_imminent 91 self._ess_disassociation_imminent = ess_disassociation_imminent 92 93 # Disassociation Timer, see IEEE 802.11-2020 Figure 9-925 94 self._disassociation_timer = disassociation_timer 95 96 # Validity Interval, see IEEE 802.11-2020 9.6.13.9 97 self._validity_interval = validity_interval 98 99 # BSS Termination Duration, see IEEE 802.11-2020 9.6.13.9 and Figure 9-341 100 self._bss_termination_duration = bss_termination_duration 101 102 # Session Information URL, see IEEE 802.11-2020 Figure 9-926 103 self._session_information_url = session_information_url 104 105 # BSS Transition Candidate List Entries, IEEE 802.11-2020 9.6.13.9. 106 self._candidate_list = candidate_list 107 108 @property 109 def preferred_candidate_list_included(self) -> bool: 110 return self._preferred_candidate_list_included 111 112 @property 113 def abridged(self) -> bool: 114 return self._abridged 115 116 @property 117 def disassociation_imminent(self) -> bool: 118 return self._disassociation_imminent 119 120 @property 121 def bss_termination_included(self) -> bool: 122 return self._bss_termination_duration is not None 123 124 @property 125 def ess_disassociation_imminent(self) -> bool: 126 return self._ess_disassociation_imminent 127 128 @property 129 def disassociation_timer(self) -> Optional[int]: 130 if self.disassociation_imminent: 131 return self._disassociation_timer 132 # Otherwise, field is reserved. 133 return None 134 135 @property 136 def validity_interval(self) -> int: 137 return self._validity_interval 138 139 @property 140 def bss_termination_duration(self) -> Optional[BssTerminationDuration]: 141 return self._bss_termination_duration 142 143 @property 144 def session_information_url(self) -> Optional[str]: 145 return self._session_information_url 146 147 @property 148 def candidate_list(self) -> Optional[BssTransitionCandidateList]: 149 return self._candidate_list 150