blob: fe80116a052b6f5485d31c0e37b1d91400d80784 [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright 2021 - 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 time
from acts import asserts
from acts import signals
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
from acts.controllers.ap_lib.hostapd_constants import BAND_2G
from acts.controllers.ap_lib.hostapd_constants import BAND_5G
from acts.controllers.ap_lib import hostapd_constants
# TODO: Find a better way to get real country code and channels data.
COUNTRY_5G_NOT_ALLOWED = ["JP", "GB", "DE"]
WIFI_5G_NON_DFS_CHANNELS = [36, 38, 40, 42, 44, 46, 48, 149, 153, 157, 161, 165]
WIFI_5G_DFS_CHANNELS = [52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140]
WIFI_EU_SRD_CHANNELS = [149, 153, 157, 161, 165]
BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS = 5
WifiEnums = wutils.WifiEnums
class WifiCountrySoftApAcsTest(WifiBaseTest):
"""WiFi WifiSoftApCountryAcsTest test class.
Test Bed Requirement:
* Android DUT x 1.
* OpenWrt x 1.
"""
def setup_class(self):
super().setup_class()
self.dut = self.android_devices[0]
self.client = self.android_devices[1]
if "OpenWrtAP" in self.user_params:
self.openwrt = self.access_points[0]
self.openwrt.log.info("Rebooting OpenWrt")
self.openwrt.reboot()
self.openwrt.verify_wifi_status(timeout=60)
req_params = []
opt_param = []
self.unpack_userparams(
req_param_names=req_params, opt_param_names=opt_param)
def setup_test(self):
super().setup_test()
for ad in self.android_devices:
wutils.reset_wifi(ad)
wutils.wifi_toggle_state(self.dut, True)
wutils.wifi_toggle_state(self.client, True)
def teardown_test(self):
super().teardown_test()
if self.dut.droid.wifiIsApEnabled():
wutils.stop_wifi_tethering(self.dut)
for ad in self.android_devices:
wutils.reset_wifi(ad)
wutils.set_wifi_country_code(
ad, wutils.WifiEnums.CountryCode.US)
def teardown_class(self):
super().teardown_class()
for ad in self.android_devices:
wutils.reset_wifi(ad)
if "AccessPoint" in self.user_params:
del self.user_params["reference_networks"]
del self.user_params["open_network"]
def is_bridgedap_supported(self, *args):
return self.dut.droid.wifiIsBridgedApConcurrencySupported()
def set_country_code_and_verify(self, ad, country_code):
""" Set Country Code to DUT.
Args:
ad: An AndroidDevice object.
country_code: String; 2 letter ISO country code, e,g,. "US".
"""
wutils.set_wifi_country_code(ad, country_code)
# Wi-Fi OFF and ON to make sure country code take effect.
wutils.wifi_toggle_state(ad, False)
wutils.wifi_toggle_state(ad, True)
country = ad.droid.wifiGetCountryCode()
asserts.assert_true(country == country_code,
"country code {} is not set".format(country_code))
ad.log.info("Country code set to : {}".format(country))
def connect_wifi_network(self, init_sta_band, init_sta_chan):
"""Enable OpenWrt with a 2G/5G channels and a DUT connect to it.
Args:
init_sta_band: String; "2g" or "5g".
init_sta_chan: Integer; use to setup OpenWrt 2G/5G channel.
Returns:
ap_freq: Integer'; represent the frequency of the AP which
the DUT connect to.
"""
# Enable a Wi-Fi network and DUT connect to it.
if init_sta_band == BAND_2G:
connect = BAND_2G
channel_2g = init_sta_chan
channel_5g = hostapd_constants.AP_DEFAULT_CHANNEL_5G
elif init_sta_band == BAND_5G:
connect = BAND_5G
channel_2g = hostapd_constants.AP_DEFAULT_CHANNEL_2G
channel_5g = init_sta_chan
# Enable OpenWrt AP.
if "OpenWrtAP" in self.user_params:
self.openwrt = self.access_points[0]
self.configure_openwrt_ap_and_start(wpa_network=True,
channel_2g=channel_2g,
channel_5g=channel_5g)
self.ap1_2g = self.wpa_networks[0][BAND_2G]
self.ap1_5g = self.wpa_networks[0][BAND_5G]
self.openwrt.log.info("OpenWrt AP 2G: {}".format(self.ap1_2g))
self.openwrt.log.info("OpenWrt AP 5G: {}".format(self.ap1_5g))
if connect == BAND_2G:
wutils.connect_to_wifi_network(self.dut, self.ap1_2g)
elif connect == BAND_5G:
wutils.connect_to_wifi_network(self.dut, self.ap1_5g)
ap_freq = self.dut.droid.wifiGetConnectionInfo()["frequency"]
self.dut.log.info("DUT connected to AP on freq: {}, chan: {}".
format(ap_freq, WifiEnums.freq_to_channel[ap_freq]))
return ap_freq
def enable_softap(self, ad):
""" Enable SoftAp of the DUT
Args:
ad: An AndroidDevice object.
Returns:
(freq1, freq2): Integer; a 2G frequency and a 5G frequency if DUT
support BridgedAp.
freq: Integer; a frequency from SoftAp.
None, bandwidth: Just a placeholder, won't be used.
Raises:
TestFailure if no BridgedAp instances.
"""
# Enable SoftAp
# Create SoftAp config.
config = wutils.create_softap_config()
# If DUT support BridgedAp, then two BridgedAp instances enabled.
if self.dut.droid.wifiIsBridgedApConcurrencySupported():
wutils.save_wifi_soft_ap_config(
ad,
config,
bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G,
WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G])
# If DUT does not support BridgedAp, 2G OR 5G SoftAp enabled.
else:
if self.init_softap_band == BAND_2G:
band = WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G
elif self.init_softap_band == BAND_5G:
band = WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G
wutils.save_wifi_soft_ap_config(ad, config, band=band)
wutils.start_wifi_tethering_saved_config(ad)
time.sleep(BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS)
# if DUT support BridgedAp:
if ad.droid.wifiIsBridgedApConcurrencySupported():
callbackId = ad.droid.registerSoftApCallback()
infos = wutils.get_current_softap_infos(ad, callbackId, True)
ad.droid.unregisterSoftApCallback(callbackId)
# if DUT BridgedAp has two instances, return two frequencies.
if len(infos) == 2:
freq_1 = infos[0]["frequency"]
freq_2 = infos[1]["frequency"]
return freq_1, freq_2
# if DUT BridgedAp has only one instances, return the frequency.
elif len(infos) == 1:
freq = infos[0]["frequency"]
return freq, None
else:
raise signals.TestFailure("There should be SoftAp instance.")
# if DUT does not support BridgedAp:
else:
# Return SoftAp frequency.
callbackId = ad.droid.registerSoftApCallback()
freq, bandwidth = wutils.get_current_softap_info(ad, callbackId,
True)
ad.log.info("SoftAp freq: {}".format(freq))
ad.droid.unregisterSoftApCallback(callbackId)
return freq, bandwidth
def collect_acs_failures(self, freq1, freq2, country, init_sta_band,
init_sta_chan, init_softap_band):
""" Verify SoftAp ACS rules and return error message when fail.
Args:
freq1: Integer; frequency from SoftAp.
freq2: Integer; frequency from SoftAp.
country: String; Two letters country code, e.g., "US".
init_sta_band: String; "2g" or "5g".
init_sta_chan: Integer; use to setup OpenWrt 2G/5G channel.
init_softap_band: String: "2g" or "5g".
Returns: List of string; contains failure messages.
"""
# If DUT support BridgedAp(Dual SoftAp).
# Decide which is softap_2g_freq, which is softap_5g_freq
self.softap_freq_1 = freq1
if self.dut.droid.wifiIsBridgedApConcurrencySupported():
self.softap_freq_2 = freq2
if self.softap_freq_1 in WifiEnums.ALL_2G_FREQUENCIES:
self.softap_2g_freq = self.softap_freq_1
elif self.softap_freq_1 in WifiEnums.ALL_5G_FREQUENCIES:
self.softap_5g_freq = self.softap_freq_1
if self.softap_freq_2 in WifiEnums.ALL_2G_FREQUENCIES:
self.softap_2g_freq = self.softap_freq_2
elif self.softap_freq_2 in WifiEnums.ALL_5G_FREQUENCIES:
self.softap_5g_freq = self.softap_freq_2
# If DUT does not support BridgedAp(Dual SoftAp).
# Decide the frequency is softap_2g_freq or softap_5g_freq
else:
if self.softap_freq_1 in WifiEnums.ALL_2G_FREQUENCIES:
self.softap_2g_freq = self.softap_freq_1
elif self.softap_freq_1 in WifiEnums.ALL_5G_FREQUENCIES:
self.softap_5g_freq = self.softap_freq_1
# Verify ACS when SoftAp 2G enabled.
failures = []
if init_softap_band == BAND_2G:
if init_sta_band == BAND_2G:
self.dut.log.info("Verifying 2G SoftAp chan == 2G STA chan")
if self.softap_2g_freq != self.actual_sta_freq:
failures.append("Expect 2G SoftAp chan == 2G STA chan")
else:
self.dut.log.info("Verifying SoftAp still operates on 2G")
if self.softap_2g_freq not in WifiEnums.ALL_2G_FREQUENCIES:
failures.append("Expect SoftAp still operates on 2G")
# Verify ACS when SoftAp 5G enabled.
elif init_softap_band == BAND_5G:
if (country in COUNTRY_5G_NOT_ALLOWED or
init_sta_chan in WIFI_5G_DFS_CHANNELS or
init_sta_chan in WIFI_EU_SRD_CHANNELS):
self.dut.log.info("Verifying SoftAp fallback to 2G")
if self.softap_2g_freq not in WifiEnums.ALL_2G_FREQUENCIES:
failures.append("Expect SoftAp fallback to 2G.")
else:
if init_sta_band == BAND_2G:
self.dut.log.info("Verifying SoftAp still operates on 5G")
if self.softap_5g_freq not in WifiEnums.ALL_5G_FREQUENCIES:
failures.append("Expect SoftAp still operates on 5G.")
elif init_sta_chan in WIFI_5G_NON_DFS_CHANNELS:
self.dut.log.info("Verify 5G SoftAp chan == 5g STA chan")
if self.softap_5g_freq != self.actual_sta_freq:
failures.append("Expect 5G SoftAp chan == 5G STA chan")
failures = "\n".join(failures)
return failures
def validate_country_softap_acs(self, country, init_sta_band,
init_sta_chan, init_softap_band):
""" Verify SoftAp ACS on certain country work as expected.
Steps:
Get country, STA band, STA channel from test case name.
Set a country code to the DUT.
Enable a Wi-Fi network.
DUT connects to the Wi-Fi network.
DUT enable SoftAp.
P20 and previous
Enable SoftAp (2G OR 5G).
P21 and later:
Enable BridgedAp (2G AND 5G)
Get SoftAp(or BridgedAp) channel.
Get AP channel.
Verify Country SoftAp ACS.
Args:
country: String; Two letters country code, e.g., "US".
init_sta_band: String; "2g" or "5g".
init_sta_chan: Integer; use to setup OpenWrt 2G/5G channel.
init_softap_band: String: "2g" or "5g".
Returns: List of string; contains failure messages.
"""
self.init_softap_band = init_softap_band
# Set a country code to the DUT.
self.set_country_code_and_verify(self.dut, country)
# Get DUT STA frequency.
self.actual_sta_freq = self.connect_wifi_network(init_sta_band,
init_sta_chan)
# DUT Enable SoftAp.
freq1, freq2 = self.enable_softap(self.dut)
# Verify Country SoftAp ACS.
return self.collect_acs_failures(freq1, freq2, country, init_sta_band,
init_sta_chan, init_softap_band)
# Tests
@test_tracker_info(uuid="003c67f7-f4cc-4f04-ab34-28c71a7602d9")
def test_country_us_softap_acs_sta_2g_ch_1_softap_2g(self):
"""Verify SoftAp ACS on STA 2G CH1 and SoftAp 2G in US.
Steps: See docstring of validate_country_softap_acs()."""
failures = self.validate_country_softap_acs("US", "2g", 1, "2g")
asserts.assert_false(failures, str(failures))
@test_tracker_info(uuid="b3c0a7a4-150f-469c-9191-8d446b2e2593")
def test_country_us_softap_acs_sta_5g_ch_36_softap_2g(self):
"""Verify SoftAp ACS on STA 5G NON-DFS CH36 and SoftAp 2G in US.
Steps: See docstring of validate_country_softap_acs()."""
failures = self.validate_country_softap_acs("US", "5g", 36, "2g")
asserts.assert_false(failures, str(failures))
@test_tracker_info(uuid="7c660706-e63d-4753-bb6e-dacdf4c36cc0")
def test_country_us_softap_acs_sta_5g_ch_132_softap_2g(self):
"""Verify SoftAp ACS on STA 5G DFS CH52 and SoftAp 2G in US.
Steps: See docstring of validate_country_softap_acs()."""
failures = self.validate_country_softap_acs("US", "5g", 132, "2g")
asserts.assert_false(failures, str(failures))
@test_tracker_info(uuid="31973348-852e-4cd7-9a72-6e8f333623c5")
def test_country_de_softap_acs_sta_5g_ch_161_softap_2g(self):
"""Verify SoftAp ACS on STA 5G EU SRD CH149 and SoftAp 2G in DE.
Steps: See docstring of validate_country_softap_acs()."""
failures = self.validate_country_softap_acs("US", "5g", 161, "2g")
asserts.assert_false(failures, str(failures))
@test_tracker_info(uuid="8ebba60c-a32c-46b3-b9da-411b1ef66288")
def test_country_us_softap_acs_sta_2g_ch_1_softap_5g(self):
"""Verify SoftAp ACS on STA 2G CH1 and SoftAp 5G in US.
Steps: See docstring of validate_country_softap_acs()."""
failures = self.validate_country_softap_acs("US", "2g", 1, "5g")
asserts.assert_false(failures, str(failures))
@test_tracker_info(uuid="503ece09-3030-4a69-ae15-320f5104ddd2")
def test_country_us_softap_acs_sta_5g_ch_36_softap_5g(self):
"""Verify SoftAp ACS on STA 5G NON-DFS CH36 and SoftAp 5G in US.
Steps: See docstring of validate_country_softap_acs()."""
failures = self.validate_country_softap_acs("US", "5g", 36, "5g")
asserts.assert_false(failures, str(failures))
@test_tracker_info(uuid="35a5f2f5-067d-4d67-aeb8-58fb253f4b97")
def test_country_us_softap_acs_sta_5g_ch_132_softap_5g(self):
"""Verify SoftAp ACS on STA 5G DFS CH52 and SoftAp 5G in US.
Steps: See docstring of validate_country_softap_acs()."""
failures = self.validate_country_softap_acs("US", "5g", 132, "5g")
asserts.assert_false(failures, str(failures))
@test_tracker_info(uuid="866954a3-72b6-4e7d-853f-9e1659cdf305")
def test_country_de_softap_acs_sta_5g_ch_161_softap_5g(self):
"""Verify SoftAp ACS on STA 5G EU SRD CH149 and SoftAp 5G in DE.
Steps: See docstring of validate_country_softap_acs()."""
failures = self.validate_country_softap_acs("DE", "5g", 161, "5g")
asserts.assert_false(failures, str(failures))
@test_tracker_info(uuid="866954a3-72b6-4e7d-853f-9e1659cdf305")
def test_country_jp_softap_acs_sta_5g_ch_36_softap_5g(self):
"""Verify SoftAp ACS on STA 5G EU SRD CH149 and SoftAp 5G in DE.
Steps: See docstring of validate_country_softap_acs()."""
failures = self.validate_country_softap_acs("JP", "5g", 36, "5g")
asserts.assert_false(failures, str(failures))