summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2021-08-03 04:03:59 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2021-08-03 04:03:59 +0000
commit46f2983bec902d4dbdf4e43327ae99e8be21abd1 (patch)
tree05ebc10a938b0aa1b89ddc112094373e1e1fb573
parent50f22064e497e5674fd729e1a2489bd575e536dd (diff)
parentfdb66097e337668cc125d47970494955d79206ea (diff)
downloadconnectivity-46f2983bec902d4dbdf4e43327ae99e8be21abd1.tar.gz
Merge "[asus_axe11000_ap] Controller for 6GHz AP." into sc-dev
-rw-r--r--acts/framework/acts/controllers/__init__.py3
-rw-r--r--acts/framework/acts/controllers/asus_axe11000_ap.py763
-rw-r--r--acts/framework/acts/keys.py3
3 files changed, 768 insertions, 1 deletions
diff --git a/acts/framework/acts/controllers/__init__.py b/acts/framework/acts/controllers/__init__.py
index 9546b4561..56b4817ca 100644
--- a/acts/framework/acts/controllers/__init__.py
+++ b/acts/framework/acts/controllers/__init__.py
@@ -26,5 +26,6 @@ def destroy(objs):
__all__ = [
"android_device", "attenuator", "bluetooth_pts_device", "monsoon",
"access_point", "iperf_server", "packet_sender", "arduino_wifi_dongle",
- "packet_capture", "fuchsia_device", "pdu", "openwrt_ap", "tigertail"
+ "packet_capture", "fuchsia_device", "pdu", "openwrt_ap", "tigertail",
+ "asus_axe11000_ap"
]
diff --git a/acts/framework/acts/controllers/asus_axe11000_ap.py b/acts/framework/acts/controllers/asus_axe11000_ap.py
new file mode 100644
index 000000000..d19af3b66
--- /dev/null
+++ b/acts/framework/acts/controllers/asus_axe11000_ap.py
@@ -0,0 +1,763 @@
+"""Controller for Asus AXE11000 access point."""
+
+import time
+from acts import logger
+from selenium import webdriver
+from selenium.common.exceptions import NoSuchElementException
+from selenium.webdriver.chrome.options import Options
+from selenium.webdriver.support.ui import Select
+
+MOBLY_CONTROLLER_CONFIG_NAME = "AsusAXE11000AP"
+ACTS_CONTROLLER_REFERENCE_NAME = "access_points"
+
+# Access point UI parameters
+USERNAME = "login_username"
+PASSWORD = "login_passwd"
+SIGN_IN_ID = "button"
+APPLY_BUTTON = "apply_btn"
+APPLY_BUTTON_ID = "applyButton"
+WIRELESS_SETTINGS = "Advanced_Wireless_Content_menu"
+GENERAL_TAB = "Advanced_Wireless_Content_tab"
+PROFESSIONAL_TAB = "Advanced_WAdvanced_Content_tab"
+HE_MODE_ID = "he_mode_field"
+WL_UNIT = "wl_unit"
+WL_11AX = "wl_11ax"
+WL_RADIO = "wl_radio"
+WL_CLOSED = "wl_closed"
+RADIO = "radio"
+BAND_2G_CHANNEL = "band0_channel"
+BAND_5G_CHANNEL = "band1_channel"
+BAND_6G_CHANNEL = "band2_channel"
+BAND_2G_AUTH = "band0_auth_mode_x"
+BAND_5G_AUTH = "band1_auth_mode_x"
+BAND_6G_AUTH = "band2_auth_mode_x"
+BAND_2G_SSID = "band0_ssid"
+BAND_5G_SSID = "band1_ssid"
+BAND_6G_SSID = "band2_ssid"
+BAND_2G_PSK = "band0_wpa_psk"
+BAND_5G_PSK = "band1_wpa_psk"
+BAND_6G_PSK = "band2_wpa_psk"
+BAND_2G_RAD_IP = "band0_radius_ipaddr"
+BAND_5G_RAD_IP = "band1_radius_ipaddr"
+BAND_2G_RAD_PORT = "band0_radius_port"
+BAND_5G_RAD_PORT = "band1_radius_port"
+BAND_2G_RAD_KEY = "band0_radius_key"
+BAND_5G_RAD_KEY = "band1_radius_key"
+SMART_CONNECT = "smartcon_enable_field"
+BROWSER_WAIT_SHORT_TIMEOUT = 6
+BROWSER_WAIT_TIMEOUT = 15
+BROWSER_WAIT_LONG_TIMEOUT = 90
+BROWSER_WAIT_VERY_LONG_TIMEOUT = 180
+
+# Access point supported modes, channels
+VALID_BANDS = ["2g", "5g", "6g"]
+WL_BAND_VALUE = {"2g": "0", "5g": "1", "6g": "2"}
+CHANNELS_2G = {
+ 0: "0",
+ 1: "1",
+ 2: "2",
+ 3: "3",
+ 4: "4",
+ 5: "5",
+ 6: "6",
+ 7: "7",
+ 8: "8",
+ 9: "9",
+ 10: "10",
+ 11: "11"
+}
+CHANNELS_5G = {
+ 0: "0",
+ 36: "36/160",
+ 40: "40/160",
+ 44: "44/160",
+ 48: "48/160",
+ 52: "52/160",
+ 56: "56/160",
+ 60: "60/160",
+ 64: "64/160",
+ 100: "100/160",
+ 104: "104/160",
+ 108: "108/160",
+ 112: "112/160",
+ 116: "116/160",
+ 120: "120/160",
+ 124: "124/160",
+ 128: "128/160",
+ 132: "132/80",
+ 136: "136/80",
+ 140: "140/80",
+ 144: "144/80",
+ 149: "149/80",
+ 153: "153/80",
+ 157: "157/80",
+ 161: "161/80",
+ 165: "165"
+}
+CHANNELS_6G = {
+ 0: "0",
+ 37: "6g37/160",
+ 53: "6g53/160",
+ 69: "6g69/160",
+ 85: "6g85/160",
+ 101: "6g101/160",
+ 117: "6g117/160",
+ 133: "6g133/160",
+ 149: "6g149/160",
+ 165: "6g165/160",
+ 181: "6g181/160",
+ 197: "6g197/160",
+ 213: "6g213/160"
+}
+
+
+def create(configs):
+ """Creates ap controllers from a json config."""
+ return [AsusAXE11000AP(c) for c in configs]
+
+
+def destroy(aps):
+ """Destroys a list of ap controllers."""
+ for ap in aps:
+ ap.reset_to_default_ap_settings()
+ ap.driver.quit()
+
+
+class AsusAXE11000AP(object):
+ """Asus AXE11000 AccessPoint controller.
+
+ Controller class for Asus AXE11000 6GHz AP. This class provides methods to
+ configure the AP with different settings required for 11ax and 6GHz testing.
+ The controller uses chrome webdriver to communicate with the AP.
+
+ The controller object is initiated in the test class. The ACTS test runner
+ calls this controller using the 'AsusAXE11000AP' keyword in the ACTS config
+ file. The AP is reset to default settings and this is handled during the
+ test teardown.
+
+ Attributes:
+ ip: IP address to reach the AP.
+ port: Port numnber to reach the AP.
+ protocol: Protcol to reach the AP (http/https).
+ username: Username to login to the AP.
+ password: Password to login to the AP.
+ config_page: web url to login to the AP.
+ ap_settings: AP settings configured at any given point.
+ default_ap_settings: Default AP settings before running the tests.
+ driver: chrome webdriver object to update the settings.
+ """
+
+ def __init__(self, config):
+ """Initialize AP.
+
+ Creates a chrome webdriver object based on the router parameters.
+ The webdriver will login to the router and goes to the wireless settings
+ page. This object will be used to change the router settings required for
+ the test cases. Required parameters are <ip_address>, <port>, <protocol>,
+ <admin_username> and <admin_password>.
+
+ Url: <procotol>://<ip_address>:<port>/Main_Login.asp
+ Login: <admin_username>/<admin_password>
+
+ Args:
+ config: dict, dictionary of router parameters required for webdriver.
+ """
+ self.ip = config["ip_address"]
+ self.port = config["port"]
+ self.protocol = config["protocol"]
+ self.username = config["admin_username"]
+ self.password = config["admin_password"]
+ lambda_msg = lambda msg: "[AsusAXE11000AP|%s] %s" % (self.ip, msg)
+ self.log = logger.create_logger(lambda_msg)
+ self.ap_settings = {"2g": {}, "5g": {}, "6g": {},}
+ self.config_page = (
+ "{protocol}://{ip_address}:{port}/Main_Login.asp").format(
+ protocol=self.protocol, ip_address=self.ip, port=self.port)
+ self.chrome_options = Options()
+ self.chrome_options.add_argument("--headless")
+ self.chrome_options.add_argument("--no-sandbox")
+ self.driver = webdriver.Chrome(options=self.chrome_options)
+ self.driver.implicitly_wait(BROWSER_WAIT_TIMEOUT*2)
+ self.driver.get(self.config_page)
+ self.driver.find_element_by_name(USERNAME).send_keys(self.username)
+ self.driver.find_element_by_name(PASSWORD).send_keys(self.password)
+ self.driver.find_element_by_id(SIGN_IN_ID).click()
+ self._wait_for_web_element(self.driver.find_element_by_id,
+ WIRELESS_SETTINGS)
+ self.driver.find_element_by_id(WIRELESS_SETTINGS).click()
+ self._wait_for_web_element(self.driver.find_element_by_id, SMART_CONNECT)
+ self._update_ap_settings()
+ self.default_ap_settings = self.ap_settings.copy()
+
+ ### Helper methods ###
+
+ def _wait_for_web_element(self,
+ find_element,
+ element,
+ attribute=None,
+ value=None):
+ """Verifies click actions/selections work.
+
+ Args:
+ find_element: func(), webdriver method to call
+ element: str, web element to look for. Ex: id, class, name
+ attribute: str, attribute to get from a webelement
+ value: str, verify attribute is set to the correct value
+
+ Raises:
+ ValueError: An error occurred if expected attribute not found.
+ """
+ curr_time = time.time()
+ while time.time() < curr_time + BROWSER_WAIT_TIMEOUT*4:
+ time.sleep(2)
+ try:
+ x = find_element(element)
+ if attribute and str(value) not in x.get_attribute(attribute):
+ raise ValueError("Attribute is not set to the right value")
+ return
+ except NoSuchElementException:
+ pass
+ raise ValueError("Failed to find web element: %s" % element)
+
+ def _update_ap_settings_2g_band(self):
+ """Read settings configured on 2g band.
+
+ Parameters Updated:
+ security type: open, wpa2-psk, wpa3-sae or wpa2-ent.
+ ssid: SSID of the wifi network.
+ password: password of the wifi network (if psk or sae network).
+ radius server ip: Radius server IP addr (if ent network).
+ radius server port: Radius server Port number (if ent network).
+ radius server secret: Radius server secret (if ent network).
+ channel: 2G band channel.
+ """
+ dict_2g = {}
+ dict_2g["security"] = self.driver.find_element_by_name(
+ BAND_2G_AUTH).get_attribute("value")
+ dict_2g["SSID"] = self.driver.find_element_by_name(
+ BAND_2G_SSID).get_attribute("value")
+ if dict_2g["security"] == "psk2" or dict_2g["security"] == "sae":
+ dict_2g["password"] = self.driver.find_element_by_name(
+ BAND_2G_PSK).get_attribute("value")
+ elif dict_2g["security"] == "wpa2":
+ dict_2g["radius_ip_addr"] = self.driver.find_element_by_name(
+ BAND_2G_RAD_IP).get_attribute("value")
+ dict_2g["radius_port"] = self.driver.find_element_by_name(
+ BAND_2G_RAD_PORT).get_attribute("value")
+ dict_2g["radius_secret"] = self.driver.find_element_by_name(
+ BAND_2G_RAD_KEY).get_attribute("value")
+ channel_field = self._get_webdriver_elements_for_channels(band)
+ ch_val = self.driver.find_element_by_name(channel_field).get_attribute(
+ "value")
+ channel = 0
+ for key, val in CHANNELS_2G.items():
+ if val == ch_val:
+ channel = key
+ break
+ self.ap_settings["2g"] = dict_2g.copy()
+ self.ap_settings["2g"]["channel"] = channel
+
+ def _update_ap_settings_5g_band(self):
+ """Read settings configured on 5g band.
+
+ Parameters Updated:
+ security type: open, wpa2-psk, wpa3-sae or wpa2-ent.
+ ssid: SSID of the wifi network.
+ password: password of the wifi network (if psk or sae network).
+ radius server ip: Radius server IP addr (if ent network).
+ radius server port: Radius server Port number (if ent network).
+ radius server secret: Radius server secret (if ent network).
+ channel: 5G band channel.
+ """
+ dict_5g = {}
+ dict_5g["security"] = self.driver.find_element_by_name(
+ BAND_5G_AUTH).get_attribute("value")
+ dict_5g["SSID"] = self.driver.find_element_by_name(
+ BAND_5G_SSID).get_attribute("value")
+ if dict_5g["security"] == "psk2" or dict_5g["security"] == "sae":
+ dict_5g["password"] = self.driver.find_element_by_name(
+ BAND_5G_PSK).get_attribute("value")
+ elif dict_5g["security"] == "wpa2":
+ dict_5g["radius_ip_addr"] = self.driver.find_element_by_name(
+ BAND_5G_RAD_IP).get_attribute("value")
+ dict_5g["radius_port"] = self.driver.find_element_by_name(
+ BAND_5G_RAD_PORT).get_attribute("value")
+ dict_2g["radius_secret"] = self.driver.find_element_by_name(
+ BAND_5G_RAD_KEY).get_attribute("value")
+ channel_field = self._get_webdriver_elements_for_channels(band)
+ ch_val = self.driver.find_element_by_name(channel_field).get_attribute(
+ "value")
+ channel = 0
+ for key, val in CHANNELS_5G.items():
+ if val == ch_val:
+ channel = key
+ break
+ self.ap_settings["5g"] = dict_5g.copy()
+ self.ap_settings["5g"]["channel"] = channel
+
+ def _update_ap_settings_6g_band(self):
+ """Read settings configured on 6g band.
+
+ Parameters Updated:
+ security type: wpa3-owe, wpa3-sae.
+ ssid: SSID of the wifi network.
+ password: password of the wifi network (if sae network).
+ channel: 6G band channel.
+ """
+ dict_6g = {}
+ dict_6g["security"] = self.driver.find_element_by_name(
+ BAND_6G_AUTH).get_attribute("value")
+ dict_6g["SSID"] = self.driver.find_element_by_name(
+ BAND_6G_SSID).get_attribute("value")
+ if dict_6g["security"] == "sae":
+ dict_6g["password"] = self.driver.find_element_by_name(
+ BAND_6G_PSK).get_attribute("value")
+ channel_field = self._get_webdriver_elements_for_channels(band)
+ ch_val = self.driver.find_element_by_name(channel_field).get_attribute(
+ "value")
+ channel = 0
+ for key, val in CHANNELS_6G.items():
+ if val == ch_val:
+ channel = key
+ break
+ self.ap_settings["6g"] = dict_6g.copy()
+ self.ap_settings["6g"]["channel"] = channel
+
+ def _update_ap_settings(self):
+ """Read AP settings of 2G, 5G and 6G bands.
+
+ This method reads the wifi network currently configured on any particular
+ band. The settings are updated to self.ap_settings object.
+ """
+ self.driver.refresh()
+ self._update_ap_settings_2g_band()
+ self._update_ap_settings_5g_band()
+ self._update_ap_settings_6g_band()
+
+ def _get_webdriver_elements_for_channels(self, band):
+ """Return webdriver elements for the band to configure channel.
+
+ Args:
+ band: str, Wifi band to configure. Ex: 2g, 5g, 6g.
+
+ Returns:
+ channel field for the specific band.
+ """
+ channel_field = BAND_2G_CHANNEL
+ if band == "5g":
+ channel_field = BAND_5G_CHANNEL
+ elif band == "6g":
+ channel_field = BAND_6G_CHANNEL
+ return channel_field
+
+ def _set_channel(self, band, channel):
+ """Configure channel on a specific band.
+
+ Args:
+ band: str, Wifi band to check. Ex: 2g, 5g, 6g.
+ channel: int, Channel to set.
+
+ Raises:
+ ValueError: An error occurred due to invalid band or configuration.
+ """
+ band = band.lower()
+ if band not in VALID_BANDS:
+ raise ValueError("Band %s is not valid" % band)
+ if (band == "2g" and channel not in CHANNELS_2G) or (
+ band == "5g" and
+ channel not in CHANNELS_5G) or (band == "6g" and
+ channel not in CHANNELS_6G):
+ raise ValueError("Channel %s is not supported in band %s" %
+ (channel, band))
+ channel_field = self._get_webdriver_elements_for_channels(band)
+ channels_val_dict = CHANNELS_6G
+ if band == "2g":
+ channels_val_dict = CHANNELS_2G
+ elif band == "5g":
+ channels_val_dict = CHANNELS_5G
+ channel = channels_val_dict[channel]
+
+ # Set channel
+ if self.driver.find_element_by_name(channel_field).get_attribute(
+ "value") != channel:
+ css_selector = "select[name=%s]" % channel_field
+ Select(self.driver.find_element_by_css_selector(
+ css_selector)).select_by_value(channel)
+ time.sleep(BROWSER_WAIT_SHORT_TIMEOUT)
+
+ def _configure_personal_network(self, band, auth, ssid=None, password=None):
+ """Configure wpa3 sae/wpa2 psk network on a specific band.
+
+ Args:
+ band: str, Wifi band to check. Ex: 2g, 5g, 6g.
+ auth: str, WPA2 PSK or WPA3 SAE security.
+ ssid: str, ssid of the wifi network.
+ password: str, password of the wifi network.
+
+ Raises:
+ ValueError: An error occurred due to invalid band or configuration.
+ """
+ band = band.lower()
+ if band not in VALID_BANDS:
+ raise ValueError("Band %s is not valid" % band)
+ if band == "6g" and auth == "psk2":
+ raise ValueError("AP doesn't support WPA2 PSK on 6g band.")
+ (auth_field, ssid_field,
+ psk_field) = self._get_webdriver_elements_for_personal_auth(band)
+
+ # configure personal network
+ css_selector = "select[name=%s]" % auth_field
+ Select(self.driver.find_element_by_css_selector(
+ css_selector)).select_by_value(auth)
+ time.sleep(BROWSER_WAIT_SHORT_TIMEOUT)
+ if ssid:
+ self.driver.find_element_by_name(ssid_field).clear()
+ self.driver.find_element_by_name(ssid_field).send_keys(ssid)
+ if password:
+ self.driver.find_element_by_name(psk_field).clear()
+ self.driver.find_element_by_name(psk_field).send_keys(password)
+
+ def _configure_open_owe_network(self, band, auth, ssid=None):
+ """Configure wpa3 owe/open network on a specific band.
+
+ Args:
+ band: str, Wifi band to check. Ex: 2g, 5g, 6g.
+ auth: str, WPA2 PSK or WPA3 SAE security.
+ ssid: str, ssid of the wifi network.
+
+ Raises:
+ ValueError: An error occurred due to invalid band or configuration.
+ """
+ band = band.lower()
+ if band not in VALID_BANDS:
+ raise ValueError("Band %s is not valid" % band)
+ if band == "6g" and auth == "open":
+ raise ValueError("AP doesn't support open network on 6g band.")
+ if (band == "2g" or band == "5g") and auth == "owe":
+ raise ValueError("AP doesn't support OWE on 2g and 5g bands.")
+ (auth_field, ssid_field,
+ _) = self._get_webdriver_elements_for_personal_auth(band)
+
+ # Configure wifi network
+ css_selector = "select[name=%s]" % auth_field
+ Select(self.driver.find_element_by_css_selector(
+ css_selector)).select_by_value(auth)
+ time.sleep(BROWSER_WAIT_SHORT_TIMEOUT)
+ if ssid:
+ self.driver.find_element_by_name(ssid_field).clear()
+ self.driver.find_element_by_name(ssid_field).send_keys(ssid)
+
+ def _configure_wpa2_ent_network(self, band, radius_ip, radius_port,
+ radius_secret, ssid=None):
+ """Configure wpa2 ent network on a specific band.
+
+ Args:
+ band: str, Wifi band to check. Ex: 2g, 5g.
+ radius_ip: str, radius server ip addr.
+ radius_port: str, radius server port number.
+ radius_secret: str, radius server secret.
+ ssid: str, ssid of the wifi network.
+
+ Raises:
+ ValueError: An error occurred due to invalid band or configuration.
+ """
+ band = band.lower()
+ if band not in VALID_BANDS:
+ raise ValueError("Band %s is not valid" % band)
+ if band == "6g":
+ raise ValueError("6GHz doesn't support enterprise network on this AP.")
+ (auth_field, ssid_field,
+ _) = self._get_webdriver_elements_for_personal_auth(band)
+ (rad_ip_field, rad_port_field,
+ rad_key_field) = self._get_webdriver_elements_for_ent_auth(band)
+
+ # Set enterprise network
+ css_selector = "select[name=%s]" % auth_field
+ Select(self.driver.find_element_by_css_selector(
+ css_selector)).select_by_value("wpa2")
+ time.sleep(BROWSER_WAIT_SHORT_TIMEOUT)
+ if ssid:
+ self.driver.find_element_by_name(ssid_field).clear()
+ self.driver.find_element_by_name(ssid_field).send_keys(ssid)
+ self.driver.find_element_by_name(rad_ip_field).clear()
+ self.driver.find_element_by_name(rad_ip_field).send_keys(radius_ip)
+ self.driver.find_element_by_name(rad_port_field).clear()
+ self.driver.find_element_by_name(rad_port_field).send_keys(radius_port)
+ self.driver.find_element_by_name(rad_key_field).clear()
+ self.driver.find_element_by_name(rad_key_field).send_keys(radius_secret)
+
+ def _get_webdriver_elements_for_personal_auth(self, band):
+ """Return webdriver elements for the band to configure personal auth.
+
+ Args:
+ band: str, Wifi band to configure. Ex: 2g, 5g, 6g.
+
+ Returns:
+ tuple of auth, ssid, psk field for the band.
+ """
+ auth_field = BAND_2G_AUTH
+ ssid_field = BAND_2G_SSID
+ psk_field = BAND_2G_PSK
+ if band == "5g":
+ auth_field = BAND_5G_AUTH
+ ssid_field = BAND_5G_SSID
+ psk_field = BAND_5G_PSK
+ elif band == "6g":
+ auth_field = BAND_6G_AUTH
+ ssid_field = BAND_6G_SSID
+ psk_field = BAND_6G_PSK
+ return (auth_field, ssid_field, psk_field)
+
+ def _get_webdriver_elements_for_ent_auth(self, band):
+ """Return webdriver elements for the band to configure ent auth.
+
+ Args:
+ band: str, Wifi band to configure. Ex: 2g, 5g, 6g.
+
+ Returns:
+ tuple of radius server IP, port, secret for the band.
+ """
+ rad_ip_field = BAND_2G_RAD_IP
+ rad_port_field = BAND_2G_RAD_PORT
+ rad_key_field = BAND_2G_RAD_KEY
+ if band == "5g":
+ rad_ip_field = BAND_5G_RAD_IP
+ rad_port_field = BAND_5G_RAD_PORT
+ rad_key_field = BAND_5G_RAD_KEY
+ return (rad_ip_field, rad_port_field, rad_key_field)
+
+ ### Methods to configure AP ###
+
+ def set_channel_and_apply(self, band, channel):
+ """Set channel for specific band.
+
+ Args:
+ band: str, Wifi band to check. Ex: 2g, 5g, 6g.
+ channel: int, Channel to set.
+ """
+ # Go back to General tab in advanced settings
+ self.driver.find_element_by_id(GENERAL_TAB).click()
+ self._wait_for_web_element(self.driver.find_element_by_id, SMART_CONNECT)
+
+ channel_field = self._get_webdriver_elements_for_channels(band)
+ self._set_channel(band, channel)
+ self.driver.find_element_by_id(APPLY_BUTTON_ID).click()
+ time.sleep(BROWSER_WAIT_LONG_TIMEOUT)
+ self._wait_for_web_element(self.driver.find_element_by_name,
+ channel_field, "value", channel)
+ self._update_ap_settings()
+
+ def get_configured_channel(self, band):
+ """Get the channel configured on specific band.
+
+ Args:
+ band: str, Wifi band to check. Ex: eg, 5g, 6g.
+
+ Returns:
+ Channel configured on the band.
+
+ Raises:
+ ValueError: An error occurred due to invalid band.
+ """
+ band = band.lower()
+ if band not in VALID_BANDS:
+ raise ValueError("Band %s is not valid" % band)
+ return self.ap_settings[band]["channel"]
+
+ def configure_ap(self, network_dict):
+ """Configure AP with settings for different bands.
+
+ Args:
+ network_dict: dict, dictionary that holds configuration for each band.
+ """
+ # Go back to General tab in advanced settings
+ self.driver.refresh()
+ self.driver.find_element_by_id(GENERAL_TAB).click()
+ self._wait_for_web_element(self.driver.find_element_by_id, SMART_CONNECT)
+
+ # configure wireless settings
+ self.log.info("Network dictionary: %s" % network_dict)
+ for band in network_dict:
+ security = network_dict[band]["security"]
+ ssid = network_dict[band]["SSID"] if "SSID" in network_dict[
+ band] else None
+ password = network_dict[band]["password"] if "password" in network_dict[
+ band] else None
+ if security == "open" or security == "owe":
+ self._configure_open_owe_network(band, security, ssid)
+ elif security == "psk2" or security == "sae":
+ self._configure_personal_network(band, security, ssid, password)
+ elif network_dict[band]["security"] == "wpa2":
+ self._configure_wpa2_ent_network(
+ band,
+ network_dict[band]["radius_server_ip"],
+ network_dict[band]["radius_server_port"],
+ network_dict[band]["radius_server_secret"],
+ ssid)
+
+ for band in network_dict:
+ if "channel" in network_dict[band]:
+ self._set_channel(band, network_dict[band]["channel"])
+ self.driver.find_element_by_id(APPLY_BUTTON_ID).click()
+ time.sleep(BROWSER_WAIT_LONG_TIMEOUT)
+
+ # update ap settings
+ self._update_ap_settings()
+
+ # configure hidden or 11ax mode
+ for band in network_dict:
+ apply_settings = False
+ if "hidden" in network_dict[band]:
+ res = self._configure_hidden_network(band, network_dict[band]["hidden"])
+ apply_settings = apply_settings or res
+ if "11ax" in network_dict[band]:
+ res = self._configure_11ax_mode(band, network_dict[band]["11ax"])
+ apply_settings = apply_settings or res
+ if apply_settings:
+ self.driver.find_element_by_id(APPLY_BUTTON).click()
+ time.sleep(BROWSER_WAIT_VERY_LONG_TIMEOUT)
+
+ def get_wifi_network(self, band):
+ """Get wifi network configured on the AP for the specific band.
+
+ Args:
+ band: str, Wifi band to check. Ex: 2g, 5g, 6g.
+
+ Returns:
+ Wifi network as a dictionary.
+
+ Raises:
+ ValueError: An error occurred due to invalid band.
+ """
+ band = band.lower()
+ if band not in VALID_BANDS:
+ raise ValueError("Band %s is not valid" % band)
+ wifi_network = {}
+ wifi_network["SSID"] = self.ap_settings[band]["SSID"]
+ if "password" in self.ap_settings[band]:
+ wifi_network["password"] = self.ap_settings[band]["password"]
+ security = self.ap_settings[band]["security"]
+ if security == "sae" or security == "owe":
+ wifi_network["security"] = security
+ return wifi_network
+
+ def _configure_hidden_network(self, band, val):
+ """Configure hidden network for a specific band.
+
+ Args:
+ band: str, Wifi band to configure hidden network.
+ val: str, String value to configure.
+
+ Returns:
+ True if settings applied, False if not.
+
+ Raises:
+ ValueError: An error occurred due to invalid band.
+ """
+ band = band.lower()
+ if band not in VALID_BANDS:
+ raise ValueError("Band %s is not valid" % band)
+
+ # Go to Professional tab in advanced settings
+ self.driver.find_element_by_id(PROFESSIONAL_TAB).click()
+ self._wait_for_web_element(self.driver.find_element_by_id, HE_MODE_ID)
+
+ # Select the requested band from the drop down menu
+ css_selector = "select[name=%s]" % WL_UNIT
+ Select(
+ self.driver.find_element_by_css_selector(css_selector)).select_by_value(
+ WL_BAND_VALUE[band]) # (TODO: gmoturu@) find if selection worked
+ time.sleep(BROWSER_WAIT_SHORT_TIMEOUT)
+
+ # Configure hidden network
+ state = True if val == "1" else False
+ return_result = False
+ if self.driver.find_element_by_name(WL_CLOSED).is_selected() != state:
+ css_selector = "input[name='%s'][value='%s']" % (WL_CLOSED, val)
+ self.driver.find_element_by_css_selector(css_selector).click()
+ time.sleep(BROWSER_WAIT_SHORT_TIMEOUT)
+ return_result = True
+
+ return return_result
+
+ def configure_hidden_network_and_apply(self, band, state=True):
+ """Configure hidden network for a specific band.
+
+ Args:
+ band: str, Wifi band to configure hidden network.
+ state: bool, Set the wifi network as hidden if True, False if not.
+ """
+ val = "1" if state else "0"
+ if self._configure_hidden_network(band, val):
+ self.driver.find_element_by_id(APPLY_BUTTON).click()
+ time.sleep(BROWSER_WAIT_VERY_LONG_TIMEOUT)
+ if self.driver.find_element_by_name(WL_CLOSED).is_selected() != state:
+ raise ValueError("Failed to configure hidden network on band: %s" % band)
+
+ # Go back to General tab in advanced settings
+ self.driver.find_element_by_id(GENERAL_TAB).click()
+ self._wait_for_web_element(self.driver.find_element_by_id, SMART_CONNECT)
+
+ def _configure_11ax_mode(self, band, val):
+ """Configure 11ax mode on a specific band.
+
+ Args:
+ band: str, Wifi band to check. Ex: 2g, 5g, 6g.
+ val: str, String value to configure.
+
+ Returns:
+ True if settings are applied, False if not.
+
+ Raises:
+ ValueError: An error occurred due to invalid band.
+ """
+ band = band.lower()
+ if band not in VALID_BANDS:
+ raise ValueError("Band %s is not valid" % band)
+
+ # Go to Professional tab in advanced settings
+ self.driver.find_element_by_id(PROFESSIONAL_TAB).click()
+ self._wait_for_web_element(self.driver.find_element_by_id, HE_MODE_ID)
+
+ # Select the requested band from the drop down menu
+ css_selector = "select[name=%s]" % WL_UNIT
+ Select(
+ self.driver.find_element_by_css_selector(css_selector)).select_by_value(
+ WL_BAND_VALUE[band]) # (TODO: gmoturu@) find if selection worked
+ time.sleep(BROWSER_WAIT_SHORT_TIMEOUT)
+
+ # Configure 11ax
+ return_result = False
+ if self.driver.find_element_by_name(WL_11AX).get_attribute(
+ "value") != val:
+ css_selector = "select[name=%s]" % WL_11AX
+ Select(self.driver.find_element_by_css_selector(
+ css_selector)).select_by_value(val)
+ time.sleep(BROWSER_WAIT_SHORT_TIMEOUT)
+ return_result = True
+
+ return return_result
+
+ def configure_11ax_mode_and_apply(self, band, state=True):
+ """Configure 11ax mode on a specific band.
+
+ Args:
+ band: str, Wifi band to check. Ex: 2g, 5g, 6g.
+ state: bool, Enable 11ax if True, disable if False
+ """
+ val = "1" if state else "0"
+ if self._configure_11ax_mode(band, val):
+ self.driver.find_element_by_id(APPLY_BUTTON).click()
+ time.sleep(BROWSER_WAIT_VERY_LONG_TIMEOUT)
+ self._wait_for_web_element(self.driver.find_element_by_name, WL_11AX,
+ "value", val)
+
+ # Go back to General tab in advanced settings
+ self.driver.find_element_by_id(GENERAL_TAB).click()
+ self._wait_for_web_element(self.driver.find_element_by_id, SMART_CONNECT)
+
+ def reset_to_default_ap_settings(self):
+ """Reset AP to the default settings."""
+ if self.default_ap_settings != self.ap_settings:
+ self.configure_ap(self.default_ap_settings)
+
diff --git a/acts/framework/acts/keys.py b/acts/framework/acts/keys.py
index 9b4b1a280..c4c4b4489 100644
--- a/acts/framework/acts/keys.py
+++ b/acts/framework/acts/keys.py
@@ -60,6 +60,7 @@ class Config(enum.Enum):
key_pdu = 'PduDevice'
key_openwrt_ap = 'OpenWrtAP'
key_tigertail = 'Tigertail'
+ key_asus_axe11000_ap = 'AsusAXE11000AP'
# Internal keys, used internally, not exposed to user's config files.
ikey_user_param = 'user_params'
ikey_testbed_name = 'testbed_name'
@@ -87,6 +88,7 @@ class Config(enum.Enum):
m_key_pdu = 'pdu'
m_key_openwrt_ap = 'openwrt_ap'
m_key_tigertail = 'tigertail'
+ m_key_asus_axe11000_ap = 'asus_axe11000_ap'
# A list of keys whose values in configs should not be passed to test
# classes without unpacking first.
@@ -114,6 +116,7 @@ class Config(enum.Enum):
key_pdu,
key_openwrt_ap,
key_tigertail,
+ key_asus_axe11000_ap,
]
# Keys that are file or folder paths.