blob: bd10a8b9a78611c0fd058db136d9f8960aa5bc65 [file] [log] [blame]
#!/usr/bin/env python3.4
#
# Copyright 2018 - 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 itertools
import pprint
import queue
import time
import acts.base_test
import acts.signals as signals
from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G
import acts.test_utils.wifi.wifi_test_utils as wutils
import acts.utils as utils
from acts import asserts
from acts.test_decorators import test_tracker_info
from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest
WifiEnums = wutils.WifiEnums
# Default timeout used for reboot, toggle WiFi and Airplane mode,
# for the system to settle down after the operation.
DEFAULT_TIMEOUT = 10
GET_MAC_ADDRESS= ("ip addr show wlan0"
"| grep 'link/ether'"
"| cut -d ' ' -f6")
MAC_SETTING = "wifi_connected_mac_randomization_enabled"
GET_MAC_RANDOMIZATION_STATUS = "settings get global {}".format(MAC_SETTING)
TURN_ON_MAC_RANDOMIZATION = "settings put global {} 1".format(MAC_SETTING)
TURN_OFF_MAC_RANDOMIZATION = "settings put global {} 0".format(MAC_SETTING)
LOG_CLEAR = "logcat -c"
LOG_GREP = "logcat -d | grep {}"
class WifiConnectedMacRandomizationTest(WifiBaseTest):
"""Tests for Connected MAC Randomization.
Test Bed Requirement:
* Two Android devices with the first one supporting MAC randomization.
* At least two Wi-Fi networks to connect to.
"""
def setup_class(self):
super().setup_class()
self.dut = self.android_devices[0]
self.dut_softap = self.android_devices[1]
wutils.wifi_test_device_init(self.dut)
wutils.wifi_test_device_init(self.dut_softap)
self.reset_mac_address_to_factory_mac()
self.dut.adb.shell(TURN_ON_MAC_RANDOMIZATION)
asserts.assert_equal(
self.dut.adb.shell(GET_MAC_RANDOMIZATION_STATUS), "1",
"Failed to enable Connected MAC Randomization on dut.")
req_params = ["reference_networks"]
opt_param = []
self.unpack_userparams(
req_param_names=req_params, opt_param_names=opt_param)
if "AccessPoint" in self.user_params:
self.legacy_configure_ap_and_start()
asserts.assert_true(
self.reference_networks[0]["2g"],
"Need at least 1 2.4Ghz reference network with psk.")
asserts.assert_true(
self.reference_networks[0]["5g"],
"Need at least 1 5Ghz reference network with psk.")
self.wpapsk_2g = self.reference_networks[0]["2g"]
self.wpapsk_5g = self.reference_networks[0]["5g"]
def setup_test(self):
self.dut.droid.wakeLockAcquireBright()
self.dut.droid.wakeUpNow()
wutils.wifi_toggle_state(self.dut, True)
wutils.wifi_toggle_state(self.dut_softap, False)
def teardown_test(self):
self.dut.droid.wakeLockRelease()
self.dut.droid.goToSleepNow()
wutils.reset_wifi(self.dut)
wutils.reset_wifi(self.dut_softap)
def on_fail(self, test_name, begin_time):
self.dut.take_bug_report(test_name, begin_time)
self.dut.cat_adb_log(test_name, begin_time)
def teardown_class(self):
wutils.stop_wifi_tethering(self.dut_softap)
self.reset_mac_address_to_factory_mac()
if "AccessPoint" in self.user_params:
del self.user_params["reference_networks"]
del self.user_params["open_network"]
"""Helper Functions"""
def get_current_mac_address(self, ad):
"""Get the device's wlan0 MAC address.
Args:
ad: AndroidDevice to get MAC address of.
Returns:
A MAC address string in the format of "12:34:56:78:90:12".
"""
return ad.adb.shell(GET_MAC_ADDRESS)
def is_valid_randomized_mac_address(self, mac):
"""Check if the given MAC address is a valid randomized MAC address.
Args:
mac: MAC address to check in the format of "12:34:56:78:90:12".
"""
asserts.assert_true(
mac != self.dut_factory_mac,
"Randomized MAC address is same as factory MAC address.")
first_byte = int(mac[:2], 16)
asserts.assert_equal(first_byte & 1, 0, "MAC address is not unicast.")
asserts.assert_equal(first_byte & 2, 2, "MAC address is not local.")
def reset_mac_address_to_factory_mac(self):
"""Reset dut to and store factory MAC address by turning off
Connected MAC Randomization and rebooting dut.
"""
self.dut.adb.shell(TURN_OFF_MAC_RANDOMIZATION)
asserts.assert_equal(
self.dut.adb.shell(GET_MAC_RANDOMIZATION_STATUS), "0",
"Failed to disable Connected MAC Randomization on dut.")
self.dut.reboot()
time.sleep(DEFAULT_TIMEOUT)
self.dut_factory_mac = self.get_current_mac_address(self.dut)
def get_connection_data(self, ad, network):
"""Connect and get network id and ssid info from connection data.
Args:
ad: AndroidDevice to use for connection
network: network info of the network to connect to
Returns:
A convenience dict with the connected network's ID and SSID.
"""
wutils.connect_to_wifi_network(ad, network)
connect_data = ad.droid.wifiGetConnectionInfo()
ssid_id_dict = dict()
ssid_id_dict[WifiEnums.NETID_KEY] = connect_data[WifiEnums.NETID_KEY]
ssid_id_dict[WifiEnums.SSID_KEY] = connect_data[WifiEnums.SSID_KEY]
return ssid_id_dict
"""Tests"""
@test_tracker_info(uuid="")
def test_wifi_connection_2G_with_mac_randomization(self):
"""Tests connection to 2G network with Connected MAC Randomization.
"""
wutils.connect_to_wifi_network(self.dut, self.wpapsk_2g)
mac = self.get_current_mac_address(self.dut)
self.is_valid_randomized_mac_address(mac)
@test_tracker_info(uuid="")
def test_wifi_connection_5G_with_mac_randomization(self):
"""Tests connection to 5G network with Connected MAC Randomization.
"""
wutils.connect_to_wifi_network(self.dut, self.wpapsk_5g)
mac = self.get_current_mac_address(self.dut)
self.is_valid_randomized_mac_address(mac)
@test_tracker_info(uuid="")
def test_randomized_mac_persistent_between_connections(self):
"""Tests that randomized MAC address assigned to each network is
persistent between connections.
Steps:
1. Connect to a 2GHz network.
2. Connect to a 5GHz network.
3. Reconnect to the 2GHz network using its network id.
4. Verify that MAC addresses in Steps 1 and 3 are equal.
5. Reconnect to the 5GHz network using its network id.
6. Verify that MAC addresses in Steps 2 and 5 are equal.
"""
connect_data_2g = self.get_connection_data(self.dut, self.wpapsk_2g)
old_mac_2g = self.get_current_mac_address(self.dut)
self.is_valid_randomized_mac_address(old_mac_2g)
connect_data_5g = self.get_connection_data(self.dut, self.wpapsk_5g)
old_mac_5g = self.get_current_mac_address(self.dut)
self.is_valid_randomized_mac_address(old_mac_5g)
asserts.assert_true(
old_mac_2g != old_mac_5g,
"Randomized MAC addresses for 2G and 5G networks are equal.")
reconnect_2g = wutils.connect_to_wifi_network_with_id(
self.dut,
connect_data_2g[WifiEnums.NETID_KEY],
connect_data_2g[WifiEnums.SSID_KEY])
if not reconnect_2g:
raise signals.TestFailure("Device did not connect to the correct"
" 2GHz network.")
new_mac_2g = self.get_current_mac_address(self.dut)
asserts.assert_equal(
old_mac_2g,
new_mac_2g,
"Randomized MAC for 2G is not persistent between connections.")
reconnect_5g = wutils.connect_to_wifi_network_with_id(
self.dut,
connect_data_5g[WifiEnums.NETID_KEY],
connect_data_5g[WifiEnums.SSID_KEY])
if not reconnect_5g:
raise signals.TestFailure("Device did not connect to the correct"
" 5GHz network.")
new_mac_5g = self.get_current_mac_address(self.dut)
asserts.assert_equal(
old_mac_5g,
new_mac_5g,
"Randomized MAC for 5G is not persistent between connections.")
@test_tracker_info(uuid="")
def test_randomized_mac_used_during_connection(self):
"""Verify that the randomized MAC address and not the factory
MAC address is used during connection by checking the softap logs.
Steps:
1. Set up softAP on dut_softap.
2. Have dut connect to the softAp.
3. Verify that only randomized MAC appears in softAp logs.
"""
self.dut_softap.adb.shell(LOG_CLEAR)
config = wutils.create_softap_config()
wutils.start_wifi_tethering(self.dut_softap,
config[wutils.WifiEnums.SSID_KEY],
config[wutils.WifiEnums.PWD_KEY],
WIFI_CONFIG_APBAND_2G)
# Internet validation fails when dut_softap does not have a valid sim
# supporting softap. Since this test is not checking for internet
# validation, we suppress failure signals.
wutils.connect_to_wifi_network(self.dut, config, assert_on_fail=False)
mac = self.get_current_mac_address(self.dut)
wutils.stop_wifi_tethering(self.dut_softap)
self.is_valid_randomized_mac_address(mac)
log = self.dut_softap.adb.shell(LOG_GREP.format(mac))
asserts.assert_true(len(log) > 0, "Randomized MAC not in log.")
log = self.dut_softap.adb.shell(LOG_GREP.format(self.dut_factory_mac))
asserts.assert_true(len(log) == 0, "Factory MAC is in log.")