1#!/usr/bin/env python3 2# 3# Copyright 2020 - 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 17import itertools 18 19from acts import asserts 20from acts import utils 21from acts.controllers.access_point import setup_ap 22from acts.controllers.ap_lib.hostapd_security import Security 23from acts.controllers.ap_lib import hostapd_constants 24from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device 25from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest 26from acts.utils import rand_ascii_str 27 28# AC Capabilities 29""" 30Capabilities Not Supported on Whirlwind: 31 - Supported Channel Width ([VHT160], [VHT160-80PLUS80]): 160mhz and 80+80 32 unsupported 33 - SU Beamformer [SU-BEAMFORMER] 34 - SU Beamformee [SU-BEAMFORMEE] 35 - MU Beamformer [MU-BEAMFORMER] 36 - MU Beamformee [MU-BEAMFORMEE] 37 - BF Antenna ([BF-ANTENNA-2], [BF-ANTENNA-3], [BF-ANTENNA-4]) 38 - Rx STBC 2, 3, & 4 ([RX-STBC-12],[RX-STBC-123],[RX-STBC-124]) 39 - VHT Link Adaptation ([VHT-LINK-ADAPT2],[VHT-LINK-ADAPT3]) 40 - VHT TXOP Power Save [VHT-TXOP-PS] 41 - HTC-VHT [HTC-VHT] 42""" 43VHT_MAX_MPDU_LEN = [ 44 hostapd_constants.AC_CAPABILITY_MAX_MPDU_7991, 45 hostapd_constants.AC_CAPABILITY_MAX_MPDU_11454, '' 46] 47RXLDPC = [hostapd_constants.AC_CAPABILITY_RXLDPC, ''] 48SHORT_GI_80 = [hostapd_constants.AC_CAPABILITY_SHORT_GI_80, ''] 49TX_STBC = [hostapd_constants.AC_CAPABILITY_TX_STBC_2BY1, ''] 50RX_STBC = [hostapd_constants.AC_CAPABILITY_RX_STBC_1, ''] 51MAX_A_MPDU = [ 52 hostapd_constants.AC_CAPABILITY_MAX_A_MPDU_LEN_EXP0, 53 hostapd_constants.AC_CAPABILITY_MAX_A_MPDU_LEN_EXP1, 54 hostapd_constants.AC_CAPABILITY_MAX_A_MPDU_LEN_EXP2, 55 hostapd_constants.AC_CAPABILITY_MAX_A_MPDU_LEN_EXP3, 56 hostapd_constants.AC_CAPABILITY_MAX_A_MPDU_LEN_EXP4, 57 hostapd_constants.AC_CAPABILITY_MAX_A_MPDU_LEN_EXP5, 58 hostapd_constants.AC_CAPABILITY_MAX_A_MPDU_LEN_EXP6, 59 hostapd_constants.AC_CAPABILITY_MAX_A_MPDU_LEN_EXP7, '' 60] 61RX_ANTENNA = [hostapd_constants.AC_CAPABILITY_RX_ANTENNA_PATTERN, ''] 62TX_ANTENNA = [hostapd_constants.AC_CAPABILITY_TX_ANTENNA_PATTERN, ''] 63 64# Default 11N Capabilities 65N_CAPABS_40MHZ = [ 66 hostapd_constants.N_CAPABILITY_LDPC, hostapd_constants.N_CAPABILITY_SGI20, 67 hostapd_constants.N_CAPABILITY_RX_STBC1, 68 hostapd_constants.N_CAPABILITY_SGI20, hostapd_constants.N_CAPABILITY_SGI40, 69 hostapd_constants.N_CAPABILITY_MAX_AMSDU_7935, 70 hostapd_constants.N_CAPABILITY_HT40_PLUS 71] 72 73N_CAPABS_20MHZ = [ 74 hostapd_constants.N_CAPABILITY_LDPC, hostapd_constants.N_CAPABILITY_SGI20, 75 hostapd_constants.N_CAPABILITY_RX_STBC1, 76 hostapd_constants.N_CAPABILITY_SGI20, 77 hostapd_constants.N_CAPABILITY_MAX_AMSDU_7935, 78 hostapd_constants.N_CAPABILITY_HT20 79] 80 81# Default wpa2 profile. 82WPA2_SECURITY = Security(security_mode=hostapd_constants.WPA2_STRING, 83 password=rand_ascii_str(20), 84 wpa_cipher=hostapd_constants.WPA2_DEFAULT_CIPER, 85 wpa2_cipher=hostapd_constants.WPA2_DEFAULT_CIPER) 86 87SECURITIES = [None, WPA2_SECURITY] 88 89 90def generate_test_name(settings): 91 """Generates a test name string based on the ac_capabilities for 92 a test case. 93 94 Args: 95 settings: a dict with the test settings (bandwidth, security, ac_capabs) 96 97 Returns: 98 A string test case name 99 """ 100 chbw = settings['chbw'] 101 sec = 'wpa2' if settings['security'] else 'open' 102 ret = [] 103 for cap in hostapd_constants.AC_CAPABILITIES_MAPPING.keys(): 104 if cap in settings['ac_capabilities']: 105 ret.append(hostapd_constants.AC_CAPABILITIES_MAPPING[cap]) 106 return 'test_11ac_%smhz_%s_%s' % (chbw, sec, ''.join(ret)) 107 108 109# 6912 test cases 110class WlanPhyCompliance11ACTest(WifiBaseTest): 111 """Tests for validating 11ac PHYS. 112 113 Test Bed Requirement: 114 * One Android device or Fuchsia device 115 * One Access Point 116 """ 117 118 def __init__(self, controllers): 119 super().__init__(controllers) 120 121 def setup_generated_tests(self): 122 test_args = self._generate_20mhz_test_args() + \ 123 self._generate_40mhz_test_args() + \ 124 self._generate_80mhz_test_args() 125 self.generate_tests(test_logic=self.setup_and_connect, 126 name_func=generate_test_name, 127 arg_sets=test_args) 128 129 def setup_class(self): 130 super().setup_class() 131 if 'dut' in self.user_params: 132 if self.user_params['dut'] == 'fuchsia_devices': 133 self.dut = create_wlan_device(self.fuchsia_devices[0]) 134 elif self.user_params['dut'] == 'android_devices': 135 self.dut = create_wlan_device(self.android_devices[0]) 136 else: 137 raise ValueError('Invalid DUT specified in config. (%s)' % 138 self.user_params['dut']) 139 else: 140 self.dut = create_wlan_device(self.android_devices[0]) 141 142 self.access_point = self.access_points[0] 143 self.android_devices = getattr(self, 'android_devices', []) 144 self.access_point.stop_all_aps() 145 146 def setup_test(self): 147 for ad in self.android_devices: 148 ad.droid.wakeLockAcquireBright() 149 ad.droid.wakeUpNow() 150 self.dut.wifi_toggle_state(True) 151 152 def teardown_test(self): 153 for ad in self.android_devices: 154 ad.droid.wakeLockRelease() 155 ad.droid.goToSleepNow() 156 self.dut.turn_location_off_and_scan_toggle_off() 157 self.dut.disconnect() 158 self.dut.reset_wifi() 159 self.download_ap_logs() 160 self.access_point.stop_all_aps() 161 162 def on_fail(self, test_name, begin_time): 163 super().on_fail(test_name, begin_time) 164 self.access_point.stop_all_aps() 165 166 def setup_and_connect(self, ap_settings): 167 """Uses ap_settings to set up ap and then attempts to associate a DUT. 168 169 Args: 170 ap_settings: a dict containing test case settings, including 171 bandwidth, security, n_capabilities, and ac_capabilities 172 173 """ 174 ssid = rand_ascii_str(20) 175 security = ap_settings['security'] 176 chbw = ap_settings['chbw'] 177 password = None 178 target_security = None 179 if security: 180 password = security.password 181 target_security = security.security_mode_string 182 n_capabilities = ap_settings['n_capabilities'] 183 ac_capabilities = ap_settings['ac_capabilities'] 184 185 setup_ap(access_point=self.access_point, 186 profile_name='whirlwind', 187 mode=hostapd_constants.MODE_11AC_MIXED, 188 channel=36, 189 n_capabilities=n_capabilities, 190 ac_capabilities=ac_capabilities, 191 force_wmm=True, 192 ssid=ssid, 193 security=security, 194 vht_bandwidth=chbw, 195 password=password) 196 asserts.assert_true( 197 self.dut.associate(ssid, 198 target_pwd=password, 199 target_security=target_security), 200 'Failed to associate.') 201 202 # 1728 tests 203 def _generate_20mhz_test_args(self): 204 test_args = [] 205 206 # 864 test cases for open security 207 # 864 test cases for wpa2 security 208 for combination in itertools.product(SECURITIES, VHT_MAX_MPDU_LEN, 209 RXLDPC, RX_STBC, TX_STBC, 210 MAX_A_MPDU, RX_ANTENNA, 211 TX_ANTENNA): 212 security = combination[0] 213 ac_capabilities = combination[1:] 214 test_args.append(({ 215 'chbw': 20, 216 'security': security, 217 'n_capabilities': N_CAPABS_20MHZ, 218 'ac_capabilities': ac_capabilities 219 }, )) 220 221 return test_args 222 223 # 1728 tests 224 def _generate_40mhz_test_args(self): 225 test_args = [] 226 227 # 864 test cases for open security 228 # 864 test cases for wpa2 security 229 for combination in itertools.product(SECURITIES, VHT_MAX_MPDU_LEN, 230 RXLDPC, RX_STBC, TX_STBC, 231 MAX_A_MPDU, RX_ANTENNA, 232 TX_ANTENNA): 233 security = combination[0] 234 ac_capabilities = combination[1:] 235 test_args.append(({ 236 'chbw': 40, 237 'security': security, 238 'n_capabilities': N_CAPABS_40MHZ, 239 'ac_capabilities': ac_capabilities 240 }, )) 241 242 return test_args 243 244 # 3456 tests 245 def _generate_80mhz_test_args(self): 246 test_args = [] 247 248 # 1728 test cases for open security 249 # 1728 test cases for wpa2 security 250 for combination in itertools.product(SECURITIES, VHT_MAX_MPDU_LEN, 251 RXLDPC, SHORT_GI_80, RX_STBC, 252 TX_STBC, MAX_A_MPDU, RX_ANTENNA, 253 TX_ANTENNA): 254 security = combination[0] 255 ac_capabilities = combination[1:] 256 test_args.append(({ 257 'chbw': 80, 258 'security': security, 259 'n_capabilities': N_CAPABS_40MHZ, 260 'ac_capabilities': ac_capabilities 261 }, )) 262 return test_args 263