1#!/usr/bin/env python3.4 2# 3# Copyright 2018 - 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 pprint 18import time 19 20from acts import asserts 21from acts import base_test 22from acts.controllers.ap_lib import hostapd_constants 23import acts.signals as signals 24from acts.test_decorators import test_tracker_info 25from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G 26from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G 27import acts.test_utils.wifi.wifi_test_utils as wutils 28from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest 29import acts.utils as utils 30 31WifiEnums = wutils.WifiEnums 32WLAN = "wlan0" 33# Channels to configure the AP for various test scenarios. 34WIFI_NETWORK_AP_CHANNEL_2G = 1 35WIFI_NETWORK_AP_CHANNEL_5G = 36 36WIFI_NETWORK_AP_CHANNEL_5G_DFS = 132 37 38 39class WifiStaApConcurrencyTest(WifiBaseTest): 40 """Tests for STA + AP concurrency scenarios. 41 42 Test Bed Requirement: 43 * Two Android devices (For AP) 44 * One Wi-Fi network visible to the device (for STA). 45 """ 46 47 def setup_class(self): 48 super().setup_class() 49 50 self.dut = self.android_devices[0] 51 self.dut_client = self.android_devices[1] 52 53 # Do a simple version of init - mainly just sync the time and enable 54 # verbose logging. This test will fail if the DUT has a sim and cell 55 # data is disabled. We would also like to test with phones in less 56 # constrained states (or add variations where we specifically 57 # constrain). 58 utils.require_sl4a(self.android_devices) 59 60 for ad in self.android_devices: 61 wutils.wifi_test_device_init(ad) 62 utils.sync_device_time(ad) 63 # Set country code explicitly to "US". 64 wutils.set_wifi_country_code(ad, WifiEnums.CountryCode.US) 65 # Enable verbose logging on the duts. 66 ad.droid.wifiEnableVerboseLogging(1) 67 68 req_params = ["dbs_supported_models", 69 "iperf_server_address", 70 "iperf_server_port"] 71 self.unpack_userparams(req_param_names=req_params,) 72 asserts.abort_class_if( 73 self.dut.model not in self.dbs_supported_models, 74 "Device %s does not support dual interfaces." % self.dut.model) 75 76 def setup_test(self): 77 for ad in self.android_devices: 78 ad.droid.wakeLockAcquireBright() 79 ad.droid.wakeUpNow() 80 self.turn_location_off_and_scan_toggle_off() 81 82 def teardown_test(self): 83 # Prevent the stop wifi tethering failure to block ap close 84 try: 85 wutils.stop_wifi_tethering(self.dut) 86 except signals.TestFailure: 87 pass 88 for ad in self.android_devices: 89 ad.droid.wakeLockRelease() 90 ad.droid.goToSleepNow() 91 wutils.reset_wifi(ad) 92 self.turn_location_on_and_scan_toggle_on() 93 wutils.wifi_toggle_state(self.dut, True) 94 self.access_points[0].close() 95 del self.user_params["reference_networks"] 96 del self.user_params["open_network"] 97 98 def on_fail(self, test_name, begin_time): 99 for ad in self.android_devices: 100 ad.take_bug_report(test_name, begin_time) 101 ad.cat_adb_log(test_name, begin_time) 102 103 ### Helper Functions ### 104 105 def configure_ap(self, channel_2g=None, channel_5g=None): 106 """Configure and bring up AP on required channel. 107 108 Args: 109 channel_2g: The channel number to use for 2GHz network. 110 channel_5g: The channel number to use for 5GHz network. 111 112 """ 113 if not channel_2g: 114 channel_2g = hostapd_constants.AP_DEFAULT_CHANNEL_2G 115 if not channel_5g: 116 channel_5g = hostapd_constants.AP_DEFAULT_CHANNEL_5G 117 self.legacy_configure_ap_and_start(channel_2g=channel_2g, 118 channel_5g=channel_5g) 119 self.open_2g = self.open_network[0]["2g"] 120 self.open_5g = self.open_network[0]["5g"] 121 122 def turn_location_on_and_scan_toggle_on(self): 123 """Turns on wifi location scans.""" 124 utils.set_location_service(self.dut, True) 125 self.dut.droid.wifiScannerToggleAlwaysAvailable(True) 126 msg = "Failed to turn on location service's scan." 127 asserts.assert_true(self.dut.droid.wifiScannerIsAlwaysAvailable(), msg) 128 129 def turn_location_off_and_scan_toggle_off(self): 130 """Turns off wifi location scans.""" 131 utils.set_location_service(self.dut, False) 132 self.dut.droid.wifiScannerToggleAlwaysAvailable(False) 133 msg = "Failed to turn off location service's scan." 134 asserts.assert_false(self.dut.droid.wifiScannerIsAlwaysAvailable(), msg) 135 136 def run_iperf_client(self, params): 137 """Run iperf traffic after connection. 138 139 Args: 140 params: A tuple of network info and AndroidDevice object. 141 """ 142 if "iperf_server_address" in self.user_params: 143 wait_time = 5 144 network, ad = params 145 ssid = network[WifiEnums.SSID_KEY] 146 self.log.info("Starting iperf traffic through {}".format(ssid)) 147 time.sleep(wait_time) 148 port_arg = "-p {}".format(self.iperf_server_port) 149 success, data = ad.run_iperf_client(self.iperf_server_address, 150 port_arg) 151 self.log.debug(pprint.pformat(data)) 152 asserts.assert_true(success, "Error occurred in iPerf traffic.") 153 154 def create_softap_config(self): 155 """Create a softap config with ssid and password.""" 156 ap_ssid = "softap_" + utils.rand_ascii_str(8) 157 ap_password = utils.rand_ascii_str(8) 158 self.dut.log.info("softap setup: %s %s", ap_ssid, ap_password) 159 config = {wutils.WifiEnums.SSID_KEY: ap_ssid} 160 config[wutils.WifiEnums.PWD_KEY] = ap_password 161 return config 162 163 def start_softap_and_verify(self, band, check_connectivity=True): 164 """Test startup of softap. 165 166 1. Bring up AP mode. 167 2. Verify SoftAP active using the client device. 168 169 Args: 170 band: wifi band to start soft ap on 171 check_connectivity: If set, verify internet connectivity 172 173 Returns: 174 Softap config 175 """ 176 config = self.create_softap_config() 177 wutils.start_wifi_tethering(self.dut, 178 config[WifiEnums.SSID_KEY], 179 config[WifiEnums.PWD_KEY], 180 band) 181 for ad in self.android_devices[1:]: 182 wutils.connect_to_wifi_network( 183 ad, config, check_connectivity=check_connectivity) 184 return config 185 186 def connect_to_wifi_network_and_start_softap(self, nw_params, softap_band): 187 """Test concurrent wifi connection and softap. 188 189 This helper method first makes a wifi connection and then starts SoftAp. 190 1. Bring up wifi. 191 2. Establish connection to a network. 192 3. Bring up softap and verify AP can be connected by a client device. 193 4. Run iperf on the wifi/softap connection to the network. 194 195 Args: 196 nw_params: Params for network STA connection. 197 softap_band: Band for the AP. 198 """ 199 wutils.connect_to_wifi_network(self.dut, nw_params) 200 softap_config = self.start_softap_and_verify(softap_band) 201 self.run_iperf_client((nw_params, self.dut)) 202 self.run_iperf_client((softap_config, self.dut_client)) 203 204 if len(self.android_devices) > 2: 205 self.log.info("Testbed has extra devices, do more validation") 206 self.verify_traffic_between_dut_clients( 207 self.dut_client, self.android_devices[2]) 208 209 asserts.assert_true(self.dut.droid.wifiCheckState(), 210 "Wifi is not reported as running") 211 asserts.assert_true(self.dut.droid.wifiIsApEnabled(), 212 "SoftAp is not reported as running") 213 214 def start_softap_and_connect_to_wifi_network(self, nw_params, softap_band): 215 """Test concurrent wifi connection and softap. 216 217 This helper method first starts SoftAp and then makes a wifi connection. 218 1. Bring up softap and verify AP can be connected by a client device. 219 2. Bring up wifi. 220 3. Establish connection to a network. 221 4. Run iperf on the wifi/softap connection to the network. 222 5. Verify wifi state and softap state. 223 224 Args: 225 nw_params: Params for network STA connection. 226 softap_band: Band for the AP. 227 """ 228 softap_config = self.start_softap_and_verify(softap_band, False) 229 wutils.connect_to_wifi_network(self.dut, nw_params) 230 self.run_iperf_client((nw_params, self.dut)) 231 self.run_iperf_client((softap_config, self.dut_client)) 232 233 if len(self.android_devices) > 2: 234 self.log.info("Testbed has extra devices, do more validation") 235 self.verify_traffic_between_dut_clients( 236 self.dut, self.android_devices[2]) 237 238 asserts.assert_true(self.dut.droid.wifiCheckState(), 239 "Wifi is not reported as running") 240 asserts.assert_true(self.dut.droid.wifiIsApEnabled(), 241 "SoftAp is not reported as running") 242 243 def verify_traffic_between_dut_clients(self, ad1, ad2, num_of_tries=2): 244 """Test the clients that connect to DUT's softap can ping each other. 245 246 Args: 247 ad1: DUT 1 248 ad2: DUT 2 249 num_of_tries: the retry times of ping test. 250 """ 251 ad1_ip = ad1.droid.connectivityGetIPv4Addresses(WLAN)[0] 252 ad2_ip = ad2.droid.connectivityGetIPv4Addresses(WLAN)[0] 253 # Ping each other 254 for _ in range(num_of_tries): 255 if utils.adb_shell_ping(ad1, count=10, dest_ip=ad2_ip, timeout=20): 256 break 257 else: 258 asserts.fail("%s ping %s failed" % (ad1.serial, ad2_ip)) 259 for _ in range(num_of_tries): 260 if utils.adb_shell_ping(ad2, count=10, dest_ip=ad1_ip, timeout=20): 261 break 262 else: 263 asserts.fail("%s ping %s failed" % (ad2.serial, ad1_ip)) 264 265 ### Tests ### 266 267 @test_tracker_info(uuid="c396e7ac-cf22-4736-a623-aa6d3c50193a") 268 def test_wifi_connection_2G_softap_2G(self): 269 """Test connection to 2G network followed by SoftAp on 2G.""" 270 self.configure_ap(channel_2g=WIFI_NETWORK_AP_CHANNEL_2G) 271 self.connect_to_wifi_network_and_start_softap( 272 self.open_2g, WIFI_CONFIG_APBAND_2G) 273 274 @test_tracker_info(uuid="1cd6120d-3db4-4624-9bae-55c976533a48") 275 def test_wifi_connection_5G_softap_5G(self): 276 """Test connection to 5G network followed by SoftAp on 5G.""" 277 self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G) 278 self.connect_to_wifi_network_and_start_softap( 279 self.open_5g, WIFI_CONFIG_APBAND_5G) 280 281 @test_tracker_info(uuid="5f980007-3490-413e-b94e-7700ffab8534") 282 def test_wifi_connection_5G_DFS_softap_5G(self): 283 """Test connection to 5G DFS network followed by SoftAp on 5G.""" 284 self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_DFS) 285 self.connect_to_wifi_network_and_start_softap( 286 self.open_5g, WIFI_CONFIG_APBAND_5G) 287 288 @test_tracker_info(uuid="d05d5d44-c738-4372-9f01-ce2a640a2f25") 289 def test_wifi_connection_5G_softap_2G(self): 290 """Test connection to 5G network followed by SoftAp on 2G.""" 291 self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G) 292 self.connect_to_wifi_network_and_start_softap( 293 self.open_5g, WIFI_CONFIG_APBAND_2G) 294 295 @test_tracker_info(uuid="909ac713-1ad3-4dad-9be3-ad60f00ed25e") 296 def test_wifi_connection_5G_DFS_softap_2G(self): 297 """Test connection to 5G DFS network followed by SoftAp on 2G.""" 298 self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_DFS) 299 self.connect_to_wifi_network_and_start_softap( 300 self.open_5g, WIFI_CONFIG_APBAND_2G) 301 302 @test_tracker_info(uuid="e8de724a-25d3-4801-94cc-22e9e0ecc8d1") 303 def test_wifi_connection_2G_softap_5G(self): 304 """Test connection to 2G network followed by SoftAp on 5G.""" 305 self.configure_ap(channel_2g=WIFI_NETWORK_AP_CHANNEL_2G) 306 self.connect_to_wifi_network_and_start_softap( 307 self.open_2g, WIFI_CONFIG_APBAND_5G) 308 309 @test_tracker_info(uuid="647f4e17-5c7a-4249-98af-f791d163a39f") 310 def test_wifi_connection_5G_softap_2G_with_location_scan_on(self): 311 """Test connection to 5G network, SoftAp on 2G with location scan on.""" 312 self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G) 313 self.turn_location_on_and_scan_toggle_on() 314 self.connect_to_wifi_network_and_start_softap( 315 self.open_5g, WIFI_CONFIG_APBAND_2G) 316 # Now toggle wifi off & ensure we can still scan. 317 wutils.wifi_toggle_state(self.dut, False) 318 wutils.start_wifi_connection_scan_and_ensure_network_found( 319 self.dut, self.open_5g[WifiEnums.SSID_KEY]) 320 321 @test_tracker_info(uuid="4aa56c11-e5bc-480b-bd61-4b4ee577a5da") 322 def test_softap_2G_wifi_connection_2G(self): 323 """Test SoftAp on 2G followed by connection to 2G network.""" 324 self.configure_ap(channel_2g=WIFI_NETWORK_AP_CHANNEL_2G) 325 self.start_softap_and_connect_to_wifi_network( 326 self.open_2g, WIFI_CONFIG_APBAND_2G) 327 328 @test_tracker_info(uuid="5f954957-ad20-4de1-b20c-6c97d0463bdd") 329 def test_softap_5G_wifi_connection_5G(self): 330 """Test SoftAp on 5G followed by connection to 5G network.""" 331 self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G) 332 self.start_softap_and_connect_to_wifi_network( 333 self.open_5g, WIFI_CONFIG_APBAND_5G) 334 335 @test_tracker_info(uuid="1306aafc-a07e-4654-ba78-674f90cf748e") 336 def test_softap_5G_wifi_connection_5G_DFS(self): 337 """Test SoftAp on 5G followed by connection to 5G DFS network.""" 338 self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_DFS) 339 self.start_softap_and_connect_to_wifi_network( 340 self.open_5g, WIFI_CONFIG_APBAND_5G) 341 342 @test_tracker_info(uuid="5e28e8b5-3faa-4cff-a782-13a796d7f572") 343 def test_softap_5G_wifi_connection_2G(self): 344 """Test SoftAp on 5G followed by connection to 2G network.""" 345 self.configure_ap(channel_2g=WIFI_NETWORK_AP_CHANNEL_2G) 346 self.start_softap_and_connect_to_wifi_network( 347 self.open_2g, WIFI_CONFIG_APBAND_5G) 348 349 @test_tracker_info(uuid="a2c62bc6-9ccd-4bc4-8a23-9a1b5d0b4b5c") 350 def test_softap_2G_wifi_connection_5G(self): 351 """Test SoftAp on 2G followed by connection to 5G network.""" 352 self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G) 353 self.start_softap_and_connect_to_wifi_network( 354 self.open_5g, WIFI_CONFIG_APBAND_2G) 355 356 @test_tracker_info(uuid="75400685-a9d9-4091-8af3-97bd539c246a") 357 def test_softap_2G_wifi_connection_5G_DFS(self): 358 """Test SoftAp on 2G followed by connection to 5G DFS network.""" 359 self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_DFS) 360 self.start_softap_and_connect_to_wifi_network( 361 self.open_5g, WIFI_CONFIG_APBAND_2G) 362 363 @test_tracker_info(uuid="aa23a3fc-31a1-4d5c-8cf5-2eb9fdf9e7ce") 364 def test_softap_5G_wifi_connection_2G_with_location_scan_on(self): 365 """Test SoftAp on 5G, connection to 2G network with location scan on.""" 366 self.configure_ap(channel_2g=WIFI_NETWORK_AP_CHANNEL_2G) 367 self.turn_location_on_and_scan_toggle_on() 368 self.start_softap_and_connect_to_wifi_network( 369 self.open_2g, WIFI_CONFIG_APBAND_5G) 370 # Now toggle wifi off & ensure we can still scan. 371 wutils.wifi_toggle_state(self.dut, False) 372 wutils.start_wifi_connection_scan_and_ensure_network_found( 373 self.dut, self.open_2g[WifiEnums.SSID_KEY]) 374