autotest: packet_capturer: Adding VHT support

The autotest start_capture method currently only supports configuration
options for channels up to 40 MHz wide. VHT80 and VHT160 options are
necessary to properly capture traffic on 80 MHz and 160 MHz bands from
within autotest.

BUG=chromium:1017533
TEST=Add packet_capture to network_WiFi_Perf (like in
chromium:1959712). Start network_WiFi_Perf.vht80 with a DUT (caroline
in my case), router, and pcap and then cancel it with Ctrl+C after
iperf runs for a cycle or two. Find the output directory in the first
few logging lines, then navigate to it. Find the pcap file in that
directory (FILE=`find . -name "*.pcap"`), open it with wireshark, and
filter based on `wlan.fc.type_subtype==0x28`. Export a new pcap with
only these frames, and then parse it using tshark: `tshark -r ${FILE}
-T fields -e radiotap.vht.bw | sort | uniq -c`. Verify that the
majority is the value 4 (the value of this field corresponding to 80
MHz).

Change-Id: I8dd0f5ddca427812909d434374d97be98a4e0940
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/1877829
Tested-by: Jared Pauletti <pauletti@google.com>
Commit-Queue: Jared Pauletti <pauletti@google.com>
Reviewed-by: Brian Norris <briannorris@chromium.org>
diff --git a/client/common_lib/cros/network/iw_runner.py b/client/common_lib/cros/network/iw_runner.py
index f865ed7..9a89704 100644
--- a/client/common_lib/cros/network/iw_runner.py
+++ b/client/common_lib/cros/network/iw_runner.py
@@ -24,9 +24,23 @@
 SUPPORTED_DEV_MODES = (DEV_MODE_AP, DEV_MODE_IBSS, DEV_MODE_MONITOR,
                        DEV_MODE_MESH_POINT, DEV_MODE_STATION)
 
-HT20 = 'HT20'
-HT40_ABOVE = 'HT40+'
-HT40_BELOW = 'HT40-'
+class _PrintableWidth:
+    """Printable width constant objects used by packet_capturer."""
+    def __init__(self, name):
+        self._name = name
+
+    def __repr__(self):
+        return '\'%s\'' % self._name
+
+    def __str__(self):
+        return self._name
+
+WIDTH_HT20 = _PrintableWidth('HT20')
+WIDTH_HT40_PLUS = _PrintableWidth('HT40+')
+WIDTH_HT40_MINUS = _PrintableWidth('HT40-')
+WIDTH_VHT80 = _PrintableWidth('VHT80')
+WIDTH_VHT160 = _PrintableWidth('VHT160')
+WIDTH_VHT80_80 = _PrintableWidth('VHT80+80')
 
 SECURITY_OPEN = 'open'
 SECURITY_WEP = 'wep'
@@ -38,9 +52,9 @@
 # Table of lookups between the output of item 'secondary channel offset:' from
 # iw <device> scan to constants.
 
-HT_TABLE = {'no secondary': HT20,
-            'above': HT40_ABOVE,
-            'below': HT40_BELOW}
+HT_TABLE = {'no secondary': WIDTH_HT20,
+            'above': WIDTH_HT40_PLUS,
+            'below': WIDTH_HT40_MINUS}
 
 IwBand = collections.namedtuple(
     'Band', ['num', 'frequencies', 'frequency_flags', 'mcs_indices'])
