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