blob: 6577a36a711bef8e35ce56998ba1284141c7bd69 [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright 2022 The Fuchsia Authors
#
# 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
from typing import NamedTuple
from honeydew.typing.wlan import CountryCode
from mobly import asserts, test_runner
from antlion import utils
from antlion.controllers.access_point import setup_ap
from antlion.controllers.ap_lib import hostapd_constants
from antlion.controllers.ap_lib.regulatory_channels import (
COUNTRY_CHANNELS,
TEST_CHANNELS,
)
from antlion.test_utils.abstract_devices.wlan_device import (
AssociationMode,
SupportsWLAN,
create_wlan_device,
)
from antlion.test_utils.wifi import base_test
N_CAPABILITIES_DEFAULT = [
hostapd_constants.N_CAPABILITY_LDPC,
hostapd_constants.N_CAPABILITY_SGI20,
hostapd_constants.N_CAPABILITY_SGI40,
hostapd_constants.N_CAPABILITY_TX_STBC,
hostapd_constants.N_CAPABILITY_RX_STBC1,
]
MAX_2_4_CHANNEL = 14
class RegulatoryTest(NamedTuple):
country_code: str
channel: int
channel_bandwidth: int
expect_association: bool
class RegulatoryComplianceTest(base_test.WifiBaseTest):
"""Tests regulatory compliance.
Testbed Requirement:
* 1 x Fuchsia device (dut)
* 1 x access point
"""
def pre_run(self) -> None:
tests: list[RegulatoryTest] = []
for country in COUNTRY_CHANNELS.values():
for channel in TEST_CHANNELS:
for bandwidth in TEST_CHANNELS[channel]:
tests.append(
RegulatoryTest(
country_code=country.country_code,
channel=channel,
channel_bandwidth=bandwidth,
expect_association=(
channel in country.allowed_channels
and bandwidth in country.allowed_channels[channel]
),
)
)
def generate_test_name(code: str, channel: int, channel_bandwidth: int, *_):
return f"test_{code}_channel_{channel}_{channel_bandwidth}mhz"
self.generate_tests(self.verify_channel_compliance, generate_test_name, tests)
def setup_class(self) -> None:
super().setup_class()
self.log = logging.getLogger()
self.fuchsia_device = self.fuchsia_devices[0]
self.dut: SupportsWLAN = create_wlan_device(
self.fuchsia_device, AssociationMode.POLICY
)
self.access_point = self.access_points[0]
self.access_point.stop_all_aps()
self.regulatory_results = [
"====CountryCode,Channel,Frequency,ChannelBandwith,Connected/Not-Connected===="
]
def teardown_class(self) -> None:
super().teardown_class()
regulatory_save_path = f"{self.log_path}/regulatory_results.txt"
with open(regulatory_save_path, "w") as file:
file.write("\n".join(self.regulatory_results))
def setup_test(self) -> None:
super().setup_test()
self.access_point.stop_all_aps()
for ad in self.android_devices:
ad.droid.wakeLockAcquireBright()
ad.droid.wakeUpNow()
self.dut.wifi_toggle_state(True)
self.dut.disconnect()
def teardown_test(self) -> None:
for ad in self.android_devices:
ad.droid.wakeLockRelease()
ad.droid.goToSleepNow()
self.dut.turn_location_off_and_scan_toggle_off()
self.dut.disconnect()
self.download_ap_logs()
self.access_point.stop_all_aps()
super().teardown_test()
def setup_ap(
self,
channel: int,
channel_bandwidth: int,
) -> str:
"""Start network on AP with basic configuration.
Args:
channel: channel to use for network
channel_bandwidth: channel bandwidth in mhz to use for network,
Returns:
SSID of the newly created and running network
Raises:
ConnectionError if network is not started successfully.
"""
ssid = utils.rand_ascii_str(hostapd_constants.AP_SSID_LENGTH_2G)
try:
setup_ap(
access_point=self.access_point,
profile_name="whirlwind",
channel=channel,
force_wmm=True,
ssid=ssid,
vht_bandwidth=channel_bandwidth,
setup_bridge=True,
)
self.log.info(
f"Network (ssid: {ssid}) up on channel {channel} "
f"w/ channel bandwidth {channel_bandwidth} MHz"
)
return ssid
except Exception as err:
raise ConnectionError(
f"Failed to setup ap on channel: {channel}, "
f"channel bandwidth: {channel_bandwidth} MHz. "
) from err
def verify_channel_compliance(
self,
country_code: str,
channel: int,
channel_bandwidth: int,
expect_association: bool,
) -> None:
"""Verify device complies with provided regulatory requirements for a
specific channel and channel bandwidth. Run with generated test cases
in the verify_regulatory_compliance parent test.
"""
self.fuchsia_device.wlan_controller.set_country_code(CountryCode(country_code))
ssid = self.setup_ap(channel, channel_bandwidth)
self.log.info(
f'Attempting to associate to network "{ssid}" on channel '
f"{channel} @ {channel_bandwidth}mhz"
)
associated = self.dut.associate(ssid)
channel_ghz = "2.4" if channel < 36 else "5"
association_code = "c" if associated else "nc"
regulatory_result = f"REGTRACKER: {country_code},{channel},{channel_ghz},{channel_bandwidth},{association_code}"
self.regulatory_results.append(regulatory_result)
self.log.info(regulatory_result)
asserts.assert_true(
associated == expect_association,
f"Expected device to{'' if expect_association else ' NOT'} "
f"associate using country code {country_code} for channel "
f"{channel} with channel bandwidth {channel_bandwidth} MHz.",
)
if __name__ == "__main__":
test_runner.main()