diff --git a/client/common_lib/cros/network/iw_runner_unittest.py b/client/common_lib/cros/network/iw_runner_unittest.py
index 976163e..b17ee4b 100755
--- a/client/common_lib/cros/network/iw_runner_unittest.py
+++ b/client/common_lib/cros/network/iw_runner_unittest.py
@@ -67,7 +67,7 @@
 
     HT20_IW_BSS = iw_runner.IwBss('aa:aa:aa:aa:aa:aa', 2412,
                                   'support_ht20', iw_runner.SECURITY_OPEN,
-                                  iw_runner.HT20, -50.00)
+                                  iw_runner.WIDTH_HT20, -50.00)
 
     HT20_2 = str('BSS 11:11:11:11:11:11 (on wlan0)\n'
         '     freq: 2462\n'
@@ -79,7 +79,7 @@
 
     HT20_2_IW_BSS = iw_runner.IwBss('11:11:11:11:11:11', 2462,
                                     'support_ht20', iw_runner.SECURITY_WPA,
-                                    iw_runner.HT40_BELOW, -42.00)
+                                    iw_runner.WIDTH_HT40_MINUS, -42.00)
 
     HT40_ABOVE = str('BSS bb:bb:bb:bb:bb:bb (on wlan0)\n'
         '    freq: 5180\n'
@@ -92,7 +92,7 @@
     HT40_ABOVE_IW_BSS = iw_runner.IwBss('bb:bb:bb:bb:bb:bb', 5180,
                                         'support_ht40_above',
                                         iw_runner.SECURITY_WPA2,
-                                        iw_runner.HT40_ABOVE, -55.00)
+                                        iw_runner.WIDTH_HT40_PLUS, -55.00)
 
     HT40_BELOW = str('BSS cc:cc:cc:cc:cc:cc (on wlan0)\n'
         '    freq: 2462\n'
@@ -106,7 +106,7 @@
     HT40_BELOW_IW_BSS = iw_runner.IwBss('cc:cc:cc:cc:cc:cc', 2462,
                                         'support_ht40_below',
                                         iw_runner.SECURITY_MIXED,
-                                        iw_runner.HT40_BELOW, -44.00)
+                                        iw_runner.WIDTH_HT40_MINUS, -44.00)
 
     NO_HT = str('BSS dd:dd:dd:dd:dd:dd (on wlan0)\n'
         '    freq: 2412\n'
@@ -130,7 +130,7 @@
 
     HIDDEN_SSID_IW_BSS = iw_runner.IwBss('ee:ee:ee:ee:ee:ee', 2462,
                                          None, iw_runner.SECURITY_OPEN,
-                                         iw_runner.HT20, -70.00)
+                                         iw_runner.WIDTH_HT20, -70.00)
 
     STATION_LINK_INFORMATION = str(
         'Connected to 12:34:56:ab:cd:ef (on wlan0)\n'
diff --git a/server/cros/clique_lib/clique_dut_control.py b/server/cros/clique_lib/clique_dut_control.py
index 1223f3d..bf5ef9f 100644
--- a/server/cros/clique_lib/clique_dut_control.py
+++ b/server/cros/clique_lib/clique_dut_control.py
@@ -5,8 +5,6 @@
 import collections
 import logging
 import multiprocessing
-import sys
-import time
 
 from autotest_lib.client.common_lib import error
 from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
@@ -479,7 +477,8 @@
             capturer = self.find_param('capturer')
             capturer_frequency = self.find_param('capturer_frequency')
             capturer_ht_type = self.find_param('capturer_ht_type')
-            capturer.start_capture(capturer_frequency, ht_type=capturer_ht_type)
+            capturer.start_capture(capturer_frequency,
+                                   width_type=capturer_ht_type)
         except Exception as e:
             result = ControlResult(uid=self.uid,
                                    run_num=run_num,
diff --git a/server/cros/network/hostap_config.py b/server/cros/network/hostap_config.py
index 362a7a9..49b3103 100644
--- a/server/cros/network/hostap_config.py
+++ b/server/cros/network/hostap_config.py
@@ -8,6 +8,7 @@
 
 from autotest_lib.client.common_lib import error
 from autotest_lib.client.common_lib.cros.network import xmlrpc_security_types
+from autotest_lib.server.cros.network import packet_capturer
 
 
 class HostapConfig(object):
@@ -131,7 +132,7 @@
             AC_CAPABILITY_RXLDPC: '[RXLDPC]',
             AC_CAPABILITY_SHORT_GI_80: '[SHORT_GI_80]',
             AC_CAPABILITY_SHORT_GI_160: '[SHORT_GI_160]',
-            AC_CAPABILITY_TX_STBC_2BY1: '[TX_STBC_2BY1',
+            AC_CAPABILITY_TX_STBC_2BY1: '[TX_STBC_2BY1]',
             AC_CAPABILITY_RX_STBC_1: '[RX_STBC_1]',
             AC_CAPABILITY_RX_STBC_12: '[RX_STBC_12]',
             AC_CAPABILITY_RX_STBC_123: '[RX_STBC_123]',
@@ -157,6 +158,16 @@
             AC_CAPABILITY_RX_ANTENNA_PATTERN: '[RX_ANTENNA_PATTERN]',
             AC_CAPABILITY_TX_ANTENNA_PATTERN: '[TX_ANTENNA_PATTERN]'}
 
+    HT_CHANNEL_WIDTH_20 = object()
+    HT_CHANNEL_WIDTH_40_PLUS = object()
+    HT_CHANNEL_WIDTH_40_MINUS = object()
+
+    HT_NAMES = {
+        HT_CHANNEL_WIDTH_20: 'HT20',
+        HT_CHANNEL_WIDTH_40_PLUS: 'HT40+',
+        HT_CHANNEL_WIDTH_40_MINUS: 'HT40-',
+    }
+
     VHT_CHANNEL_WIDTH_40 = object()
     VHT_CHANNEL_WIDTH_80 = object()
     VHT_CHANNEL_WIDTH_160 = object()
@@ -379,29 +390,49 @@
 
 
     @property
-    def ht_packet_capture_mode(self):
-        """Get an appropriate packet capture HT parameter.
+    def _ht_mode(self):
+        """@return string one of (None, HT20, HT40+, HT40-)"""
+        if not self._is_11n:
+            return None
+        if self._ht40_plus_allowed:
+            return self.HT_NAMES[self.HT_CHANNEL_WIDTH_40_PLUS]
+        if self._ht40_minus_allowed:
+            return self.HT_NAMES[self.HT_CHANNEL_WIDTH_40_MINUS]
+        return self.HT_NAMES[self.HT_CHANNEL_WIDTH_20]
+
+
+    @property
+    def packet_capture_mode(self):
+        """Get an appropriate packet capture HT/VHT parameter.
 
         When we go to configure a raw monitor we need to configure
         the phy to listen on the correct channel.  Part of doing
-        so is to specify the channel width for HT channels.  In the
+        so is to specify the channel width for HT/VHT channels.  In the
         case that the AP is configured to be either HT40+ or HT40-,
         we could return the wrong parameter because we don't know which
         configuration will be chosen by hostap.
 
-        @return string HT parameter for frequency configuration.
+        @return object width_type parameter from packet_capturer.
 
         """
-        if not self._is_11n:
-            return None
 
-        if self._ht40_plus_allowed:
-            return 'HT40+'
+        if (not self.vht_channel_width or
+                self.vht_channel_width == self.VHT_CHANNEL_WIDTH_40):
+            # if it is VHT40, capture packets on the correct 40MHz band since
+            # for packet capturing purposes, only the channel width matters
+            ht_mode = self._ht_mode
+            if ht_mode == self.HT_CHANNEL_WIDTH_40_PLUS:
+                return packet_capturer.WIDTH_HT40_PLUS
+            if ht_mode == self.HT_CHANNEL_WIDTH_40_MINUS:
+                return packet_capturer.WIDTH_HT40_MINUS
 
-        if self._ht40_minus_allowed:
-            return 'HT40-'
-
-        return 'HT20'
+        if self.vht_channel_width == self.VHT_CHANNEL_WIDTH_80:
+            return packet_capturer.WIDTH_VHT80
+        if self.vht_channel_width == self.VHT_CHANNEL_WIDTH_160:
+            return packet_capturer.WIDTH_VHT160
+        if self.vht_channel_width == self.VHT_CHANNEL_WIDTH_80_80:
+            return packet_capturer.WIDTH_VHT80_80
+        return None
 
 
     @property
@@ -417,13 +448,12 @@
     def printable_mode(self):
         """@return human readable mode string."""
 
-        # Note: VHT capture is not yet supported in ht_packet_capture_mode()
-        # (nor cros.network.packet_capturer).
         if self.vht_channel_width is not None:
             return self.VHT_NAMES[self.vht_channel_width]
 
-        if self._is_11n:
-            return self.ht_packet_capture_mode
+        ht_mode = self._ht_mode
+        if ht_mode:
+            return ht_mode
 
         return '11' + self._hw_mode.upper()
 
diff --git a/server/cros/network/packet_capturer.py b/server/cros/network/packet_capturer.py
index 3a7f1cf..d0d21b7 100644
--- a/server/cros/network/packet_capturer.py
+++ b/server/cros/network/packet_capturer.py
@@ -11,6 +11,7 @@
 from autotest_lib.client.bin import utils
 from autotest_lib.client.common_lib import error
 from autotest_lib.client.common_lib.cros import path_utils
+from autotest_lib.client.common_lib.cros.network import iw_runner
 
 
 class PacketCapturesDisabledError(Exception):
@@ -33,6 +34,50 @@
 TCPDUMP_START_TIMEOUT_SECONDS = 5
 TCPDUMP_START_POLL_SECONDS = 0.1
 
+# These are WidthType objects from iw_runner
+WIDTH_HT20 = iw_runner.WIDTH_HT20
+WIDTH_HT40_PLUS = iw_runner.WIDTH_HT40_PLUS
+WIDTH_HT40_MINUS = iw_runner.WIDTH_HT40_MINUS
+WIDTH_VHT80 = iw_runner.WIDTH_VHT80
+WIDTH_VHT160 = iw_runner.WIDTH_VHT160
+WIDTH_VHT80_80 = iw_runner.WIDTH_VHT80_80
+
+_WIDTH_STRINGS = {
+    WIDTH_HT20: 'HT20',
+    WIDTH_HT40_PLUS: 'HT40+',
+    WIDTH_HT40_MINUS: 'HT40-',
+    WIDTH_VHT80: '80MHz',
+    WIDTH_VHT160: '160',
+    WIDTH_VHT80_80: '80+80',
+}
+
+def _get_width_string(width):
+    """Returns a valid width parameter for "iw dev ${DEV} set freq".
+
+    @param width object, one of WIDTH_*
+    @return string iw readable width, or empty string
+
+    """
+    return _WIDTH_STRINGS.get(width, '')
+
+
+def _get_center_freq_160(frequency):
+    """Find the center frequency of a 160MHz channel.
+
+    Raises an error upon an invalid frequency.
+
+    @param frequency int Control frequency of the channel.
+    @return center_freq int Center frequency of the channel.
+
+    """
+    if (frequency >= 5180 and frequency <= 5320):
+        return 5250
+    if (frequency >= 5500 and frequency <= 5640):
+        return 5570
+    raise error.TestError(
+            'Frequency %s is not part of a 160MHz channel', frequency)
+
+
 def get_packet_capturer(host, host_description=None, cmd_ip=None, cmd_iw=None,
                         cmd_netdump=None, ignore_failures=False):
     cmd_iw = cmd_iw or path_utils.get_install_path('iw', host=host)
@@ -77,13 +122,13 @@
         """No-op"""
 
 
-    def create_raw_monitor(self, phy, frequency, ht_type=None,
+    def create_raw_monitor(self, phy, frequency, width_type=None,
                            monitor_device=None):
         """Appears to fail while creating a raw monitor device.
 
         @param phy string ignored.
         @param frequency int ignored.
-        @param ht_type string ignored.
+        @param width_type string ignored.
         @param monitor_device string ignored.
         @return None.
 
@@ -91,12 +136,12 @@
         return None
 
 
-    def configure_raw_monitor(self, monitor_device, frequency, ht_type=None):
+    def configure_raw_monitor(self, monitor_device, frequency, width_type=None):
         """Fails to configure a raw monitor.
 
         @param monitor_device string ignored.
         @param frequency int ignored.
-        @param ht_type string ignored.
+        @param width_type string ignored.
 
         """
 
@@ -183,7 +228,7 @@
         self._created_raw_devices = []
 
 
-    def create_raw_monitor(self, phy, frequency, ht_type=None,
+    def create_raw_monitor(self, phy, frequency, width_type=None,
                            monitor_device=None):
         """Create and configure a monitor type WiFi interface on a phy.
 
@@ -191,7 +236,8 @@
 
         @param phy string phy name for created monitor (e.g. phy0).
         @param frequency int frequency for created monitor to watch.
-        @param ht_type string optional HT type ('HT20', 'HT40+', or 'HT40-').
+        @param width_type object optional HT or VHT type, one of the keys in
+                self.WIDTH_STRINGS.
         @param monitor_device string name of monitor interface to create.
         @return string monitor device name created or None on failure.
 
@@ -211,27 +257,33 @@
             logging.error('Failed creating raw monitor.')
             return None
 
-        self.configure_raw_monitor(monitor_device, frequency, ht_type)
+        self.configure_raw_monitor(monitor_device, frequency, width_type)
         self._created_raw_devices.append(monitor_device)
         return monitor_device
 
 
-    def configure_raw_monitor(self, monitor_device, frequency, ht_type=None):
+    def configure_raw_monitor(self, monitor_device, frequency, width_type=None):
         """Configure a raw monitor with frequency and HT params.
 
         Note that this will stomp on earlier device settings.
 
         @param monitor_device string name of device to configure.
         @param frequency int WiFi frequency to dwell on.
-        @param ht_type string optional HT type ('HT20', 'HT40+', or 'HT40-').
+        @param width_type object width_type, one of the WIDTH_* objects.
 
         """
         channel_args = str(frequency)
-        if ht_type:
-            ht_type = ht_type.upper()
-            channel_args = '%s %s' % (channel_args, ht_type)
-            if ht_type not in ('HT20', 'HT40+', 'HT40-'):
-                raise error.TestError('Cannot set HT mode: %s', ht_type)
+
+        if width_type:
+            width_string = _get_width_string(width_type)
+            if not width_string:
+                raise error.TestError('Invalid width type: %r' % width_type)
+            if width_type == WIDTH_VHT80_80:
+                raise error.TestError('VHT80+80 packet capture not supported')
+            if width_type == WIDTH_VHT160:
+                width_string = '%s %d' % (width_string,
+                                          _get_center_freq_160(frequency))
+            channel_args = '%s %s' % (channel_args, width_string)
 
         self._host.run("%s link set %s up" % (self._cmd_ip, monitor_device))
         self._host.run("%s dev %s set freq %s" % (self._cmd_iw,
diff --git a/server/cros/network/random_mac_address_test_base.py b/server/cros/network/random_mac_address_test_base.py
index 82844d7..bfb9491 100644
--- a/server/cros/network/random_mac_address_test_base.py
+++ b/server/cros/network/random_mac_address_test_base.py
@@ -26,6 +26,7 @@
     DEFAULT_NUM_SCANS = 5
 
     def initialize(self, host):
+        """Generate the HostapConfig used by the AP."""
         self._ap_config = hostap_config.HostapConfig(channel=1)
 
 
@@ -43,7 +44,7 @@
         logging.debug('Starting packet capture')
         self.context.capture_host.start_capture(
                 self._ap_config.frequency,
-                ht_type=self._ap_config.ht_packet_capture_mode)
+                width_type=self._ap_config.packet_capture_mode)
 
 
     def request_scans(self, num_scans=DEFAULT_NUM_SCANS):
diff --git a/server/cros/network/wifi_test_context_manager.py b/server/cros/network/wifi_test_context_manager.py
index cf71300..f6fa938 100644
--- a/server/cros/network/wifi_test_context_manager.py
+++ b/server/cros/network/wifi_test_context_manager.py
@@ -182,7 +182,7 @@
                                       snaplen=self._packet_capture_snaplen)
         if self._enable_packet_captures:
            self.capture_host.start_capture(ap_config.frequency,
-                    ht_type=ap_config.ht_packet_capture_mode,
+                    width_type=ap_config.packet_capture_mode,
                     snaplen=self._packet_capture_snaplen)
 
 
diff --git a/server/site_linux_system.py b/server/site_linux_system.py
index d63e8d3..dbe197b 100644
--- a/server/site_linux_system.py
+++ b/server/site_linux_system.py
@@ -320,11 +320,11 @@
 
 
     def start_capture(self, frequency,
-                      ht_type=None, snaplen=None, filename=None):
+                      width_type=None, snaplen=None, filename=None):
         """Start a packet capture.
 
         @param frequency int frequency of channel to capture on.
-        @param ht_type string one of (None, 'HT20', 'HT40+', 'HT40-').
+        @param width_type object width type from iw_runner.
         @param snaplen int number of bytes to retain per capture frame.
         @param filename string filename to write capture to.
 
@@ -335,12 +335,12 @@
         full_interface = [net_dev for net_dev in self._interfaces
                           if net_dev.if_name == self._capture_interface][0]
         # If this is the only interface on this phy, we ought to configure
-        # the phy with a channel and ht_type.  Otherwise, inherit the settings
-        # of the phy as they stand.
+        # the phy with a channel and a width.  Otherwise, inherit the
+        # settings of the phy as they stand.
         if len([net_dev for net_dev in self._interfaces
                 if net_dev.phy == full_interface.phy]) == 1:
             self._packet_capturer.configure_raw_monitor(
-                    self._capture_interface, frequency, ht_type=ht_type)
+                    self._capture_interface, frequency, width_type=width_type)
         else:
             self.host.run('%s link set %s up' %
                           (self.cmd_ip, self._capture_interface))
diff --git a/server/site_tests/network_WiFi_APSupportedRates/network_WiFi_APSupportedRates.py b/server/site_tests/network_WiFi_APSupportedRates/network_WiFi_APSupportedRates.py
index a37cb93..2d7e8f8 100644
--- a/server/site_tests/network_WiFi_APSupportedRates/network_WiFi_APSupportedRates.py
+++ b/server/site_tests/network_WiFi_APSupportedRates/network_WiFi_APSupportedRates.py
@@ -83,7 +83,7 @@
         self.context.configure(ap_config)
         self.context.capture_host.start_capture(
                 ap_config.frequency,
-                ht_type=ap_config.ht_packet_capture_mode)
+                width_type=ap_config.packet_capture_mode)
         assoc_params = xmlrpc_datatypes.AssociationParameters(
                 ssid=self.context.router.get_ssid())
         self.context.assert_connect_wifi(assoc_params)
