• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3.4
2#
3#   Copyright 2016 - 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 time
18
19import acts.signals as signals
20
21from acts import asserts
22from acts import base_test
23from acts.controllers import android_device
24from acts.controllers import attenuator
25from acts.test_decorators import test_tracker_info
26from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
27from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
28
29WifiEnums = wutils.WifiEnums
30
31AP_1 = 0
32AP_2 = 1
33# WifiNetworkSelector imposes a 10 seconds gap between two selections
34NETWORK_SELECTION_TIME_GAP = 12
35LVL1_ATTN = 15
36LVL2_ATTN = 30
37MIN_ATTN = 0
38MAX_ATTN = 95
39ATTN_SLEEP = 12
40
41
42class WifiNetworkSelectorTest(WifiBaseTest):
43    """These tests verify the behavior of the Android Wi-Fi Network Selector
44    feature.
45    """
46
47    def __init__(self, configs):
48        super().__init__(configs)
49        self.enable_packet_log = True
50
51    def setup_class(self):
52        super().setup_class()
53
54        self.dut = self.android_devices[0]
55        wutils.wifi_test_device_init(self.dut)
56        self.ap1_2g_attn = 0
57        self.ap1_5g_attn = 1
58        self.ap2_2g_attn = 2
59        self.ap2_5g_attn = 3
60        if "AccessPoint" in self.user_params:
61            self.legacy_configure_ap_and_start(mirror_ap=False, ap_count=2)
62        elif "OpenWrtAP" in self.user_params:
63            self.configure_openwrt_ap_and_start(open_network=True,
64                                                wpa_network=True,
65                                                ap_count=2)
66            self.ap1_5g_attn, self.ap2_2g_attn, self.ap2_5g_attn, = 0, 1, 1
67        self.configure_packet_capture()
68
69    def setup_test(self):
70        super().setup_test()
71        self.dut.droid.wakeLockAcquireBright()
72        self.dut.droid.wakeUpNow()
73        self.dut.ed.clear_all_events()
74        for a in self.attenuators:
75            a.set_atten(MAX_ATTN)
76        time.sleep(ATTN_SLEEP)
77
78    def teardown_test(self):
79        super().teardown_test()
80        for a in self.attenuators:
81            a.set_atten(MIN_ATTN)
82        wutils.reset_wifi(self.dut)
83        self.dut.droid.wakeLockRelease()
84        self.dut.droid.goToSleepNow()
85
86    def teardown_class(self):
87        if "AccessPoint" in self.user_params:
88            del self.user_params["reference_networks"]
89            del self.user_params["open_network"]
90
91    """ Helper Functions """
92
93    def add_networks(self, ad, networks):
94        """Add Wi-Fi networks to an Android device and verify the networks were
95        added correctly.
96
97        Args:
98            ad: the AndroidDevice object to add networks to.
99            networks: a list of dicts, each dict represents a Wi-Fi network.
100        """
101        for network in networks:
102            ret = ad.droid.wifiAddNetwork(network)
103            asserts.assert_true(ret != -1,
104                                "Failed to add network %s" % network)
105            ad.droid.wifiEnableNetwork(ret, 0)
106
107        configured_networks = ad.droid.wifiGetConfiguredNetworks()
108        self.log.info("Configured networks: %s", configured_networks)
109
110    def connect_and_verify_connected_bssid(self, network):
111        """Start a scan to get the DUT connected to an AP and verify the DUT
112        is connected to the correct BSSID.
113
114        Args:
115            expected_bssid: Network bssid to which connection.
116
117        Returns:
118            True if connection to given network happen, else return False.
119        """
120        expected_ssid = network['SSID']
121        expected_bssid = network['bssid']
122        wutils.start_wifi_connection_scan_and_ensure_network_found(
123            self.dut, expected_ssid)
124        time.sleep(20)
125        actual_network = self.dut.droid.wifiGetConnectionInfo()
126        self.log.info("Actual network: %s", actual_network)
127        asserts.assert_true(
128            actual_network and WifiEnums.BSSID_KEY in actual_network and \
129                expected_bssid.lower() == actual_network[
130                    WifiEnums.BSSID_KEY].lower(),
131            "Expected BSSID: %s, Actual BSSID: %s" %
132            (expected_bssid, actual_network[WifiEnums.BSSID_KEY]))
133        self.log.info("DUT connected to valid network: %s" % expected_bssid)
134
135    """ Tests Begin """
136
137    @test_tracker_info(uuid="ffa5e278-db3f-4e17-af11-6c7a3e7c5cc2")
138    def test_network_selector_automatic_connection(self):
139        """
140            1. Add one saved network to DUT.
141            2. Move the DUT in range.
142            3. Verify the DUT is connected to the network.
143        """
144        # add a saved network to DUT
145        networks = [self.reference_networks[AP_1]['5g']]
146        self.add_networks(self.dut, networks)
147
148        # move the DUT in range
149        self.attenuators[self.ap1_5g_attn].set_atten(MIN_ATTN)
150        time.sleep(ATTN_SLEEP)
151
152        # verify DUT is connected to AP_1 5g network
153        network = self.reference_networks[AP_1]['5g'].copy()
154        if "OpenWrtAP" in self.user_params:
155            network['bssid'] = self.bssid_map[AP_1]['5g'][network["SSID"]]
156        self.connect_and_verify_connected_bssid(network)
157
158    @test_tracker_info(uuid="3ea818f2-10d7-4aad-bfab-7d8fb25aae78")
159    def test_network_selector_basic_connection_prefer_5g(self):
160        """
161            1. Add one saved SSID with 2G and 5G BSSIDs of similar RSSI.
162            2. Move the DUT in range.
163            3. Verify the DUT is connected to the 5G BSSID.
164        """
165        # add a saved network with both 2G and 5G BSSIDs to DUT
166        networks = [
167            self.reference_networks[AP_1]['2g'],
168            self.reference_networks[AP_1]['5g']
169        ]
170        self.add_networks(self.dut, networks)
171
172        # Move DUT in range
173        self.attenuators[self.ap1_2g_attn].set_atten(MIN_ATTN)
174        self.attenuators[self.ap1_5g_attn].set_atten(MIN_ATTN)
175        time.sleep(ATTN_SLEEP)
176
177        # verify DUT is connected to 5G network
178        network = self.reference_networks[AP_1]['5g'].copy()
179        if "OpenWrtAP" in self.user_params:
180            network['bssid'] = self.bssid_map[AP_1]['5g'][network["SSID"]]
181        self.connect_and_verify_connected_bssid(network)
182
183    @test_tracker_info(uuid="bebb29ca-4486-4cde-b390-c5f8f2e1580c")
184    def test_network_selector_prefer_stronger_rssi(self):
185        """
186            1. Add two saved SSIDs to DUT, same band, one has stronger RSSI
187               than the other.
188            2. Move the DUT in range.
189            3. Verify the DUT is connected to the SSID with stronger RSSI.
190        """
191        # add a 2G and a 5G saved network to DUT
192        networks = [
193            self.reference_networks[AP_1]['2g'],
194            self.reference_networks[AP_2]['2g']
195        ]
196        self.add_networks(self.dut, networks)
197
198        # move the DUT in range
199        self.attenuators[self.ap1_2g_attn].set_atten(LVL1_ATTN)
200        self.attenuators[self.ap2_2g_attn].set_atten(LVL2_ATTN)
201        time.sleep(ATTN_SLEEP)
202
203        # verify DUT is connected AP_1
204        network = self.reference_networks[AP_1]['2g'].copy()
205        if "OpenWrtAP" in self.user_params:
206            network['bssid'] = self.bssid_map[AP_1]['2g'][network["SSID"]]
207        self.connect_and_verify_connected_bssid(network)
208
209    @test_tracker_info(uuid="f9f72dc5-034f-4fe2-a27d-df1b6cae76cd")
210    def test_network_selector_prefer_secure_over_open_network(self):
211        """
212            1. Add two saved networks to DUT, same band, similar RSSI, one uses
213               WPA2 security, the other is open.
214            2. Move the DUT in range.
215            3. Verify the DUT is connected to the secure network that uses WPA2.
216        """
217        # add a open network and a secure saved network to DUT
218        networks = [
219            self.open_network[AP_1]['5g'], self.reference_networks[AP_1]['5g']
220        ]
221        self.add_networks(self.dut, networks)
222
223        # Move DUT in range
224        self.attenuators[self.ap1_5g_attn].set_atten(MIN_ATTN)
225        time.sleep(ATTN_SLEEP)
226
227        # verify DUT connects to secure network
228        network = self.reference_networks[AP_1]['5g'].copy()
229        if "OpenWrtAP" in self.user_params:
230            network['bssid'] = self.bssid_map[AP_1]['5g'][network["SSID"]]
231        self.connect_and_verify_connected_bssid(network)
232
233    @test_tracker_info(uuid="ab2c527c-0f9c-4f09-a13f-e3f461b7da52")
234    def test_network_selector_blacklist_by_connection_failure(self):
235        """
236            1. Add two saved secured networks X and Y to DUT. X has stronger
237               RSSI than Y. X has wrong password configured.
238            2. Move the DUT in range.
239            3. Verify the DUT is connected to network Y.
240        """
241        # add two saved networks to DUT, and one of them is configured with
242        # incorrect password
243        wrong_passwd_network = self.reference_networks[AP_1]['5g'].copy()
244        wrong_passwd_network['password'] += 'haha'
245        networks = [wrong_passwd_network, self.reference_networks[AP_2]['5g']]
246        self.add_networks(self.dut, networks)
247
248        # make AP_1 5G has stronger RSSI than AP_2 5G
249        self.attenuators[self.ap1_5g_attn].set_atten(MIN_ATTN)
250        self.attenuators[self.ap2_5g_attn].set_atten(LVL1_ATTN)
251        time.sleep(ATTN_SLEEP)
252
253        # start 3 scans to get AP_1 5G blacklisted because of the incorrect
254        # password
255        for _ in range(3):
256            wutils.start_wifi_connection_scan_and_return_status(self.dut)
257            time.sleep(NETWORK_SELECTION_TIME_GAP)
258
259        # verify DUT is connect AP_2 5G
260        network = self.reference_networks[AP_2]['5g'].copy()
261        if "OpenWrtAP" in self.user_params:
262            network['bssid'] = self.bssid_map[AP_2]['5g'][network["SSID"]]
263        self.connect_and_verify_connected_bssid(network)
264
265    @test_tracker_info(uuid="71d88fcf-c7b8-4fd2-a7cb-84ac4a130ecf")
266    def network_selector_2g_to_5g_prefer_same_SSID(self):
267        """
268            1. Add SSID_A and SSID_B to DUT. Both SSIDs have both 2G and 5G
269               BSSIDs.
270            2. Attenuate the networks so that the DUT is connected to SSID_A's
271               2G in the beginning.
272            3. Increase the RSSI of both SSID_A's 5G and SSID_B's 5G.
273            4. Verify the DUT switches to SSID_A's 5G.
274        """
275        #add two saved networks to DUT
276        networks = [
277            self.reference_networks[AP_1]['2g'],
278            self.reference_networks[AP_2]['2g']
279        ]
280        self.add_networks(self.dut, networks)
281        #make AP_1 2G in range
282        self.attenuators[AP_1_2G_ATTENUATOR].set_atten(0)
283        #verify
284        self.connect_and_verify_connected_bssid(
285            self.reference_networks[AP_1]['2g']['bssid'])
286        #make both AP_1 and AP_2 5G in range with similar RSSI
287        self.attenuators[AP_1_5G_ATTENUATOR].set_atten(0)
288        self.attenuators[AP_2_5G_ATTENUATOR].set_atten(0)
289        #ensure the time gap between two network selections
290        time.sleep(NETWORK_SELECTION_TIME_GAP)
291        #verify
292        self.connect_and_verify_connected_bssid(
293            self.reference_networks[AP_1]['5g']['bssid'])
294
295    @test_tracker_info(uuid="c1243cf4-d96e-427e-869e-3d640bee3f28")
296    def network_selector_2g_to_5g_different_ssid(self):
297        """
298            1. Add SSID_A and SSID_B to DUT. Both SSIDs have both 2G and 5G
299               BSSIDs.
300            2. Attenuate the networks so that the DUT is connected to SSID_A's
301               2G in the beginning.
302            3. Increase the RSSI of SSID_B's 5G while attenuate down SSID_A's
303               2G RSSI.
304            4. Verify the DUT switches to SSID_B's 5G.
305        """
306        # add two saved networks to DUT
307        networks = [
308            self.reference_networks[AP_1]['2g'],
309            self.reference_networks[AP_2]['2g']
310        ]
311        self.add_networks(self.dut, networks)
312
313        # make both AP_1 2G and AP_2 5G in range, and AP_1 2G
314        # has much stronger RSSI than AP_2 5G
315        self.attenuators[AP_1_2G_ATTENUATOR].set_atten(0)
316        self.attenuators[AP_2_5G_ATTENUATOR].set_atten(20)
317        #verify
318        self.connect_and_verify_connected_bssid(
319            self.reference_networks[AP_1]['2g']['bssid'])
320        #bump up AP_2 5G RSSI and reduce AP_1 2G RSSI
321        self.attenuators[AP_1_2G_ATTENUATOR].set_atten(40)
322        self.attenuators[AP_2_5G_ATTENUATOR].set_atten(0)
323        #ensure the time gap between two network selections
324        time.sleep(NETWORK_SELECTION_TIME_GAP)
325        #verify
326        self.connect_and_verify_connected_bssid(
327            self.reference_networks[AP_2]['5g']['bssid'])
328
329    @test_tracker_info(uuid="10da95df-83ed-4447-89f8-735b08dbe2eb")
330    def network_selector_5g_to_2g_same_ssid(self):
331        """
332            1. Add one SSID that has both 2G and 5G to the DUT.
333            2. Attenuate down the 2G RSSI.
334            3. Connect the DUT to the 5G BSSID.
335            4. Bring up the 2G RSSI and attenuate down the 5G RSSI.
336            5. Verify the DUT switches to the 2G BSSID.
337        """
338        #add a saved network to DUT
339        networks = [self.reference_networks[AP_1]['2g']]
340        self.add_networks(self.dut, networks)
341        #make both AP_1 2G and AP_2 5G in range, and AP_1 5G
342        #has much stronger RSSI than AP_2 2G
343        self.attenuators[AP_1_5G_ATTENUATOR].set_atten(0)
344        self.attenuators[AP_1_2G_ATTENUATOR].set_atten(50)
345        #verify
346        self.connect_and_verify_connected_bssid(
347            self.reference_networks[AP_1]['5g']['bssid'])
348        #bump up AP_1 2G RSSI and reduce AP_1 5G RSSI
349        self.attenuators[AP_1_2G_ATTENUATOR].set_atten(0)
350        self.attenuators[AP_1_5G_ATTENUATOR].set_atten(30)
351        #ensure the time gap between two network selections
352        time.sleep(NETWORK_SELECTION_TIME_GAP)
353        #verify
354        self.connect_and_verify_connected_bssid(
355            self.reference_networks[AP_1]['2g']['bssid'])
356
357    @test_tracker_info(uuid="ead78ae0-27ab-4bb8-ae77-0b9fe588436a")
358    def test_network_selector_stay_on_sufficient_network(self):
359        """
360            1. Add two 5G WPA2 BSSIDs X and Y to the DUT. X has higher RSSI
361               than Y.
362            2. Connect the DUT to X.
363            3. Change attenuation so that Y's RSSI goes above X's.
364            4. Verify the DUT stays on X.
365        """
366        # add two saved networks to DUT
367        networks = [
368            self.reference_networks[AP_1]['5g'],
369            self.reference_networks[AP_2]['5g']
370        ]
371        self.add_networks(self.dut, networks)
372
373        # make both AP_1 5G and AP_2 5G in range, and AP_1 5G
374        # has stronger RSSI than AP_2 5G
375        self.attenuators[self.ap1_5g_attn].set_atten(LVL1_ATTN)
376        self.attenuators[self.ap2_5g_attn].set_atten(LVL2_ATTN)
377        time.sleep(ATTN_SLEEP)
378
379        # verify DUT is connected to AP_1
380        network = self.reference_networks[AP_1]['5g'].copy()
381        if "OpenWrtAP" in self.user_params:
382            network['bssid'] = self.bssid_map[AP_1]['5g'][network["SSID"]]
383        self.connect_and_verify_connected_bssid(network)
384
385        # bump up AP_2 5G RSSI over AP_1 5G RSSI
386        self.attenuators[self.ap2_5g_attn].set_atten(MIN_ATTN)
387
388        # ensure the time gap between two network selections
389        time.sleep(NETWORK_SELECTION_TIME_GAP)
390
391        # verify DUT is still connected to AP_1
392        self.connect_and_verify_connected_bssid(network)
393
394    @test_tracker_info(uuid="5470010f-8b62-4b1c-8b83-1f91422eced0")
395    def test_network_selector_stay_on_user_selected_network(self):
396        """
397            1. Connect the DUT to SSID_A with a very low RSSI via the user select code path.
398            2. Add SSID_B to the DUT as saved network. SSID_B has higher RSSI than SSID_A.
399            3. Start a scan and network selection.
400            4. Verify DUT stays on SSID_A.
401        """
402        # set max attenuation on AP_2 and make AP_1 5G in range with low RSSI
403        self.attenuators[self.ap2_5g_attn].set_atten(MIN_ATTN)
404        self.attenuators[self.ap1_5g_attn].set_atten(LVL1_ATTN)
405        time.sleep(ATTN_SLEEP)
406
407        # connect to AP_1 via user selection and add, save AP_2
408        wutils.connect_to_wifi_network(self.dut,
409                                       self.reference_networks[AP_1]['5g'])
410        networks = [self.reference_networks[AP_2]['5g']]
411        self.add_networks(self.dut, networks)
412
413        # ensure the time gap between two network selections
414        time.sleep(NETWORK_SELECTION_TIME_GAP)
415
416        # verify we are still connected to AP_1 5G
417        network = self.reference_networks[AP_1]['5g'].copy()
418        if "OpenWrtAP" in self.user_params:
419            network['bssid'] = self.bssid_map[AP_1]['5g'][network["SSID"]]
420        self.connect_and_verify_connected_bssid(network)
421
422    @test_tracker_info(uuid="f08d8f73-8c94-42af-bba9-4c49bbf16420")
423    def test_network_selector_reselect_after_forget_network(self):
424        """
425            1. Add two 5G BSSIDs X and Y to the DUT. X has higher RSSI
426               than Y.
427            2. Connect the DUT to X.
428            3. Forget X.
429            5. Verify the DUT reselect and connect to Y.
430        """
431        # add two networks to DUT
432        networks = [
433            self.reference_networks[AP_1]['5g'],
434            self.reference_networks[AP_2]['5g']
435        ]
436        self.add_networks(self.dut, networks)
437
438        # make both AP_1 5G and AP_2 5G in range. AP_1 5G has stronger
439        # RSSI than AP_2 5G
440        self.attenuators[self.ap1_5g_attn].set_atten(MIN_ATTN)
441        self.attenuators[self.ap2_5g_attn].set_atten(LVL1_ATTN)
442        time.sleep(ATTN_SLEEP)
443
444        # verify DUT connected to AP1
445        network = self.reference_networks[AP_1]['5g'].copy()
446        if "OpenWrtAP" in self.user_params:
447            network['bssid'] = self.bssid_map[AP_1]['5g'][network["SSID"]]
448        self.connect_and_verify_connected_bssid(network)
449
450        # forget AP_1
451        wutils.wifi_forget_network(self.dut,
452                                   self.reference_networks[AP_1]['5g']['SSID'])
453
454        # verify DUT connected to AP2
455        network = self.reference_networks[AP_2]['5g'].copy()
456        if "OpenWrtAP" in self.user_params:
457            network['bssid'] = self.bssid_map[AP_2]['5g'][network["SSID"]]
458        self.connect_and_verify_connected_bssid(network)
459