• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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