diff --git a/server/site_tests/network_WiFi_ChaosConnectDisconnect/network_WiFi_ChaosConnectDisconnect.py b/server/site_tests/network_WiFi_ChaosConnectDisconnect/network_WiFi_ChaosConnectDisconnect.py
index b7755a5..7543aab 100644
--- a/server/site_tests/network_WiFi_ChaosConnectDisconnect/network_WiFi_ChaosConnectDisconnect.py
+++ b/server/site_tests/network_WiFi_ChaosConnectDisconnect/network_WiFi_ChaosConnectDisconnect.py
@@ -22,7 +22,7 @@
 
         @param capturer: a packet capture device
         @param capturer_frequency: integer channel frequency in MHz.
-        @param capturer_ht_type: string specifier of channel HT type.
+        @param capturer_ht_type: object specifier of channel HT type.
         @param host: an Autotest host object, DUT.
         @param assoc_params: an AssociationParameters object.
         @param client: WiFiClient object
@@ -38,7 +38,8 @@
             if not client.shill.init_test_network_state():
                 return 'Failed to set up isolated test context profile.'
 
-            capturer.start_capture(capturer_frequency, ht_type=capturer_ht_type)
+            capturer.start_capture(capturer_frequency,
+                    width_type=capturer_ht_type)
             try:
                 success = False
                 logging.info('Connection attempt %d', i)
