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 time 17 18from acts import asserts 19from acts.test_decorators import test_tracker_info 20import acts_contrib.test_utils.wifi.wifi_test_utils as wutils 21from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest 22 23WifiEnums = wutils.WifiEnums 24MAX_ATTN = 95 25 26class WifiPnoTest(WifiBaseTest): 27 28 def __init__(self, configs): 29 super().__init__(configs) 30 self.enable_packet_log = True 31 32 def setup_class(self): 33 super().setup_class() 34 35 self.dut = self.android_devices[0] 36 wutils.wifi_test_device_init(self.dut) 37 req_params = ["attn_vals", "pno_interval", "wifi6_models"] 38 opt_param = ["reference_networks"] 39 self.unpack_userparams( 40 req_param_names=req_params, opt_param_names=opt_param) 41 42 if "AccessPoint" in self.user_params: 43 self.legacy_configure_ap_and_start() 44 elif "OpenWrtAP" in self.user_params: 45 self.configure_openwrt_ap_and_start(wpa_network=True, 46 ap_count=2) 47 self.pno_network_a = self.reference_networks[0]['2g'] 48 self.pno_network_b = self.reference_networks[0]['5g'] 49 if "OpenWrtAP" in self.user_params: 50 self.pno_network_b = self.reference_networks[1]['5g'] 51 self.attn_a = self.attenuators[0] 52 self.attn_b = self.attenuators[1] 53 # Disable second AP's networks, so that it does not interfere during PNO 54 self.attenuators[2].set_atten(MAX_ATTN) 55 self.attenuators[3].set_atten(MAX_ATTN) 56 self.set_attns("default") 57 58 def setup_test(self): 59 super().setup_test() 60 self.dut.droid.wifiStartTrackingStateChange() 61 self.dut.droid.wakeLockRelease() 62 self.dut.droid.goToSleepNow() 63 wutils.reset_wifi(self.dut) 64 self.dut.ed.clear_all_events() 65 # DUT to the saved networks so they won't be excluded from PNO scan. 66 wutils.connect_to_wifi_network(self.dut, self.pno_network_a) 67 wutils.connect_to_wifi_network(self.dut, self.pno_network_b) 68 69 def teardown_test(self): 70 super().teardown_test() 71 self.dut.droid.wifiStopTrackingStateChange() 72 wutils.reset_wifi(self.dut) 73 self.dut.ed.clear_all_events() 74 self.set_attns("default") 75 76 def teardown_class(self): 77 if "AccessPoint" in self.user_params: 78 del self.user_params["reference_networks"] 79 del self.user_params["open_network"] 80 81 """Helper Functions""" 82 83 def set_attns(self, attn_val_name): 84 """Sets attenuation values on attenuators used in this test. 85 86 Args: 87 attn_val_name: Name of the attenuation value pair to use. 88 """ 89 self.log.info("Set attenuation values to %s", 90 self.attn_vals[attn_val_name]) 91 try: 92 self.attn_a.set_atten(self.attn_vals[attn_val_name][0]) 93 self.attn_b.set_atten(self.attn_vals[attn_val_name][1]) 94 except: 95 self.log.error("Failed to set attenuation values %s.", 96 attn_val_name) 97 raise 98 99 def trigger_pno_and_assert_connect(self, attn_val_name, expected_con): 100 """Sets attenuators to disconnect current connection to trigger PNO. 101 Validate that the DUT connected to the new SSID as expected after PNO. 102 103 Args: 104 attn_val_name: Name of the attenuation value pair to use. 105 expected_con: The expected info of the network to we expect the DUT 106 to roam to. 107 """ 108 connection_info = self.dut.droid.wifiGetConnectionInfo() 109 self.log.info("Triggering PNO connect from %s to %s", 110 connection_info[WifiEnums.SSID_KEY], 111 expected_con[WifiEnums.SSID_KEY]) 112 self.set_attns(attn_val_name) 113 self.log.info("Wait %ss for PNO to trigger.", self.pno_interval) 114 time.sleep(self.pno_interval) 115 try: 116 self.log.info("Connected to %s network after PNO interval" 117 % self.dut.droid.wifiGetConnectionInfo()) 118 expected_ssid = expected_con[WifiEnums.SSID_KEY] 119 verify_con = {WifiEnums.SSID_KEY: expected_ssid} 120 wutils.verify_wifi_connection_info(self.dut, verify_con) 121 self.log.info("Connected to %s successfully after PNO", 122 expected_ssid) 123 wutils.verify_11ax_wifi_connection( 124 self.dut, self.wifi6_models, "wifi6_ap" in self.user_params) 125 finally: 126 pass 127 128 def add_and_enable_test_networks(self, num_networks): 129 """Add some test networks to the device and enable them. 130 131 Args: 132 num_networks: Number of networks to add. 133 """ 134 ssid_name_base = "pno_test_network_" 135 for i in range(0, num_networks): 136 network = {} 137 network[WifiEnums.SSID_KEY] = ssid_name_base + str(i) 138 network[WifiEnums.PWD_KEY] = "pno_test" 139 self.add_network_and_enable(network) 140 141 def add_network_and_enable(self, network): 142 """Add a network and enable it. 143 144 Args: 145 network : Network details for the network to be added. 146 147 """ 148 ret = self.dut.droid.wifiAddNetwork(network) 149 asserts.assert_true(ret != -1, "Add network %r failed" % network) 150 self.dut.droid.wifiEnableNetwork(ret, 0) 151 152 153 """ Tests Begin """ 154 155 @test_tracker_info(uuid="33d3cae4-5fa7-4e90-b9e2-5d3747bba64c") 156 def test_simple_pno_connection_5g_to_2g(self): 157 """Test PNO triggered autoconnect to a network. 158 159 Steps: 160 1. Switch off the screen on the device. 161 2. Save 2 valid network configurations (a & b) in the device. 162 3. Attenuate 5Ghz network and wait for a few seconds to trigger PNO. 163 4. Check the device connected to 2Ghz network automatically. 164 """ 165 self.add_network_and_enable(self.pno_network_a) 166 self.add_network_and_enable(self.pno_network_b) 167 self.trigger_pno_and_assert_connect("a_on_b_off", self.pno_network_a) 168 169 @test_tracker_info(uuid="39b945a1-830f-4f11-9e6a-9e9641066a96") 170 def test_simple_pno_connection_2g_to_5g(self): 171 """Test PNO triggered autoconnect to a network. 172 173 Steps: 174 1. Switch off the screen on the device. 175 2. Save 2 valid network configurations (a & b) in the device. 176 3. Attenuate 2Ghz network and wait for a few seconds to trigger PNO. 177 4. Check the device connected to 5Ghz network automatically. 178 179 """ 180 self.add_network_and_enable(self.pno_network_a) 181 self.add_network_and_enable(self.pno_network_b) 182 self.trigger_pno_and_assert_connect("b_on_a_off", self.pno_network_b) 183 184 @test_tracker_info(uuid="844b15be-ff45-4b09-a11b-0b2b4bb13b22") 185 def test_pno_connection_with_multiple_saved_networks(self): 186 """Test PNO triggered autoconnect to a network when there are more 187 than 16 networks saved in the device. 188 189 16 is the max list size of PNO watch list for most devices. The device should automatically 190 pick the 16 most recently connected networks. For networks that were never connected, the 191 networks seen in the previous scan result would have higher priority. 192 193 Steps: 194 1. Save 16 test network configurations in the device. 195 2. Add 2 connectable networks and do a normal scan. 196 3. Trigger PNO scan 197 """ 198 self.add_and_enable_test_networks(16) 199 self.add_network_and_enable(self.pno_network_a) 200 self.add_network_and_enable(self.pno_network_b) 201 # Force single scan so that both networks become preferred before PNO. 202 wutils.start_wifi_connection_scan_and_return_status(self.dut) 203 time.sleep(10) 204 self.trigger_pno_and_assert_connect("b_on_a_off", self.pno_network_b) 205 206 """ Tests End """ 207