1 # Copyright (c) 2015 The Chromium OS Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 from autotest_lib.client.common_lib import error 6 from autotest_lib.client.common_lib import utils 7 from autotest_lib.client.common_lib.cros.network import iw_runner 8 from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes 9 from autotest_lib.server.cros.network import hostap_config 10 from autotest_lib.server.cros.network import wifi_cell_test_base 11 12 class network_WiFi_RoamDbus(wifi_cell_test_base.WiFiCellTestBase): 13 """Tests an intentional client-driven roam between APs 14 15 This test seeks to associate the DUT with an AP with a set of 16 association parameters, create a second AP with a second set of 17 parameters but the same SSID, and send roam command to shill. After 18 that shill will send a dbus roam command to wpa_supplicant. We seek 19 to observe that the DUT successfully connects to the second AP in 20 a reasonable amount of time. 21 """ 22 23 version = 1 24 TIMEOUT_SECONDS = 15 25 26 def dut_sees_bss(self, bssid): 27 """ 28 Check if a DUT can see a BSS in scan results. 29 30 @param bssid: string bssid of AP we expect to see in scan results. 31 @return True iff scan results from DUT include the specified BSS. 32 33 """ 34 runner = iw_runner.IwRunner(remote_host=self.context.client.host) 35 is_requested_bss = lambda iw_bss: iw_bss.bss == bssid 36 scan_results = runner.scan(self.context.client.wifi_if) 37 return scan_results and filter(is_requested_bss, scan_results) 38 39 def run_once(self,host): 40 """Test body.""" 41 self._router0_conf = hostap_config.HostapConfig(channel=48, 42 mode=hostap_config.HostapConfig.MODE_11A) 43 self._router1_conf = hostap_config.HostapConfig(channel=1) 44 self._client_conf = xmlrpc_datatypes.AssociationParameters() 45 46 # Configure the inital AP. 47 self.context.configure(self._router0_conf) 48 router_ssid = self.context.router.get_ssid() 49 50 # Connect to the inital AP. 51 self._client_conf.ssid = router_ssid 52 self.context.assert_connect_wifi(self._client_conf) 53 54 # Setup a second AP with the same SSID. 55 self._router1_conf.ssid = router_ssid 56 self.context.configure(self._router1_conf, multi_interface=True) 57 58 # Get BSSIDs of the two APs 59 bssid0 = self.context.router.get_hostapd_mac(0) 60 bssid1 = self.context.router.get_hostapd_mac(1) 61 62 # Wait for DUT to see the second AP 63 utils.poll_for_condition( 64 condition=lambda: self.dut_sees_bss(bssid1), 65 exception=error.TestFail( 66 'Timed out waiting for DUT to see second AP'), 67 timeout=self.TIMEOUT_SECONDS, 68 sleep_interval=1) 69 70 # Check which AP we are currently connected. 71 # This is to include the case that wpa_supplicant 72 # automatically roam to AP2 during the scan. 73 interface = self.context.client.wifi_if 74 current_bssid = self.context.client.iw_runner.get_current_bssid(interface) 75 if current_bssid == bssid0: 76 roam_to_bssid = bssid1 77 else: 78 roam_to_bssid = bssid0 79 # Send roam command to shill, 80 # and shill will send dbus roam command to wpa_supplicant 81 self.context.client.request_roam_dbus(roam_to_bssid, interface) 82 83 # Expect that the DUT will re-connect to the new AP. 84 if not self.context.client.wait_for_roam( 85 roam_to_bssid, timeout_seconds=self.TIMEOUT_SECONDS): 86 raise error.TestFail('Failed to roam.') 87 self.context.router.deconfig() 88