1# 2# Copyright 2014 - The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import logging 17import time 18 19from acts import asserts 20from acts.test_decorators import test_tracker_info 21import acts_contrib.test_utils.wifi.wifi_test_utils as wutils 22from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest 23 24WifiEnums = wutils.WifiEnums 25MAX_ATTN = 95 26WAIT_WIFI_SCAN_RESULTS_SEC = 10 27WAIT_ATTENUATION_SEC = 5 28WAIT_WIFI_DISCONNECT_SEC = 60 29 30class WifiPnoTest(WifiBaseTest): 31 32 def __init__(self, configs): 33 super().__init__(configs) 34 self.enable_packet_log = True 35 36 def setup_class(self): 37 super().setup_class() 38 39 self.dut = self.android_devices[0] 40 wutils.wifi_test_device_init(self.dut) 41 req_params = ["attn_vals", "pno_interval", "wifi6_models"] 42 opt_param = ["reference_networks"] 43 self.unpack_userparams( 44 req_param_names=req_params, opt_param_names=opt_param) 45 46 if "AccessPoint" in self.user_params: 47 self.legacy_configure_ap_and_start() 48 elif "OpenWrtAP" in self.user_params: 49 self.configure_openwrt_ap_and_start(wpa_network=True, ap_count=2) 50 for i in range(len(self.user_params["OpenWrtAP"])): 51 self.openwrt = self.access_points[i] 52 logging.info( 53 f"AP{i+1}: {self.openwrt.get_bssids_for_wifi_networks()}") 54 self.pno_network_a = self.reference_networks[0]['2g'] 55 self.pno_network_b = self.reference_networks[0]['5g'] 56 if "OpenWrtAP" in self.user_params: 57 self.pno_network_b = self.reference_networks[1]['5g'] 58 self.attn_a = self.attenuators[0] 59 self.attn_b = self.attenuators[1] 60 # Disable second AP's networks, so that it does not interfere during PNO 61 self.attenuators[2].set_atten(MAX_ATTN) 62 self.attenuators[3].set_atten(MAX_ATTN) 63 self.set_attns("default") 64 # Scan for WiFi networks right after APs launched and attenuators set. 65 time.sleep(WAIT_ATTENUATION_SEC) 66 wutils.list_scan_results(self.dut) 67 68 def setup_test(self): 69 super().setup_test() 70 self.dut.droid.wifiStartTrackingStateChange() 71 self.dut.droid.wakeLockRelease() 72 self.dut.droid.goToSleepNow() 73 wutils.reset_wifi(self.dut) 74 self.dut.ed.clear_all_events() 75 76 def teardown_test(self): 77 super().teardown_test() 78 self.dut.droid.wifiStopTrackingStateChange() 79 wutils.reset_wifi(self.dut) 80 self.dut.ed.clear_all_events() 81 self.set_attns("default") 82 83 def teardown_class(self): 84 if "AccessPoint" in self.user_params: 85 del self.user_params["reference_networks"] 86 del self.user_params["open_network"] 87 88 """Helper Functions""" 89 90 def set_attns(self, attn_val_name): 91 """Sets attenuation values on attenuators used in this test. 92 93 Args: 94 attn_val_name: Name of the attenuation value pair to use. 95 """ 96 self.log.info("Set attenuation values to %s", 97 self.attn_vals[attn_val_name]) 98 try: 99 self.attn_a.set_atten(self.attn_vals[attn_val_name][0]) 100 self.attn_b.set_atten(self.attn_vals[attn_val_name][1]) 101 except: 102 self.log.error("Failed to set attenuation values %s.", 103 attn_val_name) 104 raise 105 106 def trigger_pno_and_assert_connect(self, ad, attn_val_name, expected_con): 107 """Trigger PNO and verify the connection after PNO. 108 109 Args: 110 ad: Android Device to trigger PNO on. 111 attn_val_name: Name of the attenuation value pair to use. 112 expected_con: The expected info of the network to we expect the DUT 113 to connect to. 114 """ 115 connection_info = ad.droid.wifiGetConnectionInfo() 116 117 # Stops APs to force DUT to disconnect and restart APs. 118 for i in range(len(self.user_params["OpenWrtAP"])): 119 self.openwrt = self.access_points[i] 120 self.openwrt.stop_ap() 121 122 wutils.wait_for_disconnect(self.dut, 123 timeout=WAIT_WIFI_DISCONNECT_SEC) 124 125 for i in range(len(self.user_params["OpenWrtAP"])): 126 self.openwrt = self.access_points[i] 127 self.openwrt.start_ap() 128 129 self.set_attns(attn_val_name) 130 131 ad.log.info("Wait %ss for triggering PNO scan, connect from %s to %s.", 132 self.pno_interval, 133 connection_info[WifiEnums.SSID_KEY], 134 expected_con[WifiEnums.SSID_KEY]) 135 time.sleep(self.pno_interval) 136 137 try: 138 ad.log.info("Expect it's connected to %s after PNO interval" 139 % ad.droid.wifiGetConnectionInfo()[WifiEnums.SSID_KEY]) 140 expected_ssid = expected_con[WifiEnums.SSID_KEY] 141 verify_con = {WifiEnums.SSID_KEY: expected_ssid} 142 wutils.verify_wifi_connection_info(ad, verify_con) 143 ad.log.info("Connected to %s successfully after PNO", 144 expected_ssid) 145 wutils.verify_11ax_wifi_connection( 146 ad, self.wifi6_models, "wifi6_ap" in self.user_params) 147 finally: 148 pass 149 150 def add_and_enable_test_networks(self, num_networks): 151 """Add some test networks to the device and enable them. 152 153 Args: 154 num_networks: Number of networks to add. 155 """ 156 ssid_name_base = "pno_test_network_" 157 for i in range(0, num_networks): 158 network = {} 159 network[WifiEnums.SSID_KEY] = ssid_name_base + str(i) 160 network[WifiEnums.PWD_KEY] = "pno_test" 161 self.add_network_and_enable(network) 162 163 def add_network_and_enable(self, network): 164 """Add a network and enable it. 165 166 Args: 167 network : Network details for the network to be added. 168 169 """ 170 ret = self.dut.droid.wifiAddNetwork(network) 171 asserts.assert_true(ret != -1, "Add network %r failed" % network) 172 self.dut.droid.wifiEnableNetwork(ret, 0) 173 174 175 """ Tests Begin """ 176 177 @test_tracker_info(uuid="33d3cae4-5fa7-4e90-b9e2-5d3747bba64c") 178 def test_simple_pno_connection_5g_to_2g(self): 179 """Test PNO triggered autoconnect to a network. 180 181 Steps: 182 1. Puts the DUT to sleep. 183 2. DUT connects to a 2G(a) DUT and a 5G(b) network so they will be 184 saved network and won't be excluded from PNO scan. 185 3. Stops APs to force DUT to disconnect and restart APs. 186 4. Attenuates to (2G in range, 5G out of range). 187 5. Waits for 120 seconds PNO interval. 188 6. Checks the device connected to 2G network automatically. 189 """ 190 wutils.connect_to_wifi_network(self.dut, self.pno_network_a) 191 wutils.connect_to_wifi_network(self.dut, self.pno_network_b) 192 self.trigger_pno_and_assert_connect(self.dut, 193 "a_on_b_off", 194 self.pno_network_a) 195 196 @test_tracker_info(uuid="39b945a1-830f-4f11-9e6a-9e9641066a96") 197 def test_simple_pno_connection_2g_to_5g(self): 198 """Test PNO triggered autoconnect to a network. 199 200 Steps: 201 1. Puts the DUT to sleep. 202 2. DUT connects to a 5G(b) DUT and a 2G(a) network so they will be 203 saved network and won't be excluded from PNO scan. 204 3. Stops APs to force DUT to disconnect from WiFi and restart APs. 205 4. Attenuates to (5G in range, 2G out of range). 206 5. Waits for 120 seconds PNO interval. 207 6. Checks the device connected to 5G network automatically. 208 """ 209 # DUT connects to the saved networks so they won't be excluded from PNO scan. 210 wutils.connect_to_wifi_network(self.dut, self.pno_network_b) 211 wutils.connect_to_wifi_network(self.dut, self.pno_network_a) 212 self.trigger_pno_and_assert_connect(self.dut, 213 "b_on_a_off", 214 self.pno_network_b) 215 216 @test_tracker_info(uuid="844b15be-ff45-4b09-a11b-0b2b4bb13b22") 217 def test_pno_connection_with_multiple_saved_networks(self): 218 """Test autoconnect with multiple saved networks after PNO. 219 220 Test PNO triggered autoconnect to a network when there are more 221 than 16 networks saved in the device. 222 223 16 is the max list size of PNO watch list for most devices. The device 224 should automatically pick the 16 most recently connected networks. 225 For networks that were never connected, the networks seen in the 226 previous scan result would have higher priority. 227 228 Steps: 229 1. Puts the DUt to sleep. 230 2. Saves 16 test network configurations in the device. 231 3. DUT connects to a 5G(b) DUT and a 2G(a) network so they will be 232 saved network and won't be excluded from PNO scan. 233 4. Stops APs to force DUT to disconnect from WiFi and restart APs. 234 5. Attenuates to (5G in range, 2G out of range). 235 6. Waits for 120 seconds PNO interval. 236 7. Checks the device connected to 5G network automatically. 237 """ 238 self.add_and_enable_test_networks(16) 239 # DUT connects to the saved networks so they won't be excluded from PNO scan. 240 wutils.connect_to_wifi_network(self.dut, self.pno_network_b) 241 wutils.connect_to_wifi_network(self.dut, self.pno_network_a) 242 # Force single scan so that both networks become preferred before PNO. 243 wutils.start_wifi_connection_scan_and_return_status(self.dut) 244 time.sleep(10) 245 self.trigger_pno_and_assert_connect(self.dut, 246 "b_on_a_off", 247 self.pno_network_b) 248 249 """ Tests End """ 250