Home | History | Annotate | Download | only in network_WiFi_DarkResumeActiveScans
      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