blob: 05337f872d84f4edab8c6af205eddc881377b34a [file] [log] [blame]
#
# Copyright 2014 - The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
import time
from acts import asserts
from acts.test_decorators import test_tracker_info
import acts_contrib.test_utils.wifi.wifi_test_utils as wutils
from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
WifiEnums = wutils.WifiEnums
MAX_ATTN = 95
WAIT_WIFI_SCAN_RESULTS_SEC = 10
WAIT_ATTENUATION_SEC = 5
WAIT_WIFI_DISCONNECT_SEC = 60
class WifiPnoTest(WifiBaseTest):
def __init__(self, configs):
super().__init__(configs)
self.enable_packet_log = True
def setup_class(self):
super().setup_class()
self.dut = self.android_devices[0]
wutils.wifi_test_device_init(self.dut)
req_params = ["attn_vals", "pno_interval", "wifi6_models"]
opt_param = ["reference_networks"]
self.unpack_userparams(
req_param_names=req_params, opt_param_names=opt_param)
if "AccessPoint" in self.user_params:
self.legacy_configure_ap_and_start()
elif "OpenWrtAP" in self.user_params:
self.configure_openwrt_ap_and_start(wpa_network=True, ap_count=2)
for i in range(len(self.user_params["OpenWrtAP"])):
self.openwrt = self.access_points[i]
logging.info(
f"AP{i+1}: {self.openwrt.get_bssids_for_wifi_networks()}")
self.pno_network_a = self.reference_networks[0]['2g']
self.pno_network_b = self.reference_networks[0]['5g']
if "OpenWrtAP" in self.user_params:
self.pno_network_b = self.reference_networks[1]['5g']
self.attn_a = self.attenuators[0]
self.attn_b = self.attenuators[1]
# Disable second AP's networks, so that it does not interfere during PNO
self.attenuators[2].set_atten(MAX_ATTN)
self.attenuators[3].set_atten(MAX_ATTN)
self.set_attns("default")
# Scan for WiFi networks right after APs launched and attenuators set.
time.sleep(WAIT_ATTENUATION_SEC)
wutils.list_scan_results(self.dut)
def setup_test(self):
super().setup_test()
self.dut.droid.wifiStartTrackingStateChange()
self.dut.droid.wakeLockRelease()
self.dut.droid.goToSleepNow()
wutils.reset_wifi(self.dut)
self.dut.ed.clear_all_events()
def teardown_test(self):
super().teardown_test()
self.dut.droid.wifiStopTrackingStateChange()
wutils.reset_wifi(self.dut)
self.dut.ed.clear_all_events()
self.set_attns("default")
def teardown_class(self):
if "AccessPoint" in self.user_params:
del self.user_params["reference_networks"]
del self.user_params["open_network"]
"""Helper Functions"""
def set_attns(self, attn_val_name):
"""Sets attenuation values on attenuators used in this test.
Args:
attn_val_name: Name of the attenuation value pair to use.
"""
self.log.info("Set attenuation values to %s",
self.attn_vals[attn_val_name])
try:
self.attn_a.set_atten(self.attn_vals[attn_val_name][0])
self.attn_b.set_atten(self.attn_vals[attn_val_name][1])
except:
self.log.error("Failed to set attenuation values %s.",
attn_val_name)
raise
def trigger_pno_and_assert_connect(self, ad, attn_val_name, expected_con):
"""Trigger PNO and verify the connection after PNO.
Args:
ad: Android Device to trigger PNO on.
attn_val_name: Name of the attenuation value pair to use.
expected_con: The expected info of the network to we expect the DUT
to connect to.
"""
connection_info = ad.droid.wifiGetConnectionInfo()
# Stops APs to force DUT to disconnect and restart APs.
for i in range(len(self.user_params["OpenWrtAP"])):
self.openwrt = self.access_points[i]
self.openwrt.stop_ap()
wutils.wait_for_disconnect(self.dut,
timeout=WAIT_WIFI_DISCONNECT_SEC)
for i in range(len(self.user_params["OpenWrtAP"])):
self.openwrt = self.access_points[i]
self.openwrt.start_ap()
self.set_attns(attn_val_name)
ad.log.info("Wait %ss for triggering PNO scan, connect from %s to %s.",
self.pno_interval,
connection_info[WifiEnums.SSID_KEY],
expected_con[WifiEnums.SSID_KEY])
time.sleep(self.pno_interval)
try:
ad.log.info("Expect it's connected to %s after PNO interval"
% ad.droid.wifiGetConnectionInfo()[WifiEnums.SSID_KEY])
expected_ssid = expected_con[WifiEnums.SSID_KEY]
verify_con = {WifiEnums.SSID_KEY: expected_ssid}
wutils.verify_wifi_connection_info(ad, verify_con)
ad.log.info("Connected to %s successfully after PNO",
expected_ssid)
wutils.verify_11ax_wifi_connection(
ad, self.wifi6_models, "wifi6_ap" in self.user_params)
finally:
pass
def add_and_enable_test_networks(self, num_networks):
"""Add some test networks to the device and enable them.
Args:
num_networks: Number of networks to add.
"""
ssid_name_base = "pno_test_network_"
for i in range(0, num_networks):
network = {}
network[WifiEnums.SSID_KEY] = ssid_name_base + str(i)
network[WifiEnums.PWD_KEY] = "pno_test"
self.add_network_and_enable(network)
def add_network_and_enable(self, network):
"""Add a network and enable it.
Args:
network : Network details for the network to be added.
"""
ret = self.dut.droid.wifiAddNetwork(network)
asserts.assert_true(ret != -1, "Add network %r failed" % network)
self.dut.droid.wifiEnableNetwork(ret, 0)
""" Tests Begin """
@test_tracker_info(uuid="33d3cae4-5fa7-4e90-b9e2-5d3747bba64c")
def test_simple_pno_connection_5g_to_2g(self):
"""Test PNO triggered autoconnect to a network.
Steps:
1. Puts the DUT to sleep.
2. DUT connects to a 2G(a) DUT and a 5G(b) network so they will be
saved network and won't be excluded from PNO scan.
3. Stops APs to force DUT to disconnect and restart APs.
4. Attenuates to (2G in range, 5G out of range).
5. Waits for 120 seconds PNO interval.
6. Checks the device connected to 2G network automatically.
"""
wutils.connect_to_wifi_network(self.dut, self.pno_network_a)
wutils.connect_to_wifi_network(self.dut, self.pno_network_b)
self.trigger_pno_and_assert_connect(self.dut,
"a_on_b_off",
self.pno_network_a)
@test_tracker_info(uuid="39b945a1-830f-4f11-9e6a-9e9641066a96")
def test_simple_pno_connection_2g_to_5g(self):
"""Test PNO triggered autoconnect to a network.
Steps:
1. Puts the DUT to sleep.
2. DUT connects to a 5G(b) DUT and a 2G(a) network so they will be
saved network and won't be excluded from PNO scan.
3. Stops APs to force DUT to disconnect from WiFi and restart APs.
4. Attenuates to (5G in range, 2G out of range).
5. Waits for 120 seconds PNO interval.
6. Checks the device connected to 5G network automatically.
"""
# DUT connects to the saved networks so they won't be excluded from PNO scan.
wutils.connect_to_wifi_network(self.dut, self.pno_network_b)
wutils.connect_to_wifi_network(self.dut, self.pno_network_a)
self.trigger_pno_and_assert_connect(self.dut,
"b_on_a_off",
self.pno_network_b)
@test_tracker_info(uuid="844b15be-ff45-4b09-a11b-0b2b4bb13b22")
def test_pno_connection_with_multiple_saved_networks(self):
"""Test autoconnect with multiple saved networks after PNO.
Test PNO triggered autoconnect to a network when there are more
than 16 networks saved in the device.
16 is the max list size of PNO watch list for most devices. The device
should automatically pick the 16 most recently connected networks.
For networks that were never connected, the networks seen in the
previous scan result would have higher priority.
Steps:
1. Puts the DUt to sleep.
2. Saves 16 test network configurations in the device.
3. DUT connects to a 5G(b) DUT and a 2G(a) network so they will be
saved network and won't be excluded from PNO scan.
4. Stops APs to force DUT to disconnect from WiFi and restart APs.
5. Attenuates to (5G in range, 2G out of range).
6. Waits for 120 seconds PNO interval.
7. Checks the device connected to 5G network automatically.
"""
self.add_and_enable_test_networks(16)
# DUT connects to the saved networks so they won't be excluded from PNO scan.
wutils.connect_to_wifi_network(self.dut, self.pno_network_b)
wutils.connect_to_wifi_network(self.dut, self.pno_network_a)
# Force single scan so that both networks become preferred before PNO.
wutils.start_wifi_connection_scan_and_return_status(self.dut)
time.sleep(10)
self.trigger_pno_and_assert_connect(self.dut,
"b_on_a_off",
self.pno_network_b)
""" Tests End """