diff --git a/server/site_tests/network_WiFi_ChaosLongConnect/network_WiFi_ChaosLongConnect.py b/server/site_tests/network_WiFi_ChaosLongConnect/network_WiFi_ChaosLongConnect.py
index b5a5cf6..ef759fe 100644
--- a/server/site_tests/network_WiFi_ChaosLongConnect/network_WiFi_ChaosLongConnect.py
+++ b/server/site_tests/network_WiFi_ChaosLongConnect/network_WiFi_ChaosLongConnect.py
@@ -24,7 +24,7 @@
 
         @param capturer: a packet capture device
         @param capturer_frequency: integer channel frequency in MHz.
-        @param capturer_ht_type: string specifier of channel HT type.
+        @param capturer_ht_type: object specifier of channel HT type.
         @param host: an Autotest host object, DUT.
         @param assoc_params: an AssociationParameters object.
         @param client: WiFiClient object
@@ -41,7 +41,7 @@
             raise error.TestError('Failed to set up isolated test context '
                     'profile.')
 
-        capturer.start_capture(capturer_frequency, ht_type=capturer_ht_type)
+        capturer.start_capture(capturer_frequency, width_type=capturer_ht_type)
         try:
             success = False
             for i in range(DUT_CONNECTION_RETRIES):
diff --git a/server/site_tests/network_WiFi_CliqueLongConnect/network_WiFi_CliqueLongConnect.py b/server/site_tests/network_WiFi_CliqueLongConnect/network_WiFi_CliqueLongConnect.py
index ddee098..05d8e40 100644
--- a/server/site_tests/network_WiFi_CliqueLongConnect/network_WiFi_CliqueLongConnect.py
+++ b/server/site_tests/network_WiFi_CliqueLongConnect/network_WiFi_CliqueLongConnect.py
@@ -24,7 +24,7 @@
 
         @param capturer: a packet capture device
         @param capturer_frequency: integer channel frequency in MHz.
