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 success, state, elapsed_seconds = \ 55 self.context.client.wait_for_service_states( 56 network_WiFi_SSIDSwitchBack.SSID_1, ['idle'], 30) 57 58 59 def run_once(self): 60 """Test body.""" 61 # Connect to the first AP. This just guarantees that this AP has 62 # been placed in the connection manager profile. Then deconfig. 63 self.configure_connect_verify_deconfig_wait( 64 network_WiFi_SSIDSwitchBack.SSID_1, 65 network_WiFi_SSIDSwitchBack.FREQUENCY_1, 66 hostap_config.HostapConfig.MODE_11B, 67 network_WiFi_SSIDSwitchBack.BSSID_1) 68 69 # Configure and connect to the second AP. Then deconfig. 70 self.configure_connect_verify_deconfig_wait( 71 network_WiFi_SSIDSwitchBack.SSID_2, 72 network_WiFi_SSIDSwitchBack.FREQUENCY_2, 73 hostap_config.HostapConfig.MODE_11G, 74 network_WiFi_SSIDSwitchBack.BSSID_2) 75 76 # Bring the first AP back up. 77 ap_config = hostap_config.HostapConfig( 78 ssid=network_WiFi_SSIDSwitchBack.SSID_1, 79 frequency=network_WiFi_SSIDSwitchBack.FREQUENCY_1, 80 mode=hostap_config.HostapConfig.MODE_11B, 81 bssid=network_WiFi_SSIDSwitchBack.BSSID_1) 82 self.context.configure(ap_config) 83 84 # Instead of explicitly connecting, just wait to see if the DUT 85 # re-connects by itself 86 success, state, elapsed_seconds = \ 87 self.context.client.wait_for_service_states( 88 network_WiFi_SSIDSwitchBack.SSID_1, 89 network_WiFi_SSIDSwitchBack.CONNECTED_STATE, 30) 90 if (not success or 91 state not in network_WiFi_SSIDSwitchBack.CONNECTED_STATE): 92 raise error.TestFail( 93 'Failed to connect to "%s" in %f seconds (state=%s)' % 94 (network_WiFi_SSIDSwitchBack.SSID_1, elapsed_seconds, 95 state)) 96 97 # Verify that we're connected. 98 self.context.assert_ping_from_dut() 99 100 # Verify that the client switched to the original frequency 101 self.context.client.check_iw_link_value( 102 iw_runner.IW_LINK_KEY_FREQUENCY, 103 network_WiFi_SSIDSwitchBack.FREQUENCY_1) 104 self.context.router.deconfig() 105