| # Copyright 2015 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 contextlib |
| import logging |
| import time |
| |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.client.common_lib.cros.network import tcpdump_analyzer |
| from autotest_lib.server.cros.network import hostap_config |
| from autotest_lib.server.cros.network import lucid_sleep_test_base |
| from autotest_lib.server.cros.network import wifi_client |
| |
| class network_WiFi_DarkResumeActiveScans( |
| lucid_sleep_test_base.LucidSleepTestBase): |
| """ |
| Test that no active scans are launched when the system wakes on dark resumes |
| triggered by RTC timers and wake on pattern. |
| """ |
| |
| version = 1 |
| |
| def stop_capture_and_check_for_probe_requests(self, mac): |
| """ |
| Stop packet capture and check that no probe requests launched by the DUT |
| with MAC address |mac| are found in the packet capture. Fails test if |
| any probe request frames are found. |
| |
| @param mac: MAC address of the DUT. |
| """ |
| logging.info('Stopping packet capture') |
| results = self.context.capture_host.stop_capture() |
| if len(results) != 1: |
| raise error.TestError('Expected to generate one packet ' |
| 'capture but got %d captures instead.' % |
| len(results)) |
| |
| logging.info('Analyzing packet capture...') |
| probe_req_pcap_filter = '%s and wlan.sa==%s' % ( |
| tcpdump_analyzer.WLAN_PROBE_REQ_ACCEPTOR, mac) |
| # Get all the frames in chronological order. |
| frames = tcpdump_analyzer.get_frames(results[0].local_pcap_path, |
| probe_req_pcap_filter, reject_bad_fcs=False) |
| if len(frames) > 0: |
| raise error.TestFail('Packet capture contained probe requests!') |
| |
| logging.info('Packet capture contained no probe requests') |
| |
| |
| def run_once(self): |
| """Body of the test.""" |
| ap_config = hostap_config.HostapConfig(channel=1) |
| self.configure_and_connect_to_ap(ap_config) |
| self.context.assert_ping_from_dut() |
| |
| client = self.context.client |
| router = self.context.router |
| dut_mac = client.wifi_mac |
| dut_ip = client.wifi_ip |
| prev_num_dark_resumes = 0 |
| |
| logging.info('DUT WiFi MAC = %s, IPv4 = %s', dut_mac, dut_ip) |
| logging.info('Router WiFi IPv4 = %s', router.wifi_ip) |
| |
| # Trigger a wake on packet dark resume, and make sure that no probe |
| # requests were launched during this dark resume. |
| with client.wake_on_wifi_features(wifi_client.WAKE_ON_WIFI_PACKET): |
| logging.info('Set up WoWLAN') |
| |
| # Wake on packets from the router. |
| client.add_wake_packet_source(self.context.router.wifi_ip) |
| |
| with self.dr_utils.suspend(): |
| time.sleep(wifi_client.SUSPEND_WAIT_TIME_SECONDS) |
| |
| # Start capture after suspend concludes in case probe requests |
| # are launched on the way to suspend. |
| self.context.capture_host.start_capture( |
| ap_config.frequency, |
| width_type=ap_config.packet_capture_mode) |
| |
| # Send the DUT a packet from the router to wake it up. |
| router.send_magic_packet(dut_ip, dut_mac) |
| |
| # Wait for the DUT to wake up in dark resume and suspend again. |
| time.sleep(wifi_client.RECEIVE_PACKET_WAIT_TIME_SECONDS + |
| wifi_client.DARK_RESUME_WAIT_TIME_SECONDS) |
| |
| # Check for packet capture before waking the DUT with |
| # |count_dark_resumes| because probe requests might be launched |
| # during the wake. |
| self.stop_capture_and_check_for_probe_requests(mac=dut_mac) |
| |
| prev_num_dark_resumes = self.dr_utils.count_dark_resumes() |
| if prev_num_dark_resumes < 1: |
| raise error.TestFail('Client failed to wake on packet.') |
| logging.info('Client woke up on packet successfully.') |
| |
| # Trigger a wake to scan RTC timer dark resume, and make sure that no |
| # probe requests were launched during this dark resume. |
| with contextlib.nested( |
| client.wake_on_wifi_features( |
| wifi_client.WAKE_ON_WIFI_DARKCONNECT), |
| client.wake_to_scan_period_seconds( |
| wifi_client.WAKE_TO_SCAN_PERIOD_SECONDS), |
| client.force_wake_to_scan_timer(True)): |
| |
| # Bring the AP down so the DUT suspends disconnected. |
| router.deconfig_aps() |
| time.sleep(wifi_client.DISCONNECT_WAIT_TIME_SECONDS) |
| |
| with self.dr_utils.suspend(): |
| time.sleep(wifi_client.SUSPEND_WAIT_TIME_SECONDS) |
| |
| # Start capture after suspend concludes in case probe requests |
| # are launched on the way to suspend. |
| self.context.capture_host.start_capture( |
| ap_config.frequency, |
| width_type=ap_config.packet_capture_mode) |
| |
| # Wait for the DUT to wake to scan and suspend again. |
| time.sleep(wifi_client.WAKE_TO_SCAN_PERIOD_SECONDS + |
| wifi_client.DARK_RESUME_WAIT_TIME_SECONDS) |
| |
| # Check for packet capture before waking the DUT with |
| # |count_dark_resumes| because probe requests might be launched |
| # during the wake. |
| self.stop_capture_and_check_for_probe_requests(mac=dut_mac) |
| |
| if (self.dr_utils.count_dark_resumes() - |
| prev_num_dark_resumes) < 1: |
| raise error.TestFail('Client failed to wake up to scan.') |
| logging.info('Client woke up to scan successfully.') |