-        @param capturer_ht_type: string specifier of channel HT type.
+        @param capturer_ht_type: object specifier of channel HT type.
         @param dut_pool: the DUT pool to be used for the test. It is a 2D list
                          of DUTObjects.
         @param assoc_params_list: a list of AssociationParameters objects.
diff --git a/server/site_tests/network_WiFi_DarkResumeActiveScans/network_WiFi_DarkResumeActiveScans.py b/server/site_tests/network_WiFi_DarkResumeActiveScans/network_WiFi_DarkResumeActiveScans.py
index bd3605f..a46b94b 100644
--- a/server/site_tests/network_WiFi_DarkResumeActiveScans/network_WiFi_DarkResumeActiveScans.py
+++ b/server/site_tests/network_WiFi_DarkResumeActiveScans/network_WiFi_DarkResumeActiveScans.py
@@ -78,7 +78,7 @@
                 # are launched on the way to suspend.
                 self.context.capture_host.start_capture(
                         ap_config.frequency,
-                        ht_type=ap_config.ht_packet_capture_mode)
+                        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)
@@ -117,7 +117,7 @@
                 # are launched on the way to suspend.
                 self.context.capture_host.start_capture(
                         ap_config.frequency,
-                        ht_type=ap_config.ht_packet_capture_mode)
+                        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 +
diff --git a/server/site_tests/network_WiFi_HiddenScan/network_WiFi_HiddenScan.py b/server/site_tests/network_WiFi_HiddenScan/network_WiFi_HiddenScan.py
index 0716c2d..d01478d 100644
--- a/server/site_tests/network_WiFi_HiddenScan/network_WiFi_HiddenScan.py
+++ b/server/site_tests/network_WiFi_HiddenScan/network_WiFi_HiddenScan.py
@@ -24,7 +24,7 @@
         # Start capture before starting anything else.
         self.context.capture_host.start_capture(
                 ap_config.frequency,
-                ht_type=ap_config.ht_packet_capture_mode,
+                width_type=ap_config.packet_capture_mode,
                 snaplen=packet_capturer.SNAPLEN_WIFI_PROBE_REQUEST)
 
         # We're looking for the MAC address, so disable randomization.
