autotest: iw_runner.py: VHT support in _parse_scan_results
Add support for VHT output parsing in the IwRunner scanning utility.
BUG=chromium:1018812
TEST=Unit tests in iw_runner_unittest.py
Cq-Depend: chromium:1877829
Change-Id: Id77b99b6eb817cb4aacebd6c00cdafd80445891b
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/1894795
Commit-Queue: Jared Pauletti <pauletti@google.com>
Tested-by: 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 2bb7208..3b33938 100644
--- a/client/common_lib/cros/network/iw_runner.py
+++ b/client/common_lib/cros/network/iw_runner.py
@@ -42,6 +42,8 @@
WIDTH_VHT160 = _PrintableWidth('VHT160')
WIDTH_VHT80_80 = _PrintableWidth('VHT80+80')
+VHT160_CENTER_CHANNELS = ('50','114')
+
SECURITY_OPEN = 'open'
SECURITY_WEP = 'wep'
SECURITY_WPA = 'wpa'
@@ -59,7 +61,7 @@
IwBand = collections.namedtuple(
'Band', ['num', 'frequencies', 'frequency_flags', 'mcs_indices'])
IwBss = collections.namedtuple('IwBss', ['bss', 'frequency', 'ssid', 'security',
- 'ht', 'signal'])
+ 'width', 'signal'])
IwNetDev = collections.namedtuple('IwNetDev', ['phy', 'if_name', 'if_type'])
IwTimedScan = collections.namedtuple('IwTimedScan', ['time', 'bss_list'])
@@ -310,19 +312,27 @@
frequency = None
ssid = None
ht = None
+ vht = None
signal = None
security = None
supported_securities = []
bss_list = []
+ # TODO(crbug.com/1032892): The parsing logic here wasn't really designed
+ # for the presence of multiple information elements like HT, VHT, and
+ # (eventually) HE. We should eventually update it to check that we are
+ # in the right section (e.g., verify the '* channel width' match is a
+ # match in the VHT section and not a different section). Also, we should
+ # probably add in VHT20, and VHT40 whenever we finish this bug.
for line in output.splitlines():
line = line.strip()
bss_match = re.match('BSS ([0-9a-f:]+)', line)
if bss_match:
if bss != None:
security = self.determine_security(supported_securities)
- iwbss = IwBss(bss, frequency, ssid, security, ht, signal)
+ iwbss = IwBss(bss, frequency, ssid, security,
+ vht if vht else ht, signal)
bss_list.append(iwbss)
- bss = frequency = ssid = security = ht = None
+ bss = frequency = ssid = security = ht = vht = None
supported_securities = []
bss = bss_match.group(1)
if line.startswith('freq:'):
@@ -333,12 +343,31 @@
_, ssid = line.split(': ', 1)
if line.startswith('* secondary channel offset'):
ht = HT_TABLE[line.split(':')[1].strip()]
+ # Checking for the VHT channel width based on IEEE 802.11-2016
+ # Table 9-252.
+ if line.startswith('* channel width:'):
+ chan_width_subfield = line.split(':')[1].strip()[0]
+ if chan_width_subfield == '1':
+ vht = WIDTH_VHT80
+ # 2 and 3 are deprecated but are included here for older APs.
+ if chan_width_subfield == '2':
+ vht = WIDTH_VHT160
+ if chan_width_subfield == '3':
+ vht = WIDTH_VHT80_80
+ if line.startswith('* center freq segment 2:'):
+ center_chan_two = line.split(':')[1].strip()
+ if vht == WIDTH_VHT80:
+ if center_chan_two in VHT160_CENTER_CHANNELS:
+ vht = WIDTH_VHT160
+ elif center_chan_two != '0':
+ vht = WIDTH_VHT80_80
if line.startswith('WPA'):
supported_securities.append(SECURITY_WPA)
if line.startswith('RSN'):
supported_securities.append(SECURITY_WPA2)
security = self.determine_security(supported_securities)
- bss_list.append(IwBss(bss, frequency, ssid, security, ht, signal))
+ bss_list.append(IwBss(bss, frequency, ssid, security,
+ vht if vht else ht, signal))
return bss_list
diff --git a/client/common_lib/cros/network/iw_runner_unittest.py b/client/common_lib/cros/network/iw_runner_unittest.py
index b17ee4b..83e3b28 100755
--- a/client/common_lib/cros/network/iw_runner_unittest.py
+++ b/client/common_lib/cros/network/iw_runner_unittest.py
@@ -117,6 +117,78 @@
'no_ht_support', iw_runner.SECURITY_OPEN,
None, -45.00)
+ VHT_CAPA_20 = str('BSS ff:ff:ff:ff:ff:ff (on wlan0)\n'
+ ' freq: 2462\n'
+ ' signal: -44.00 dBm\n'
+ ' SSID: vht_capable_20\n'
+ ' HT operation:\n'
+ ' * secondary channel offset: no secondary\n'
+ ' VHT capabilities:\n'
+ ' VHT Capabilities (0x0f8369b1):\n'
+ ' Max MPDU length: 7991\n'
+ ' Supported Channel Width: neither 160 nor 80+80\n'
+ ' VHT operation:\n'
+ ' * channel width: 0 (20 or 40 MHz)\n'
+ ' * center freq segment 1: 11\n')
+
+ VHT_CAPA_20_IW_BSS = iw_runner.IwBss('ff:ff:ff:ff:ff:ff', 2462,
+ 'vht_capable_20',
+ iw_runner.SECURITY_OPEN,
+ iw_runner.WIDTH_HT20, -44.00)
+
+ VHT80 = str('BSS ff:ff:ff:ff:ff:ff (on wlan0)\n'
+ ' freq: 2462\n'
+ ' signal: -44.00 dBm\n'
+ ' SSID: support_vht80\n'
+ ' HT operation:\n'
+ ' * secondary channel offset: below\n'
+ ' VHT capabilities:\n'
+ ' VHT Capabilities (0x0f8369b1):\n'
+ ' Max MPDU length: 7991\n'
+ ' Supported Channel Width: neither 160 nor 80+80\n'
+ ' VHT operation:\n'
+ ' * channel width: 1 (80 MHz)\n'
+ ' * center freq segment 1: 11\n'
+ ' * center freq segment 2: 0\n')
+
+ VHT80_IW_BSS = iw_runner.IwBss('ff:ff:ff:ff:ff:ff', 2462,
+ 'support_vht80', iw_runner.SECURITY_OPEN,
+ iw_runner.WIDTH_VHT80, -44.00)
+
+ VHT160 = str('BSS 12:34:56:78:90:aa (on wlan0)\n'
+ ' freq: 5180\n'
+ ' signal: -44.00 dBm\n'
+ ' SSID: support_vht160\n'
+ ' HT operation:\n'
+ ' * secondary channel offset: below\n'
+ ' VHT capabilities:\n'
+ ' VHT Capabilities (0x0f8369b1):\n'
+ ' Max MPDU length: 7991\n'
+ ' Supported Channel Width: 160 MHz\n'
+ ' VHT operation:\n'
+ ' * channel width: 1 (80 MHz)\n'
+ ' * center freq segment 1: 42\n'
+ ' * center freq segment 2: 50\n')
+
+ VHT160_IW_BSS = iw_runner.IwBss('12:34:56:78:90:aa', 5180,
+ 'support_vht160', iw_runner.SECURITY_OPEN,
+ iw_runner.WIDTH_VHT160, -44.00)
+
+ VHT80_80 = str('BSS ab:cd:ef:fe:dc:ba (on wlan0)\n'
+ ' freq: 5180\n'
+ ' signal: -44.00 dBm\n'
+ ' SSID: support_vht80_80\n'
+ ' HT operation:\n'
+ ' * secondary channel offset: below\n'
+ ' VHT operation:\n'
+ ' * channel width: 1 (80 MHz)\n'
+ ' * center freq segment 1: 42\n'
+ ' * center freq segment 2: 106\n')
+
+ VHT80_80_IW_BSS = iw_runner.IwBss('ab:cd:ef:fe:dc:ba', 5180,
+ 'support_vht80_80', iw_runner.SECURITY_OPEN,
+ iw_runner.WIDTH_VHT80_80, -44.00)
+
HIDDEN_SSID = str('BSS ee:ee:ee:ee:ee:ee (on wlan0)\n'
' freq: 2462\n'
' signal: -70.00 dBm\n'
@@ -514,11 +586,12 @@
@param iw_bss_2: an IWBss object
"""
+
self.assertEquals(iw_bss_1.bss, iw_bss_2.bss)
self.assertEquals(iw_bss_1.ssid, iw_bss_2.ssid)
self.assertEquals(iw_bss_1.frequency, iw_bss_2.frequency)
self.assertEquals(iw_bss_1.security, iw_bss_2.security)
- self.assertEquals(iw_bss_1.ht, iw_bss_2.ht)
+ self.assertEquals(iw_bss_1.width, iw_bss_2.width)
self.assertEquals(iw_bss_1.signal, iw_bss_2.signal)
@@ -572,6 +645,29 @@
self.search_by_bss(scan_output, self.NO_HT_IW_BSS)
+ def test_vht_20(self):
+ """Test with a network that supports vht but is 20 MHz wide."""
+ scan_output = self.HT20 + self.NO_HT + self.VHT_CAPA_20
+ self.search_by_bss(scan_output, self.VHT_CAPA_20_IW_BSS)
+
+
+ def test_vht80(self):
+ """Test with a VHT80 network."""
+ scan_output = self.HT20 + self.VHT80 + self.HT40_ABOVE
+ self.search_by_bss(scan_output, self.VHT80_IW_BSS)
+
+
+ def test_vht160(self):
+ """Test with a VHT160 network."""
+ scan_output = self.VHT160 + self.VHT80 + self.HT40_ABOVE
+ self.search_by_bss(scan_output, self.VHT160_IW_BSS)
+
+ def test_vht80_80(self):
+ """Test with a VHT80+80 network."""
+ scan_output = self.VHT160 + self.VHT80_80
+ self.search_by_bss(scan_output, self.VHT80_80_IW_BSS)
+
+
def test_hidden_ssid(self):
"""Test with a network with a hidden ssid."""
scan_output = self.HT20 + self.HIDDEN_SSID + self.NO_HT
diff --git a/server/cros/chaos_lib/chaos_runner.py b/server/cros/chaos_lib/chaos_runner.py
index a258ad7..9174d7e 100644
--- a/server/cros/chaos_lib/chaos_runner.py
+++ b/server/cros/chaos_lib/chaos_runner.py
@@ -245,7 +245,7 @@
result = job.run_test(self._test,
capturer=capturer,
capturer_frequency=networks[0].frequency,
- capturer_ht_type=networks[0].ht,
+ capturer_ht_type=networks[0].width,
host=self._host,
assoc_params=assoc_params,
client=client,
diff --git a/server/cros/chaos_lib/static_runner.py b/server/cros/chaos_lib/static_runner.py
index 2f3550c..5941321 100644
--- a/server/cros/chaos_lib/static_runner.py
+++ b/server/cros/chaos_lib/static_runner.py
@@ -199,7 +199,7 @@
result = job.run_test(self._test,
capturer=capturer,
capturer_frequency=networks[0].frequency,
- capturer_ht_type=networks[0].ht,
+ capturer_ht_type=networks[0].width,
host=self._host,
assoc_params=assoc_params,
client=client,
diff --git a/server/cros/clique_lib/clique_runner.py b/server/cros/clique_lib/clique_runner.py
index 91e0ba1..13511d9 100644
--- a/server/cros/clique_lib/clique_runner.py
+++ b/server/cros/clique_lib/clique_runner.py
@@ -4,15 +4,12 @@
import datetime
import logging
-import os
import pprint
import time
-import re
import common
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros.network import ap_constants
-from autotest_lib.server import hosts
from autotest_lib.server import site_linux_system
from autotest_lib.server.cros import host_lock_manager
from autotest_lib.server.cros.ap_configurators import ap_batch_locker
@@ -294,7 +291,7 @@
self._test,
capturer=capturer,
capturer_frequency=networks[0].frequency,
- capturer_ht_type=networks[0].ht,
+ capturer_ht_type=networks[0].width,
dut_pool=self._dut_pool,
assoc_params_list=assoc_params_list,
tries=tries,