diff options
23 files changed, 2968 insertions, 238 deletions
diff --git a/acts/framework/acts/controllers/asus_axe11000_ap.py b/acts/framework/acts/controllers/asus_axe11000_ap.py index d19af3b66..c549d6e40 100644 --- a/acts/framework/acts/controllers/asus_axe11000_ap.py +++ b/acts/framework/acts/controllers/asus_axe11000_ap.py @@ -246,7 +246,7 @@ class AsusAXE11000AP(object): 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) + channel_field = self._get_webdriver_elements_for_channels("2g") ch_val = self.driver.find_element_by_name(channel_field).get_attribute( "value") channel = 0 @@ -282,9 +282,9 @@ class AsusAXE11000AP(object): 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( + dict_5g["radius_secret"] = self.driver.find_element_by_name( BAND_5G_RAD_KEY).get_attribute("value") - channel_field = self._get_webdriver_elements_for_channels(band) + channel_field = self._get_webdriver_elements_for_channels("5g") ch_val = self.driver.find_element_by_name(channel_field).get_attribute( "value") channel = 0 @@ -312,7 +312,7 @@ class AsusAXE11000AP(object): 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) + channel_field = self._get_webdriver_elements_for_channels("6g") ch_val = self.driver.find_element_by_name(channel_field).get_attribute( "value") channel = 0 diff --git a/acts/framework/acts/controllers/openwrt_ap.py b/acts/framework/acts/controllers/openwrt_ap.py index 714ebb243..ac0712dea 100644 --- a/acts/framework/acts/controllers/openwrt_ap.py +++ b/acts/framework/acts/controllers/openwrt_ap.py @@ -1,14 +1,17 @@ """Controller for Open WRT access point.""" +import random import re import time from acts import logger +from acts import signals from acts.controllers.ap_lib import hostapd_constants from acts.controllers.openwrt_lib import network_settings from acts.controllers.openwrt_lib import wireless_config from acts.controllers.openwrt_lib import wireless_settings_applier from acts.controllers.utils_lib.ssh import connection from acts.controllers.utils_lib.ssh import settings +from acts.controllers.openwrt_lib.openwrt_constants import OpenWrtWifiSetting import yaml MOBLY_CONTROLLER_CONFIG_NAME = "OpenWrtAP" @@ -20,11 +23,13 @@ WEP_SECURITY = "wep" ENT_SECURITY = "wpa2" OWE_SECURITY = "owe" SAE_SECURITY = "sae" +SAEMIXED_SECURITY = "sae-mixed" ENABLE_RADIO = "0" PMF_ENABLED = 2 WIFI_2G = "wifi2g" WIFI_5G = "wifi5g" WAIT_TIME = 20 +DEFAULT_RADIOS = ("radio0", "radio1") def create(configs): @@ -105,7 +110,7 @@ class OpenWrtAP(object): lambda msg: "[OpenWrtAP|%s] %s" % (self.ssh_settings.hostname, msg)) self.wireless_setting = None self.network_setting = network_settings.NetworkSettings( - self.ssh, config["ssh_config"]["host"], self.log) + self.ssh, self.ssh_settings, self.log) def configure_ap(self, wifi_configs, channel_2g, channel_5g): """Configure AP with the required settings. @@ -292,7 +297,7 @@ class OpenWrtAP(object): else: self.ssh.run( 'uci set wireless.@wifi-iface[{}].key={}'.format(3, pwd_5g)) - self.log.info("Set 5G password to :{}".format(pwd_2g)) + self.log.info("Set 5G password to :{}".format(pwd_5g)) if pwd_2g: if len(pwd_2g) < 8 or len(pwd_2g) > 63: @@ -308,6 +313,89 @@ class OpenWrtAP(object): self.ssh.run("uci commit wireless") self.ssh.run("wifi") + def set_ssid(self, ssid_5g=None, ssid_2g=None): + """Set SSID for individual interface. + + Args: + ssid_5g: 8 ~ 63 chars for 5g network. + ssid_2g: 8 ~ 63 chars for 2g network. + """ + if ssid_5g: + if len(ssid_5g) < 8 or len(ssid_5g) > 63: + self.log.error("SSID must be 8~63 characters long") + # Only accept ascii letters and digits + else: + self.ssh.run( + 'uci set wireless.@wifi-iface[{}].ssid={}'.format(3, ssid_5g)) + self.log.info("Set 5G SSID to :{}".format(ssid_5g)) + + if ssid_2g: + if len(ssid_2g) < 8 or len(ssid_2g) > 63: + self.log.error("SSID must be 8~63 characters long") + # Only accept ascii letters and digits + else: + self.ssh.run( + 'uci set wireless.@wifi-iface[{}].ssid={}'.format(2, ssid_2g)) + self.log.info("Set 2G SSID to :{}".format(ssid_2g)) + + self.ssh.run("uci commit wireless") + self.ssh.run("wifi") + + def generate_mobility_domain(self): + """Generate 4-character hexadecimal ID + + Returns: String; a 4-character hexadecimal ID. + """ + md = "{:04x}".format(random.getrandbits(16)) + self.log.info("Mobility Domain ID: {}".format(md)) + return md + + def enable_80211r(self, iface, md): + """Enable 802.11r for one single radio. + + Args: + iface: index number of wifi-iface. + 2: radio1 + 3: radio0 + md: mobility domain. a 4-character hexadecimal ID. + Raises: TestSkip if 2g or 5g radio is not up or 802.11r is not enabled. + """ + str_output = self.ssh.run("wifi status").stdout + wifi_status = yaml.load(str_output.replace("\t", "").replace("\n", ""), + Loader=yaml.FullLoader) + # Check if the radio is up. + if iface == OpenWrtWifiSetting.IFACE_2G: + if wifi_status['radio1']['up']: + self.log.info("2g network is ENABLED") + else: + raise signals.TestSkip("2g network is NOT ENABLED") + elif iface == OpenWrtWifiSetting.IFACE_5G: + if wifi_status['radio0']['up']: + self.log.info("5g network is ENABLED") + else: + raise signals.TestSkip("5g network is NOT ENABLED") + + # Setup 802.11r. + self.ssh.run( + "uci set wireless.@wifi-iface[{}].ieee80211r='1'".format(iface)) + self.ssh.run( + "uci set wireless.@wifi-iface[{}].ft_psk_generate_local='1'" + .format(iface)) + self.ssh.run( + "uci set wireless.@wifi-iface[{}].mobility_domain='{}'" + .format(iface, md)) + self.ssh.run( + "uci commit wireless") + self.ssh.run("wifi") + + # Check if 802.11r is enabled. + result = self.ssh.run( + "uci get wireless.@wifi-iface[{}].ieee80211r".format(iface)).stdout + if result == '1': + self.log.info("802.11r is ENABLED") + else: + raise signals.TestSkip("802.11r is NOT ENABLED") + def generate_wireless_configs(self, wifi_configs): """Generate wireless configs to configure. @@ -334,7 +422,8 @@ class OpenWrtAP(object): config["security"], hostapd_constants.BAND_2G, password=config["password"], - hidden=config["hiddenSSID"])) + hidden=config["hiddenSSID"], + ieee80211w=config["ieee80211w"])) elif config["security"] == PSK1_SECURITY: wireless_configs.append( wireless_config.WirelessConfig("%s%s" % (WIFI_2G, num_2g), @@ -342,7 +431,8 @@ class OpenWrtAP(object): config["security"], hostapd_constants.BAND_2G, password=config["password"], - hidden=config["hiddenSSID"])) + hidden=config["hiddenSSID"], + ieee80211w=config["ieee80211w"])) elif config["security"] == WEP_SECURITY: wireless_configs.append( wireless_config.WirelessConfig("%s%s" % (WIFI_2G, num_2g), @@ -375,6 +465,15 @@ class OpenWrtAP(object): password=config["password"], hidden=config["hiddenSSID"], ieee80211w=PMF_ENABLED)) + elif config["security"] == SAEMIXED_SECURITY: + wireless_configs.append( + wireless_config.WirelessConfig("%s%s" % (WIFI_2G, num_2g), + config["SSID"], + config["security"], + hostapd_constants.BAND_2G, + password=config["password"], + hidden=config["hiddenSSID"], + ieee80211w=config["ieee80211w"])) elif config["security"] == ENT_SECURITY: wireless_configs.append( wireless_config.WirelessConfig( @@ -396,7 +495,8 @@ class OpenWrtAP(object): config["security"], hostapd_constants.BAND_5G, password=config["password"], - hidden=config["hiddenSSID"])) + hidden=config["hiddenSSID"], + ieee80211w=config["ieee80211w"])) elif config["security"] == PSK1_SECURITY: wireless_configs.append( wireless_config.WirelessConfig("%s%s" % (WIFI_5G, num_5g), @@ -404,7 +504,8 @@ class OpenWrtAP(object): config["security"], hostapd_constants.BAND_5G, password=config["password"], - hidden=config["hiddenSSID"])) + hidden=config["hiddenSSID"], + ieee80211w=config["ieee80211w"])) elif config["security"] == WEP_SECURITY: wireless_configs.append( wireless_config.WirelessConfig("%s%s" % (WIFI_5G, num_5g), @@ -437,6 +538,15 @@ class OpenWrtAP(object): password=config["password"], hidden=config["hiddenSSID"], ieee80211w=PMF_ENABLED)) + elif config["security"] == SAEMIXED_SECURITY: + wireless_configs.append( + wireless_config.WirelessConfig("%s%s" % (WIFI_5G, num_5g), + config["SSID"], + config["security"], + hostapd_constants.BAND_5G, + password=config["password"], + hidden=config["hiddenSSID"], + ieee80211w=config["ieee80211w"])) elif config["security"] == ENT_SECURITY: wireless_configs.append( wireless_config.WirelessConfig( @@ -478,6 +588,40 @@ class OpenWrtAP(object): return wifi_network return None + def get_wifi_status(self, radios=DEFAULT_RADIOS): + """Check if radios are up. Default are 2G and 5G bands. + + Args: + radios: Wifi interfaces for check status. + Returns: + True if both radios are up. False if not. + """ + status = True + for radio in radios: + str_output = self.ssh.run("wifi status %s" % radio).stdout + wifi_status = yaml.load(str_output.replace("\t", "").replace("\n", ""), + Loader=yaml.FullLoader) + status = wifi_status[radio]["up"] and status + return status + + def verify_wifi_status(self, radios=DEFAULT_RADIOS, timeout=20): + """Ensure wifi interfaces are ready. + + Args: + radios: Wifi interfaces for check status. + timeout: An integer that is the number of times to try + wait for interface ready. + Returns: + True if both radios are up. False if not. + """ + start_time = time.time() + end_time = start_time + timeout + while time.time() < end_time: + if self.get_wifi_status(radios): + return True + time.sleep(1) + return False + def close(self): """Reset wireless and network settings to default and stop AP.""" if self.network_setting.config: diff --git a/acts/framework/acts/controllers/openwrt_lib/network_const.py b/acts/framework/acts/controllers/openwrt_lib/network_const.py index 76dd34baa..0a3fb4233 100644 --- a/acts/framework/acts/controllers/openwrt_lib/network_const.py +++ b/acts/framework/acts/controllers/openwrt_lib/network_const.py @@ -42,9 +42,55 @@ IPSEC_L2TP_RSA = { } } +IPSEC_HYBRID_RSA = { + "conn HYBRID_RSA": { + "keyexchange": "ikev1", + "left": "192.168.1.1", + "leftsubnet": "0.0.0.0/0", + "leftauth": "pubkey", + "leftcert": "serverCert.der", + "leftsendcert": "always", + "right": "%any", + "rightsubnet": "0.0.0.0/0", + "rightauth": "pubkey", + "rightauth2": "xauth", + "xauth": "server", + "auto": "add", + } +} + +IPSEC_XAUTH_PSK = { + "conn XAUTH_PSK": { + "keyexchange": "ikev1", + "left": "192.168.1.1", + "leftsubnet": "0.0.0.0/0", + "leftauth": "psk", + "right": "%any", + "rightsubnet": "0.0.0.0/0", + "rightauth": "psk", + "rightauth2": "xauth", + "auto": "add", + } +} + +IPSEC_XAUTH_RSA = { + "conn XAUTH_RSA": { + "keyexchange": "ikev1", + "left": "192.168.1.1", + "leftsubnet": "0.0.0.0/0", + "leftcert": "serverCert.der", + "leftsendcert": "always", + "right": "%any", + "rightsubnet": "0.0.0.0/0", + "rightauth": "xauth", + "xauth": "server", + "auto": "add", + } +} + # parmas for lx2tpd -XL2TPD_CONF_GLOBAL = [ +XL2TPD_CONF_GLOBAL = ( "[global]", "ipsec saref = no", "debug tunnel = no", @@ -54,9 +100,9 @@ XL2TPD_CONF_GLOBAL = [ "access control = no", "rand source = dev", "port = 1701", -] +) -XL2TPD_CONF_INS = [ +XL2TPD_CONF_INS = ( "[lns default]", "require authentication = yes", "pass peer = yes", @@ -64,9 +110,9 @@ XL2TPD_CONF_INS = [ "length bit = yes", "refuse pap = yes", "refuse chap = yes", -] +) -XL2TPD_OPTION = [ +XL2TPD_OPTION = ( "require-mschap-v2", "refuse-mschap", "ms-dns 8.8.8.8", @@ -87,17 +133,17 @@ XL2TPD_OPTION = [ "lcp-echo-interval 30", "lcp-echo-failure 4", "nomppe" -] +) # iptable rules for vpn_pptp -FIREWALL_RULES_FOR_PPTP = [ +FIREWALL_RULES_FOR_PPTP = ( "iptables -A input_rule -i ppp+ -j ACCEPT", "iptables -A output_rule -o ppp+ -j ACCEPT", "iptables -A forwarding_rule -i ppp+ -j ACCEPT" -] +) # iptable rules for vpn_l2tp -FIREWALL_RULES_FOR_L2TP = [ +FIREWALL_RULES_FOR_L2TP = ( "iptables -I INPUT -m policy --dir in --pol ipsec --proto esp -j ACCEPT", "iptables -I FORWARD -m policy --dir in --pol ipsec --proto esp -j ACCEPT", "iptables -I FORWARD -m policy --dir out --pol ipsec --proto esp -j ACCEPT", @@ -111,7 +157,14 @@ FIREWALL_RULES_FOR_L2TP = [ "iptables -A INPUT -p udp --dport 500 -j ACCEPT", "iptables -A INPUT -p udp --dport 4500 -j ACCEPT", "iptables -A INPUT -p udp -m policy --dir in --pol ipsec -m udp --dport 1701 -j ACCEPT" -] +) + +FIREWALL_RULES_DISABLE_DNS_RESPONSE = ( + "iptables -I OUTPUT -p udp --sport 53 -j DROP", + "iptables -I OUTPUT -p tcp --sport 53 -j DROP", + "ip6tables -I OUTPUT -p udp --sport 53 -j DROP", + "ip6tables -I OUTPUT -p tcp --sport 53 -j DROP", +) # Object for vpn profile diff --git a/acts/framework/acts/controllers/openwrt_lib/network_settings.py b/acts/framework/acts/controllers/openwrt_lib/network_settings.py index 91cdb0372..efbd59003 100644 --- a/acts/framework/acts/controllers/openwrt_lib/network_settings.py +++ b/acts/framework/acts/controllers/openwrt_lib/network_settings.py @@ -13,8 +13,13 @@ # limitations under the License. import re +import time + +from acts import signals +from acts import utils from acts.controllers.openwrt_lib import network_const + SERVICE_DNSMASQ = "dnsmasq" SERVICE_STUNNEL = "stunnel" SERVICE_NETWORK = "network" @@ -22,8 +27,13 @@ SERVICE_PPTPD = "pptpd" SERVICE_FIREWALL = "firewall" SERVICE_IPSEC = "ipsec" SERVICE_XL2TPD = "xl2tpd" +SERVICE_ODHCPD = "odhcpd" +SERVICE_NODOGSPLASH = "nodogsplash" PPTP_PACKAGE = "pptpd kmod-nf-nathelper-extra" L2TP_PACKAGE = "strongswan-full openssl-util xl2tpd" +NAT6_PACKAGE = "ip6tables kmod-ipt-nat6" +CAPTIVE_PORTAL_PACKAGE = "nodogsplash" +MDNS_PACKAGE = "avahi-utils avahi-daemon-service-http avahi-daemon-service-ssh libavahi-client avahi-dbus-daemon" STUNNEL_CONFIG_PATH = "/etc/stunnel/DoTServer.conf" HISTORY_CONFIG_PATH = "/etc/dirty_configs" PPTPD_OPTION_PATH = "/etc/ppp/options.pptpd" @@ -31,6 +41,7 @@ XL2TPD_CONFIG_PATH = "/etc/xl2tpd/xl2tpd.conf" XL2TPD_OPTION_CONFIG_PATH = "/etc/ppp/options.xl2tpd" FIREWALL_CUSTOM_OPTION_PATH = "/etc/firewall.user" PPP_CHAP_SECRET_PATH = "/etc/ppp/chap-secrets" +TCPDUMP_DIR = "/tmp/tcpdump/" LOCALHOST = "192.168.1.1" DEFAULT_PACKAGE_INSTALL_TIMEOUT = 200 @@ -40,26 +51,30 @@ class NetworkSettings(object): Attributes: ssh: ssh connection object. - service_manager: Object manage service configuration + ssh_settings: ssh settings for AccessPoint. + service_manager: Object manage service configuration. + user: username for ssh. ip: ip address for AccessPoint. log: Logging object for AccessPoint. config: A list to store changes on network settings. - firewall_rules_list: A list of firewall rule name list + firewall_rules_list: A list of firewall rule name list. cleanup_map: A dict for compare oppo functions. l2tp: profile for vpn l2tp server. """ - def __init__(self, ssh, ip, logger): + def __init__(self, ssh, ssh_settings, logger): """Initialize wireless settings. Args: ssh: ssh connection object. - ip: ip address for AccessPoint. + ssh_settings: ssh settings for AccessPoint. logger: Logging object for AccessPoint. """ self.ssh = ssh self.service_manager = ServiceManager(ssh) - self.ip = ip + self.ssh_settings = ssh_settings + self.user = self.ssh_settings.username + self.ip = self.ssh_settings.hostname self.log = logger self.config = set() self.firewall_rules_list = [] @@ -67,7 +82,14 @@ class NetworkSettings(object): "setup_dns_server": self.remove_dns_server, "setup_vpn_pptp_server": self.remove_vpn_pptp_server, "setup_vpn_l2tp_server": self.remove_vpn_l2tp_server, - "disable_ipv6": self.enable_ipv6 + "disable_ipv6": self.enable_ipv6, + "setup_ipv6_bridge": self.remove_ipv6_bridge, + "default_dns": self.del_default_dns, + "default_v6_dns": self.del_default_v6_dns, + "ipv6_prefer_option": self.remove_ipv6_prefer_option, + "block_dns_response": self.unblock_dns_response, + "setup_mdns": self.remove_mdns, + "setup_captive_portal": self.remove_cpative_portal } # This map contains cleanup functions to restore the configuration to # its default state. We write these keys to HISTORY_CONFIG_PATH prior to @@ -75,6 +97,7 @@ class NetworkSettings(object): # This makes it easier to recover after an aborted test. self.update_firewall_rules_list() self.cleanup_network_settings() + self.clear_tcpdump() def cleanup_network_settings(self): """Reset all changes on Access point.""" @@ -88,7 +111,11 @@ class NetworkSettings(object): if self.config: temp = self.config.copy() for change in temp: - self.cleanup_map[change]() + change_list = change.split() + if len(change_list) > 1: + self.cleanup_map[change_list[0]](*change_list[1:]) + else: + self.cleanup_map[change]() self.config = set() if self.file_exists(HISTORY_CONFIG_PATH): @@ -397,11 +424,11 @@ class NetworkSettings(object): org: Organization name for generate cert keys. """ self.l2tp = network_const.VpnL2tp(vpn_server_hostname, - vpn_server_address, - vpn_username, - vpn_password, - psk_secret, - server_name) + vpn_server_address, + vpn_username, + vpn_password, + psk_secret, + server_name) self.package_install(L2TP_PACKAGE) self.config.add("setup_vpn_l2tp_server") @@ -416,6 +443,8 @@ class NetworkSettings(object): self.setup_ppp_secret() # /etc/config/firewall & /etc/firewall.user self.setup_firewall_rules_for_l2tp() + # setup vpn server local ip + self.setup_vpn_local_ip() # generate cert and key for rsa self.generate_vpn_cert_keys(country, org) # restart service @@ -428,6 +457,7 @@ class NetworkSettings(object): """Remove l2tp vpn server on OpenWrt.""" self.config.discard("setup_vpn_l2tp_server") self.restore_firewall_rules_for_l2tp() + self.remove_vpn_local_ip() self.service_manager.need_restart(SERVICE_IPSEC) self.service_manager.need_restart(SERVICE_XL2TPD) self.service_manager.need_restart(SERVICE_FIREWALL) @@ -451,28 +481,35 @@ class NetworkSettings(object): def setup_ipsec(self): """Setup ipsec config.""" - def load_config(data): + def load_ipsec_config(data, rightsourceip=False): for i in data.keys(): config.append(i) for j in data[i].keys(): config.append("\t %s=%s" % (j, data[i][j])) + if rightsourceip: + config.append("\t rightsourceip=%s.16/26" % self.l2tp.address.rsplit(".", 1)[0]) config.append("") config = [] - load_config(network_const.IPSEC_CONF) - load_config(network_const.IPSEC_L2TP_PSK) - load_config(network_const.IPSEC_L2TP_RSA) + load_ipsec_config(network_const.IPSEC_CONF) + load_ipsec_config(network_const.IPSEC_L2TP_PSK) + load_ipsec_config(network_const.IPSEC_L2TP_RSA) + load_ipsec_config(network_const.IPSEC_HYBRID_RSA, True) + load_ipsec_config(network_const.IPSEC_XAUTH_PSK, True) + load_ipsec_config(network_const.IPSEC_XAUTH_RSA, True) self.create_config_file("\n".join(config), "/etc/ipsec.conf") ipsec_secret = [] ipsec_secret.append(r": PSK \"%s\"" % self.l2tp.psk_secret) ipsec_secret.append(r": RSA \"%s\"" % "serverKey.der") + ipsec_secret.append(r"%s : XAUTH \"%s\"" % (self.l2tp.username, + self.l2tp.password)) self.create_config_file("\n".join(ipsec_secret), "/etc/ipsec.secrets") def setup_xl2tpd(self, ip_range=20): """Setup xl2tpd config.""" net_id, host_id = self.l2tp.address.rsplit(".", 1) - xl2tpd_conf = network_const.XL2TPD_CONF_GLOBAL + xl2tpd_conf = list(network_const.XL2TPD_CONF_GLOBAL) xl2tpd_conf.append("auth file = %s" % PPP_CHAP_SECRET_PATH) xl2tpd_conf.extend(network_const.XL2TPD_CONF_INS) xl2tpd_conf.append("ip range = %s.%s-%s.%s" % @@ -483,7 +520,7 @@ class NetworkSettings(object): xl2tpd_conf.append("pppoptfile = %s" % XL2TPD_OPTION_CONFIG_PATH) self.create_config_file("\n".join(xl2tpd_conf), XL2TPD_CONFIG_PATH) - xl2tpd_option = network_const.XL2TPD_OPTION + xl2tpd_option = list(network_const.XL2TPD_OPTION) xl2tpd_option.append("name %s" % self.l2tp.name) self.create_config_file("\n".join(xl2tpd_option), XL2TPD_OPTION_CONFIG_PATH) @@ -574,7 +611,7 @@ class NetworkSettings(object): self.ssh.run("uci set firewall.@rule[-1].src='wan'") self.ssh.run("uci set firewall.@rule[-1].proto='47'") - iptable_rules = network_const.FIREWALL_RULES_FOR_PPTP + iptable_rules = list(network_const.FIREWALL_RULES_FOR_PPTP) self.add_custom_firewall_rules(iptable_rules) self.service_manager.need_restart(SERVICE_FIREWALL) @@ -617,7 +654,7 @@ class NetworkSettings(object): self.ssh.run("uci set firewall.@rule[-1].proto='ah'") net_id = self.l2tp.address.rsplit(".", 1)[0] - iptable_rules = network_const.FIREWALL_RULES_FOR_L2TP + iptable_rules = list(network_const.FIREWALL_RULES_FOR_L2TP) iptable_rules.append("iptables -A FORWARD -s %s.0/24" " -j ACCEPT" % net_id) iptable_rules.append("iptables -t nat -A POSTROUTING" @@ -670,6 +707,24 @@ class NetworkSettings(object): """Disable pptp service.""" self.package_remove(PPTP_PACKAGE) + def setup_vpn_local_ip(self): + """Setup VPN Server local ip on OpenWrt for client ping verify.""" + self.ssh.run("uci set network.lan2=interface") + self.ssh.run("uci set network.lan2.type=bridge") + self.ssh.run("uci set network.lan2.ifname=eth1.2") + self.ssh.run("uci set network.lan2.proto=static") + self.ssh.run("uci set network.lan2.ipaddr=\"%s\"" % self.l2tp.address) + self.ssh.run("uci set network.lan2.netmask=255.255.255.0") + self.ssh.run("uci set network.lan2=interface") + self.service_manager.reload(SERVICE_NETWORK) + self.commit_changes() + + def remove_vpn_local_ip(self): + """Discard vpn local ip on OpenWrt.""" + self.ssh.run("uci delete network.lan2") + self.service_manager.reload(SERVICE_NETWORK) + self.commit_changes() + def enable_ipv6(self): """Enable ipv6 on OpenWrt.""" self.ssh.run("uci set network.lan.ipv6=1") @@ -688,6 +743,194 @@ class NetworkSettings(object): self.service_manager.reload(SERVICE_NETWORK) self.commit_changes() + def setup_ipv6_bridge(self): + """Setup ipv6 bridge for client have ability to access network.""" + self.config.add("setup_ipv6_bridge") + + self.ssh.run("uci set dhcp.lan.dhcpv6=relay") + self.ssh.run("uci set dhcp.lan.ra=relay") + self.ssh.run("uci set dhcp.lan.ndp=relay") + + self.ssh.run("uci set dhcp.wan6=dhcp") + self.ssh.run("uci set dhcp.wan6.dhcpv6=relay") + self.ssh.run("uci set dhcp.wan6.ra=relay") + self.ssh.run("uci set dhcp.wan6.ndp=relay") + self.ssh.run("uci set dhcp.wan6.master=1") + self.ssh.run("uci set dhcp.wan6.interface=wan6") + + # Enable service + self.service_manager.need_restart(SERVICE_ODHCPD) + self.commit_changes() + + def remove_ipv6_bridge(self): + """Discard ipv6 bridge on OpenWrt.""" + if "setup_ipv6_bridge" in self.config: + self.config.discard("setup_ipv6_bridge") + + self.ssh.run("uci set dhcp.lan.dhcpv6=server") + self.ssh.run("uci set dhcp.lan.ra=server") + self.ssh.run("uci delete dhcp.lan.ndp") + + self.ssh.run("uci delete dhcp.wan6") + + self.service_manager.need_restart(SERVICE_ODHCPD) + self.commit_changes() + + def _add_dhcp_option(self, args): + self.ssh.run("uci add_list dhcp.lan.dhcp_option=\"%s\"" % args) + + def _remove_dhcp_option(self, args): + self.ssh.run("uci del_list dhcp.lan.dhcp_option=\"%s\"" % args) + + def add_default_dns(self, addr_list): + """Add default dns server for client. + + Args: + addr_list: dns ip address for Openwrt client. + """ + self._add_dhcp_option("6,%s" % ",".join(addr_list)) + self.config.add("default_dns %s" % addr_list) + self.service_manager.need_restart(SERVICE_DNSMASQ) + self.commit_changes() + + def del_default_dns(self, addr_list): + """Remove default dns server for client. + + Args: + addr_list: list of dns ip address for Openwrt client. + """ + self._remove_dhcp_option("6,%s" % addr_list) + self.config.discard("default_dns %s" % addr_list) + self.service_manager.need_restart(SERVICE_DNSMASQ) + self.commit_changes() + + def add_default_v6_dns(self, addr_list): + """Add default v6 dns server for client. + + Args: + addr_list: dns ip address for Openwrt client. + """ + self.ssh.run("uci add_list dhcp.lan.dns=\"%s\"" % addr_list) + self.config.add("default_v6_dns %s" % addr_list) + self.service_manager.need_restart(SERVICE_ODHCPD) + self.commit_changes() + + def del_default_v6_dns(self, addr_list): + """Del default v6 dns server for client. + + Args: + addr_list: dns ip address for Openwrt client. + """ + self.ssh.run("uci del_list dhcp.lan.dns=\"%s\"" % addr_list) + self.config.add("default_v6_dns %s" % addr_list) + self.service_manager.need_restart(SERVICE_ODHCPD) + self.commit_changes() + + def add_ipv6_prefer_option(self): + self._add_dhcp_option("108,1800i") + self.config.add("ipv6_prefer_option") + self.service_manager.need_restart(SERVICE_DNSMASQ) + self.commit_changes() + + def remove_ipv6_prefer_option(self): + self._remove_dhcp_option("108,1800i") + self.config.discard("ipv6_prefer_option") + self.service_manager.need_restart(SERVICE_DNSMASQ) + self.commit_changes() + + def start_tcpdump(self, test_name, args="", interface="br-lan"): + """"Start tcpdump on OpenWrt. + + Args: + test_name: Test name for create tcpdump file name. + args: Option args for tcpdump. + interface: Interface to logging. + Returns: + tcpdump_file_name: tcpdump file name on OpenWrt. + pid: tcpdump process id. + """ + if not self.path_exists(TCPDUMP_DIR): + self.ssh.run("mkdir %s" % TCPDUMP_DIR) + tcpdump_file_name = "openwrt_%s_%s.pcap" % (test_name, + time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime(time.time()))) + tcpdump_file_path = "".join([TCPDUMP_DIR, tcpdump_file_name]) + cmd = "tcpdump -i %s -s0 %s -w %s" % (interface, args, tcpdump_file_path) + self.ssh.run_async(cmd) + pid = self._get_tcpdump_pid(tcpdump_file_name) + if not pid: + raise signals.TestFailure("Fail to start tcpdump on OpenWrt.") + # Set delay to prevent tcpdump fail to capture target packet. + time.sleep(15) + return tcpdump_file_name + + def stop_tcpdump(self, tcpdump_file_name, pull_dir=None): + """Stop tcpdump on OpenWrt and pull the pcap file. + + Args: + tcpdump_file_name: tcpdump file name on OpenWrt. + pull_dir: Keep none if no need to pull. + Returns: + tcpdump abs_path on host. + """ + # Set delay to prevent tcpdump fail to capture target packet. + time.sleep(15) + pid = self._get_tcpdump_pid(tcpdump_file_name) + self.ssh.run("kill -9 %s" % pid, ignore_status=True) + if self.path_exists(TCPDUMP_DIR) and pull_dir: + tcpdump_path = "".join([TCPDUMP_DIR, tcpdump_file_name]) + tcpdump_remote_path = "/".join([pull_dir, tcpdump_file_name]) + tcpdump_local_path = "%s@%s:%s" % (self.user, self.ip, tcpdump_path) + utils.exe_cmd("scp %s %s" % (tcpdump_local_path, tcpdump_remote_path)) + + if self._get_tcpdump_pid(tcpdump_file_name): + raise signals.TestFailure("Failed to stop tcpdump on OpenWrt.") + if self.file_exists(tcpdump_path): + self.ssh.run("rm -f %s" % tcpdump_path) + return tcpdump_remote_path if pull_dir else None + + def clear_tcpdump(self): + self.ssh.run("killall tpcdump", ignore_status=True) + if self.ssh.run("pgrep tpcdump", ignore_status=True).stdout: + raise signals.TestFailure("Failed to clean up tcpdump process.") + + def _get_tcpdump_pid(self, tcpdump_file_name): + """Check tcpdump process on OpenWrt.""" + return self.ssh.run("pgrep -f %s" % (tcpdump_file_name), ignore_status=True).stdout + + def setup_mdns(self): + self.config.add("setup_mdns") + self.package_install(MDNS_PACKAGE) + self.commit_changes() + + def remove_mdns(self): + self.config.discard("setup_mdns") + self.package_remove(MDNS_PACKAGE) + self.commit_changes() + + def block_dns_response(self): + self.config.add("block_dns_response") + iptable_rules = list(network_const.FIREWALL_RULES_DISABLE_DNS_RESPONSE) + self.add_custom_firewall_rules(iptable_rules) + self.service_manager.need_restart(SERVICE_FIREWALL) + self.commit_changes() + + def unblock_dns_response(self): + self.config.discard("block_dns_response") + self.remove_custom_firewall_rules() + self.service_manager.need_restart(SERVICE_FIREWALL) + self.commit_changes() + + def setup_captive_portal(self): + self.package_install(CAPTIVE_PORTAL_PACKAGE) + self.config.add("setup_captive_portal") + self.service_manager.need_restart(SERVICE_NODOGSPLASH) + self.commit_changes() + + def remove_cpative_portal(self): + self.package_remove(CAPTIVE_PORTAL_PACKAGE) + self.config.discard("setup_captive_portal") + self.commit_changes() + class ServiceManager(object): """Class for service on OpenWrt. @@ -720,6 +963,8 @@ class ServiceManager(object): def restart_services(self): """Restart all services need to restart.""" for service in self._need_restart: + if service == SERVICE_NETWORK: + self.reload(service) self.restart(service) self._need_restart = set() diff --git a/acts/framework/acts/controllers/openwrt_lib/openwrt_constants.py b/acts/framework/acts/controllers/openwrt_lib/openwrt_constants.py index 5848b5b8b..5ab412491 100644 --- a/acts/framework/acts/controllers/openwrt_lib/openwrt_constants.py +++ b/acts/framework/acts/controllers/openwrt_lib/openwrt_constants.py @@ -23,4 +23,8 @@ class OpenWrtWifiSecurity: WPA2_PSK_DEFAULT = "psk2" WPA2_PSK_CCMP = "psk2+ccmp" WPA2_PSK_TKIP = "psk2+tkip" - WPA2_PSK_TKIP_AND_CCMP = "psk2+tkip+ccmp"
\ No newline at end of file + WPA2_PSK_TKIP_AND_CCMP = "psk2+tkip+ccmp" + +class OpenWrtWifiSetting: + IFACE_2G = 2 + IFACE_5G = 3
\ No newline at end of file diff --git a/acts/framework/acts/controllers/openwrt_lib/wireless_settings_applier.py b/acts/framework/acts/controllers/openwrt_lib/wireless_settings_applier.py index ec0bbf100..a366c02c4 100644 --- a/acts/framework/acts/controllers/openwrt_lib/wireless_settings_applier.py +++ b/acts/framework/acts/controllers/openwrt_lib/wireless_settings_applier.py @@ -15,6 +15,7 @@ WEP_SECURITY = "wep" ENT_SECURITY = "wpa2" OWE_SECURITY = "owe" SAE_SECURITY = "sae" +SAEMIXED_SECURITY = "sae-mixed" ENABLE_RADIO = "0" DISABLE_RADIO = "1" ENABLE_HIDDEN = "1" @@ -108,7 +109,8 @@ class WirelessSettingsApplier(object): self.ssh.run("uci set wireless.%s.encryption='%s'" % (config.name, config.security)) if config.security == PSK_SECURITY or config.security == SAE_SECURITY\ - or config.security == PSK1_SECURITY: + or config.security == PSK1_SECURITY\ + or config.security == SAEMIXED_SECURITY: self.ssh.run("uci set wireless.%s.key='%s'" % (config.name, config.password)) elif config.security == WEP_SECURITY: diff --git a/acts/framework/acts/libs/ota/ota_tools/update_device_ota_tool.py b/acts/framework/acts/libs/ota/ota_tools/update_device_ota_tool.py index ec5d7d7df..7d5d7725e 100644 --- a/acts/framework/acts/libs/ota/ota_tools/update_device_ota_tool.py +++ b/acts/framework/acts/libs/ota/ota_tools/update_device_ota_tool.py @@ -25,7 +25,7 @@ from acts import utils # OTA Packages can be upwards of 1 GB. This may take some time to transfer over # USB 2.0. A/B devices must also complete the update in the background. -UPDATE_TIMEOUT = 30 * 60 +UPDATE_TIMEOUT = 60 * 60 UPDATE_LOCATION = '/data/ota_package/update.zip' diff --git a/acts_tests/acts_contrib/test_utils/net/connectivity_const.py b/acts_tests/acts_contrib/test_utils/net/connectivity_const.py index 49996c6e2..591c83f8c 100644 --- a/acts_tests/acts_contrib/test_utils/net/connectivity_const.py +++ b/acts_tests/acts_contrib/test_utils/net/connectivity_const.py @@ -74,13 +74,29 @@ MULTIPATH_PREFERENCE_RELIABILITY = 1 << 1 MULTIPATH_PREFERENCE_PERFORMANCE = 1 << 2 # Private DNS constants -DNS_GOOGLE = "dns.google" -DNS_QUAD9 = "dns.quad9.net" -DNS_CLOUDFLARE = "1dot1dot1dot1.cloudflare-dns.com" +DNS_GOOGLE_HOSTNAME = "dns.google" +DNS_QUAD9_HOSTNAME = "dns.quad9.net" +DNS_CLOUDFLARE_HOSTNAME = "1dot1dot1dot1.cloudflare-dns.com" +DOH_CLOUDFLARE_HOSTNAME = "cloudflare-dns.com" PRIVATE_DNS_MODE_OFF = "off" PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic" PRIVATE_DNS_MODE_STRICT = "hostname" +DNS_SUPPORT_TYPE = { + DNS_GOOGLE_HOSTNAME: ["Do53", "DoT", "DoH"], + DNS_CLOUDFLARE_HOSTNAME: ["Do53","DoT"], + DOH_CLOUDFLARE_HOSTNAME: ["DoH"] +} + +DNS_GOOGLE_ADDR_V4 = ["8.8.4.4", "8.8.8.8"] +DNS_GOOGLE_ADDR_V6 = ["2001:4860:4860::8888", + "2001:4860:4860::8844"] +DNS_CLOUDFLARE_ADDR_V4 = ["1.1.1.1", "1.0.0.1"] +DOH_CLOUDFLARE_ADDR_V4 = ["104.16.248.249", "104.16.249.249"] +DOH_CLOUDFLARE_ADDR_V6 = ["2606:4700::6810:f8f9", + "2606:4700::6810:f9f9"] + + # IpSec constants SOCK_STREAM = 1 SOCK_DGRAM = 2 diff --git a/acts_tests/acts_contrib/test_utils/wifi/WifiBaseTest.py b/acts_tests/acts_contrib/test_utils/wifi/WifiBaseTest.py index ab87f88da..1f8085816 100644 --- a/acts_tests/acts_contrib/test_utils/wifi/WifiBaseTest.py +++ b/acts_tests/acts_contrib/test_utils/wifi/WifiBaseTest.py @@ -406,10 +406,12 @@ class WifiBaseTest(BaseTestClass): ent_network_pwd=False, owe_network=False, sae_network=False, + saemixed_network=False, radius_conf_2g=None, radius_conf_5g=None, radius_conf_pwd=None, - ap_count=1): + ap_count=1, + ieee80211w=None): """Create, configure and start OpenWrt AP. Args: @@ -429,10 +431,12 @@ class WifiBaseTest(BaseTestClass): 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.") @@ -458,6 +462,7 @@ class WifiBaseTest(BaseTestClass): self.open_network = [] self.owe_networks = [] self.sae_networks = [] + self.saemixed_networks = [] self.bssid_map = [] for i in range(ap_count): network_list = [] @@ -470,6 +475,8 @@ class WifiBaseTest(BaseTestClass): passphrase_length_5g) wpa1_dict[hostapd_constants.BAND_2G]["security"] = "psk" wpa1_dict[hostapd_constants.BAND_5G]["security"] = "psk" + wpa1_dict[hostapd_constants.BAND_2G]["ieee80211w"] = ieee80211w + wpa1_dict[hostapd_constants.BAND_5G]["ieee80211w"] = ieee80211w self.wpa1_networks.append(wpa1_dict) network_list.append(wpa1_dict) if wpa_network: @@ -481,6 +488,8 @@ class WifiBaseTest(BaseTestClass): passphrase_length_5g) wpa_dict[hostapd_constants.BAND_2G]["security"] = "psk2" wpa_dict[hostapd_constants.BAND_5G]["security"] = "psk2" + wpa_dict[hostapd_constants.BAND_2G]["ieee80211w"] = ieee80211w + wpa_dict[hostapd_constants.BAND_5G]["ieee80211w"] = ieee80211w self.wpa_networks.append(wpa_dict) network_list.append(wpa_dict) if wep_network: @@ -533,6 +542,18 @@ class WifiBaseTest(BaseTestClass): sae_dict[hostapd_constants.BAND_2G]["security"] = "sae" sae_dict[hostapd_constants.BAND_5G]["security"] = "sae" network_list.append(sae_dict) + if saemixed_network: + saemixed_dict = self.get_psk_network(mirror_ap, self.saemixed_networks, + hidden, same_ssid, + hostapd_constants.SAE_KEY_MGMT, + ssid_length_2g, ssid_length_5g, + passphrase_length_2g, + passphrase_length_5g) + saemixed_dict[hostapd_constants.BAND_2G]["security"] = "sae-mixed" + saemixed_dict[hostapd_constants.BAND_5G]["security"] = "sae-mixed" + saemixed_dict[hostapd_constants.BAND_2G]["ieee80211w"] = ieee80211w + saemixed_dict[hostapd_constants.BAND_5G]["ieee80211w"] = ieee80211w + network_list.append(saemixed_dict) self.access_points[i].configure_ap(network_list, channels_2g[i], channels_5g[i]) self.access_points[i].start_ap() diff --git a/acts_tests/acts_contrib/test_utils/wifi/wifi_test_utils.py b/acts_tests/acts_contrib/test_utils/wifi/wifi_test_utils.py index 420afb8f0..2e3f336d6 100755 --- a/acts_tests/acts_contrib/test_utils/wifi/wifi_test_utils.py +++ b/acts_tests/acts_contrib/test_utils/wifi/wifi_test_utils.py @@ -909,13 +909,18 @@ def start_wifi_connection_scan_and_check_for_network(ad, True: if network_ssid is found in scan results. False: if network_ssid is not found in scan results. """ + start_time = time.time() for num_tries in range(max_tries): if start_wifi_connection_scan_and_return_status(ad): scan_results = ad.droid.wifiGetScanResults() match_results = match_networks({WifiEnums.SSID_KEY: network_ssid}, scan_results) if len(match_results) > 0: + ad.log.debug("Found network in %s seconds." % + (time.time() - start_time)) return True + ad.log.debug("Did not find network in %s seconds." % + (time.time() - start_time)) return False @@ -1466,11 +1471,9 @@ def ensure_no_disconnect(ad, duration=10): ad.droid.wifiStopTrackingStateChange() -def connect_to_wifi_network(ad, - network, - assert_on_fail=True, - check_connectivity=True, - hidden=False): +def connect_to_wifi_network(ad, network, assert_on_fail=True, + check_connectivity=True, hidden=False, + num_of_scan_tries=3, num_of_connect_tries=3): """Connection logic for open and psk wifi networks. Args: @@ -1479,16 +1482,20 @@ def connect_to_wifi_network(ad, assert_on_fail: If true, errors from wifi_connect will raise test failure signals. hidden: Is the Wifi network hidden. + num_of_scan_tries: The number of times to try scan + interface before declaring failure. + num_of_connect_tries: The number of times to try + connect wifi before declaring failure. """ if hidden: start_wifi_connection_scan_and_ensure_network_not_found( - ad, network[WifiEnums.SSID_KEY]) + ad, network[WifiEnums.SSID_KEY], max_tries=num_of_scan_tries) else: start_wifi_connection_scan_and_ensure_network_found( - ad, network[WifiEnums.SSID_KEY]) + ad, network[WifiEnums.SSID_KEY], max_tries=num_of_scan_tries) wifi_connect(ad, network, - num_of_tries=3, + num_of_tries=num_of_connect_tries, assert_on_fail=assert_on_fail, check_connectivity=check_connectivity) diff --git a/acts_tests/tests/google/net/CaptivePortalTest.py b/acts_tests/tests/google/net/CaptivePortalTest.py index eaafa258f..7542ee9bd 100644 --- a/acts_tests/tests/google/net/CaptivePortalTest.py +++ b/acts_tests/tests/google/net/CaptivePortalTest.py @@ -16,6 +16,7 @@ import time from acts import asserts +from acts.controllers.openwrt_ap import MOBLY_CONTROLLER_CONFIG_NAME as OPENWRT from acts import base_test from acts.test_decorators import test_tracker_info from acts_contrib.test_utils.net import connectivity_const as cconst @@ -33,8 +34,8 @@ CONNECTED = "Connected" SIGN_IN_NOTIFICATION = "Sign in to network" -class CaptivePortalTest(base_test.BaseTestClass): - """Tests for Captive portal.""" +class CaptivePortalTest(WifiBaseTest): + """Check device can access the network after pass captive portal check.""" def setup_class(self): """Setup devices for tests and unpack params. @@ -48,10 +49,20 @@ class CaptivePortalTest(base_test.BaseTestClass): 4. uic_zip: Zip file location of UICD application """ self.dut = self.android_devices[0] - req_params = ["rk_captive_portal", "gg_captive_portal"] - self.unpack_userparams(req_param_names=req_params,) + opt_params = ["rk_captive_portal", "gg_captive_portal", + "configure_OpenWrt", "wifi_network"] + self.unpack_userparams(opt_param_names=opt_params,) wutils.wifi_test_device_init(self.dut) + if OPENWRT in self.user_params: + self.openwrt = self.access_points[0] + if hasattr(self, "configure_OpenWrt") and self.configure_OpenWrt == "skip": + self.dut.log.info("Skip configure Wifi interface due to config setup.") + else: + self.configure_openwrt_ap_and_start(wpa_network=True) + self.wifi_network = self.openwrt.get_wifi_network() + self.openwrt.network_setting.setup_captive_portal() + def teardown_class(self): """Reset devices.""" cutils.set_private_dns(self.dut, cconst.PRIVATE_DNS_MODE_OPPORTUNISTIC) @@ -76,7 +87,7 @@ class CaptivePortalTest(base_test.BaseTestClass): uutils.has_element(self.dut, text="Network & internet"), "Failed to find 'Network & internet' icon") uutils.wait_and_click(self.dut, text="Network & internet") - uutils.wait_and_click(self.dut, text="Not connected") + uutils.wait_and_click(self.dut, text="Internet") def _verify_sign_in_notification(self): """Verify sign in notification shows for captive portal.""" @@ -225,3 +236,44 @@ class CaptivePortalTest(base_test.BaseTestClass): # verify connection to captive portal network self._verify_captive_portal(self.gg_captive_portal) + + @test_tracker_info(uuid="c25a1be7-f202-41c4-ac95-bed1720833ab") + def test_openwrt_captive_portal_default(self): + """Verify captive portal network. + + Steps: + 1. Set default private dns mode + 2. Connect to openwrt captive portal network + 3. Verify connectivity + """ + cutils.set_private_dns(self.dut, cconst.PRIVATE_DNS_MODE_OPPORTUNISTIC) + self.openwrt.network_setting.service_manager.restart("nodogsplash") + self._verify_captive_portal(self.wifi_network, click_accept="Continue") + + @test_tracker_info(uuid="1419e36d-0303-44ba-bc60-4d707b45ef48") + def test_openwrt_captive_portal_private_dns_off(self): + """Verify captive portal network. + + Steps: + 1. Turn off private dns mode + 2. Connect to openwrt captive portal network + 3. Verify connectivity + """ + cutils.set_private_dns(self.dut, cconst.PRIVATE_DNS_MODE_OFF) + self.openwrt.network_setting.service_manager.restart("nodogsplash") + self._verify_captive_portal(self.wifi_network, click_accept="Continue") + + @test_tracker_info(uuid="5aae44ee-fa62-47b9-9b3d-8121f9f92da1") + def test_openwrt_captive_portal_private_dns_strict(self): + """Verify captive portal network. + + Steps: + 1. Set strict private dns mode + 2. Connect to openwrt captive portal network + 3. Verify connectivity + """ + cutils.set_private_dns(self.dut, + cconst.PRIVATE_DNS_MODE_STRICT, + cconst.DNS_GOOGLE) + self.openwrt.network_setting.service_manager.restart("nodogsplash") + self._verify_captive_portal(self.wifi_network, click_accept="Continue") diff --git a/acts_tests/tests/google/net/DNSTest.py b/acts_tests/tests/google/net/DNSTest.py new file mode 100644 index 000000000..d0f99d936 --- /dev/null +++ b/acts_tests/tests/google/net/DNSTest.py @@ -0,0 +1,132 @@ +# +# 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 random + +from acts import asserts +from acts.controllers.openwrt_ap import MOBLY_CONTROLLER_CONFIG_NAME as OPENWRT +from acts_contrib.test_utils.wifi import wifi_test_utils as wutils +from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest +from scapy.all import rdpcap, DNSRR, DNSQR, IP, IPv6 + + +WLAN = "wlan0" +PING_ADDR = "google.com" + + +class DNSTest(WifiBaseTest): + """DNS related test for Android.""" + + def setup_class(self): + self.dut = self.android_devices[0] + wutils.wifi_test_device_init(self.dut) + + req_params = [] + opt_param = ["wifi_network", "configure_OpenWrt"] + self.unpack_userparams( + req_param_names=req_params, opt_param_names=opt_param) + + asserts.assert_true(OPENWRT in self.user_params, + "OpenWrtAP is not in testbed.") + self.openwrt = self.access_points[0] + if hasattr(self, "configure_OpenWrt") and self.configure_OpenWrt == "skip": + self.dut.log.info("Skip configure Wifi interface due to config setup.") + else: + self.configure_openwrt_ap_and_start(wpa_network=True) + self.wifi_network = self.openwrt.get_wifi_network() + + asserts.assert_true(self.openwrt.verify_wifi_status(), + "OpenWrt Wifi interface is not ready.") + + def teardown_class(self): + """Reset wifi to make sure VPN tears down cleanly.""" + wutils.reset_wifi(self.dut) + + def teardown_test(self): + """Reset wifi to make sure VPN tears down cleanly.""" + wutils.reset_wifi(self.dut) + + def ping(self, addr, ignore_status=True, timeout=60): + """Start a ping from DUT and return ping result. + + Args: + addr: Address to ping. + ignore_status: ignore non zero return. + timeout: cmd timeout. + Returns: + Boolean for ping result. + """ + return "100%" not in self.dut.adb.shell("ping -c 1 %s" % addr, + ignore_status=ignore_status, + timeout=timeout) + + def generate_query_qname(self): + """Return a random query name.""" + return "%s-ds.metric.gstatic.com" % random.randint(0, 99999999) + + def test_dns_query(self): + # Setup environment + wutils.connect_to_wifi_network(self.dut, self.wifi_network) + # Start tcpdump on OpenWrt + remote_pcap_path = self.openwrt.network_setting.start_tcpdump(self.test_name) + # Generate query name + test_qname = self.generate_query_qname() + self.dut.log.info("Test query name = %s" % test_qname) + # Start send a query + ping_result = self.ping(test_qname) + local_pcap_path = self.openwrt.network_setting.stop_tcpdump(remote_pcap_path, + self.dut.device_log_path) + # Check DNSRR.rrname in tcpdump to verify DNS response + packets = rdpcap(local_pcap_path) + self.dut.log.info("pcap file path : %s" % local_pcap_path) + pkt_count = 0 + for pkt in packets: + if pkt.haslayer(DNSRR) and pkt[DNSRR].rrname.decode().strip(".") == test_qname: + pkt_count = pkt_count + 1 + self.dut.log.info("DNS query response count : %s" % pkt_count) + if not ping_result: + asserts.assert_true(pkt_count > 0, + "Did not find match standard query response in tcpdump.") + asserts.assert_true(ping_result, "Device ping fail.") + + def test_dns_query_retransmit(self): + # Setup environment + wutils.connect_to_wifi_network(self.dut, self.wifi_network) + self.openwrt.network_setting.block_dns_response() + # Start tcpdump on OpenWrt + remote_pcap_path = self.openwrt.network_setting.start_tcpdump(self.test_name) + # Generate query name + test_qname = self.generate_query_qname() + self.dut.log.info("Test query name = %s" % test_qname) + # Start send a query + self.ping(test_qname) + local_pcap_path = self.openwrt.network_setting.stop_tcpdump(remote_pcap_path, + self.dut.device_log_path) + # Check DNSQR.qname in tcpdump to verify device retransmit the query + packets = rdpcap(local_pcap_path) + self.dut.log.info("pcap file path : %s" % local_pcap_path) + pkt_count = 0 + pkt6_count = 0 + for pkt in packets: + if pkt.haslayer(DNSQR) and pkt[DNSQR].qname.decode().strip(".") == test_qname: + if pkt.haslayer(IP): + pkt_count = pkt_count + 1 + if pkt.haslayer(IPv6): + pkt6_count = pkt6_count + 1 + self.dut.log.info("IPv4 DNS query count : %s" % pkt_count) + self.dut.log.info("IPv6 DNS query count : %s" % pkt6_count) + self.openwrt.network_setting.unblock_dns_response() + asserts.assert_true(pkt_count >= 2 or pkt6_count >= 2, + "Did not find match standard query in tcpdump.") diff --git a/acts_tests/tests/google/net/DhcpTest.py b/acts_tests/tests/google/net/DhcpTest.py new file mode 100644 index 000000000..739f6ca0c --- /dev/null +++ b/acts_tests/tests/google/net/DhcpTest.py @@ -0,0 +1,92 @@ +# +# 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.controllers.openwrt_ap import MOBLY_CONTROLLER_CONFIG_NAME as OPENWRT +from acts_contrib.test_utils.wifi import wifi_test_utils as wutils +from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest + +WLAN = "wlan0" +PING_ADDR = "google.com" + + +class DhcpTest(WifiBaseTest): + """DHCP related test for Android.""" + + def setup_class(self): + self.dut = self.android_devices[0] + + wutils.wifi_test_device_init(self.dut) + asserts.assert_true(OPENWRT in self.user_params, + "OpenWrtAP is not in testbed.") + self.openwrt = self.access_points[0] + self.configure_openwrt_ap_and_start(wpa_network=True) + self.wifi_network = self.openwrt.get_wifi_network() + self.openwrt.network_setting.setup_ipv6_bridge() + asserts.assert_true(self.openwrt.verify_wifi_status(), + "OpenWrt Wifi interface is not ready.") + def teardown_class(self): + """Reset wifi to make sure VPN tears down cleanly.""" + wutils.reset_wifi(self.dut) + + def teardown_test(self): + """Reset wifi to make sure VPN tears down cleanly.""" + wutils.reset_wifi(self.dut) + + def _verify_ping(self, option="", dest=PING_ADDR): + try: + out = self.dut.adb.shell("ping%s -c1 %s" % (option, dest)) + return "100%" not in out + except Exception as e: + self.dut.log.debug(e) + return False + + def _verify_device_address(self, ipv4=True, ipv6=True, timeout=15): + """Verify device get assign address on wireless interface.""" + current_time = time.time() + while time.time() < current_time + timeout: + try: + if ipv4: + ipv4_addr = self.dut.droid.connectivityGetIPv4Addresses(WLAN)[0] + self.dut.log.info("ipv4_address is %s" % ipv4_addr) + if ipv6: + ipv6_addr = self.dut.droid.connectivityGetIPv6Addresses(WLAN)[0] + self.dut.log.info("ipv6_address is %s" % ipv6_addr) + return True + except: + time.sleep(1) + return False + + def test_ipv4_ipv6_network(self): + """Verify device can get both ipv4 ipv6 address.""" + wutils.connect_to_wifi_network(self.dut, self.wifi_network) + + asserts.assert_true(self._verify_device_address(), + "Fail to get ipv4/ipv6 address.") + asserts.assert_true(self._verify_ping(), "Fail to ping on ipv4.") + asserts.assert_true(self._verify_ping("6"), "Fail to ping on ipv6.") + + def test_ipv6_only_prefer_option(self): + """Verify DUT can only get ipv6 address and ping out.""" + self.openwrt.network_setting.add_ipv6_prefer_option() + wutils.connect_to_wifi_network(self.dut, self.wifi_network) + + asserts.assert_true(self._verify_device_address(ipv4=False), + "Fail to get ipv6 address.") + asserts.assert_false(self._verify_ping(), + "Should not ping on success on ipv4.") + asserts.assert_true(self._verify_ping("6"), + "Fail to ping on ipv6.") diff --git a/acts_tests/tests/google/net/DnsOverHttpsTest.py b/acts_tests/tests/google/net/DnsOverHttpsTest.py new file mode 100644 index 000000000..56f379296 --- /dev/null +++ b/acts_tests/tests/google/net/DnsOverHttpsTest.py @@ -0,0 +1,295 @@ +# +# 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.controllers.openwrt_ap import MOBLY_CONTROLLER_CONFIG_NAME as OPENWRT +from acts.test_decorators import test_tracker_info +from acts_contrib.test_utils.net import connectivity_const as cconst +from acts_contrib.test_utils.net import connectivity_test_utils as cutils +from acts_contrib.test_utils.net.net_test_utils import start_tcpdump +from acts_contrib.test_utils.net.net_test_utils import stop_tcpdump +from acts_contrib.test_utils.wifi import wifi_test_utils as wutils +from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest +from scapy.all import rdpcap +from scapy.all import Scapy_Exception +from scapy.all import TCP +from scapy.all import UDP + + +DEFAULT_DNS_TIMEOUT = 5 + + +class DnsOverHttpsTest(WifiBaseTest): + """Tests for DnsoverHttps feature.""" + + def setup_class(self): + """Setup devices and OpenWrt for DnsoverHttps test and unpack params.""" + + self.dut = self.android_devices[0] + if len(self.android_devices) > 1: + self.dut_b = self.android_devices[1] + for ad in self.android_devices: + wutils.reset_wifi(ad) + ad.droid.setPrivateDnsMode(True) + req_params = ("ping_hosts",) + opt_params = ("wifi_network", "configure_OpenWrt", + "ipv4_only_network", "ipv4_ipv6_network") + self.unpack_userparams(req_param_names=req_params, + opt_param_names=opt_params) + if OPENWRT in self.user_params: + self.openwrt = self.access_points[0] + if hasattr(self, "configure_OpenWrt") and self.configure_OpenWrt == "skip": + self.dut.log.info("Skip configure Wifi interface due to config setup.") + else: + self.configure_openwrt_ap_and_start(wpa_network=True) + self.tcpdump_pid = None + self.default_dns = None + self.default_dns_v6 = None + self._setup_doh(self.dut, self.get_wifi_network()) + + def teardown_test(self): + wutils.reset_wifi(self.dut) + if OPENWRT in self.user_params: + self.openwrt.network_setting.del_default_dns(self.default_dns) + self.default_dns = None + self.default_dns_v6 = None + + def teardown_class(self): + for ad in self.android_devices: + ad.droid.setPrivateDnsMode(True) + self._setup_doh(ad, self.get_wifi_network(), enable=False) + + def on_fail(self, test_name, begin_time): + self.dut.take_bug_report(test_name, begin_time) + + def get_wifi_network(self, ipv6_supported=False): + """Return fit network for conditions. + + Args: + ipv6_supported: Boolean for select network. + Returns: + A dict for network object for connect wifi. + """ + if OPENWRT in self.user_params: + if ipv6_supported: + self.openwrt.network_setting.enable_ipv6() + self.openwrt.network_setting.setup_ipv6_bridge() + else: + self.openwrt.network_setting.disable_ipv6() + self.openwrt.network_setting.remove_ipv6_bridge() + if self.default_dns: + self.openwrt.network_setting.add_default_dns(self.default_dns) + if self.default_dns_v6: + for ipv6_dns in self.default_dns_v6: + self.openwrt.network_setting.add_default_v6_dns(ipv6_dns) + if hasattr(self, "configure_OpenWrt") and self.configure_OpenWrt == "skip": + return self.wifi_network + return self.openwrt.get_wifi_network() + if ipv6_supported: + return self.ipv4_ipv6_network + return self.ipv4_only_network + + def _verify_doh_queries(self, pcap_file, over_https): + """Verify if DNS queries were over https or not. + + Args: + pcap_file: tcpdump file + over_https: True if excepted all dns go through doh. + """ + try: + packets = rdpcap(pcap_file) + except Scapy_Exception: + asserts.fail("Not a valid pcap file") + + for pkt in packets: + summary = "%s" % pkt.summary() + for host in self.ping_hosts: + host = host.split(".")[-2] + if UDP in pkt and pkt[UDP].sport == 53 and host in summary: + if over_https: + asserts.fail("Found query to port 53: %s" % summary) + else: + self.dut.log.info("Found query to port 53: %s" % summary) + if TCP in pkt and pkt[TCP].sport == 853: + asserts.fail("Found query to port 853: %s" % summary) + + def _test_public_doh_mode(self, ad, net, dns_mode, hostname=None): + """Test step for DoH. + + Args: + ad: android device object. + net: wifi network to connect to, LTE network if None. + dns_mode: private DNS mode. + hostname: private DNS hostname to set to. + """ + + # set private dns mode + if dns_mode: + cutils.set_private_dns(self.dut, dns_mode, hostname) + # connect to wifi + wutils.start_wifi_connection_scan_and_ensure_network_found( + self.dut, net[wutils.WifiEnums.SSID_KEY]) + wutils.wifi_connect(self.dut, net) + self._verify_tls_completed() + + # start tcpdump on the device + self.tcpdump_pid = start_tcpdump(self.dut, self.test_name) + + # ping hosts should pass + for host in self.ping_hosts: + self.log.info("Pinging %s" % host) + status = wutils.validate_connection(self.dut, host) + asserts.assert_true(status, "Failed to ping host %s" % host) + self.log.info("Ping successful") + + # stop tcpdump + pcap_file = stop_tcpdump(self.dut, self.tcpdump_pid, self.test_name) + + # verify DNS queries + overhttps = dns_mode != cconst.PRIVATE_DNS_MODE_OFF + self._verify_doh_queries(pcap_file, overhttps) + + # reset wifi + wutils.reset_wifi(self.dut) + + def _verify_tls_completed(self, retry_count=5): + """Verify tls finish verification process. + + Expect all private dns server status, should be + "success", or "fail". + + Args: + retry_count: int for retry times. + Raises: + TimeoutError: if TLS verification stuck in processing. + """ + for attempt in range(retry_count): + out = self.dut.adb.shell("dumpsys dnsresolver") + if "status{in_process}" in out: + if attempt + 1 < retry_count: + self.dut.log.info("DoT still validating, retrying...") + time.sleep(DEFAULT_DNS_TIMEOUT) + else: + return + raise TimeoutError("Fail to completed TLS verification.") + + def _setup_doh(self, ad, net, enable=True): + """Enable/Disable DoH option. + + Args: + ad: android devies. + net: network as wifi. + enable: if True, sets the 'doh' experiment flag. + """ + if enable: + ad.adb.shell("setprop persist.device_config.netd_native.doh 1") + else: + ad.adb.shell("setprop persist.device_config.netd_native.doh 0") + wutils.wifi_connect(ad, net) + wutils.reset_wifi(ad) + out = ad.adb.shell("dumpsys dnsresolver |grep doh") + ad.log.debug(out) + + def test_mix_server_ipv4_only_wifi_network_with_dns_strict_mode(self): + """Test doh flag with below situation. + + - Android device in strict mode + - DNS server supporting both Dns, DoT and DoH protocols + - IPv4-only network + """ + self._test_public_doh_mode(self.dut, self.get_wifi_network(), + cconst.PRIVATE_DNS_MODE_STRICT, + hostname=cconst.DNS_GOOGLE_HOSTNAME) + + def test_mix_server_ipv4_ipv6_wifi_network_with_dns_strict_mode(self): + """Test doh flag with below situation. + + - Android device in strict mode + - DNS server supporting both Dns, DoT and DoH protocols + - IPv4-IPv6 network + """ + self._test_public_doh_mode(self.dut, self.get_wifi_network(), + cconst.PRIVATE_DNS_MODE_STRICT, + hostname=cconst.DNS_GOOGLE_HOSTNAME) + + def test_pure_server_ipv4_only_wifi_network_with_dns_strict_mode(self): + """Test doh flag with below situation. + + - Android device in strict mode + - DNS server only supporting DoH protocols + - IPv4-only network + """ + self._test_public_doh_mode(self.dut, self.get_wifi_network(), + cconst.PRIVATE_DNS_MODE_STRICT, + hostname=cconst.DOH_CLOUDFLARE_HOSTNAME) + + def test_pure_server_ipv4_ipv6_wifi_network_with_dns_strict_mode(self): + """Test doh flag with below situation. + + - Android device in strict mode + - DNS server only supporting DoH protocols + - IPv4-IPv6 network + """ + self._test_public_doh_mode(self.dut, self.get_wifi_network(), + cconst.PRIVATE_DNS_MODE_STRICT, + hostname=cconst.DOH_CLOUDFLARE_HOSTNAME) + + def test_mix_server_ipv4_only_wifi_network_with_dns_opportunistic_mode(self): + """Test doh flag with below situation. + + - Android device in opportunistic mode + - DNS server supporting both Dns, DoT and DoH protocols + - IPv4-only network + """ + self.default_dns = cconst.DNS_GOOGLE_ADDR_V4 + self._test_public_doh_mode(self.dut, self.get_wifi_network(), + cconst.PRIVATE_DNS_MODE_OPPORTUNISTIC) + + def test_mix_server_ipv4_ipv6_wifi_network_with_dns_opportunistic_mode(self): + """Test doh flag with below situation. + + - Android device in opportunistic mode + - DNS server supporting both Dns, DoT and DoH protocols + - IPv4-IPv6 network + """ + self.default_dns = cconst.DNS_GOOGLE_ADDR_V4 + self.default_dns_v6 = cconst.DNS_GOOGLE_ADDR_V6 + self._test_public_doh_mode(self.dut, self.get_wifi_network(), + cconst.PRIVATE_DNS_MODE_OPPORTUNISTIC) + + def test_mix_server_ipv4_only_wifi_network_with_dns_off_mode(self): + """Test doh with below situation. + + - Android device in dns off mode + - DNS server supporting both Dns, DoT and DoH protocols + - IPv4-only network + """ + self.default_dns = cconst.DNS_GOOGLE_ADDR_V4 + self._test_public_doh_mode(self.dut, self.get_wifi_network(), + cconst.PRIVATE_DNS_MODE_OFF) + + def test_mix_server_ipv4_ipv6_wifi_network_with_dns_off_mode(self): + """Test doh with below situation. + + - Android device in dns off mode + - DNS server supporting both Dns, DoT and DoH protocols + - IPv4-IPv6 network + """ + self.default_dns = cconst.DNS_GOOGLE_ADDR_V4 + self.default_dns_v6 = cconst.DNS_GOOGLE_ADDR_V6 + self._test_public_doh_mode(self.dut, self.get_wifi_network(), + cconst.PRIVATE_DNS_MODE_OFF) diff --git a/acts_tests/tests/google/net/LegacyVpnTest.py b/acts_tests/tests/google/net/LegacyVpnTest.py index 6e9710bf1..4003a2f9d 100644 --- a/acts_tests/tests/google/net/LegacyVpnTest.py +++ b/acts_tests/tests/google/net/LegacyVpnTest.py @@ -43,7 +43,8 @@ class LegacyVpnTest(WifiBaseTest): req_params = [ x for x in req_params if not x.startswith("__") ] - opt_params = ["wifi_network", "vpn_cert_country", "vpn_cert_org"] + opt_params = ["wifi_network", "vpn_cert_country", + "vpn_cert_org", "configure_OpenWrt"] self.unpack_userparams(req_param_names=req_params, opt_param_names=opt_params) @@ -51,8 +52,12 @@ class LegacyVpnTest(WifiBaseTest): wutils.wifi_toggle_state(self.dut, True) if OPENWRT in self.user_params: self.openwrt = self.access_points[0] - self.configure_openwrt_ap_and_start(wpa_network=True) - self.wifi_network = self.openwrt.get_wifi_network() + if hasattr(self, "configure_OpenWrt") and self.configure_OpenWrt == "skip": + self.dut.log.info("Skip configure Wifi interface due to config setup.") + else: + self.configure_openwrt_ap_and_start(wpa_network=True) + self.wifi_network = self.openwrt.get_wifi_network() + # Wait for OpenWrt statement update time.sleep(10) self.openwrt.network_setting.setup_vpn_pptp_server( diff --git a/acts_tests/tests/google/net/MutlicastDNSTest.py b/acts_tests/tests/google/net/MutlicastDNSTest.py new file mode 100644 index 000000000..475ad4534 --- /dev/null +++ b/acts_tests/tests/google/net/MutlicastDNSTest.py @@ -0,0 +1,79 @@ +# +# 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. + + +from acts import asserts +from acts.controllers.openwrt_ap import MOBLY_CONTROLLER_CONFIG_NAME as OPENWRT +from acts.test_decorators import test_tracker_info +from acts_contrib.test_utils.wifi import wifi_test_utils as wutils +from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest + + +class MulticastDNSTest(WifiBaseTest): + """Verify Multicast DNS can work on Android devices.""" + + def setup_class(self): + """Setup Openwrt and unpack params for mDNS test.""" + self.dut = self.android_devices[0] + req_params = [] + opt_params = ["configure_OpenWrt", "wifi_network"] + self.unpack_userparams(req_params, opt_params) + if OPENWRT in self.user_params: + self.openwrt = self.access_points[0] + if hasattr(self, "configure_OpenWrt") and self.configure_OpenWrt == "skip": + self.dut.log.info("Skip configure Wifi interface due to config setup.") + else: + self.configure_openwrt_ap_and_start(wpa_network=True) + self.wifi_network = self.openwrt.get_wifi_network() + + def on_fail(self, test_name, begin_time): + """Take bugreport if test failed.""" + self.dut.take_bug_report(test_name, begin_time) + + def teardown_test(self): + """Reset wifi settings after test case.""" + wutils.reset_wifi(self.dut) + + def verify_ping(self, hostname, expect_ping_pass=True): + """Verify if result of the ping as excepted. + + Args: + hostname: ping address. + expect_ping_pass: excepted ping result is True or False. + Returns: + Boolean if ping result work as expected. + """ + out = self.dut.adb.shell("ping -c 1 %s" % hostname) + result = ("100%" not in out) == expect_ping_pass + if not result: + self.dut.log.info(out) + return result + + def test_mdns_query_ipv4_only(self): + """Verify mdns query work in ipv4 only network.""" + self.openwrt.network_setting.disable_ipv6() + self.openwrt.network_setting.setup_mdns() + wutils.wifi_connect(self.dut, self.wifi_network) + asserts.assert_true(self.verify_ping("openwrt.local"), + "Fail to ping openwrt.local.") + + def test_mdns_query_ipv4_ipv6(self): + """Verify mdns query work in ipv4 & ipv6 network.""" + self.openwrt.network_setting.enable_ipv6() + self.openwrt.network_setting.setup_mdns() + wutils.wifi_connect(self.dut, self.wifi_network) + asserts.assert_true(self.verify_ping("openwrt.local"), + "Fail to ping openwrt.local.") + diff --git a/acts_tests/tests/google/wifi/WifiBridgedApTest.py b/acts_tests/tests/google/wifi/WifiBridgedApTest.py index 87b980c50..5cc94d6ad 100644 --- a/acts_tests/tests/google/wifi/WifiBridgedApTest.py +++ b/acts_tests/tests/google/wifi/WifiBridgedApTest.py @@ -25,16 +25,18 @@ from acts_contrib.test_utils.wifi import wifi_constants 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 WifiEnums = wutils.WifiEnums +# Each wait time add 5 seconds as buffer. BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS = 5 -BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES = 300 +BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES = 305 BRIDGED_AP_SHUTDOWN_INTERVAL_5_SECONDS = 5 -SOFT_AP_SHUTDOWN_INTERVAL_10_MINUTES = 600 -INTERVAL_9_MINUTES = 540 -INTERVAL_2_MINUTES = 120 -INTERVAL_1_MINUTES = 60 +SOFT_AP_SHUTDOWN_INTERVAL_10_MINUTES = 605 +INTERVAL_9_MINUTES = 545 +INTERVAL_2_MINUTES = 125 +INTERVAL_1_MINUTES = 65 class WifiBridgedApTest(WifiBaseTest): @@ -44,6 +46,7 @@ class WifiBridgedApTest(WifiBaseTest): * Android device x 1 with BridgedAp supported. * Android devices x2 as clients, at least Android 10. * OpenWrt AP x 1. + * Google Wi-Fi x 2 as packet captures. """ def setup_class(self): @@ -59,9 +62,6 @@ class WifiBridgedApTest(WifiBaseTest): if not self.dut.droid.wifiIsBridgedApConcurrencySupported(): raise signals.TestAbortClass("Legacy phone is not supported") - for ad in self.android_devices: - wutils.wifi_test_device_init(ad) - req_params = ["dbs_supported_models"] opt_param = ["cnss_diag_file", "pixel_models"] @@ -85,6 +85,16 @@ class WifiBridgedApTest(WifiBaseTest): wutils.set_wifi_country_code( ad, wutils.WifiEnums.CountryCode.US) + # Stop packet captures. + if hasattr(self, "sniffer_procs"): + for i in range(len(self.sniffer_procs)): + try: + wutils.stop_pcap( + self.packet_capture[i], self.sniffer_procs[i], False) + logging.info("packet_capture[{}] is STOPPED".format(i)) + except: + logging.info("packet_capture[{}] is NOT STOPPED".format(i)) + def teardown_class(self): super().teardown_class() for ad in self.android_devices: @@ -102,7 +112,7 @@ class WifiBridgedApTest(WifiBaseTest): country = ad.droid.wifiGetCountryCode() asserts.assert_true(country == country_code, "country code {} is not set".format(country_code)) - ad.log.info("code code set to : {}".format(country)) + ad.log.info("Country code set to : {}".format(country)) def verify_clients_support_wpa3_sae(self, *args): """Check if clients support WPA3 SAE. @@ -125,13 +135,16 @@ class WifiBridgedApTest(WifiBaseTest): e,g,. [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G] """ + self.dut.log.info("Length of infos: {}, Length of bands: {}" + .format(len(infos), len(bands))) asserts.assert_true(len(infos) == len(bands), - "length of infos and bands not matched") + "There should be {} BridgedAp instance, " + "instead of {}".format(len(bands), len(infos))) if len(bands) == 1 and (bands[0] == WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G): asserts.assert_true(infos[0][wifi_constants. SOFTAP_INFO_FREQUENCY_CALLBACK_KEY] in WifiEnums.softap_band_frequencies[bands[0]], - "This should be a %s instance", bands[0]) + "This should be a {} instance".format(bands[0])) if len(bands) == 2 and (bands[0] == WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G): asserts.assert_true((infos[0][wifi_constants. SOFTAP_INFO_FREQUENCY_CALLBACK_KEY] @@ -171,6 +184,19 @@ class WifiBridgedApTest(WifiBaseTest): e,g,. [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G] freq_equal: True if need to check SoftAp freq equals to STA freq. + + Returns: + infos: A List of SoftAp info, e.g., + [{'autoShutdownTimeoutMillis': 600000, + 'bandwidth': 4, + 'bssid': '12:dd:0b:b9:4b:cc', + 'frequency': 5180, + 'wifiStandard': 6}, + {'autoShutdownTimeoutMillis': 600000, + 'bandwidth': 2, + 'bssid': '12:22:f4:b9:4b:cc', + 'frequency': 2462, + 'wifiStandard': 4}] """ callbackId = ad.droid.registerSoftApCallback() infos = wutils.get_current_softap_infos(ad, callbackId, True) @@ -178,6 +204,7 @@ class WifiBridgedApTest(WifiBaseTest): if freq_equal: self.verify_softap_freq_equals_to_ap_freq(ad, infos) ad.droid.unregisterSoftApCallback(callbackId) + return infos def verify_expected_number_of_softap_clients(self, ad, number): """Verify the number of softap clients. @@ -219,6 +246,148 @@ class WifiBridgedApTest(WifiBaseTest): logging.info("Wait {} minutes".format(interval/60)) time.sleep(interval) + def generate_softap_config(self, security): + """Return a soft ap config + + Args: + security: String; represent certain security. e.g., "WPA3_SAE" + """ + config = wutils.create_softap_config() + config[WifiEnums.SECURITY] = security + return config + + def enable_bridged_ap(self, ad, security, bands, **kwargs): + """Enable BridgedAp. + + Args: + security: String; represent certain security. e.g., "WPA3_SAE" + bands: specifies the band list for the soft ap. + """ + self.config = self.generate_softap_config(security) + wutils.save_wifi_soft_ap_config( + ad, + self.config, + bands=bands, + **kwargs) + wutils.start_wifi_tethering_saved_config(self.dut) + # Wait 5 seconds for BridgedAp launch. + self.wait_interval(BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS) + + def sniffing_bridgedap_channels(self, infos): + """Sniff BridgedAp channels. + + Args: + infos: A List of SoftAp info. e.g., + [{'autoShutdownTimeoutMillis': 600000, + 'bandwidth': 4, + 'bssid': '12:dd:0b:b9:4b:cc', + 'frequency': 5180, + 'wifiStandard': 6}, + {'autoShutdownTimeoutMillis': 600000, + 'bandwidth': 2, + 'bssid': '12:22:f4:b9:4b:cc', + 'frequency': 2462, + 'wifiStandard': 4}] + """ + if hasattr(self, "packet_capture") and len(self.packet_capture) == 2: + # Create sniffer_config. + self.sniffer_config = {} + for i in range(len(infos)): + if (infos[i][WifiEnums.frequency_key] in + WifiEnums.ALL_5G_FREQUENCIES): + self.sniffer_config[BAND_5G] = WifiEnums.freq_to_channel[ + int(infos[i][WifiEnums.frequency_key])] + if (infos[i][WifiEnums.frequency_key] in + WifiEnums.ALL_2G_FREQUENCIES): + self.sniffer_config[BAND_2G] = WifiEnums.freq_to_channel[ + int(infos[i][WifiEnums.frequency_key])] + logging.info("sniffer_config : {}".format(self.sniffer_config)) + + # Enable sniffers. + self.sniffer_procs = [] + for i in range(len(self.sniffer_config)): + self.packet_capture[i].log.info( + "Enable packet_capture[{}]".format(i)) + result = self.packet_capture[i].configure_monitor_mode( + list(self.sniffer_config.keys())[i], + list(self.sniffer_config.values())[i]) + if not result: + logging.error("Failed to enable packet_capture" + "on {}".format(self.packet_capture[i])) + self.pcap_procs = wutils.start_pcap( + self.packet_capture[i], + list(self.sniffer_config.keys())[i], + self.test_name) + self.sniffer_procs.append(self.pcap_procs) + logging.info("sniffer_procs: {}".format(self.sniffer_procs)) + else: + logging.warning("Packet_capture not enabled, " + "because two packet_capture hardware required") + + def sniffing_ap_channels(self, channel1, channel2): + """Sniff on two Wi-Fi channels. + + Args: + channel1: Integer; a Wi-Fi channel, e.g., 6. + channel2: Integer; a Wi-Fi channel, e,g,. 36. + """ + if not channel1: + channel1 = hostapd_constants.AP_DEFAULT_CHANNEL_2G + if not channel2: + channel2 = hostapd_constants.AP_DEFAULT_CHANNEL_5G + + if hasattr(self, "packet_capture") and len(self.packet_capture) == 2: + # Create sniffer_config. + self.sniffer_config = {} + if channel1 in WifiEnums.channel_2G_to_freq: + self.sniffer_config[BAND_2G] = channel1 + if channel1 in WifiEnums.channel_5G_to_freq: + self.sniffer_config[BAND_5G] = channel1 + if channel2 in WifiEnums.channel_2G_to_freq: + self.sniffer_config[BAND_2G] = channel2 + if channel2 in WifiEnums.channel_5G_to_freq: + self.sniffer_config[BAND_5G] = channel2 + logging.info("sniffer_config : {}".format(self.sniffer_config)) + + # Enable sniffers. + self.sniffer_procs = [] + for i in range(len(self.sniffer_config)): + self.packet_capture[i].log.info( + "Enable packet_capture[{}]".format(i)) + result = self.packet_capture[i].configure_monitor_mode( + list(self.sniffer_config.keys())[i], + list(self.sniffer_config.values())[i]) + if not result: + logging.error("Failed to enable packet_capture" + "on {}".format(self.packet_capture[i])) + self.pcap_procs = wutils.start_pcap( + self.packet_capture[i], + list(self.sniffer_config.keys())[i], + self.test_name) + self.sniffer_procs.append(self.pcap_procs) + logging.info("sniffer_procs: {}".format(self.sniffer_procs)) + else: + logging.debug("Packet_capture not enabled, " + "because two packet_capture hardware required") + + def start_ap(self, channel_2g, channel_5g): + """Enable OpenWrt AP with specific 2G/5G channels + + Args: + channel_2g: Integer; a 2G channel, e.g., 6. + channel_5g: Integer; a 5G channel, e,g,. 36 + """ + if not channel_2g: + channel_2g = hostapd_constants.AP_DEFAULT_CHANNEL_2G + if not channel_5g: + channel_5g = hostapd_constants.AP_DEFAULT_CHANNEL_5G + + # Enable OpenWrt AP. + if "OpenWrtAP" in self.user_params: + self.configure_openwrt_ap_and_start(wpa_network=True, + channel_2g=channel_2g, + channel_5g=channel_5g) + def two_clients_connect_to_wifi_network(self, dut1, dut2, config): """Connect two clients to different BridgedAp instances. This function will be called only when BridgedAp ON. @@ -269,10 +438,46 @@ class WifiBridgedApTest(WifiBaseTest): asserts.assert_true(client2_bssid == bssid_2g, "Client2 does not connect to the 2G instance") + def client_connects_to_a_bridgeap(self, ad, band): + """One client connects to a BridgeAp instance + + Args: + band: String; '2g' or '5g'. + """ + callbackId = self.dut.droid.registerSoftApCallback() + infos = wutils.get_current_softap_infos(self.dut, callbackId, True) + self.dut.droid.unregisterSoftApCallback(callbackId) + # Make one client connects to 2G instance if band == '2g'. + if band == BAND_2G: + if (infos[0][wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY] + in WifiEnums.ALL_2G_FREQUENCIES): + bssid_2g = (infos[0][wifi_constants. + SOFTAP_INFO_BSSID_CALLBACK_KEY]) + else: + bssid_2g = (infos[1][wifi_constants. + SOFTAP_INFO_BSSID_CALLBACK_KEY]) + config_2g = self.config.copy() + config_2g[WifiEnums.BSSID_KEY] = bssid_2g + wutils.connect_to_wifi_network(ad, config_2g, + check_connectivity=False) + # Make one client connects to 5G instance if band == '5g'. + elif band == BAND_5G: + if (infos[0][wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY] + in WifiEnums.ALL_5G_FREQUENCIES): + bssid_5g = (infos[0][wifi_constants. + SOFTAP_INFO_BSSID_CALLBACK_KEY]) + else: + bssid_5g = (infos[1][wifi_constants. + SOFTAP_INFO_BSSID_CALLBACK_KEY]) + config_5g = self.config.copy() + config_5g[WifiEnums.BSSID_KEY] = bssid_5g + wutils.connect_to_wifi_network(ad, config_5g, + check_connectivity=False) + # Tests @test_tracker_info(uuid="6f776b4a-b080-4b52-a330-52aa641b18f2") - def test_two_clients_ping_on_bridged_ap_band_2_and_5_with_wpa3_in_country_us(self): + def test_two_clients_ping_bridged_ap_5g_2g_wpa3_country_us(self): """Test clients on different instances can ping each other. Steps: @@ -282,14 +487,51 @@ class WifiBridgedApTest(WifiBaseTest): Enable BridgedAp with bridged configuration. RegisterSoftApCallback. Check the bridged AP enabled succeed. + start sniffer and sniffing on BridgedAp channels. Force client#1 connect to 5G. Force client#2 connect to 2.4G. Trigger client#1 and client#2 each other. + Stop sniffers. Restore config. """ # Backup config original_softap_config = self.dut.droid.wifiGetApConfiguration() + # Make sure clients support WPA3 SAE. + self.verify_clients_support_wpa3_sae(self.client1, self.client2) + # Make sure DUT is able to enable BridgedAp. + is_supported = wutils.check_available_channels_in_bands_2_5( + self.dut, wutils.WifiEnums.CountryCode.US) + asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" + .format(wutils.WifiEnums.CountryCode.US)) + # Enable BridgedAp and verify both 2G,5G instances have been enabled. + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA3_SAE, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) + infos = self.verify_number_band_freq_of_bridged_ap( + self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False) + + self.sniffing_bridgedap_channels(infos) + + self.two_clients_connect_to_wifi_network(self.client1, self.client2, + self.config) + # Trigger client#1 and client#2 ping each other. + wutils.validate_ping_between_two_clients(self.client1, self.client2) + + # Restore config + wutils.save_wifi_soft_ap_config(self.dut, original_softap_config) + @test_tracker_info(uuid="8685a6cb-f7be-4384-b25b-23cecb4cb6dc") + def test_two_clients_ping_bridged_ap_5g_2g_wpa3_sae_transition_country_us(self): + """Test clients on different instances can ping each other. + + Steps: + Refer to test_two_clients_ping_bridged_ap_5g_2g_wpa3_country_us, + but this case enable WPA3/WPA2-Personal SoftAp security type. + """ + # Backup config + original_softap_config = self.dut.droid.wifiGetApConfiguration() # Make sure clients support WPA3 SAE. self.verify_clients_support_wpa3_sae(self.client1, self.client2) # Make sure DUT is able to enable BridgedAp. @@ -298,19 +540,89 @@ class WifiBridgedApTest(WifiBaseTest): asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" .format(wutils.WifiEnums.CountryCode.US)) - # Enable BridgedAp - config = wutils.create_softap_config() - config[WifiEnums.SECURITY] = WifiEnums.SoftApSecurityType.WPA3_SAE - wutils.save_wifi_soft_ap_config( - self.dut, config, - bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, - WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) - wutils.start_wifi_tethering_saved_config(self.dut) - # Wait 5 seconds for BridgedAp launch. - self.wait_interval(BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS) + # Enable BridgedAp and verify both 2G,5G instances have been enabled. + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA3_SAE_TRANSITION, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) + infos = self.verify_number_band_freq_of_bridged_ap( + self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False) + + self.sniffing_bridgedap_channels(infos) self.two_clients_connect_to_wifi_network(self.client1, self.client2, - config) + self.config) + # Trigger client#1 and client#2 ping each other. + wutils.validate_ping_between_two_clients(self.client1, self.client2) + + # Restore config + wutils.save_wifi_soft_ap_config(self.dut, original_softap_config) + + @test_tracker_info(uuid="b217d4de-cd09-4a8f-b27d-302ae5b86c7e") + def test_two_clients_ping_bridged_ap_5g_2g_wpa2_country_us(self): + """Test clients on different instances can ping each other. + + Steps: + Refer to test_two_clients_ping_bridged_ap_5g_2g_wpa3_country_us, + but this case enable WPA2-Personal SoftAp security type. + """ + # Backup config + original_softap_config = self.dut.droid.wifiGetApConfiguration() + # Make sure DUT is able to enable BridgedAp. + is_supported = wutils.check_available_channels_in_bands_2_5( + self.dut, wutils.WifiEnums.CountryCode.US) + asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" + .format(wutils.WifiEnums.CountryCode.US)) + + # Enable BridgedAp and verify both 2G,5G instances have been enabled. + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA2, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) + infos = self.verify_number_band_freq_of_bridged_ap( + self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False) + + self.sniffing_bridgedap_channels(infos) + + self.two_clients_connect_to_wifi_network(self.client1, self.client2, + self.config) + # Trigger client#1 and client#2 ping each other. + wutils.validate_ping_between_two_clients(self.client1, self.client2) + + # Restore config + wutils.save_wifi_soft_ap_config(self.dut, original_softap_config) + + @test_tracker_info(uuid="ef98a5ea-c7d5-4cc4-a2f8-e5fd44648788") + def test_two_clients_ping_bridged_ap_5g_2g_no_security_country_us(self): + """Test clients on different instances can ping each other. + + Steps: + Refer to test_two_clients_ping_bridged_ap_5g_2g_wpa3_country_us, + but this case enable OPEN SoftAp security type. + """ + # Backup config + original_softap_config = self.dut.droid.wifiGetApConfiguration() + # Make sure DUT is able to enable BridgedAp. + is_supported = wutils.check_available_channels_in_bands_2_5( + self.dut, wutils.WifiEnums.CountryCode.US) + asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" + .format(wutils.WifiEnums.CountryCode.US)) + + # Enable BridgedAp and verify both 2G,5G instances have been enabled. + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.OPEN, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) + infos = self.verify_number_band_freq_of_bridged_ap( + self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False) + + self.sniffing_bridgedap_channels(infos) + + self.two_clients_connect_to_wifi_network(self.client1, self.client2, + self.config) # Trigger client#1 and client#2 ping each other. wutils.validate_ping_between_two_clients(self.client1, self.client2) @@ -325,8 +637,10 @@ class WifiBridgedApTest(WifiBaseTest): Steps: Backup config. DUT enable BridgedAp. + start sniffer and sniffing on AP channels. DUT connect to a 5G DFS channel Wi-Fi network. Verify 5G instance is shutdown. + Stop sniffers. Restore config. """ # Backup config @@ -338,28 +652,19 @@ class WifiBridgedApTest(WifiBaseTest): asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" .format(wutils.WifiEnums.CountryCode.US)) - # Enable BridgedAp - config = wutils.create_softap_config() - config[WifiEnums.SECURITY] = WifiEnums.SoftApSecurityType.WPA3_SAE - wutils.save_wifi_soft_ap_config( - self.dut, config, - bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, - WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) - wutils.start_wifi_tethering_saved_config(self.dut) - # Wait 5 seconds for BridgedAp launch. - self.wait_interval(BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS) + # Enable BridgedAp and verify both 2G,5G instances have been enabled. + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA3_SAE, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) self.verify_number_band_freq_of_bridged_ap( self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False) - # STA connect to a 5G DFS Channel. + self.sniffing_ap_channels(channel1=None, channel2=132) + self.start_ap(channel_2g=None, channel_5g=132) wutils.wifi_toggle_state(self.dut, True) - if "OpenWrtAP" in self.user_params: - self.configure_openwrt_ap_and_start(wpa_network=True, - channel_2g=6, - channel_5g=132) - wutils.connect_to_wifi_network(self.dut, - self.wpa_networks[0][BAND_5G]) + wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0][BAND_5G]) self.verify_number_band_freq_of_bridged_ap( self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G], False) @@ -374,8 +679,10 @@ class WifiBridgedApTest(WifiBaseTest): Steps: Backup config. DUT enable BridgedAp. + start sniffer and sniffing on AP channels. DUT connect to a 5G non-DFS channel Wi-Fi network. Verify STA frequency equals to 5G BridgedAp frequency. + Stop sniffers. Restore config. """ # Backup config @@ -387,25 +694,19 @@ class WifiBridgedApTest(WifiBaseTest): asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" .format(wutils.WifiEnums.CountryCode.US)) - # Enable BridgedAp - config = wutils.create_softap_config() - config[WifiEnums.SECURITY] = WifiEnums.SoftApSecurityType.WPA3_SAE - wutils.save_wifi_soft_ap_config( - self.dut, config, - bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, - WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) - wutils.start_wifi_tethering_saved_config(self.dut) - # Wait 5 seconds for BridgedAp launch. - self.wait_interval(BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS) + # Enable BridgedAp and verify both 2G,5G instances have been enabled. + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA3_SAE, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) + self.verify_number_band_freq_of_bridged_ap( + self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False) - # STA connect to a 5G Non-DFS Channel. + self.sniffing_ap_channels(channel1=None, channel2=36) + self.start_ap(channel_2g=None, channel_5g=36) wutils.wifi_toggle_state(self.dut, True) - if "OpenWrtAP" in self.user_params: - self.configure_openwrt_ap_and_start(wpa_network=True, - channel_2g=6, - channel_5g=36) - wutils.connect_to_wifi_network(self.dut, - self.wpa_networks[0][BAND_5G]) + wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0][BAND_5G]) self.verify_number_band_freq_of_bridged_ap( self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, @@ -421,8 +722,10 @@ class WifiBridgedApTest(WifiBaseTest): Steps: Backup config. DUT enable BridgedAp. + start sniffer and sniffing on AP channels. STA connect to a 2G Wi-Fi network. Verify STA frequency equals to 2G BridgedAp frequency. + Stop sniffers. Restore config. """ # Backup config @@ -434,25 +737,19 @@ class WifiBridgedApTest(WifiBaseTest): asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" .format(wutils.WifiEnums.CountryCode.US)) - # Enable BridgedAp - config = wutils.create_softap_config() - config[WifiEnums.SECURITY] = WifiEnums.SoftApSecurityType.WPA3_SAE - wutils.save_wifi_soft_ap_config( - self.dut, config, - bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, - WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) - wutils.start_wifi_tethering_saved_config(self.dut) - # Wait 5 seconds for BridgedAp launch. - self.wait_interval(BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS) + # Enable BridgedAp and verify both 2G,5G instances have been enabled. + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA3_SAE, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) + self.verify_number_band_freq_of_bridged_ap( + self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False) - # STA connect to a 2G Channel. + self.sniffing_ap_channels(channel1=6, channel2=None) + self.start_ap(channel_2g=6, channel_5g=None) wutils.wifi_toggle_state(self.dut, True) - if "OpenWrtAP" in self.user_params: - self.configure_openwrt_ap_and_start(wpa_network=True, - channel_2g=6, - channel_5g=36) - wutils.connect_to_wifi_network(self.dut, - self.wpa_networks[0][BAND_2G]) + wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0][BAND_2G]) self.verify_number_band_freq_of_bridged_ap( self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, @@ -468,9 +765,12 @@ class WifiBridgedApTest(WifiBaseTest): Steps: Backup config. + start sniffer and sniffing on AP channels. + Enable a Wi-Fi network. DUT connect to a 5G DFS channel Wi-Fi network. DUT enable BridgedAp. Verify 5G instance is shutdown and only 2G instance enabled. + Stop sniffers. Restore config. """ # Backup config @@ -482,26 +782,16 @@ class WifiBridgedApTest(WifiBaseTest): asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" .format(wutils.WifiEnums.CountryCode.US)) - # STA connect to a 5G DFS Channel. + self.sniffing_ap_channels(channel1=None, channel2=132) + self.start_ap(channel_2g=None, channel_5g=132) wutils.wifi_toggle_state(self.dut, True) - if "OpenWrtAP" in self.user_params: - self.configure_openwrt_ap_and_start(wpa_network=True, - channel_2g=6, - channel_5g=132) - wutils.connect_to_wifi_network(self.dut, - self.wpa_networks[0][BAND_5G]) + wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0][BAND_5G]) # Enable BridgedAp - config = wutils.create_softap_config() - config[WifiEnums.SECURITY] = WifiEnums.SoftApSecurityType.WPA3_SAE - wutils.save_wifi_soft_ap_config( - self.dut, config, - bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, - WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) - wutils.start_wifi_tethering_saved_config(self.dut) - # Wait 5 seconds for BridgedAp launch. - self.wait_interval(BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS) - + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA3_SAE, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) # # Verify only 2G instance enabled. self.verify_number_band_freq_of_bridged_ap( self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G], False) @@ -515,9 +805,12 @@ class WifiBridgedApTest(WifiBaseTest): Steps: Backup config. + start sniffer and sniffing on AP channels. + Enable a Wi-Fi network. DUT connect to a 5G non-DFS channel Wi-Fi network. DUT enable BridgedAp. Verify STA frequency equals to 5G BridgedAp frequency. + Stop sniffers. Restore config. """ # Backup config @@ -529,26 +822,16 @@ class WifiBridgedApTest(WifiBaseTest): asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" .format(wutils.WifiEnums.CountryCode.US)) - # STA connect to a 5G non-DFS Channel. + self.sniffing_ap_channels(channel1=None, channel2=36) + self.start_ap(channel_2g=None, channel_5g=36) wutils.wifi_toggle_state(self.dut, True) - if "OpenWrtAP" in self.user_params: - self.configure_openwrt_ap_and_start(wpa_network=True, - channel_2g=6, - channel_5g=36) - wutils.connect_to_wifi_network(self.dut, - self.wpa_networks[0][BAND_5G]) - - # Enable BridgedAp - config = wutils.create_softap_config() - config[WifiEnums.SECURITY] = WifiEnums.SoftApSecurityType.WPA3_SAE - wutils.save_wifi_soft_ap_config( - self.dut, config, - bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, - WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) - wutils.start_wifi_tethering_saved_config(self.dut) - # Wait 5 seconds for BridgedAp launch. - self.wait_interval(BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS) + wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0][BAND_5G]) + # Enable BridgedAp and verify both 2G,5G instances have been enabled. + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA3_SAE, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) # Verify STA frequency equals to 5G BridgedAp frequency. self.verify_number_band_freq_of_bridged_ap( self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, @@ -563,9 +846,12 @@ class WifiBridgedApTest(WifiBaseTest): Steps: Backup config. + start sniffer and sniffing on AP channels. + Enable a Wi-Fi network. DUT connect to a 2G Wi-Fi network. DUT enable BridgedAp. Verify STA frequency equals to 2G BridgedAp frequency. + Stop sniffers. Restore config. """ # Backup config @@ -577,25 +863,16 @@ class WifiBridgedApTest(WifiBaseTest): asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" .format(wutils.WifiEnums.CountryCode.US)) - # STA connect to a 2G Channel. + self.sniffing_ap_channels(channel1=6, channel2=None) + self.start_ap(channel_2g=6, channel_5g=None) wutils.wifi_toggle_state(self.dut, True) - if "OpenWrtAP" in self.user_params: - self.configure_openwrt_ap_and_start(wpa_network=True, - channel_2g=6, - channel_5g=36) - wutils.connect_to_wifi_network(self.dut, - self.wpa_networks[0][BAND_2G]) - # Enable BridgedAp - config = wutils.create_softap_config() - config[WifiEnums.SECURITY] = WifiEnums.SoftApSecurityType.WPA3_SAE - wutils.save_wifi_soft_ap_config( - self.dut, config, - bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, - WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) - wutils.start_wifi_tethering_saved_config(self.dut) - # Wait 5 seconds for BridgedAp launch. - self.wait_interval(BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS) + wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0][BAND_2G]) + # Enable BridgedAp and verify both 2G,5G instances have been enabled. + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA3_SAE, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) self.verify_number_band_freq_of_bridged_ap( self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], True) @@ -627,16 +904,14 @@ class WifiBridgedApTest(WifiBaseTest): asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" .format(wutils.WifiEnums.CountryCode.US)) - # Enable BridgedAp - config = wutils.create_softap_config() - config[WifiEnums.SECURITY] = WifiEnums.SoftApSecurityType.WPA3_SAE - wutils.save_wifi_soft_ap_config( - self.dut, config, - bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, - WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) - wutils.start_wifi_tethering_saved_config(self.dut) - # Wait 5 seconds for BridgedAp launch. - self.wait_interval(BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS) + # Enable BridgedAp and verify both 2G,5G instances have been enabled. + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA3_SAE, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) + infos = self.verify_number_band_freq_of_bridged_ap( + self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False) # No client connection, wait 5 minutes, verify 5G is shutdown. self.verify_expected_number_of_softap_clients(self.dut, 0) @@ -659,6 +934,7 @@ class WifiBridgedApTest(WifiBaseTest): Steps: Backup config. DUT turns ON BridgedAp. + start sniffer and sniffing on BridgedAp channels. Verify no client connect to the BridgedAp. Wait for 5 minutes. Verify that 5G BridgedAp instance is shutdown. @@ -666,6 +942,7 @@ class WifiBridgedApTest(WifiBaseTest): The client disconnect from 2G BridgedAp. Wait for 10 minutes. Verify 2G BridgedAp is shutdown, no BridgedAp instance enabled. + Stop sniffers. Restore config. """ # Backup config @@ -677,19 +954,17 @@ class WifiBridgedApTest(WifiBaseTest): asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" .format(wutils.WifiEnums.CountryCode.US)) - # Enable BridgedAp - config = wutils.create_softap_config() - config[WifiEnums.SECURITY] = WifiEnums.SoftApSecurityType.WPA3_SAE - wutils.save_wifi_soft_ap_config( - self.dut, config, - bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, - WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) - wutils.start_wifi_tethering_saved_config(self.dut) - self.wait_interval(BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS) - self.verify_number_band_freq_of_bridged_ap( + # Enable BridgedAp and verify both 2G,5G instances have been enabled. + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA3_SAE, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) + infos = self.verify_number_band_freq_of_bridged_ap( self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False) + self.sniffing_bridgedap_channels(infos) + # Verify no connection to BridgedAp, wait for 5 mins, 5G shutdown. self.verify_expected_number_of_softap_clients(self.dut, 0) self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES) @@ -701,7 +976,7 @@ class WifiBridgedApTest(WifiBaseTest): infos = wutils.get_current_softap_infos(self.dut, callbackId, True) self.dut.droid.unregisterSoftApCallback(callbackId) bssid_2g = infos[0][wifi_constants.SOFTAP_INFO_BSSID_CALLBACK_KEY] - config_2g = config.copy() + config_2g = self.config.copy() config_2g[WifiEnums.BSSID_KEY] = bssid_2g wutils.connect_to_wifi_network(self.client1, config_2g, check_connectivity=False) @@ -733,6 +1008,7 @@ class WifiBridgedApTest(WifiBaseTest): Steps: Backup config. DUT turns ON BridgedAp. + start sniffer and sniffing on BridgedAp channels. Verify no client connect to the BridgedAp. Wait for 5 minutes. Verify that 5G BridgedAp instance is shutdown. @@ -740,6 +1016,7 @@ class WifiBridgedApTest(WifiBaseTest): The client disconnect from 2G BridgedAp at 9th minutes. Wait for 10 minutes. Verify 2G BridgedAp is shutdown, no BridgedAp instance enabled. + Stop sniffers. Restore config. """ # Backup config @@ -751,21 +1028,19 @@ class WifiBridgedApTest(WifiBaseTest): asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" .format(wutils.WifiEnums.CountryCode.US)) - # Enable BridgedAp - config = wutils.create_softap_config() - config[WifiEnums.SECURITY] = WifiEnums.SoftApSecurityType.WPA3_SAE - wutils.save_wifi_soft_ap_config( - self.dut, config, - bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, - WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G], - bridged_opportunistic_shutdown_enabled=True, - shutdown_timeout_enable=True) - wutils.start_wifi_tethering_saved_config(self.dut) - self.wait_interval(BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS) - - self.verify_number_band_freq_of_bridged_ap( + # Enable BridgedAp and verify both 2G,5G instances have been enabled. + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA3_SAE, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G], + bridged_opportunistic_shutdown_enabled=True, + shutdown_timeout_enable=True) + infos = self.verify_number_band_freq_of_bridged_ap( self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False) + + self.sniffing_bridgedap_channels(infos) + self.verify_expected_number_of_softap_clients(self.dut, 0) self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES) self.verify_number_band_freq_of_bridged_ap( @@ -777,7 +1052,7 @@ class WifiBridgedApTest(WifiBaseTest): infos = wutils.get_current_softap_infos(self.dut, callbackId, True) self.dut.droid.unregisterSoftApCallback(callbackId) bssid_2g = infos[0][wifi_constants.SOFTAP_INFO_BSSID_CALLBACK_KEY] - config_2g = config.copy() + config_2g = self.config.copy() config_2g[WifiEnums.BSSID_KEY] = bssid_2g wutils.connect_to_wifi_network(self.client1, config_2g, check_connectivity=False) @@ -818,18 +1093,243 @@ class WifiBridgedApTest(WifiBaseTest): # Set country code to JP and enable BridgedAp self.set_country_code_and_verify(self.dut, WifiEnums.CountryCode.JAPAN) - config = wutils.create_softap_config() - config[WifiEnums.SECURITY] = WifiEnums.SoftApSecurityType.WPA3_SAE - wutils.save_wifi_soft_ap_config( - self.dut, config, - bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, - WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) - wutils.start_wifi_tethering_saved_config(self.dut) - self.wait_interval(BRIDGED_AP_LAUNCH_INTERVAL_5_SECONDS) + # Enable BridgedAp + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA3_SAE, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) # Verify only 2G BridgedAp instance enabled. + infos = self.verify_number_band_freq_of_bridged_ap( + self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G], False) + self.sniffing_bridgedap_channels(infos) + + # Restore config + wutils.save_wifi_soft_ap_config(self.dut, original_softap_config) + + @test_tracker_info(uuid="b5c7c6df-b181-4bba-a7b3-48fad0d7fa98") + def test_bridged_ap_5g_2g_shutdown_2g_after_5_minutes(self): + """Test the BridgeAp shutdown mechanism. + + Steps: + Backup config. + DUT turns ON BridgedAp. + start sniffer and sniffing on BridgedAp channels. + A Client connect to BridgeAp 5G instance. + Wait for 5 minutes. + Verify 2G instance is shutdown and only 5G instance exists. + Stop sniffers. + Restore config.""" + # Backup config + original_softap_config = self.dut.droid.wifiGetApConfiguration() + + # Make sure DUT is able to enable BridgedAp. + is_supported = wutils.check_available_channels_in_bands_2_5( + self.dut, wutils.WifiEnums.CountryCode.US) + asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" + .format(wutils.WifiEnums.CountryCode.US)) + + # Enable BridgedAp and verify both 2G,5G instances have been enabled. + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA3_SAE, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) + infos = self.verify_number_band_freq_of_bridged_ap( + self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False) + + self.sniffing_bridgedap_channels(infos) + + # Client connects to the 5G BridgedAp instance. + self.client_connects_to_a_bridgeap(self.client1, BAND_5G) + self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES) + # Verify there is only one client connects to the BridgedAp. + self.verify_expected_number_of_softap_clients(self.dut, 1) + # Verify the BridgedAp instance is 5G. + self.verify_number_band_freq_of_bridged_ap( + self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False) + # Restore config + wutils.save_wifi_soft_ap_config(self.dut, original_softap_config) + + @test_tracker_info(uuid="683b2c7f-7f24-4324-be09-0b6554d5d7a8") + def test_bridged_ap_5g_2g_shutdown_5g_after_5_minutes(self): + """Test the BridgeAp shutdown mechanism. + + Steps: + Backup config. + DUT turns ON BridgedAp. + start sniffer and sniffing on BridgedAp channels. + A Client connect to BridgeAp 2G instance. + Wait for 5 minutes. + Verify 5G instance is shutdown and only 2G instance exists. + Stop sniffers. + Restore config.""" + # Backup config + original_softap_config = self.dut.droid.wifiGetApConfiguration() + + # Make sure DUT is able to enable BridgedAp. + is_supported = wutils.check_available_channels_in_bands_2_5( + self.dut, wutils.WifiEnums.CountryCode.US) + asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" + .format(wutils.WifiEnums.CountryCode.US)) + + # Enable BridgedAp and verify both 2G,5G instances have been enabled. + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA3_SAE, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) + infos = self.verify_number_band_freq_of_bridged_ap( + self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False) + self.sniffing_bridgedap_channels(infos) + + # Client connects to the 2G BridgedAp instance. + self.client_connects_to_a_bridgeap(self.client1, BAND_2G) + self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES) + # Verify there is only one client connects to the BridgedAp. + self.verify_expected_number_of_softap_clients(self.dut, 1) + # Verify the BridgedAp instance is 2G. self.verify_number_band_freq_of_bridged_ap( self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G], False) + # Restore config + wutils.save_wifi_soft_ap_config(self.dut, original_softap_config) + + @test_tracker_info(uuid="6de46e5b-04c3-4fba-a21d-e914a3e34e24") + def test_bridged_ap_5g_2g_no_shutdown_after_5_minutes(self): + """Test clients on different instances can ping each other. + + Steps: + Backup config. + Make sure clients support WPA3 SAE. + Make sure DUT is able to enable BridgedAp. + Enable BridgedAp with bridged configuration. + RegisterSoftApCallback. + Check the bridged AP enabled succeed. + start sniffer and sniffing on BridgedAp channels. + Client#1 connect to 5G instance. + Client#2 connect to 2G instance. + Wait for 5 minutes. + Verify both 2G/5G BridgedAp instances are exist. + Stop sniffers. + Restore config. + """ + # Backup config + original_softap_config = self.dut.droid.wifiGetApConfiguration() + # Make sure clients support WPA3 SAE. + self.verify_clients_support_wpa3_sae(self.client1, self.client2) + # Make sure DUT is able to enable BridgedAp. + is_supported = wutils.check_available_channels_in_bands_2_5( + self.dut, wutils.WifiEnums.CountryCode.US) + asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" + .format(wutils.WifiEnums.CountryCode.US)) + + # Enable BridgedAp and verify both 2G,5G instances have been enabled. + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA3_SAE, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G]) + infos = self.verify_number_band_freq_of_bridged_ap( + self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False) + self.sniffing_bridgedap_channels(infos) + + self.two_clients_connect_to_wifi_network(self.client1, self.client2, + self.config) + self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES) + # Verify there are two clients connect to the BridgedAp. + self.verify_expected_number_of_softap_clients(self.dut, 2) + # Verify both 2G/5G BridgedAp instances are exist. + self.verify_number_band_freq_of_bridged_ap( + self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False) + # Restore config + wutils.save_wifi_soft_ap_config(self.dut, original_softap_config) + + @test_tracker_info(uuid="f8742dfb-5232-4fe8-b568-3a99a9356d59") + def test_bridged_ap_5g_2g_extend_compatibility_on_no_shutdown_5g(self): + """Test BridgedAp mechanism when "Extend compatibility is ON. + + Steps: + Backup config. + Make sure clients support WPA3 SAE. + Make sure DUT is able to enable BridgedAp. + Enable BridgedAp with Extend compatibility is ON. + RegisterSoftApCallback. + Check the bridged AP enabled succeed. + start sniffer and sniffing on BridgedAp channels. + Client#1 connect to 2G. + Verify both 2G/5G instances are exist. + Stop sniffers. + Restore config. + """ + # Backup config + original_softap_config = self.dut.droid.wifiGetApConfiguration() + # Make sure clients support WPA3 SAE. + self.verify_clients_support_wpa3_sae(self.client1, self.client2) + # Make sure DUT is able to enable BridgedAp. + is_supported = wutils.check_available_channels_in_bands_2_5( + self.dut, wutils.WifiEnums.CountryCode.US) + asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" + .format(wutils.WifiEnums.CountryCode.US)) + # Enable BridgedAp with "Extend compatibility set to ON". + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA3_SAE, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G], + bridged_opportunistic_shutdown_enabled=False) + # Client connects to the 2G BridgedAp instance and wait 5 minutes. + self.client_connects_to_a_bridgeap(self.client1, BAND_2G) + self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES) + # Verify there are two clients connect to the BridgedAp. + self.verify_expected_number_of_softap_clients(self.dut, 2) + # Verify both 2G/5G BridgedAp instances exist. + self.verify_number_band_freq_of_bridged_ap( + self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False) + # Restore config + wutils.save_wifi_soft_ap_config(self.dut, original_softap_config) + + @test_tracker_info(uuid="050f8dd8-ed38-4f7a-87a9-9dbdade58cc7") + def test_bridged_ap_5g_2g_extend_compatibility_on_no_shutdown_2g(self): + """Test BridgedAp mechanism when "Extend compatibility is ON. + + Steps: + Backup config. + Make sure clients support WPA3 SAE. + Make sure DUT is able to enable BridgedAp. + Enable BridgedAp with Extend compatibility is ON. + RegisterSoftApCallback. + Check the bridged AP enabled succeed. + start sniffer and sniffing on BridgedAp channels. + Client#1 connect to 5G. + Verify both 2G/5G instances are exist. + Stop sniffers. + Restore config. + """ + # Backup config + original_softap_config = self.dut.droid.wifiGetApConfiguration() + # Make sure clients support WPA3 SAE. + self.verify_clients_support_wpa3_sae(self.client1, self.client2) + # Make sure DUT is able to enable BridgedAp. + is_supported = wutils.check_available_channels_in_bands_2_5( + self.dut, wutils.WifiEnums.CountryCode.US) + asserts.skip_if(not is_supported, "BridgedAp is not supported in {}" + .format(wutils.WifiEnums.CountryCode.US)) + # Enable BridgedAp with "Extend compatibility set to ON". + self.enable_bridged_ap(self.dut, + WifiEnums.SoftApSecurityType.WPA3_SAE, + bands=[WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G_5G], + bridged_opportunistic_shutdown_enabled=False) + # Client connects to the 5G BridgedAp instance and wait 5 minutes. + self.client_connects_to_a_bridgeap(self.client1, BAND_5G) + self.wait_interval(BRIDGED_AP_SHUTDOWN_INTERVAL_5_MINUTES) + # Verify there are two clients connect to the BridgedAp. + self.verify_expected_number_of_softap_clients(self.dut, 2) + # Verify both 2G/5G BridgedAp instances exist. + self.verify_number_band_freq_of_bridged_ap( + self.dut, [WifiEnums.WIFI_CONFIG_SOFTAP_BAND_2G, + WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G], False) # Restore config wutils.save_wifi_soft_ap_config(self.dut, original_softap_config) diff --git a/acts_tests/tests/google/wifi/WifiEnterpriseRoamingTest.py b/acts_tests/tests/google/wifi/WifiEnterpriseRoamingTest.py index 6eea51295..daf9b1a9e 100644 --- a/acts_tests/tests/google/wifi/WifiEnterpriseRoamingTest.py +++ b/acts_tests/tests/google/wifi/WifiEnterpriseRoamingTest.py @@ -103,6 +103,14 @@ class WifiEnterpriseRoamingTest(WifiBaseTest): Ent.EAP: int(EAP.SIM), WifiEnums.SSID_KEY: self.ent_roaming_ssid, } + self.config_aka = { + Ent.EAP: int(EAP.AKA), + WifiEnums.SSID_KEY: self.ent_roaming_ssid, + } + self.config_aka_prime = { + Ent.EAP: int(EAP.AKA_PRIME), + WifiEnums.SSID_KEY: self.ent_roaming_ssid, + } self.attn_a = self.attenuators[0] self.attn_b = self.attenuators[2] if "OpenWrtAP" in self.user_params: @@ -236,4 +244,16 @@ class WifiEnterpriseRoamingTest(WifiBaseTest): config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.GTC.value self.roaming_between_a_and_b_logic(config) - """ Tests End """ + @test_tracker_info(uuid="e014fc94-a547-4aa7-953e-cff3bfe3f20c") + def test_roaming_with_config_sim(self): + self.roaming_between_a_and_b_logic(self.config_sim) + + @test_tracker_info(uuid="2e45a59e-ec22-4bf4-811f-1a3a4b9bb330") + def test_roaming_with_config_aka(self): + self.roaming_between_a_and_b_logic(self.config_aka) + + @test_tracker_info(uuid="63ebfdf5-e765-47ff-9754-f60e3f6e7409") + def test_roaming_with_config_aka_prime(self): + self.roaming_between_a_and_b_logic(self.config_aka_prime) + + """ Tests End """
\ No newline at end of file diff --git a/acts_tests/tests/google/wifi/WifiPasspointTest.py b/acts_tests/tests/google/wifi/WifiPasspointTest.py index 494919505..3c78e0623 100755 --- a/acts_tests/tests/google/wifi/WifiPasspointTest.py +++ b/acts_tests/tests/google/wifi/WifiPasspointTest.py @@ -367,7 +367,9 @@ class WifiPasspointTest(WifiBaseTest): current_ssid = current_passpoint[WifiEnums.SSID_KEY] if current_ssid not in passpoint_ssid: raise signals.TestFailure("Device did not connect to any of the " - "configured Passpoint networks.") + "configured Passpoint networks." + "current: {}, expected: {}" + .format(current_ssid, passpoint_ssid)) expected_ssid = self.passpoint_networks[0][WifiEnums.SSID_KEY] if current_ssid in expected_ssid: diff --git a/acts_tests/tests/google/wifi/WifiRoamingTest.py b/acts_tests/tests/google/wifi/WifiRoamingTest.py index c70e56f01..2af178b01 100644 --- a/acts_tests/tests/google/wifi/WifiRoamingTest.py +++ b/acts_tests/tests/google/wifi/WifiRoamingTest.py @@ -23,6 +23,7 @@ from acts_contrib.test_utils.net import connectivity_const as cconsts from acts_contrib.test_utils.wifi import wifi_test_utils as wutils from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest from acts_contrib.test_utils.wifi.aware import aware_test_utils as autils +from acts.controllers.openwrt_lib.openwrt_constants import OpenWrtWifiSetting import os WifiEnums = wutils.WifiEnums @@ -427,3 +428,777 @@ class WifiRoamingTest(WifiBaseTest): self.log.info("Roaming failed to AP2 with incorrect BSSID") wutils.wait_for_disconnect(self.dut) self.log.info("Device is disconnect") + + @test_tracker_info(uuid="641b35c1-7bf8-4d85-a813-1bc30d7bd0d4") + def test_roaming_between_psk_2g_to_psk_5g(self): + """Verify psk when after roaming from 2.4 Ghz to 5 Ghz with OpenWrtAP + + Steps: + 1. Configure 2 APs + 2. Configure AP2 5Ghz and AP1 2.4Ghz WiFi to same SSID and password + 3. Connect DUT to AP1 2.4Ghz WiFi + 4. Roam to AP2 5Ghz WiFi + 5. Verify the DUT can connect from 2.4Ghz to 5Ghz + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(wpa_network=True, + ap_count=2) + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + ap1_network = self.reference_networks[0]["2g"] + ap2_network = self.reference_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["2g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + # Change 2 APs to same password and SSID + self.openwrt1.set_ssid(ssid_2g="testSSID") + self.openwrt2.set_ssid(ssid_5g="testSSID") + self.openwrt2.set_password(pwd_5g=ap1_network["password"]) + ap1_network["SSID"] = "testSSID" + ap2_network["SSID"] = "testSSID" + ap2_network["password"] = ap1_network["password"] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="fa1fe3bb-abb9-4d75-88bd-cd88c04073c6") + def test_roaming_between_psk_withoutPMF_5g(self): + """Verify psk without PMF when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs without PMF + 2. Connect DUT to AP1 + 3. Roam to AP2 + 4. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(wpa_network=True, + ap_count=2, + mirror_ap=True, + ieee80211w=0) + ap1_network = self.reference_networks[0]["5g"] + ap2_network = self.reference_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="496e048a-3da5-45c4-aa0f-c5bd127eb06f") + def test_roaming_between_psk_withPMF_5g(self): + """Verify psk with PMF when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs with PMF + 2. Connect DUT to AP1 + 3. Roam to AP2 + 4. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(wpa_network=True, + ap_count=2, + mirror_ap=True, + ieee80211w=2) + ap1_network = self.reference_networks[0]["5g"] + ap2_network = self.reference_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="524c97c5-4bca-46b0-97f9-aad749768cd8") + def test_roaming_between_psk_wPMF_to_psk_woPMF_5g(self): + """Verify psk with/without PMF when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs without PMF + 2. Configure AP1 with PMF + 3. Connect DUT to AP1 + 4. Roam to AP2 + 5. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(wpa_network=True, + ap_count=2, + mirror_ap=True, + ieee80211w=0) + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + ap1_network = self.reference_networks[0]["5g"] + ap2_network = self.reference_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + # Configure AP1 to enable PMF. + self.configure_openwrt_ap_and_start(wpa_network=True, + ieee80211w=2) + ap1_network = self.reference_networks[0]["5g"] + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + + # Change AP2 password and SSID same as AP1. + self.openwrt2.set_password(pwd_5g=ap1_network["password"]) + self.openwrt2.set_ssid(ssid_5g=ap1_network["SSID"]) + ap2_network["SSID"] = ap1_network["SSID"] + ap2_network["password"] = ap1_network["password"] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="714ceac1-d8af-4679-9385-2c9c6d885634") + def test_roaming_between_psk_woPMF_to_psk_wPMF_5g(self): + """Verify psk without/with PMF when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs with PMF + 2. Configure AP1 without PMF + 3. Connect DUT to AP1 + 4. Roam to AP2 + 5. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(wpa_network=True, + ap_count=2, + mirror_ap=True, + ieee80211w=2) + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + ap1_network = self.reference_networks[0]["5g"] + ap2_network = self.reference_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + # Configure AP1 to disable PMF. + self.configure_openwrt_ap_and_start(wpa_network=True, + ieee80211w=0) + ap1_network = self.reference_networks[0]["5g"] + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + + # Change AP2 password and SSID same as AP1. + self.openwrt2.set_password(pwd_5g=ap1_network["password"]) + self.openwrt2.set_ssid(ssid_5g=ap1_network["SSID"]) + ap2_network["SSID"] = ap1_network["SSID"] + ap2_network["password"] = ap1_network["password"] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="4b201d7b-38ec-49c2-95c3-81cba51ba11d") + def test_roaming_between_psk_capablePMF_5g(self): + """Verify psk capable PMF when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs with capable PMF + 2. Connect DUT to AP1 + 3. Roam to AP2 + 4. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(wpa_network=True, + ap_count=2, + mirror_ap=True, + ieee80211w=1) + ap1_network = self.reference_networks[0]["5g"] + ap2_network = self.reference_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="588a9279-1f84-44d2-acbb-051c5ba0bcb1") + def test_roaming_between_psk_capPMF_to_psk_woPMF_5g(self): + """Verify psk capable/without PMF when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs without PMF + 2. Configure AP1 with capable PMF + 3. Connect DUT to AP1 + 4. Roam to AP2 + 5. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(wpa_network=True, + ap_count=2, + mirror_ap=True, + ieee80211w=0) + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + ap1_network = self.reference_networks[0]["5g"] + ap2_network = self.reference_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + # Configure AP1 to enable capable PMF. + self.configure_openwrt_ap_and_start(wpa_network=True, + ieee80211w=1) + ap1_network = self.reference_networks[0]["5g"] + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + + # Change AP2 password and SSID same as AP1. + self.openwrt2.set_password(pwd_5g=ap1_network["password"]) + self.openwrt2.set_ssid(ssid_5g=ap1_network["SSID"]) + ap2_network["SSID"] = ap1_network["SSID"] + ap2_network["password"] = ap1_network["password"] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="d239b56d-515c-4589-b63a-ebce62c321af") + def test_roaming_between_psk_capPMF_to_psk_wPMF_5g(self): + """Verify psk capable/with PMF when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs with PMF + 2. Configure AP1 with capable PMF + 3. Connect DUT to AP1 + 4. Roam to AP2 + 5. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(wpa_network=True, + ap_count=2, + mirror_ap=True, + ieee80211w=2) + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + ap1_network = self.reference_networks[0]["5g"] + ap2_network = self.reference_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + # Configure AP1 to enable capable PMF. + self.configure_openwrt_ap_and_start(wpa_network=True, + ieee80211w=1) + ap1_network = self.reference_networks[0]["5g"] + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + + # Change AP2 password and SSID same as AP1. + self.openwrt2.set_password(pwd_5g=ap1_network["password"]) + self.openwrt2.set_ssid(ssid_5g=ap1_network["SSID"]) + ap2_network["SSID"] = ap1_network["SSID"] + ap2_network["password"] = ap1_network["password"] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="57ec9401-b336-40cb-bc46-c2b4cfc22516") + def test_roaming_between_psk_wPMF_to_psk_capPMF_5g(self): + """Verify psk with/capable PMF when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs with capable PMF + 2. Configure AP1 with PMF + 3. Connect DUT to AP1 + 4. Roam to AP2 + 5. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(wpa_network=True, + ap_count=2, + mirror_ap=True, + ieee80211w=1) + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + ap1_network = self.reference_networks[0]["5g"] + ap2_network = self.reference_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + # Configure AP1 to enable PMF. + self.configure_openwrt_ap_and_start(wpa_network=True, + ieee80211w=2) + ap1_network = self.reference_networks[0]["5g"] + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + + # Change AP2 password and SSID same as AP1. + self.openwrt2.set_password(pwd_5g=ap1_network["password"]) + self.openwrt2.set_ssid(ssid_5g=ap1_network["SSID"]) + ap2_network["SSID"] = ap1_network["SSID"] + ap2_network["password"] = ap1_network["password"] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="a32d24f0-36cc-41f0-90b4-db74973db29f") + def test_roaming_between_psk_woPMF_to_psk_capPMF_5g(self): + """Verify psk without/capable PMF when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs with capable PMF + 2. Configure AP1 without PMF + 3. Connect DUT to AP1 + 4. Roam to AP2 + 5. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(wpa_network=True, + ap_count=2, + mirror_ap=True, + ieee80211w=1) + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + ap1_network = self.reference_networks[0]["5g"] + ap2_network = self.reference_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + # Configure AP1 to disable PMF. + self.configure_openwrt_ap_and_start(wpa_network=True, + ieee80211w=0) + ap1_network = self.reference_networks[0]["5g"] + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + + # Change AP2 password and SSID same as AP1. + self.openwrt2.set_password(pwd_5g=ap1_network["password"]) + self.openwrt2.set_ssid(ssid_5g=ap1_network["SSID"]) + ap2_network["SSID"] = ap1_network["SSID"] + ap2_network["password"] = ap1_network["password"] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="44f45dc9-e85c-419d-bbab-d02e9548a377") + def test_roaming_between_psk_to_saemixed_woPMF_5g(self): + """Verify psk to saemixed without PMF when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs security type to saemixed without PMF + 2. Configure AP1 security type to psk + 3. Connect DUT to AP1 + 4. Roam to AP2 + 5. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(saemixed_network=True, + ap_count=2, + mirror_ap=True, + ieee80211w=0) + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + ap1_network = self.saemixed_networks[0]["5g"] + ap2_network = self.saemixed_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + # Configure AP1 security type. + self.configure_openwrt_ap_and_start(wpa_network=True) + ap1_network = self.reference_networks[0]["5g"] + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + + # Change AP2 password and SSID same as AP1. + self.openwrt2.set_password(pwd_5g=ap1_network["password"]) + self.openwrt2.set_ssid(ssid_5g=ap1_network["SSID"]) + ap2_network["SSID"] = ap1_network["SSID"] + ap2_network["password"] = ap1_network["password"] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="9827f3b3-51cd-406b-ba2b-3ef4a9df7378") + def test_roaming_between_psk_to_saemixed_wPMF_5g(self): + """Verify psk to saemixed with PMF when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs security type to saemixed with PMF + 2. Configure AP1 security type to psk + 3. Connect DUT to AP1 + 4. Roam to AP2 + 5. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(saemixed_network=True, + ap_count=2, + mirror_ap=True, + ieee80211w=2) + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + ap1_network = self.saemixed_networks[0]["5g"] + ap2_network = self.saemixed_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + # Configure AP1 security type. + self.configure_openwrt_ap_and_start(wpa_network=True) + ap1_network = self.reference_networks[0]["5g"] + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + + # Change AP2 password and SSID same as AP1. + self.openwrt2.set_password(pwd_5g=ap1_network["password"]) + self.openwrt2.set_ssid(ssid_5g=ap1_network["SSID"]) + ap2_network["SSID"] = ap1_network["SSID"] + ap2_network["password"] = ap1_network["password"] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="037602b1-2ce8-4dbb-b46a-00e0a582d976") + def test_roaming_between_saemixed_withoutPMF_5g(self): + """Verify saemixed without PMF when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs to saemixed without PMF + 2. Connect DUT to AP1 + 3. Roam to AP2 + 4. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(saemixed_network=True, + ap_count=2, + mirror_ap=True, + ieee80211w=0) + ap1_network = self.saemixed_networks[0]["5g"] + ap2_network = self.saemixed_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="94514f72-9e90-4d73-bba5-65b95e721cd8") + def test_roaming_between_saemixed_withPMF_5g(self): + """Verify saemixed with PMF when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs to saemixed with PMF + 2. Connect DUT to AP1 + 3. Roam to AP2 + 4. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(saemixed_network=True, + ap_count=2, + mirror_ap=True, + ieee80211w=2) + ap1_network = self.saemixed_networks[0]["5g"] + ap2_network = self.saemixed_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="05834382-5c3f-48d9-a6e6-8794ebf176f8") + def test_roaming_between_saemixed_woPMF_to_saemixed_wPMF_5g(self): + """Verify saemixed without/with PMF when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs to saemixed with PMF + 2. Configure AP1 to saemixed without PMF + 3. Connect DUT to AP1 + 4. Roam to AP2 + 5. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(saemixed_network=True, + ap_count=2, + mirror_ap=True, + ieee80211w=2) + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + ap1_network = self.saemixed_networks[0]["5g"] + ap2_network = self.saemixed_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + # Configure AP1 to disable PMF. + self.configure_openwrt_ap_and_start(saemixed_network=True, + ieee80211w=0) + ap1_network = self.saemixed_networks[0]["5g"] + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + + # Change AP2 password and SSID same as AP1. + self.openwrt2.set_password(pwd_5g=ap1_network["password"]) + self.openwrt2.set_ssid(ssid_5g=ap1_network["SSID"]) + ap2_network["SSID"] = ap1_network["SSID"] + ap2_network["password"] = ap1_network["password"] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="4d7cba89-40f1-4a2a-891d-4bb757f73442") + def test_roaming_between_saemixed_wPMF_to_saemixed_woPMF_5g(self): + """Verify saemixed with/without PMF when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs to saemixed without PMF + 2. Configure AP1 to saemixed with PMF + 3. Connect DUT to AP1 + 4. Roam to AP2 + 5. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(saemixed_network=True, + ap_count=2, + mirror_ap=True, + ieee80211w=0) + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + ap1_network = self.saemixed_networks[0]["5g"] + ap2_network = self.saemixed_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + # Configure AP1 to enable PMF. + self.configure_openwrt_ap_and_start(saemixed_network=True, + ieee80211w=2) + ap1_network = self.saemixed_networks[0]["5g"] + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + + # Change AP2 password and SSID same as AP1. + self.openwrt2.set_password(pwd_5g=ap1_network["password"]) + self.openwrt2.set_ssid(ssid_5g=ap1_network["SSID"]) + ap2_network["SSID"] = ap1_network["SSID"] + ap2_network["password"] = ap1_network["password"] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="57caaf0a-5251-4191-b4d1-de31d7c12295") + def test_roaming_between_sae_to_saemixed_woPMF_5g(self): + """Verify sae to saemixed without PMF when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs security type to saemixed without PMF + 2. Configure AP1 security type to sae + 3. Connect DUT to AP1 + 4. Roam to AP2 + 5. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(saemixed_network=True, + ap_count=2, + mirror_ap=True, + ieee80211w=0) + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + ap1_network = self.saemixed_networks[0]["5g"] + ap2_network = self.saemixed_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + # Configure AP1 security type. + self.configure_openwrt_ap_and_start(sae_network=True) + ap1_network = self.sae_networks[0]["5g"] + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + + # Change AP2 password and SSID same as AP1. + self.openwrt2.set_password(pwd_5g=ap1_network["password"]) + self.openwrt2.set_ssid(ssid_5g=ap1_network["SSID"]) + ap2_network["SSID"] = ap1_network["SSID"] + ap2_network["password"] = ap1_network["password"] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="0f5ca9d9-ef40-4a95-bf55-4c78358a9a3e") + def test_roaming_between_sae_to_saemixed_wPMF_5g(self): + """Verify sae to saemixed with PMF when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs security type to saemixed with PMF + 2. Configure AP1 security type to sae + 3. Connect DUT to AP1 + 4. Roam to AP2 + 5. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(saemixed_network=True, + ap_count=2, + mirror_ap=True, + ieee80211w=2) + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + ap1_network = self.saemixed_networks[0]["5g"] + ap2_network = self.saemixed_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + # Configure AP1 security type. + self.configure_openwrt_ap_and_start(sae_network=True) + ap1_network = self.sae_networks[0]["5g"] + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + + # Change AP2 password and SSID same as AP1. + self.openwrt2.set_password(pwd_5g=ap1_network["password"]) + self.openwrt2.set_ssid(ssid_5g=ap1_network["SSID"]) + ap2_network["SSID"] = ap1_network["SSID"] + ap2_network["password"] = ap1_network["password"] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="e875233f-d242-4ddd-b357-8e3e215af050") + def test_roaming_fail_between_psk_to_sae_5g(self): + """Verify fail with diff security type after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs security type to sae + 2. Configure AP1 security type to psk + 3. Connect DUT to AP1 + 4. Roam to AP2 + 5. Verify the DUT can't connect to AP2 after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(sae_network=True, + ap_count=2, + mirror_ap=True) + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + ap1_network = self.sae_networks[0]["5g"] + ap2_network = self.sae_networks[1]["5g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + # Configure AP1 security type. + self.configure_openwrt_ap_and_start(wpa_network=True) + ap1_network = self.reference_networks[0]["5g"] + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + + # Change AP2 password and SSID same as AP1. + self.openwrt2.set_password(pwd_5g=ap1_network["password"]) + self.openwrt2.set_ssid(ssid_5g=ap1_network["SSID"]) + ap2_network["SSID"] = ap1_network["SSID"] + ap2_network["password"] = ap1_network["password"] + + try: + # DUT roaming from AP1 to AP2 with diff security type. + self.dut.log.info("Roaming via WPA2 AP1 to SAE AP2 [{}]" + .format(ap2_network["bssid"])) + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + except: + self.dut.log.info("Failed roaming to AP2 with diff security type") + else: + raise signals.TestFailure("DUT unexpectedly connect to Wi-Fi.") + + @test_tracker_info(uuid="76098016-56a4-4b92-8c13-7333a21c9a1b") + def test_roaming_between_psk_to_saemixed_2g(self): + """Verify psk to saemixed with 11n when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs security type to saemixed with 11n mode + 2. Configure AP1 security type to psk with 11n mode + 3. Connect DUT to AP1 + 4. Roam to AP2 + 5. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(saemixed_network=True, + ap_count=2, + mirror_ap=True) + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + ap1_network = self.saemixed_networks[0]["2g"] + ap2_network = self.saemixed_networks[1]["2g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["2g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["2g"][ap2_network["SSID"]] + + # Configure AP1 security type. + self.configure_openwrt_ap_and_start(wpa_network=True) + ap1_network = self.reference_networks[0]["2g"] + ap1_network["bssid"] = self.bssid_map[0]["2g"][ap1_network["SSID"]] + + # Change AP2 password and SSID same as AP1. + self.openwrt2.set_password(pwd_2g=ap1_network["password"]) + self.openwrt2.set_ssid(ssid_2g=ap1_network["SSID"]) + ap2_network["SSID"] = ap1_network["SSID"] + ap2_network["password"] = ap1_network["password"] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="2caf668d-6b05-4ba5-ac6b-1ec989fdf9ff") + def test_roaming_between_psk1_to_saemixed_2g(self): + """Verify psk1 to saemixed with 11n when after roaming with OpenWrtAP + + Steps: + 1. Configure 2 APs security type to saemixed with 11n mode + 2. Configure AP1 security type to psk1 with 11n mode + 3. Connect DUT to AP1 + 4. Roam to AP2 + 5. Verify the DUT can connect after roaming + """ + # Use OpenWrt as Wi-Fi AP when it's available in testbed. + asserts.skip_if("OpenWrtAP" not in self.user_params, "OpenWrtAP not in user_params") + self.configure_openwrt_ap_and_start(saemixed_network=True, + ap_count=2, + mirror_ap=True) + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + ap1_network = self.saemixed_networks[0]["2g"] + ap2_network = self.saemixed_networks[1]["2g"] + # Get & Setup APs' BSSIDs. + ap1_network["bssid"] = self.bssid_map[0]["2g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["2g"][ap2_network["SSID"]] + + # Configure AP1 security type. + self.configure_openwrt_ap_and_start(wpa1_network=True) + ap1_network = self.wpa1_networks[0]["2g"] + ap1_network["bssid"] = self.bssid_map[0]["2g"][ap1_network["SSID"]] + + # Change AP2 password and SSID same as AP1. + self.openwrt2.set_password(pwd_2g=ap1_network["password"]) + self.openwrt2.set_ssid(ssid_2g=ap1_network["SSID"]) + ap2_network["SSID"] = ap1_network["SSID"] + ap2_network["password"] = ap1_network["password"] + + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="cc8781ec-12fb-47a4-86d4-80d13231c75d") + def test_connect_to_wpa2_psk_2g_80211r(self): + """Test WPA2-PSK 802.11r 2G connectivity ant roaming.""" + if "OpenWrtAP" in self.user_params: + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + self.configure_openwrt_ap_and_start(wpa_network=True, + ap_count=2, + mirror_ap=True) + ap1_network = self.reference_networks[0]["2g"] + ap2_network = self.reference_networks[1]["2g"] + ap1_network["bssid"] = self.bssid_map[0]["2g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["2g"][ap2_network["SSID"]] + + md = self.openwrt1.generate_mobility_domain() + self.openwrt1.enable_80211r(OpenWrtWifiSetting.IFACE_2G, md) + self.openwrt2.enable_80211r(OpenWrtWifiSetting.IFACE_2G, md) + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) + + @test_tracker_info(uuid="8b0ee65e-bba2-4786-a8b9-8990316d123d") + def test_connect_to_wpa2_psk_5g_80211r(self): + """Test WPA2-PSK 802.11r 5G connectivity and roaming.""" + if "OpenWrtAP" in self.user_params: + self.openwrt1 = self.access_points[0] + self.openwrt2 = self.access_points[1] + self.configure_openwrt_ap_and_start(wpa_network=True, + ap_count=2, + mirror_ap=True) + ap1_network = self.reference_networks[0]["5g"] + ap2_network = self.reference_networks[1]["5g"] + ap1_network["bssid"] = self.bssid_map[0]["5g"][ap1_network["SSID"]] + ap2_network["bssid"] = self.bssid_map[1]["5g"][ap2_network["SSID"]] + + md = self.openwrt1.generate_mobility_domain() + self.openwrt1.enable_80211r(OpenWrtWifiSetting.IFACE_5G, md) + self.openwrt2.enable_80211r(OpenWrtWifiSetting.IFACE_5G, md) + self.roaming_from_AP1_and_AP2(ap1_network, ap2_network) diff --git a/acts_tests/tests/google/wifi/WifiSoftApAcsTest.py b/acts_tests/tests/google/wifi/WifiSoftApAcsTest.py index 974a784f0..da7877d8f 100644 --- a/acts_tests/tests/google/wifi/WifiSoftApAcsTest.py +++ b/acts_tests/tests/google/wifi/WifiSoftApAcsTest.py @@ -150,6 +150,8 @@ class WifiSoftApAcsTest(WifiBaseTest): self.log.debug("DUT is connected to softAP %s with details: %s" % (softap[wutils.WifiEnums.SSID_KEY], softap_info)) frequency = softap_info['frequency'] + self.dut.log.info("DUT SoftAp operates on Channel: {}". + format(WifiEnums.freq_to_channel[frequency])) if frequency > 0: break time.sleep(1) # frequency not updated yet, try again after a delay @@ -194,6 +196,10 @@ class WifiSoftApAcsTest(WifiBaseTest): return channel # Connect to the AP and start IPerf traffic, while we bring up softap. wutils.connect_to_wifi_network(self.dut_client, network) + freq = self.dut_client.droid.wifiGetConnectionInfo()["frequency"] + ap_chan = wutils.WifiEnums.freq_to_channel[freq] + self.dut_client.log.info("{} operates on channel: {}" + .format(network["SSID"], ap_chan)) wutils.verify_11ax_wifi_connection( self.dut_client, self.wifi6_models, "wifi6_ap" in self.user_params) t = Thread(target=self.run_iperf_client,args=((network,self.dut_client),)) diff --git a/acts_tests/tests/google/wifi/WifiTeleCoexTest.py b/acts_tests/tests/google/wifi/WifiTeleCoexTest.py index 6619ba478..7260919fb 100644 --- a/acts_tests/tests/google/wifi/WifiTeleCoexTest.py +++ b/acts_tests/tests/google/wifi/WifiTeleCoexTest.py @@ -6,6 +6,7 @@ import time import acts.base_test import acts_contrib.test_utils.wifi.wifi_test_utils as wifi_utils import acts_contrib.test_utils.tel.tel_test_utils as tele_utils +import acts_contrib.test_utils.tel.tel_mms_utils as mms_utils import acts.utils from acts import asserts @@ -28,6 +29,7 @@ ATTENUATORS = "attenuators" WIFI_SSID = "wifi_network_ssid" WIFI_PWD = "wifi_network_pass" STRESS_COUNT = "stress_iteration" +DEFAULT_TIMEOUT = 10 class WifiTeleCoexTest(TelephonyBaseTest): """Tests for WiFi, Celular Co-existance.""" @@ -57,6 +59,7 @@ class WifiTeleCoexTest(TelephonyBaseTest): for ad in self.android_devices: ad.droid.wakeLockAcquireBright() ad.droid.wakeUpNow() + ad.droid.telephonyToggleDataConnection(True) wifi_utils.wifi_toggle_state(self.dut, True) @@ -64,8 +67,9 @@ class WifiTeleCoexTest(TelephonyBaseTest): """ End test make sure the DUT return idle""" for ad in self.android_devices: wifi_utils.reset_wifi(ad) + ad.droid.telephonyToggleDataConnection(False) tele_utils.ensure_phones_idle(self.log, self.android_devices) - + nutil.stop_usb_tethering(self.dut) """Helper Functions""" @@ -453,4 +457,121 @@ class WifiTeleCoexTest(TelephonyBaseTest): self.connect_to_wifi(self.dut, self.network) except: raise signals.TestFailure("The Wifi connect failed after modem restart." - "WiFi State = %d" %self.dut.droid.wifiCheckState())
\ No newline at end of file + "WiFi State = %d" %self.dut.droid.wifiCheckState()) + + @test_tracker_info(uuid="a72ff9da-3855-4c21-b447-b80f43227961") + @TelephonyBaseTest.tel_test_wrap + def test_internet_accessing_over_wifi_and_mms_test(self): + + """Verify when MMS is working WLAN connection can work normally as well. + + Raises: + signals.TestFailure: Internet_connection is stop + + Steps: + 1. Connect to WiFi + 2. Prepare two DUT for testing (DUT1 and DUT2) + 3. Send 5 MMS from DUT1 to DUT2 + + Verification: + The internet cannot be impacted by MMS delivery. + MMS can be sent / received successfully and content is correct. + """ + self.dut1 = self.android_devices[0] + self.dut2 = self.android_devices[1] + self.connect_to_wifi(self.dut1, self.network) + wifi_utils.wifi_toggle_state(self.dut2, True) + self.connect_to_wifi(self.dut2, self.network) + mms = 5 + for count in range(mms): + mms_utils._mms_test(self.log, self.ads) + if not tele_utils.verify_internet_connection( + self.dut2.log, self.dut2): + raise signals.TestFailure("The internet connection is stop." + "Current WiFi state is %d" + % self.dut2.droid.wifiCheckState()) + time.sleep(30) + + @test_tracker_info(uuid="a7d774e4-ead3-465c-b4a6-f39a6397dfe3") + @TelephonyBaseTest.tel_test_wrap + def test_internet_accessing_wifi_and_data_test(self): + + """Verify interwork between Wi-Fi and data. + + Raises: + signals.TestFailure: Internet_connection is stop for WiFi off or + Data off + + Steps: + 1. Connect to WiFi + 2. To Wi-Fi and data switched for 5 times, + 3. DUT is kept awake during testing. + Verification: + The internet cannot be impacted after data path switched + + """ + self.dut = self.android_devices[0] + self.connect_to_wifi(self.dut, self.network) + data_count = 5 + for count in range(data_count): + wifi_utils.wifi_toggle_state(self.dut, False) + time.sleep(60) + if not tele_utils.verify_internet_connection( + self.dut.log, self.dut): + raise signals.TestFailure( + "The internet connection is stop" + "for WiFi off. Current WiFi state is %d" + % self.dut.droid.wifiCheckState()) + wifi_utils.wifi_toggle_state(self.dut, True) + time.sleep(DEFAULT_TIMEOUT) + self.dut.log.info("DUT data is disable") + self.dut.droid.telephonyToggleDataConnection(False) + time.sleep(30) + if not tele_utils.verify_internet_connection( + self.dut.log, self.dut): + raise signals.TestFailure( + "The internet connection is stop" + "for Data off. Current WiFi state is %d" + % self.dut.droid.wifiCheckState()) + self.dut.log.info("DUT data is enable") + self.dut.droid.telephonyToggleDataConnection(True) + time.sleep(DEFAULT_TIMEOUT) + + @test_tracker_info(uuid="e53adef6-d537-4098-a354-1e63457ab444") + @TelephonyBaseTest.tel_test_wrap + def test_internet_accessing_wifi_and_usb_tethering(self): + + """Verify interwork between Wi-Fi and USB_TETHERED. + + Raises: + signals.TestFailure: Internet_connection is stop for enable or + disable USB tethering + + Steps: + 1.Connect to WiFi + 2. enable/disable USB tethering for 5 cycles, + + Verification: + The Internet cannot be impacted after enable/disable USB tethering + + """ + self.dut = self.android_devices[0] + nutil.verify_lte_data_and_tethering_supported(self.dut) + self.connect_to_wifi(self.dut, self.network) + usb_count = 5 + for count in range(usb_count): + time.sleep(DEFAULT_TIMEOUT) + nutil.start_usb_tethering(self.dut) + time.sleep(DEFAULT_TIMEOUT) + if not tele_utils.verify_internet_connection( + self.dut.log, self.dut): + raise signals.TestFailure("The internet connection is stop" + "for tethering enable. Current WiFi state is %d" + % self.dut.droid.wifiCheckState()) + nutil.stop_usb_tethering(self.dut) + time.sleep(DEFAULT_TIMEOUT) + if not tele_utils.verify_internet_connection( + self.dut.log, self.dut): + raise signals.TestFailure("The internet connection is stop" + "for tethering disable. Current WiFi state is %d" + % self.dut.droid.wifiCheckState()) diff --git a/acts_tests/tests/google/wifi/WifiWpa2PersonalTest.py b/acts_tests/tests/google/wifi/WifiWpa2PersonalTest.py index 71c8a1871..65b8235ce 100644 --- a/acts_tests/tests/google/wifi/WifiWpa2PersonalTest.py +++ b/acts_tests/tests/google/wifi/WifiWpa2PersonalTest.py @@ -14,13 +14,15 @@ # See the License for the specific language governing permissions and # limitations under the License. - +import time 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 import hostapd_constants from acts.controllers.openwrt_lib.openwrt_constants import OpenWrtWifiSecurity from acts.test_decorators import test_tracker_info from acts import asserts +from acts import utils +from acts import signals WifiEnums = wutils.WifiEnums @@ -40,8 +42,9 @@ class WifiWpa2PersonalTest(WifiBaseTest): def setup_class(self): super().setup_class() self.dut = self.android_devices[0] + req_params = ["roaming_attn"] opt_params = ["pixel_models", "cnss_diag_file"] - self.unpack_userparams(opt_params) + self.unpack_userparams(req_params, opt_params) def setup_test(self): super().setup_test() @@ -175,3 +178,159 @@ class WifiWpa2PersonalTest(WifiBaseTest): wutils.connect_to_wifi_network(self.dut, self.wpa2_psk_5g) self.verify_wpa_network_encryption( OpenWrtWifiSecurity.WPA2_PSK_TKIP_AND_CCMP) + + @test_tracker_info(uuid="4e8286a0-1b7c-4186-9d86-1cc5cd7a6be2") + def test_connect_to_wpa2_psk_ccmp_2g_after_airplane_mode(self): + """Test Wi-Fi reconnection after enabling Airplane Mode. + + Steps: + DUT connect to 2GHz Wi-Fi network. + DUT turns ON Airplane Mode. + DUT turns ON Wi-Fi. + DUT verify internet connection with HTTP ping. + DUT turns OFF Airplane Mode. + DUT verify internet connection with HTTP ping. + """ + self.start_openwrt() + self.openwrt.log.info("Enable WPA2-PSK CCMP on OpenWrt AP") + self.openwrt.set_wpa_encryption(OpenWrtWifiSecurity.WPA2_PSK_CCMP) + wutils.connect_to_wifi_network(self.dut, self.wpa2_psk_2g) + self.verify_wpa_network_encryption(OpenWrtWifiSecurity.WPA2_PSK_CCMP) + # Turn ON DUT's Airplane Mode. + self.dut.log.info("Toggle Airplane Mode ON") + utils.force_airplane_mode(self.dut, True) + self.dut.log.info("Toggle Wi-Fi ON") + # Turn ON DUT's Wi-Fi + wutils.wifi_toggle_state(self.dut, True) + wutils.wait_for_connect(self.dut, + self.wpa2_psk_2g[WifiEnums.SSID_KEY]) + wutils.validate_connection(self.dut) + utils.force_airplane_mode(self.dut, False) + wutils.validate_connection(self.dut) + + @test_tracker_info(uuid="091c9b6a-d729-41d0-85e7-acf777aa3d1f") + def test_connect_to_wpa2_psk_ccmp_2g_after_wifi_off(self): + """Test Wi-Fi reconnection after Turn OFF Wi-Fi. + + Steps: + DUT connect to 2GHz Wi-Fi network. + DUT turns OFF Wi-Fi. + DUT turns ON Wi-Fi. + DUT verify internet connection with HTTP ping. + """ + self.start_openwrt() + self.openwrt.log.info("Enable WPA2-PSK CCMP on OpenWrt AP") + self.openwrt.set_wpa_encryption(OpenWrtWifiSecurity.WPA2_PSK_CCMP) + wutils.connect_to_wifi_network(self.dut, self.wpa2_psk_2g) + self.verify_wpa_network_encryption(OpenWrtWifiSecurity.WPA2_PSK_CCMP) + self.dut.log.info("Toggle Wi-Fi OFF") + # Turn OFF DUT's Wi-Fi then Turn if ON. + wutils.wifi_toggle_state(self.dut, False) + wutils.wifi_toggle_state(self.dut, True) + wutils.wait_for_connect(self.dut, + self.wpa2_psk_2g[WifiEnums.SSID_KEY]) + wutils.validate_connection(self.dut) + + @test_tracker_info(uuid="9eb74878-1527-4c5b-980e-1a9305f601aa") + def test_connect_to_wpa2_psk_ccmp_2g_after_suspend_resume(self): + """Test Wi-Fi reconnection after Suspend. + + Steps: + DUT connect to 2GHz Wi-Fi network. + DUT suspend and resume. + DUT verify internet connection with HTTP ping. + """ + self.start_openwrt() + self.openwrt.log.info("Enable WPA2-PSK CCMP on OpenWrt AP") + self.openwrt.set_wpa_encryption(OpenWrtWifiSecurity.WPA2_PSK_CCMP) + wutils.connect_to_wifi_network(self.dut, self.wpa2_psk_2g) + self.verify_wpa_network_encryption(OpenWrtWifiSecurity.WPA2_PSK_CCMP) + self.dut.log.info("Suspend the DUT and wait for 10 seconds") + # Suspend and Resume the DUT. + self.dut.go_to_sleep() + time.sleep(10) + self.dut.log.info("Resume the DUT") + self.dut.wakeup_screen() + wutils.validate_connection(self.dut) + + @test_tracker_info(uuid="44e5d946-620a-4e30-9578-f921460fe3f3") + def test_connect_to_wpa2_psk_ccmp_2g_after_reboot(self): + """Test Wi-Fi reconnection after reboot. + + Steps: + DUT connect to 2GHz Wi-Fi network. + DUT reboot. + DUT verify internet connection with HTTP ping. + """ + self.start_openwrt() + self.openwrt.log.info("Enable WPA2-PSK CCMP on OpenWrt AP") + self.openwrt.set_wpa_encryption(OpenWrtWifiSecurity.WPA2_PSK_CCMP) + wutils.connect_to_wifi_network(self.dut, self.wpa2_psk_2g) + self.verify_wpa_network_encryption(OpenWrtWifiSecurity.WPA2_PSK_CCMP) + # Reboot the DUT. + self.dut.log.info("Reboot the DUT") + self.dut.reboot() + self.dut.wait_for_boot_completion() + wutils.wait_for_connect(self.dut, + self.wpa2_psk_2g[WifiEnums.SSID_KEY]) + wutils.validate_connection(self.dut) + + @test_tracker_info(uuid="7cb462c8-0a6e-4f33-b2fc-bf630d57e087") + def test_connect_to_wpa2_psk_ccmp_2g_after_incorrect_password(self): + """Test Wi-Fi reconnection after incorrect password. + + Steps: + DUT connect to 2GHz Wi-Fi network. + DUT try to connect to the Wi-Fi network with incorrect password. + Connection fail as expected. + DUT connect to the Wi-Fi network with correct password. + DUT verify internet connection with HTTP ping. + """ + self.start_openwrt() + self.openwrt.log.info("Enable WPA2-PSK CCMP on OpenWrt AP") + self.openwrt.set_wpa_encryption(OpenWrtWifiSecurity.WPA2_PSK_CCMP) + self.wpa2_psk_2g_fail = self.wpa2_psk_2g.copy() + self.wpa2_psk_2g_fail["password"] = "incorrect_password" + # Try to connect a Wi-Fi network with incorrect password. + try: + self.dut.log.info("Connect to Wi-Fi with wrong password") + wutils.wifi_connect(self.dut, self.wpa2_psk_2g_fail, num_of_tries=1) + except: + self.dut.log.info("Connect to Wi-Fi with correct password") + wutils.wifi_connect(self.dut, self.wpa2_psk_2g) + else: + raise signals.TestFailure("DUT connect to Wi-Fi with wrong password") + self.verify_wpa_network_encryption(OpenWrtWifiSecurity.WPA2_PSK_CCMP) + wutils.validate_connection(self.dut) + + @test_tracker_info(uuid="890712de-2a3e-4b24-8529-e93893c8d99c") + def test_connect_to_wpa2_psk_ccmp_2g_after_out_of_range(self): + """Test Wi-Fi reconnection after out of range. + + Steps: + DUT connect to 2GHz Wi-Fi network. + DUT out of Wi-Fi range. + Make Wi-Fi network is not visible by DUT. + DUT back in Wi-Fi range. + Wi-Fi network is visible by DUT. + DUT connect to the Wi-Fi network. + DUT verify internet connection with HTTP ping. + """ + self.start_openwrt() + self.openwrt.log.info("Enable WPA2-PSK CCMP on OpenWrt AP") + self.openwrt.set_wpa_encryption(OpenWrtWifiSecurity.WPA2_PSK_CCMP) + wutils.connect_to_wifi_network(self.dut, self.wpa2_psk_2g) + # Make the DUT out of range. + wutils.set_attns(self.attenuators, + "atten1_off_atten2_off", + self.roaming_attn) + wutils.start_wifi_connection_scan_and_ensure_network_not_found( + self.dut, + self.wpa2_psk_2g[WifiEnums.SSID_KEY]) + # Make the DUT back in range. + wutils.set_attns(self.attenuators, + "atten1_on_atten2_on", + self.roaming_attn) + wutils.start_wifi_connection_scan_and_ensure_network_found( + self.dut, self.wpa2_psk_2g[WifiEnums.SSID_KEY]) + wutils.connect_to_wifi_network(self.dut, self.wpa2_psk_2g) |