blob: c7c81f0976207ea9b17001a488e8c1b3b0db1e98 [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.
"""
Base Class for Defining Common WiFi Test Functionality
"""
import copy
import os
from typing import Any, Dict, TypedDict, TypeVar, Union
from mobly.base_test import STAGE_NAME_TEARDOWN_CLASS
from mobly.config_parser import TestRunConfig
from mobly.records import TestResultRecord
from antlion import context, controllers, utils
from antlion.base_test import AntlionBaseTest
from antlion.controllers.access_point import AccessPoint
from antlion.controllers.android_device import AndroidDevice
from antlion.controllers.ap_lib import hostapd_constants
from antlion.controllers.ap_lib.hostapd_security import (
OpenWRTEncryptionMode,
SecurityMode,
)
from antlion.controllers.attenuator import Attenuator
from antlion.controllers.fuchsia_device import FuchsiaDevice
from antlion.controllers.iperf_client import IPerfClientBase
from antlion.controllers.iperf_server import IPerfServerOverSsh
from antlion.controllers.openwrt_ap import PMF_ENABLED, BSSIDMap, OpenWrtAP
from antlion.controllers.openwrt_lib.wireless_config import WirelessConfig
from antlion.controllers.packet_capture import PacketCapture
from antlion.controllers.pdu import PduDevice
from antlion.keys import Config
from antlion.test_utils.net import net_test_utils as nutils
from antlion.test_utils.wifi import wifi_test_utils as wutils
WifiEnums = wutils.WifiEnums
MAX_AP_COUNT = 2
class Network(TypedDict):
SSID: str
security: SecurityMode
password: str | None
hiddenSSID: bool
wepKeys: list[str] | None
ieee80211w: str | None
class NetworkUpdate(TypedDict, total=False):
SSID: str
security: SecurityMode
password: str | None
hiddenSSID: bool
wepKeys: list[str] | None
ieee80211w: str | None
NetworkList = Dict[str, Network]
class WifiBaseTest(AntlionBaseTest):
def __init__(self, configs: TestRunConfig) -> None:
super().__init__(configs)
self.enable_packet_log = False
self.packet_log_2g = hostapd_constants.AP_DEFAULT_CHANNEL_2G
self.packet_log_5g = hostapd_constants.AP_DEFAULT_CHANNEL_5G
self.tcpdump_proc: list[Any] = []
self.packet_log_pid: Dict[str, Any] = {}
def setup_class(self) -> None:
T = TypeVar("T")
def register_controller(module: Any) -> list[T]:
controllers: list[T] | None = self.register_controller(
module, required=False
)
if controllers is None:
return []
return controllers
self.access_points: list[AccessPoint] = register_controller(
controllers.access_point
)
self.openwrt_aps: list[OpenWrtAP] = register_controller(controllers.openwrt_ap)
self.android_devices: list[AndroidDevice] = register_controller(
controllers.android_device
)
self.attenuators: list[Attenuator] = register_controller(controllers.attenuator)
self.fuchsia_devices: list[FuchsiaDevice] = register_controller(
controllers.fuchsia_device
)
self.iperf_clients: list[IPerfClientBase] = register_controller(
controllers.iperf_client
)
self.iperf_servers: list[IPerfServerOverSsh] = register_controller(
controllers.iperf_server
)
self.pdu_devices: list[PduDevice] = register_controller(controllers.pdu)
self.packet_capture: list[PacketCapture] = register_controller(
controllers.packet_capture
)
for attenuator in self.attenuators:
attenuator.set_atten(0)
self.pixel_models: list[str] | None = self.user_params.get("pixel_models")
self.cnss_diag_file: Union[str, list[str]] | None = self.user_params.get(
"cnss_diag_file"
)
self.country_code_file: Union[str, list[str]] | None = self.user_params.get(
"country_code_file"
)
if self.cnss_diag_file:
if isinstance(self.cnss_diag_file, list):
self.cnss_diag_file = self.cnss_diag_file[0]
if not os.path.isfile(self.cnss_diag_file):
self.cnss_diag_file = os.path.join(
self.user_params[Config.key_config_path.value], self.cnss_diag_file
)
self.packet_logger: PacketCapture | None = None
if self.enable_packet_log and self.packet_capture:
self.packet_logger = self.packet_capture[0]
self.packet_logger.configure_monitor_mode("2G", self.packet_log_2g)
self.packet_logger.configure_monitor_mode("5G", self.packet_log_5g)
for ad in self.android_devices:
wutils.wifi_test_device_init(ad)
if self.country_code_file:
if isinstance(self.country_code_file, list):
self.country_code_file = self.country_code_file[0]
if not os.path.isfile(self.country_code_file):
self.country_code_file = os.path.join(
self.user_params[Config.key_config_path.value],
self.country_code_file,
)
self.country_code = utils.load_config(self.country_code_file)["country"]
else:
self.country_code = WifiEnums.CountryCode.US
wutils.set_wifi_country_code(ad, self.country_code)
def setup_test(self) -> None:
if self.android_devices and self.cnss_diag_file and self.pixel_models:
wutils.start_cnss_diags(
self.android_devices, self.cnss_diag_file, self.pixel_models
)
self.tcpdump_proc = []
for ad in self.android_devices:
proc = nutils.start_tcpdump(ad, self.current_test_info.name)
self.tcpdump_proc.append((ad, proc))
if self.packet_logger:
self.packet_log_pid = wutils.start_pcap(
self.packet_logger, "dual", self.current_test_info.name
)
def teardown_test(self) -> None:
if self.android_devices and self.cnss_diag_file and self.pixel_models:
wutils.stop_cnss_diags(self.android_devices, self.pixel_models)
for proc in self.tcpdump_proc:
nutils.stop_tcpdump(
proc[0], proc[1], self.current_test_info.name, pull_dump=False
)
self.tcpdump_proc = []
if self.packet_logger and self.packet_log_pid:
wutils.stop_pcap(self.packet_logger, self.packet_log_pid, test_status=True)
self.packet_log_pid = {}
def teardown_class(self) -> None:
begin_time = utils.get_current_epoch_time()
super().teardown_class()
for device in getattr(self, "fuchsia_devices", []):
device.take_bug_report(STAGE_NAME_TEARDOWN_CLASS, begin_time)
def on_fail(self, record: TestResultRecord) -> None:
"""A function that is executed upon a test failure.
Args:
record: A copy of the test record for this test, containing all information of
the test execution including exception objects.
"""
if self.android_devices:
for ad in self.android_devices:
ad.take_bug_report(record.test_name, record.begin_time)
ad.cat_adb_log(record.test_name, record.begin_time)
wutils.get_ssrdumps(ad)
if self.cnss_diag_file and self.pixel_models:
wutils.stop_cnss_diags(self.android_devices, self.pixel_models)
for ad in self.android_devices:
wutils.get_cnss_diag_log(ad)
for proc in self.tcpdump_proc:
nutils.stop_tcpdump(proc[0], proc[1], record.test_name)
self.tcpdump_proc = []
if self.packet_logger and self.packet_log_pid:
wutils.stop_pcap(self.packet_logger, self.packet_log_pid, test_status=False)
self.packet_log_pid = {}
# Gets a wlan_device log and calls the generic device fail on DUT.
for fd in self.fuchsia_devices:
self.on_device_fail(fd, record)
def on_device_fail(self, device: FuchsiaDevice, record: TestResultRecord) -> None:
"""Gets a generic device DUT bug report.
This method takes a bug report if the device has the
'take_bug_report_on_fail' config value, and if the flag is true. This
method also power cycles if 'hard_reboot_on_fail' is True.
Args:
device: Generic device to gather logs from.
record: More information about the test.
"""
if (
not hasattr(device, "take_bug_report_on_fail")
or device.take_bug_report_on_fail
):
device.take_bug_report(record)
if hasattr(device, "hard_reboot_on_fail") and device.hard_reboot_on_fail:
device.reboot(reboot_type="hard", testbed_pdus=self.pdu_devices)
def download_ap_logs(self) -> None:
"""Downloads the DHCP and hostapad logs from the access_point.
Using the current TestClassContext and TestCaseContext this method pulls
the DHCP and hostapd logs and outputs them to the correct path.
"""
current_path = context.get_current_context().get_full_output_path()
for access_point in self.access_points:
dhcp_log = access_point.get_dhcp_logs()
if dhcp_log:
dhcp_log_path = os.path.join(
current_path, f"{access_point.identifier}_dhcp_log.txt"
)
with open(dhcp_log_path, "w") as f:
f.write(dhcp_log)
hostapd_logs = access_point.get_hostapd_logs()
for interface in hostapd_logs:
hostapd_log_path = os.path.join(
current_path,
f"{access_point.identifier}_hostapd_log_{interface}.txt",
)
with open(hostapd_log_path, "w") as f:
f.write(hostapd_logs[interface])
radvd_log = access_point.get_radvd_logs()
if radvd_log:
radvd_log_path = os.path.join(
current_path, f"{access_point.identifier}_radvd_log.txt"
)
with open(radvd_log_path, "w") as f:
f.write(radvd_log)
def get_psk_network(
self,
mirror_ap: bool,
reference_networks: list[NetworkList],
hidden: bool = False,
same_ssid: bool = False,
security_mode: SecurityMode = SecurityMode.WPA2,
ssid_length_2g: int = hostapd_constants.AP_SSID_LENGTH_2G,
ssid_length_5g: int = hostapd_constants.AP_SSID_LENGTH_5G,
passphrase_length_2g: int = hostapd_constants.AP_PASSPHRASE_LENGTH_2G,
passphrase_length_5g: int = hostapd_constants.AP_PASSPHRASE_LENGTH_5G,
) -> NetworkList:
"""Generates SSID and passphrase for a WPA2 network using random
generator.
Args:
mirror_ap: Determines if both APs use the same hostapd config or
different configs.
reference_networks: PSK networks.
same_ssid: Determines if both bands on AP use the same SSID.
ssid_length_2g: Number of characters to use for 2G SSID.
ssid_length_5g: Number of characters to use for 5G SSID.
passphrase_length_2g: Length of password for 2G network.
passphrase_length_5g: Length of password for 5G network.
Returns: A dict of 2G and 5G network lists for hostapd configuration.
"""
if same_ssid:
ref_2g_ssid = f"xg_{utils.rand_ascii_str(ssid_length_2g)}"
ref_5g_ssid = ref_2g_ssid
ref_2g_passphrase = utils.rand_ascii_str(passphrase_length_2g)
ref_5g_passphrase = ref_2g_passphrase
else:
ref_2g_ssid = f"2g_{utils.rand_ascii_str(ssid_length_2g)}"
ref_2g_passphrase = utils.rand_ascii_str(passphrase_length_2g)
ref_5g_ssid = f"5g_{utils.rand_ascii_str(ssid_length_5g)}"
ref_5g_passphrase = utils.rand_ascii_str(passphrase_length_5g)
network_dict_2g = Network(
SSID=ref_2g_ssid,
security=security_mode,
password=ref_2g_passphrase,
hiddenSSID=hidden,
wepKeys=None,
ieee80211w=None,
)
network_dict_5g = Network(
SSID=ref_5g_ssid,
security=security_mode,
password=ref_5g_passphrase,
hiddenSSID=hidden,
wepKeys=None,
ieee80211w=None,
)
for _ in range(MAX_AP_COUNT):
reference_networks.append(
{"2g": copy.copy(network_dict_2g), "5g": copy.copy(network_dict_5g)}
)
if not mirror_ap:
break
return {"2g": network_dict_2g, "5g": network_dict_5g}
def get_open_network(
self,
mirror_ap: bool,
open_network: list[NetworkList],
hidden: bool = False,
same_ssid: bool = False,
ssid_length_2g: int = hostapd_constants.AP_SSID_LENGTH_2G,
ssid_length_5g: int = hostapd_constants.AP_SSID_LENGTH_5G,
security_mode: SecurityMode = SecurityMode.OPEN,
) -> NetworkList:
"""Generates SSIDs for a open network using a random generator.
Args:
mirror_ap: Boolean, determines if both APs use the same hostapd
config or different configs.
open_network: List of open networks.
same_ssid: Boolean, determines if both bands on AP use the same
SSID.
ssid_length_2g: Int, number of characters to use for 2G SSID.
ssid_length_5g: Int, number of characters to use for 5G SSID.
security_mode: 'none' for open and 'OWE' for WPA3 OWE.
Returns: A dict of 2G and 5G network lists for hostapd configuration.
"""
if same_ssid:
open_2g_ssid = f"xg_{utils.rand_ascii_str(ssid_length_2g)}"
open_5g_ssid = open_2g_ssid
else:
open_2g_ssid = f"2g_{utils.rand_ascii_str(ssid_length_2g)}"
open_5g_ssid = f"5g_{utils.rand_ascii_str(ssid_length_5g)}"
network_dict_2g = Network(
SSID=open_2g_ssid,
security=security_mode,
password=None,
hiddenSSID=hidden,
wepKeys=None,
ieee80211w=None,
)
network_dict_5g = Network(
SSID=open_5g_ssid,
security=security_mode,
password=None,
hiddenSSID=hidden,
wepKeys=None,
ieee80211w=None,
)
for _ in range(MAX_AP_COUNT):
open_network.append(
{"2g": copy.copy(network_dict_2g), "5g": copy.copy(network_dict_5g)}
)
if not mirror_ap:
break
return {"2g": network_dict_2g, "5g": network_dict_5g}
def get_wep_network(
self,
mirror_ap: bool,
networks: list[NetworkList],
hidden: bool = False,
same_ssid: bool = False,
ssid_length_2g: int = hostapd_constants.AP_SSID_LENGTH_2G,
ssid_length_5g: int = hostapd_constants.AP_SSID_LENGTH_5G,
passphrase_length_2g: int = hostapd_constants.AP_PASSPHRASE_LENGTH_2G,
passphrase_length_5g: int = hostapd_constants.AP_PASSPHRASE_LENGTH_5G,
) -> NetworkList:
"""Generates SSID and passphrase for a WEP network using random
generator.
Args:
mirror_ap: Determines if both APs use the same hostapd config or
different configs.
networks: List of WEP networks.
same_ssid: Determines if both bands on AP use the same SSID.
ssid_length_2g: Number of characters to use for 2G SSID.
ssid_length_5g: Number of characters to use for 5G SSID.
passphrase_length_2g: Length of password for 2G network.
passphrase_length_5g: Length of password for 5G network.
Returns: A dict of 2G and 5G network lists for hostapd configuration.
"""
if same_ssid:
ref_2g_ssid = f"xg_{utils.rand_ascii_str(ssid_length_2g)}"
ref_5g_ssid = ref_2g_ssid
ref_2g_passphrase = utils.rand_hex_str(passphrase_length_2g)
ref_5g_passphrase = ref_2g_passphrase
else:
ref_2g_ssid = f"2g_{utils.rand_ascii_str(ssid_length_2g)}"
ref_2g_passphrase = utils.rand_hex_str(passphrase_length_2g)
ref_5g_ssid = f"5g_{utils.rand_ascii_str(ssid_length_5g)}"
ref_5g_passphrase = utils.rand_hex_str(passphrase_length_5g)
network_dict_2g = Network(
SSID=ref_2g_ssid,
security=SecurityMode.WEP,
password=None,
hiddenSSID=hidden,
wepKeys=[ref_2g_passphrase] * 4,
ieee80211w=None,
)
network_dict_5g = Network(
SSID=ref_5g_ssid,
security=SecurityMode.WEP,
password=None,
hiddenSSID=hidden,
wepKeys=[ref_5g_passphrase] * 4,
ieee80211w=None,
)
for _ in range(MAX_AP_COUNT):
networks.append(
{"2g": copy.copy(network_dict_2g), "5g": copy.copy(network_dict_5g)}
)
if not mirror_ap:
break
return {"2g": network_dict_2g, "5g": network_dict_5g}
def configure_openwrt_ap_and_start(
self,
channel_5g: int = hostapd_constants.AP_DEFAULT_CHANNEL_5G,
channel_2g: int = hostapd_constants.AP_DEFAULT_CHANNEL_2G,
channel_5g_ap2: int | None = None,
channel_2g_ap2: int | None = None,
ssid_length_2g: int = hostapd_constants.AP_SSID_LENGTH_2G,
passphrase_length_2g: int = hostapd_constants.AP_PASSPHRASE_LENGTH_2G,
ssid_length_5g: int = hostapd_constants.AP_SSID_LENGTH_5G,
passphrase_length_5g: int = hostapd_constants.AP_PASSPHRASE_LENGTH_5G,
mirror_ap: bool = False,
hidden: bool = False,
same_ssid: bool = False,
open_network: bool = False,
wpa1_network: bool = False,
wpa_network: bool = False,
wep_network: bool = False,
ent_network: bool = False,
ent_network_pwd: bool = False,
owe_network: bool = False,
sae_network: bool = False,
saemixed_network: bool = False,
radius_conf_2g: Dict[str, Any] | None = None,
radius_conf_5g: Dict[str, Any] | None = None,
radius_conf_pwd: Dict[str, Any] | None = None,
ap_count: int = 1,
ieee80211w: int | None = None,
) -> None:
"""Create, configure and start OpenWrt AP.
Args:
channel_5g: 5G channel to configure.
channel_2g: 2G channel to configure.
channel_5g_ap2: 5G channel to configure on AP2.
channel_2g_ap2: 2G channel to configure on AP2.
ssid_length_2g: Int, number of characters to use for 2G SSID.
passphrase_length_2g: Int, length of password for 2G network.
ssid_length_5g: Int, number of characters to use for 5G SSID.
passphrase_length_5g: Int, length of password for 5G network.
same_ssid: Boolean, determines if both bands on AP use the same SSID.
open_network: Boolean, to check if open network should be configured.
wpa_network: Boolean, to check if wpa network should be configured.
wep_network: Boolean, to check if wep network should be configured.
ent_network: Boolean, to check if ent network should be configured.
ent_network_pwd: Boolean, to check if ent pwd network should be configured.
owe_network: Boolean, to check if owe network should be configured.
sae_network: Boolean, to check if sae network should be configured.
saemixed_network: Boolean, to check if saemixed network should be configured.
radius_conf_2g: dictionary with enterprise radius server details.
radius_conf_5g: dictionary with enterprise radius server details.
radius_conf_pwd: dictionary with enterprise radiuse server details.
ap_count: APs to configure.
ieee80211w:PMF to configure
"""
if mirror_ap and ap_count == 1:
raise ValueError("ap_count cannot be 1 if mirror_ap is True.")
if (channel_5g_ap2 or channel_2g_ap2) and ap_count == 1:
raise ValueError("ap_count cannot be 1 if channels of AP2 are provided.")
# we are creating a channel list for 2G and 5G bands. The list is of
# size 2 and this is based on the assumption that each testbed will have
# at most 2 APs.
if not channel_5g_ap2:
channel_5g_ap2 = channel_5g
if not channel_2g_ap2:
channel_2g_ap2 = channel_2g
channels_2g = [channel_2g, channel_2g_ap2]
channels_5g = [channel_5g, channel_5g_ap2]
if radius_conf_2g is None:
radius_conf_2g = {}
if radius_conf_5g is None:
radius_conf_5g = {}
if radius_conf_pwd is None:
radius_conf_pwd = {}
self.bssid_map: list[BSSIDMap] = []
for i in range(ap_count):
configs: list[WirelessConfig] = []
num_2g: int = 1
num_5g: int = 1
if wpa1_network:
networks = self.get_psk_network(
mirror_ap,
[],
hidden,
same_ssid,
SecurityMode.WPA,
ssid_length_2g,
ssid_length_5g,
passphrase_length_2g,
passphrase_length_5g,
)
def add_config(name, band):
configs.append(
WirelessConfig(
name=name,
ssid=networks[band]["SSID"],
security=OpenWRTEncryptionMode.PSK,
band=band,
password=networks[band]["password"],
hidden=networks[band]["hiddenSSID"],
ieee80211w=ieee80211w,
)
)
add_config(f"wifi_2g_{num_2g}", hostapd_constants.BAND_2G)
add_config(f"wifi_5g_{num_5g}", hostapd_constants.BAND_5G)
num_2g += 1
num_5g += 1
if wpa_network:
networks = self.get_psk_network(
mirror_ap,
[],
hidden,
same_ssid,
SecurityMode.WPA2,
ssid_length_2g,
ssid_length_5g,
passphrase_length_2g,
passphrase_length_5g,
)
def add_config(name, band):
configs.append(
WirelessConfig(
name=name,
ssid=networks[band]["SSID"],
security=OpenWRTEncryptionMode.PSK2,
band=band,
password=networks[band]["password"],
hidden=networks[band]["hiddenSSID"],
ieee80211w=ieee80211w,
)
)
add_config(f"wifi_2g_{num_2g}", hostapd_constants.BAND_2G)
add_config(f"wifi_5g_{num_5g}", hostapd_constants.BAND_5G)
num_2g += 1
num_5g += 1
if wep_network:
networks = self.get_wep_network(
mirror_ap,
[],
hidden,
same_ssid,
ssid_length_2g,
ssid_length_5g,
)
def add_config(name, band):
configs.append(
WirelessConfig(
name=name,
ssid=networks[band]["SSID"],
security=OpenWRTEncryptionMode.WEP,
band=band,
wep_key=networks[band]["wepKeys"],
hidden=networks[band]["hiddenSSID"],
)
)
add_config(f"wifi_2g_{num_2g}", hostapd_constants.BAND_2G)
add_config(f"wifi_5g_{num_5g}", hostapd_constants.BAND_5G)
num_2g += 1
num_5g += 1
if ent_network:
networks = self.get_open_network(
mirror_ap,
[],
hidden,
same_ssid,
ssid_length_2g,
ssid_length_5g,
SecurityMode.WPA2,
)
def add_config_with_radius(name, band, radius_conf):
configs.append(
WirelessConfig(
name=name,
ssid=networks[band]["SSID"],
security=OpenWRTEncryptionMode.WPA2,
band=band,
radius_server_ip=radius_conf.get("radius_server_ip"),
radius_server_port=radius_conf.get("radius_server_port"),
radius_server_secret=radius_conf.get(
"radius_server_secret"
),
hidden=networks[band]["hiddenSSID"],
)
)
add_config_with_radius(
f"wifi_2g_{num_2g}", hostapd_constants.BAND_2G, radius_conf_2g
)
add_config_with_radius(
f"wifi_5g_{num_5g}", hostapd_constants.BAND_5G, radius_conf_5g
)
num_2g += 1
num_5g += 1
if ent_network_pwd:
networks = self.get_open_network(
mirror_ap,
[],
hidden,
same_ssid,
ssid_length_2g,
ssid_length_5g,
SecurityMode.WPA2,
)
radius_conf = {} if radius_conf_pwd is None else radius_conf_pwd
def add_config(name, band):
configs.append(
WirelessConfig(
name=name,
ssid=networks[band]["SSID"],
security=OpenWRTEncryptionMode.WPA2,
band=band,
radius_server_ip=radius_conf.get("radius_server_ip"),
radius_server_port=radius_conf.get("radius_server_port"),
radius_server_secret=radius_conf.get(
"radius_server_secret"
),
hidden=networks[band]["hiddenSSID"],
)
)
add_config(f"wifi_2g_{num_2g}", hostapd_constants.BAND_2G)
add_config(f"wifi_5g_{num_5g}", hostapd_constants.BAND_5G)
num_2g += 1
num_5g += 1
if open_network:
networks = self.get_open_network(
mirror_ap,
[],
hidden,
same_ssid,
ssid_length_2g,
ssid_length_5g,
)
def add_config(name, band):
configs.append(
WirelessConfig(
name=name,
ssid=networks[band]["SSID"],
security=OpenWRTEncryptionMode.NONE,
band=band,
hidden=networks[band]["hiddenSSID"],
)
)
add_config(f"wifi_2g_{num_2g}", hostapd_constants.BAND_2G)
add_config(f"wifi_5g_{num_5g}", hostapd_constants.BAND_5G)
num_2g += 1
num_5g += 1
if owe_network:
networks = self.get_open_network(
mirror_ap,
[],
hidden,
same_ssid,
ssid_length_2g,
ssid_length_5g,
)
def add_config(name, band):
configs.append(
WirelessConfig(
name=name,
ssid=networks[band]["SSID"],
security=OpenWRTEncryptionMode.OWE,
band=band,
hidden=networks[band]["hiddenSSID"],
ieee80211w=PMF_ENABLED,
)
)
add_config(f"wifi_2g_{num_2g}", hostapd_constants.BAND_2G)
add_config(f"wifi_5g_{num_5g}", hostapd_constants.BAND_5G)
num_2g += 1
num_5g += 1
if sae_network:
networks = self.get_psk_network(
mirror_ap,
[],
hidden,
same_ssid,
ssid_length_2g=ssid_length_2g,
ssid_length_5g=ssid_length_5g,
passphrase_length_2g=passphrase_length_2g,
passphrase_length_5g=passphrase_length_5g,
)
def add_config(name, band):
configs.append(
WirelessConfig(
name=name,
ssid=networks[band]["SSID"],
security=OpenWRTEncryptionMode.SAE,
band=band,
password=networks[band]["password"],
hidden=networks[band]["hiddenSSID"],
ieee80211w=PMF_ENABLED,
)
)
add_config(f"wifi_2g_{num_2g}", hostapd_constants.BAND_2G)
add_config(f"wifi_5g_{num_5g}", hostapd_constants.BAND_5G)
num_2g += 1
num_5g += 1
if saemixed_network:
networks = self.get_psk_network(
mirror_ap,
[],
hidden,
same_ssid,
ssid_length_2g=ssid_length_2g,
ssid_length_5g=ssid_length_5g,
passphrase_length_2g=passphrase_length_2g,
passphrase_length_5g=passphrase_length_5g,
)
def add_config(name, band):
configs.append(
WirelessConfig(
name=name,
ssid=networks[band]["SSID"],
security=OpenWRTEncryptionMode.SAE_MIXED,
band=band,
password=networks[band]["password"],
hidden=networks[band]["hiddenSSID"],
ieee80211w=ieee80211w,
)
)
add_config(f"wifi_2g_{num_2g}", hostapd_constants.BAND_2G)
add_config(f"wifi_5g_{num_5g}", hostapd_constants.BAND_5G)
num_2g += 1
num_5g += 1
openwrt_ap = self.openwrt_aps[i]
openwrt_ap.configure_ap(configs, channels_2g[i], channels_5g[i])
openwrt_ap.start_ap()
self.bssid_map.append(openwrt_ap.get_bssids_for_wifi_networks())
if mirror_ap:
openwrt_ap_mirror = self.openwrt_aps[i + 1]
openwrt_ap_mirror.configure_ap(
configs, channels_2g[i + 1], channels_5g[i + 1]
)
openwrt_ap_mirror.start_ap()
self.bssid_map.append(openwrt_ap_mirror.get_bssids_for_wifi_networks())
break