diff --git a/server/site_tests/network_WiFi_MalformedProbeResp/network_WiFi_MalformedProbeResp.py b/server/site_tests/network_WiFi_MalformedProbeResp/network_WiFi_MalformedProbeResp.py
index 4d62da7..c5d6cbb 100644
--- a/server/site_tests/network_WiFi_MalformedProbeResp/network_WiFi_MalformedProbeResp.py
+++ b/server/site_tests/network_WiFi_MalformedProbeResp/network_WiFi_MalformedProbeResp.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
+# Copyright 2019 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.
 
@@ -39,7 +39,7 @@
         logging.debug('pretest_reset_count=%d', pretest_reset_count)
         self.context.capture_host.start_capture(
                 configuration.frequency,
-                ht_type=configuration.ht_packet_capture_mode)
+                width_type=configuration.packet_capture_mode)
         assoc_params = xmlrpc_datatypes.AssociationParameters()
         assoc_params.ssid = self.context.router.get_ssid(instance=0)
         self.context.assert_connect_wifi(assoc_params)
diff --git a/server/site_tests/network_WiFi_RateControl/network_WiFi_RateControl.py b/server/site_tests/network_WiFi_RateControl/network_WiFi_RateControl.py
index 1ff8801..46e84bb 100644
--- a/server/site_tests/network_WiFi_RateControl/network_WiFi_RateControl.py
+++ b/server/site_tests/network_WiFi_RateControl/network_WiFi_RateControl.py
@@ -5,7 +5,6 @@
 import logging
 
 from autotest_lib.client.common_lib import error
