1#!/usr/bin/env python3.4 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 17import acts.asserts as asserts 18from acts.controllers.android_device import SL4A_APK_NAME 19from acts.test_decorators import test_tracker_info 20from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest 21import acts_contrib.test_utils.net.connectivity_const as cconsts 22import acts_contrib.test_utils.wifi.wifi_test_utils as wutils 23import acts_contrib.test_utils.wifi.aware.aware_test_utils as autils 24 25WifiEnums = wutils.WifiEnums 26 27WIFI_NETWORK_AP_CHANNEL_2G_1 = 1 28WIFI_NETWORK_AP_CHANNEL_5G_1 = 36 29WIFI_NETWORK_AP_CHANNEL_5G_DFS_1 = 132 30 31WIFI_NETWORK_AP_CHANNEL_2G_2 = 2 32WIFI_NETWORK_AP_CHANNEL_5G_2 = 40 33WIFI_NETWORK_AP_CHANNEL_5G_DFS_2 = 136 34 35class WifiStaConcurrencyNetworkRequestTest(WifiBaseTest): 36 """STA + STA Tests for concurrency between intenet connectivity & 37 peer to peer connectivity using NetworkRequest with WifiNetworkSpecifier 38 API surface. 39 40 Test Bed Requirement: 41 * one Android device 42 * Several Wi-Fi networks visible to the device, including an open Wi-Fi 43 network. 44 """ 45 def __init__(self, configs): 46 super().__init__(configs) 47 self.enable_packet_log = True 48 self.p2p_key = None 49 50 def setup_class(self): 51 super().setup_class() 52 53 self.dut = self.android_devices[0] 54 wutils.wifi_test_device_init(self.dut) 55 req_params = ["sta_concurrency_supported_models", "wifi6_models"] 56 opt_param = [ 57 "open_network", "reference_networks" 58 ] 59 self.unpack_userparams( 60 req_param_names=req_params, opt_param_names=opt_param) 61 62 asserts.abort_class_if( 63 self.dut.model not in self.sta_concurrency_supported_models, 64 "Device %s doesn't support STA+STA, skipping tests") 65 66 asserts.abort_class_if( 67 "OpenWrtAP" not in self.user_params, 68 "Setup doesn't support OpenWrt AP, skipping tests") 69 70 71 def setup_test(self): 72 super().setup_test() 73 self.dut.droid.wakeLockAcquireBright() 74 self.dut.droid.wakeUpNow() 75 self.remove_approvals() 76 self.clear_user_disabled_networks() 77 wutils.wifi_toggle_state(self.dut, True) 78 self.dut.ed.clear_all_events() 79 80 def teardown_test(self): 81 super().teardown_test() 82 self.disconnect_both() 83 self.dut.droid.wakeLockRelease() 84 self.dut.droid.goToSleepNow() 85 self.dut.droid.wifiDisconnect() 86 wutils.reset_wifi(self.dut) 87 # Ensure we disconnected from the current network before the next test. 88 if self.dut.droid.wifiGetConnectionInfo()["supplicant_state"] != "disconnected": 89 wutils.wait_for_disconnect(self.dut) 90 wutils.wifi_toggle_state(self.dut, False) 91 self.dut.ed.clear_all_events() 92 # Reset access point state. 93 for ap in self.access_points: 94 ap.close() 95 96 def teardown_class(self): 97 if "AccessPoint" in self.user_params: 98 del self.user_params["reference_networks"] 99 del self.user_params["open_network"] 100 101 """Helper Functions""" 102 def remove_approvals(self): 103 self.dut.log.debug("Removing all approvals from sl4a app") 104 self.dut.adb.shell( 105 "cmd wifi network-requests-remove-user-approved-access-points" 106 + " " + SL4A_APK_NAME) 107 108 def clear_user_disabled_networks(self): 109 self.dut.log.debug("Clearing user disabled networks") 110 self.dut.adb.shell( 111 "cmd wifi clear-user-disabled-networks") 112 113 def register_network_callback_for_internet(self): 114 self.dut.log.debug("Registering network callback for wifi internet connectivity") 115 network_request = { 116 cconsts.NETWORK_CAP_TRANSPORT_TYPE_KEY : 117 cconsts.NETWORK_CAP_TRANSPORT_WIFI, 118 cconsts.NETWORK_CAP_CAPABILITY_KEY : 119 [cconsts.NETWORK_CAP_CAPABILITY_INTERNET] 120 } 121 key = self.dut.droid.connectivityRegisterNetworkCallback(network_request) 122 return key 123 124 def connect_to_internet_and_wait_for_on_available(self, network): 125 self.dut.log.info("Triggering internet connection after registering " 126 "network callback") 127 self.internet_request_key = ( 128 self.register_network_callback_for_internet()) 129 wutils.connect_to_wifi_network(self.dut, network) 130 # Ensure that the internet connection completed and we got the 131 # ON_AVAILABLE callback. 132 autils.wait_for_event_with_keys( 133 self.dut, 134 cconsts.EVENT_NETWORK_CALLBACK, 135 20, 136 (cconsts.NETWORK_CB_KEY_ID, self.internet_request_key), 137 (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_AVAILABLE)) 138 wutils.verify_11ax_wifi_connection( 139 self.dut, self.wifi6_models, "wifi6_ap" in self.user_params) 140 141 def connect_to_p2p_and_wait_for_on_available(self, network): 142 self.p2p_key = wutils.wifi_connect_using_network_request(self.dut, 143 network, 144 network) 145 wutils.verify_11ax_wifi_connection( 146 self.dut, self.wifi6_models, "wifi6_ap" in self.user_params) 147 148 def ensure_both_connections_are_active(self): 149 self.dut.log.info("Ensuring both connections are active") 150 network_caps = ( 151 self.dut.droid.connectivityNetworkGetAllCapabilities()) 152 self.dut.log.info("Active network caps: %s", network_caps) 153 num_wifi_networks = 0 154 for network_cap in network_caps: 155 transport_types = ( 156 network_cap[cconsts.NETWORK_CAP_TRANSPORT_TYPE_KEY]) 157 if cconsts.NETWORK_CAP_TRANSPORT_WIFI in transport_types: 158 num_wifi_networks += 1 159 self.dut.log.info("Wifi connection %s: %s", 160 num_wifi_networks, network_cap) 161 asserts.assert_equal(2, num_wifi_networks, "Expected 2 wifi networks") 162 163 164 def ensure_both_connections_are_active_and_dont_disconnect(self): 165 self.ensure_both_connections_are_active() 166 167 # Don't use the key_id in event to ensure there are no disconnects 168 # from either connection. 169 self.dut.log.info("Ensuring no connection loss") 170 autils.fail_on_event_with_keys( 171 self.dut, 172 cconsts.EVENT_NETWORK_CALLBACK, 173 20, 174 (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_LOST)) 175 176 def disconnect_both(self): 177 self.dut.log.info("Disconnecting both connections") 178 if self.p2p_key: 179 asserts.assert_true( 180 self.dut.droid.connectivityUnregisterNetworkCallback( 181 self.p2p_key), 182 "Failed to release the p2p request") 183 self.p2p_key = None 184 self.dut.droid.wifiDisconnect() 185 186 def configure_ap(self, 187 channel_2g=None, 188 channel_5g=None, 189 channel_2g_ap2=None, 190 channel_5g_ap2=None, 191 mirror_ap=False, 192 ap_count=1): 193 """Configure ap based on test requirements.""" 194 if ap_count==1: 195 self.configure_openwrt_ap_and_start( 196 wpa_network=True, 197 channel_2g=WIFI_NETWORK_AP_CHANNEL_2G_1, 198 channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_1, 199 ap_count=1) 200 elif ap_count == 2 and channel_2g_ap2: 201 self.configure_openwrt_ap_and_start( 202 wpa_network=True, 203 channel_2g=WIFI_NETWORK_AP_CHANNEL_2G_1, 204 channel_2g_ap2=WIFI_NETWORK_AP_CHANNEL_2G_2, 205 mirror_ap=mirror_ap, 206 ap_count=2) 207 elif ap_count == 2 and channel_5g_ap2: 208 self.configure_openwrt_ap_and_start( 209 wpa_network=True, 210 channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_1, 211 channel_5g_ap2=WIFI_NETWORK_AP_CHANNEL_5G_2, 212 mirror_ap=mirror_ap, 213 ap_count=2) 214 215 @test_tracker_info(uuid="64a6c35f-d45d-431f-83e8-7fcfaef943e2") 216 def test_connect_to_2g_p2p_while_connected_to_5g_internet(self): 217 """ 218 Initiates a connection to a peer to peer network via network request while 219 already connected to an internet connectivity network. 220 221 Steps: 222 1. Setup 5G & 2G band WPA-PSK networks. 223 2. Connect to WPA-PSK 5G network for internet connectivity. 224 3. Send a network specifier with the specific SSID/credentials of 225 WPA-PSK 2G network. 226 4. Wait for platform to scan and find matching networks. 227 5. Simulate user selecting the network. 228 6. Ensure that the device connects to the network. 229 7. Ensure that the device remains connected to both the networks. 230 8. Disconnect both connections. 231 """ 232 self.configure_ap( 233 channel_2g=WIFI_NETWORK_AP_CHANNEL_2G_1, 234 channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_1, 235 ap_count=1) 236 237 self.connect_to_internet_and_wait_for_on_available( 238 self.wpa_networks[0]["5g"]) 239 self.connect_to_p2p_and_wait_for_on_available( 240 self.wpa_networks[0]["2g"]) 241 242 self.ensure_both_connections_are_active_and_dont_disconnect() 243 244 245 @test_tracker_info(uuid="aa8af713-5d97-4f05-8104-e697f0055d6e") 246 def test_connect_to_2g_internet_while_connected_to_5g_p2p(self): 247 """ 248 Initiates a connection to a peer to peer network via network request while 249 already connected to an internet connectivity network. 250 251 Steps: 252 1. Setup 5G & 2G band WPA-PSK networks. 253 2. Send a network specifier with the specific SSID/credentials of 254 WPA-PSK 5G network. 255 3. Wait for platform to scan and find matching networks. 256 4. Simulate user selecting the network. 257 5. Ensure that the device connects to the network. 258 6. Connect to WPA-PSK 2G network for internet connectivity. 259 7. Ensure that the device remains connected to both the networks. 260 8. Disconnect both connections. 261 """ 262 self.configure_ap( 263 channel_2g=WIFI_NETWORK_AP_CHANNEL_2G_1, 264 channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_1, 265 ap_count=1) 266 267 self.connect_to_p2p_and_wait_for_on_available( 268 self.wpa_networks[0]["5g"]) 269 self.connect_to_internet_and_wait_for_on_available( 270 self.wpa_networks[0]["2g"]) 271 272 self.ensure_both_connections_are_active_and_dont_disconnect() 273 274 275 @test_tracker_info(uuid="64dd09a7-28f6-4000-b1a1-10302922641b") 276 def test_connect_to_2g_internet_while_connected_to_2g_p2p(self): 277 """ 278 Initiates a connection to a peer to peer network via network request while 279 already connected to an internet connectivity network. 280 281 Steps: 282 1. Setup 2 5G & 2G band WPA-PSK networks. 283 2. Send a network specifier with the specific SSID/credentials of 284 WPA-PSK 2G network. 285 3. Wait for platform to scan and find matching networks. 286 4. Simulate user selecting the network. 287 5. Ensure that the device connects to the network. 288 6. Connect to WPA-PSK 2G network for internet connectivity. 289 7. Ensure that the device remains connected to both the networks. 290 8. Disconnect both connections. 291 """ 292 self.configure_ap( 293 channel_2g=WIFI_NETWORK_AP_CHANNEL_2G_1, 294 channel_2g_ap2=WIFI_NETWORK_AP_CHANNEL_2G_2, 295 ap_count=2) 296 297 self.connect_to_p2p_and_wait_for_on_available( 298 self.wpa_networks[0]["2g"]) 299 self.connect_to_internet_and_wait_for_on_available( 300 self.wpa_networks[1]["2g"]) 301 302 self.ensure_both_connections_are_active_and_dont_disconnect() 303 304 305 @test_tracker_info(uuid="0c3df2f1-7311-4dd2-b0dc-1de4bd731495") 306 def test_connect_to_5g_internet_while_connected_to_5g_p2p(self): 307 """ 308 Initiates a connection to a peer to peer network via network request while 309 already connected to an internet connectivity network. 310 311 Steps: 312 1. Setup 2 5G & 2G band WPA-PSK networks. 313 2. Send a network specifier with the specific SSID/credentials of 314 WPA-PSK 5G network. 315 3. Wait for platform to scan and find matching networks. 316 4. Simulate user selecting the network. 317 5. Ensure that the device connects to the network. 318 6. Connect to WPA-PSK 5G network for internet connectivity. 319 7. Ensure that the device remains connected to both the networks. 320 8. Disconnect both connections. 321 """ 322 self.configure_ap( 323 channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_1, 324 channel_5g_ap2=WIFI_NETWORK_AP_CHANNEL_5G_2, 325 ap_count=2) 326 327 self.connect_to_p2p_and_wait_for_on_available( 328 self.wpa_networks[0]["5g"]) 329 self.connect_to_internet_and_wait_for_on_available( 330 self.wpa_networks[1]["5g"]) 331 332 self.ensure_both_connections_are_active_and_dont_disconnect() 333 334 @test_tracker_info(uuid="be22f7f8-b761-4f40-8d10-ff802761cb8b") 335 def test_connect_to_5g_dfs_internet_while_connected_to_5g_dfs_p2p(self): 336 """ 337 Initiates a connection to a peer to peer network via network request while 338 already connected to an internet connectivity network. 339 340 Steps: 341 1. Setup 2 5G-DFS & 2G band WPA-PSK networks. 342 2. Send a network specifier with the specific SSID/credentials of 343 WPA-PSK 5G-DFS network. 344 3. Wait for platform to scan and find matching networks. 345 4. Simulate user selecting the network. 346 5. Ensure that the device connects to the network. 347 6. Connect to WPA-PSK 5G network for internet connectivity. 348 7. Ensure that the device remains connected to both the networks. 349 8. Disconnect both connections. 350 """ 351 self.configure_ap( 352 channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_DFS_1, 353 channel_5g_ap2=WIFI_NETWORK_AP_CHANNEL_5G_DFS_2, 354 ap_count=2) 355 356 self.connect_to_p2p_and_wait_for_on_available( 357 self.wpa_networks[0]["5g"]) 358 self.connect_to_internet_and_wait_for_on_available( 359 self.wpa_networks[1]["5g"]) 360 361 self.ensure_both_connections_are_active_and_dont_disconnect() 362 363 @test_tracker_info(uuid="dc390b3f-2856-4c96-880b-9732e3dc228f") 364 def test_connect_to_2g_internet_while_connected_to_2g_p2p_same_ssid(self): 365 """ 366 Initiates a connection to a peer to peer network via network request while 367 already connected to an internet connectivity network. 368 369 Steps: 370 1. Setup 2 5G & 2G band WPA-PSK networks with the same SSID. 371 2. Send a network specifier with the specific SSID/credentials of 372 WPA-PSK 2G network. 373 3. Wait for platform to scan and find matching networks. 374 4. Simulate user selecting the network. 375 5. Ensure that the device connects to the network. 376 6. Connect to WPA-PSK 2G network for internet connectivity. 377 7. Ensure that the device remains connected to both the networks. 378 8. Disconnect both connections. 379 """ 380 self.configure_ap( 381 channel_2g=WIFI_NETWORK_AP_CHANNEL_2G_1, 382 channel_2g_ap2=WIFI_NETWORK_AP_CHANNEL_2G_2, 383 mirror_ap=True, 384 ap_count=2) 385 386 self.connect_to_p2p_and_wait_for_on_available( 387 self.wpa_networks[0]["2g"]) 388 self.connect_to_internet_and_wait_for_on_available( 389 self.wpa_networks[0]["2g"]) 390 391 self.ensure_both_connections_are_active_and_dont_disconnect() 392 393 @test_tracker_info(uuid="033d324d-94e0-440e-9532-993bc2682269") 394 def test_connect_to_5g_p2p_while_connected_to_5g_internet_same_ssid(self): 395 """ 396 Initiates a connection to a peer to peer network via network request while 397 already connected to an internet connectivity network. 398 399 Steps: 400 1. Setup 2 5G & 2G band WPA-PSK networks with the same SSID. 401 2. Connect to WPA-PSK 5G network for internet connectivity. 402 3. Send a network specifier with the specific SSID/credentials of 403 WPA-PSK 5G network (with the other bssid). 404 4. Wait for platform to scan and find matching networks. 405 5. Simulate user selecting the network. 406 6. Ensure that the device connects to the network. 407 7. Ensure that the device remains connected to both the networks. 408 8. Disconnect both connections. 409 """ 410 self.configure_ap( 411 channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_1, 412 channel_5g_ap2=WIFI_NETWORK_AP_CHANNEL_5G_2, 413 mirror_ap=True, 414 ap_count=2) 415 416 self.connect_to_internet_and_wait_for_on_available( 417 self.wpa_networks[0]["5g"]) 418 419 ssid = self.wpa_networks[0]["5g"][WifiEnums.SSID_KEY] 420 bssids = [self.bssid_map[0]["5g"][ssid], self.bssid_map[1]["5g"][ssid]] 421 # Find the internet connection bssid. 422 wifi_info = self.dut.droid.wifiGetConnectionInfo() 423 connected_bssid = wifi_info[WifiEnums.BSSID_KEY].upper() 424 # Find the bssid of the other access point with same ssid. 425 p2p_bssid = set(bssids) - {connected_bssid} 426 427 # Construct specifier for the other bssid. 428 network_specifier_with_bssid = self.wpa_networks[0]["5g"].copy() 429 network_specifier_with_bssid[WifiEnums.BSSID_KEY] = next(iter(p2p_bssid)) 430 self.connect_to_p2p_and_wait_for_on_available( 431 network_specifier_with_bssid) 432 433 self.ensure_both_connections_are_active_and_dont_disconnect() 434