1 # Copyright 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 import contextlib 6 import logging 7 import time 8 9 from autotest_lib.client.common_lib import error 10 from autotest_lib.client.common_lib.cros.network import tcpdump_analyzer 11 from autotest_lib.server import site_linux_system 12 from autotest_lib.server.cros.network import hostap_config 13 from autotest_lib.server.cros.network import lucid_sleep_test_base 14 from autotest_lib.server.cros.network import wifi_client 15 16 class network_WiFi_DarkResumeActiveScans( 17 lucid_sleep_test_base.LucidSleepTestBase): 18 """ 19 Test that no active scans are launched when the system wakes on dark resumes 20 triggered by RTC timers and wake on pattern. 21 """ 22 23 version = 1 24 25 def stop_capture_and_check_for_probe_requests(self, mac): 26 """ 27 Stop packet capture and check that no probe requests launched by the DUT 28 with MAC address |mac| are found in the packet capture. Fails test if 29 any probe request frames are found. 30 31 @param mac: MAC address of the DUT. 32 """ 33 logging.info('Stopping packet capture') 34 results = self.context.capture_host.stop_capture() 35 if len(results) != 1: 36 raise error.TestError('Expected to generate one packet ' 37 'capture but got %d captures instead.' % 38 len(results)) 39 40 logging.info('Analyzing packet capture...') 41 probe_req_pcap_filter = '%s and wlan.sa==%s' % ( 42 tcpdump_analyzer.WLAN_PROBE_REQ_ACCEPTOR, mac) 43 # Get all the frames in chronological order. 44 frames = tcpdump_analyzer.get_frames( 45 results[0].local_pcap_path, 46 probe_req_pcap_filter, 47 bad_fcs='include') 48 if len(frames) > 0: 49 raise error.TestFail('Packet capture contained probe requests!') 50 51 logging.info('Packet capture contained no probe requests') 52 53 54 def run_once(self): 55 """Body of the test.""" 56 self.context.router.require_capabilities( 57 [site_linux_system.LinuxSystem.CAPABILITY_MULTI_AP_SAME_BAND]) 58 59 ap_config = hostap_config.HostapConfig(channel=1) 60 self.configure_and_connect_to_ap(ap_config) 61 self.context.assert_ping_from_dut() 62 63 client = self.context.client 64 router = self.context.router 65 dut_mac = client.wifi_mac 66 dut_ip = client.wifi_ip 67 prev_num_dark_resumes = 0 68 69 logging.info('DUT WiFi MAC = %s, IPv4 = %s', dut_mac, dut_ip) 70 logging.info('Router WiFi IPv4 = %s', router.wifi_ip) 71 72 # Trigger a wake on packet dark resume, and make sure that no probe 73 # requests were launched during this dark resume. 74 with client.wake_on_wifi_features(wifi_client.WAKE_ON_WIFI_PACKET): 75 logging.info('Set up WoWLAN') 76 77 # Wake on packets from the router. 78 client.add_wake_packet_source(self.context.router.wifi_ip) 79 80 with self.dr_utils.suspend(): 81 time.sleep(wifi_client.SUSPEND_WAIT_TIME_SECONDS) 82 83 # Start capture after suspend concludes in case probe requests 84 # are launched on the way to suspend. 85 self.context.capture_host.start_capture( 86 ap_config.frequency, 87 ht_type=ap_config.ht_packet_capture_mode) 88 89 # Send the DUT a packet from the router to wake it up. 90 router.send_magic_packet(dut_ip, dut_mac) 91 92 # Wait for the DUT to wake up in dark resume and suspend again. 93 time.sleep(wifi_client.RECEIVE_PACKET_WAIT_TIME_SECONDS + 94 wifi_client.DARK_RESUME_WAIT_TIME_SECONDS) 95 96 # Check for packet capture before waking the DUT with 97 # |count_dark_resumes| because probe requests might be launched 98 # during the wake. 99 self.stop_capture_and_check_for_probe_requests(mac=dut_mac) 100 101 prev_num_dark_resumes = self.dr_utils.count_dark_resumes() 102 if prev_num_dark_resumes < 1: 103 raise error.TestFail('Client failed to wake on packet.') 104 logging.info('Client woke up on packet successfully.') 105 106 # Trigger a wake to scan RTC timer dark resume, and make sure that no 107 # probe requests were launched during this dark resume. 108 with contextlib.nested( 109 client.wake_on_wifi_features( 110 wifi_client.WAKE_ON_WIFI_DARKCONNECT), 111 client.wake_to_scan_period_seconds( 112 wifi_client.WAKE_TO_SCAN_PERIOD_SECONDS), 113 client.force_wake_to_scan_timer(True)): 114 115 # Bring the AP down so the DUT suspends disconnected. 116 router.deconfig_aps() 117 time.sleep(wifi_client.DISCONNECT_WAIT_TIME_SECONDS) 118 119 with self.dr_utils.suspend(): 120 time.sleep(wifi_client.SUSPEND_WAIT_TIME_SECONDS) 121 122 # Start capture after suspend concludes in case probe requests 123 # are launched on the way to suspend. 124 self.context.capture_host.start_capture( 125 ap_config.frequency, 126 ht_type=ap_config.ht_packet_capture_mode) 127 128 # Wait for the DUT to wake to scan and suspend again. 129 time.sleep(wifi_client.WAKE_TO_SCAN_PERIOD_SECONDS + 130 wifi_client.DARK_RESUME_WAIT_TIME_SECONDS) 131 132 # Check for packet capture before waking the DUT with 133 # |count_dark_resumes| because probe requests might be launched 134 # during the wake. 135 self.stop_capture_and_check_for_probe_requests(mac=dut_mac) 136 137 if (self.dr_utils.count_dark_resumes() - 138 prev_num_dark_resumes) < 1: 139 raise error.TestFail('Client failed to wake up to scan.') 140 logging.info('Client woke up to scan successfully.') 141