-from autotest_lib.client.common_lib import utils
 from autotest_lib.client.common_lib.cros.network import iw_runner
 from autotest_lib.client.common_lib.cros.network import tcpdump_analyzer
 from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
@@ -133,7 +132,7 @@
             self.context.configure(ap_config)
             self.context.capture_host.start_capture(
                     ap_config.frequency,
-                    ht_type=ap_config.ht_packet_capture_mode,
+                    width_type=ap_config.packet_capture_mode,
                     snaplen=self.TEST_SNAPLEN)
             assoc_params = xmlrpc_datatypes.AssociationParameters(
                     ssid=self.context.router.get_ssid())
diff --git a/server/site_tests/network_WiFi_SetOptionalDhcpProperties/network_WiFi_SetOptionalDhcpProperties.py b/server/site_tests/network_WiFi_SetOptionalDhcpProperties/network_WiFi_SetOptionalDhcpProperties.py
index ecce58d..2bad9e2 100644
--- a/server/site_tests/network_WiFi_SetOptionalDhcpProperties/network_WiFi_SetOptionalDhcpProperties.py
+++ b/server/site_tests/network_WiFi_SetOptionalDhcpProperties/network_WiFi_SetOptionalDhcpProperties.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2016 The Chromium OS Authors. All rights reserved.
+# Copyright 2019 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.
 
