blob: a49c8688fb6c14b823c2b8ac800bfd3320243d38 [file] [log] [blame]
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
from autotest_lib.server.cros.network import hostap_config
from autotest_lib.server.cros.network import wifi_cell_test_base
class network_WiFi_BSSTMReq(wifi_cell_test_base.WiFiCellTestBase):
"""Tests a BSS Transition Management Request sent from the AP
This test seeks to associate the DUT with an AP with a set of
association parameters, create a second AP with a second set of
parameters but the same SSID, and send a BSS Transition Management Request
to the client. After that, the client will send a BSS Transition Management
Response back to the first AP. We seek to observe that the DUT successfully
connects to the second AP in a reasonable amount of time.
"""
version = 1
TIMEOUT_SECONDS = 15
def _run_test(self, wait_for_scan=True):
"""Send BSS TM Requests and verify the behaviour.
Setup an AP and make the DUT connect to that AP. Setup a second AP with
the same SSID. Then send a BSS TM Request from the first AP to the
second AP and verify that the DUT connects to te second AP.
Args:
wait_for_scan: when True, trigger a scan on the DUT and ensure that
it has seen AP#2 before AP#1 sends a BSS TM Request.
"""
router0_conf = hostap_config.HostapConfig(channel=1)
router1_conf = hostap_config.HostapConfig(channel=48,
mode=hostap_config.HostapConfig.MODE_11A)
client_conf = xmlrpc_datatypes.AssociationParameters()
# Capture the detection and connection to the second AP.
self.context.capture_host.start_capture(router1_conf.frequency)
# Configure the initial AP.
self.context.configure(router0_conf)
router_ssid = self.context.router.get_ssid()
# Connect to the initial AP.
client_conf.ssid = router_ssid
self.context.assert_connect_wifi(client_conf)
# Setup a second AP with the same SSID.
router1_conf.ssid = router_ssid
self.context.configure(router1_conf, multi_interface=True)
# BSSID of the second AP. The DUT will have to roam to that second AP.
bssid_roam = self.context.router.get_hostapd_mac(1)
# Flush all scanned BSS from supplicant. Otherwise the DUT may have
# noticed them in a scan before, which would change the behaviour of the
# test.
self.context.client.flush_bss(age=0)
if wait_for_scan:
# Wait for DUT to see the second AP.
logging.info('Scanning to find BSS "%s"', bssid_roam)
self.context.client.wait_for_bss(bssid_roam)
# Send BSS Transition Management Request to client.
reply = self.context.router.send_bss_tm_req(
self.context.client.wifi_mac,
[bssid_roam])
if reply == 'OK':
pass
elif reply.startswith('Unknown command'):
raise error.TestNAError('AP does not support BSS Transition '
'Management')
else:
raise error.TestFail('Failed to send BSS TM Request: %s' % reply)
# Expect that the DUT will re-connect to the new AP.
# In some cases, the DUT may have roamed to the second AP on its own,
# without waiting for the BSS TM Request. In those particular runs, the
# test would not test the BSS TM feature, but the result would be
# identical. And in most runs the roam will be caused by the BSS TM
# Request anyway, so it's still a valid way to test the feature.
# TODO: Enforce correct roaming behaviour when porting the test to Tast.
if not self.context.client.wait_for_roam(
bssid_roam, timeout_seconds=self.TIMEOUT_SECONDS):
raise error.TestFail('Failed to roam after%s scanning.' %
('' if wait_for_scan else ' not'))
# Tear down.
self.context.client.shill.disconnect(router_ssid)
self.context.router.deconfig_aps()
self.context.capture_host.stop_capture()
def run_once(self):
"""Test body."""
# Before sending the BSS TM Request, run a scan and make sure the DUT
# has seen the second AP. In that case, the DUT will typically re-use
# the result of the scan when receiving the request instead of probing
# the second AP.
self._run_test(wait_for_scan=True)
# After setting up both APs, immediately send the BSS TM Request before
# the DUT has scanned and noticed the second AP (at least in the
# majority of test runs). Instead of relying on the result of a previous
# scan, the DUT will probe for the second AP when receiving the
# transition request.
self._run_test(wait_for_scan=False)
def cleanup(self):
"""Cleanup function."""
super(network_WiFi_BSSTMReq, self).cleanup()