1 # Copyright (c) 2013 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.cros.network import iw_runner 7 from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes 8 from autotest_lib.server.cros.network import hostap_config 9 from autotest_lib.server.cros.network import wifi_cell_test_base 10 11 class network_WiFi_SSIDSwitchBack(wifi_cell_test_base.WiFiCellTestBase): 12 """Tests roaming to a previous AP when current AP disappears.""" 13 14 version = 1 15 16 FREQUENCY_1 = 2412 17 FREQUENCY_2 = 2437 18 BSSID_1 = "00:01:02:03:04:05" 19 BSSID_2 = "06:07:08:09:0a:0b" 20 SSID_1 = "InsideADogItsTooDarkToRead" 21 SSID_2 = "HeReallyIsAnIdiot" 22 CONNECTED_STATE = 'ready', 'portal', 'online' 23 24 25 def configure_connect_verify_deconfig_wait(self, ssid, freq, mode, bssid): 26 """Configure an AP, connect to it, then tear it all down, again. 27 28 This method does the following: configures the AP, connects to it and 29 verifies the connection, deconfigures the AP and waits for the 30 disconnect to complete. 31 32 @param ssid string SSID for the new connection. 33 @param freq int Frequency which the AP is to support. 34 @param mode string AP mode from hostap_config.HostapConfig.MODE_*. 35 @param bssid string BSSID for the new connection. 36 37 """ 38 # Change channels on the AP. This happens in full view of the DUT 39 # and the AP deauths everyone as it exits. 40 ap_config = hostap_config.HostapConfig(ssid=ssid, frequency=freq, 41 mode=mode, bssid=bssid) 42 self.context.configure(ap_config) 43 assoc_params = xmlrpc_datatypes.AssociationParameters( 44 ssid=self.context.router.get_ssid()) 45 self.context.assert_connect_wifi(assoc_params) 46 47 self.context.assert_ping_from_dut() # Verify that we're connected. 48 self.context.client.check_iw_link_value( 49 iw_runner.IW_LINK_KEY_FREQUENCY, 50 freq) # Verify that the client switched to new frequency 51 52 # Deconfig and wait for the DUT to disconnect and end up at 'idle'. 53 self.context.router.deconfig() 54 self.context.client.wait_for_service_states( 55 network_WiFi_SSIDSwitchBack.SSID_1, ['idle'], 30) 56 57 58 def run_once(self): 59 """Test body.""" 60 # Connect to the first AP. This just guarantees that this AP has 61 # been placed in the connection manager profile. Then deconfig. 62 self.configure_connect_verify_deconfig_wait( 63 network_WiFi_SSIDSwitchBack.SSID_1, 64 network_WiFi_SSIDSwitchBack.FREQUENCY_1, 65 hostap_config.HostapConfig.MODE_11B, 66 network_WiFi_SSIDSwitchBack.BSSID_1) 67 68 # Configure and connect to the second AP. Then deconfig. 69 self.configure_connect_verify_deconfig_wait( 70 network_WiFi_SSIDSwitchBack.SSID_2, 71 network_WiFi_SSIDSwitchBack.FREQUENCY_2, 72 hostap_config.HostapConfig.MODE_11G, 73 network_WiFi_SSIDSwitchBack.BSSID_2) 74 75 # Bring the first AP back up. 76 ap_config = hostap_config.HostapConfig( 77 ssid=network_WiFi_SSIDSwitchBack.SSID_1, 78 frequency=network_WiFi_SSIDSwitchBack.FREQUENCY_1, 79 mode=hostap_config.HostapConfig.MODE_11B, 80 bssid=network_WiFi_SSIDSwitchBack.BSSID_1) 81 self.context.configure(ap_config) 82 83 # Instead of explicitly connecting, just wait to see if the DUT 84 # re-connects by itself 85 success, state, elapsed_seconds = \ 86 self.context.client.wait_for_service_states( 87 network_WiFi_SSIDSwitchBack.SSID_1, 88 network_WiFi_SSIDSwitchBack.CONNECTED_STATE, 30) 89 if (not success or 90 state not in network_WiFi_SSIDSwitchBack.CONNECTED_STATE): 91 raise error.TestFail( 92 'Failed to connect to "%s" in %f seconds (state=%s)' % 93 (network_WiFi_SSIDSwitchBack.SSID_1, elapsed_seconds, 94 state)) 95 96 # Verify that we're connected. 97 self.context.assert_ping_from_dut() 98 99 # Verify that the client switched to the original frequency 100 self.context.client.check_iw_link_value( 101 iw_runner.IW_LINK_KEY_FREQUENCY, 102 network_WiFi_SSIDSwitchBack.FREQUENCY_1) 103 self.context.router.deconfig() 104