@@ -67,7 +67,7 @@
                                              self.VENDORCLASS_VALUE):
                 self.context.capture_host.start_capture(
                         configuration.frequency,
-                        ht_type=configuration.ht_packet_capture_mode)
+                        width_type=configuration.packet_capture_mode)
                 assoc_params = xmlrpc_datatypes.AssociationParameters()
                 assoc_params.ssid = self.context.router.get_ssid(instance=0)
                 self.context.assert_connect_wifi(assoc_params)
diff --git a/server/site_tests/network_WiFi_SimpleConnect/network_WiFi_SimpleConnect.py b/server/site_tests/network_WiFi_SimpleConnect/network_WiFi_SimpleConnect.py
index 0dc3678..125fcf7 100644
--- a/server/site_tests/network_WiFi_SimpleConnect/network_WiFi_SimpleConnect.py
+++ b/server/site_tests/network_WiFi_SimpleConnect/network_WiFi_SimpleConnect.py
@@ -28,7 +28,7 @@
         for router_conf, client_conf in self._configurations:
             self.context.configure(router_conf)
             self.context.capture_host.start_capture(router_conf.frequency,
-                    ht_type=router_conf.ht_packet_capture_mode)
+                    width_type=router_conf.packet_capture_mode)
             client_conf.ssid = self.context.router.get_ssid()
             assoc_result = self.context.assert_connect_wifi(client_conf)
             if client_conf.expect_failure:
diff --git a/server/site_tests/network_WiFi_VisibleScan/network_WiFi_VisibleScan.py b/server/site_tests/network_WiFi_VisibleScan/network_WiFi_VisibleScan.py
index b145e69..74d3247 100644
--- a/server/site_tests/network_WiFi_VisibleScan/network_WiFi_VisibleScan.py
+++ b/server/site_tests/network_WiFi_VisibleScan/network_WiFi_VisibleScan.py
@@ -35,7 +35,7 @@
         # Start capture before starting anything else.
         self.context.capture_host.start_capture(
                     ap_config.frequency,
-                    ht_type=ap_config.ht_packet_capture_mode,
+                    width_type=ap_config.packet_capture_mode,
                     snaplen=packet_capturer.SNAPLEN_WIFI_PROBE_REQUEST)
 
         # We're looking for the MAC address, so disable randomization.