Merge "platform: change jsonpoll port to match glaukus"
diff --git a/conman/connection_manager.py b/conman/connection_manager.py
index eaaf7cf..7379d88 100755
--- a/conman/connection_manager.py
+++ b/conman/connection_manager.py
@@ -85,6 +85,10 @@
if self.ssid is None:
raise ValueError('Command file does not specify SSID')
+ if self.wifi.initial_ssid == self.ssid:
+ logging.debug('Connected to WLAN at startup')
+ self.client_up = True
+
def start_access_point(self):
"""Start an access point."""
@@ -237,11 +241,21 @@
# If the ethernet file doesn't exist for any reason when conman starts,
# check explicitly and run ifplugd.action to create the file.
- if not os.path.exists(os.path.join(self._interface_status_dir,
- self.ETHERNET_STATUS_FILE)):
- ethernet_up = self.is_ethernet_up()
- self.bridge.ethernet = ethernet_up
+ if not os.path.exists(os.path.join(self._interface_status_dir, 'eth0')):
+ ethernet_up = self.is_interface_up('eth0')
self.ifplugd_action('eth0', ethernet_up)
+ self.bridge.ethernet = ethernet_up
+
+ # Do the same for wifi interfaces , but rather than explicitly setting that
+ # the wpa_supplicant link is up, attempt to attach to the wpa_supplicant
+ # control interface.
+ for wifi in self.wifi:
+ if not os.path.exists(
+ os.path.join(self._interface_status_dir, wifi.name)):
+ wifi_up = self.is_interface_up(wifi.name)
+ self.ifplugd_action(wifi.name, wifi_up)
+ if wifi_up:
+ wifi.attach_wpa_control(self._wpa_control_interface)
for path, prefix in ((self._status_dir, self.GATEWAY_FILE_PREFIX),
(self._interface_status_dir, ''),
@@ -259,13 +273,16 @@
self._interface_update_counter = 0
self._try_wlan_after = {'5': 0, '2.4': 0}
- def is_ethernet_up(self):
- """Explicitly check whether ethernet is up.
+ def is_interface_up(self, interface_name):
+ """Explicitly check whether an interface is up.
Only used on startup, and only if ifplugd file is missing.
+ Args:
+ interface_name: The name of the interface to check.
+
Returns:
- Whether the ethernet link is up.
+ Whether the interface is up.
"""
try:
lines = subprocess.check_output(self.IP_LINK).splitlines()
@@ -273,7 +290,7 @@
raise EnvironmentError('Failed to call "ip link": %r', e.message)
for line in lines:
- if 'eth0' in line and 'LOWER_UP' in line:
+ if interface_name in line and 'LOWER_UP' in line:
return True
return False
diff --git a/conman/connection_manager_test.py b/conman/connection_manager_test.py
index 4ebd48b..c22fbeb 100755
--- a/conman/connection_manager_test.py
+++ b/conman/connection_manager_test.py
@@ -193,13 +193,39 @@
WIFI_SETCLIENT = ['echo', 'setclient']
IFUP = ['echo', 'ifup']
IFPLUGD_ACTION = ['echo', 'ifplugd.action']
- # This simulates the output of 'ip link' when eth0 is up.
- IP_LINK = ['echo', 'eth0 LOWER_UP']
def __init__(self, *args, **kwargs):
+ self.interfaces_already_up = kwargs.pop('__test_interfaces_already_up',
+ ['eth0'])
+
+ wifi_interfaces_already_up = [ifc for ifc in self.interfaces_already_up
+ if ifc.startswith('wcli')]
+ for wifi in wifi_interfaces_already_up:
+ # wcli1 is always 5 GHz. wcli0 always *includes* 2.4.
+ band = '5' if wifi == 'wcli1' else '2.4'
+ # This will happen in the super function, but in order for
+ # write_wlan_config to work we have to do it now. This has to happen
+ # before the super function so that the files exist before the inotify
+ # registration.
+ self._config_dir = kwargs['config_dir']
+ self.write_wlan_config(band, 'my ssid', 'passphrase')
+
+ # Also create the wpa_supplicant socket to which to attach.
+ open(os.path.join(kwargs['wpa_control_interface'], wifi), 'w')
+
super(ConnectionManager, self).__init__(*args, **kwargs)
+
+ for wifi in wifi_interfaces_already_up:
+ # pylint: disable=protected-access
+ self.interface_by_name(wifi)._initially_connected = True
+
self.scan_has_results = False
+ @property
+ def IP_LINK(self):
+ return ['echo'] + ['%s LOWER_UP' % ifc
+ for ifc in self.interfaces_already_up]
+
def _update_access_point(self, wlan_configuration):
client_was_up = wlan_configuration.client_up
super(ConnectionManager, self)._update_access_point(wlan_configuration)
@@ -356,7 +382,7 @@
self.run_once()
-def connection_manager_test(radio_config):
+def connection_manager_test(radio_config, **cm_kwargs):
"""Returns a decorator that does ConnectionManager test boilerplate."""
def inner(f):
"""The actual decorator."""
@@ -388,7 +414,8 @@
wpa_control_interface=wpa_control_interface,
run_duration_s=run_duration_s,
interface_update_period=interface_update_period,
- wifi_scan_period_s=wifi_scan_period_s)
+ wifi_scan_period_s=wifi_scan_period_s,
+ **cm_kwargs)
c.test_interface_update_period = interface_update_period
c.test_wifi_scan_period = wifi_scan_period
@@ -720,6 +747,7 @@
wvtest.WVPASS(c.wifi_for_band('5').current_route())
+
@wvtest.wvtest
@connection_manager_test(WIFI_SHOW_OUTPUT_ONE_RADIO_NO_5GHZ)
def connection_manager_test_one_radio_no_5ghz(c):
@@ -757,5 +785,18 @@
wvtest.WVPASS(c.wifi_for_band('2.4').current_route())
+@wvtest.wvtest
+@connection_manager_test(WIFI_SHOW_OUTPUT_ONE_RADIO,
+ __test_interfaces_already_up=['eth0', 'wcli0'])
+def connection_manager_test_wifi_already_up(c):
+ """Test ConnectionManager when wifi is already up.
+
+ Args:
+ c: The ConnectionManager set up by @connection_manager_test.
+ """
+ wvtest.WVPASS(c._connected_to_wlan(c.wifi_for_band('2.4')))
+ wvtest.WVPASS(c.wifi_for_band('2.4').current_route)
+
+
if __name__ == '__main__':
wvtest.wvtest_main()
diff --git a/conman/interface.py b/conman/interface.py
index 0a26959..9b9c653 100755
--- a/conman/interface.py
+++ b/conman/interface.py
@@ -306,6 +306,7 @@
self.bands = kwargs.pop('bands', [])
super(Wifi, self).__init__(*args, **kwargs)
self._wpa_control = None
+ self.initial_ssid = None
@property
def wpa_supplicant(self):
@@ -331,8 +332,14 @@
logging.error('Error attaching to wpa_supplicant: %s', e)
return
- self.wpa_supplicant = ('wpa_state=COMPLETED' in
- self._wpa_control.request('STATUS'))
+ for line in self._wpa_control.request('STATUS').splitlines():
+ if '=' not in line:
+ continue
+ key, value = line.split('=', 1)
+ if key == 'wpa_state':
+ self.wpa_supplicant = value == 'COMPLETED'
+ elif key == 'ssid' and not self._initialized:
+ self.initial_ssid = value
def get_wpa_control(self, socket):
return wpactrl.WPACtrl(socket)
@@ -367,3 +374,10 @@
break
self.update_routes()
+
+ def initialize(self):
+ """Unset self.initial_ssid, which is only relevant during initialization."""
+
+ self.initial_ssid = None
+ super(Wifi, self).initialize()
+
diff --git a/conman/interface_test.py b/conman/interface_test.py
index 6368a83..1e86125 100755
--- a/conman/interface_test.py
+++ b/conman/interface_test.py
@@ -89,7 +89,8 @@
def request(self, request_type):
if request_type == 'STATUS':
- return 'foo\nwpa_state=COMPLETED\nbar' if self.connected else 'foo'
+ return ('foo\nwpa_state=COMPLETED\nssid=my ssid\nbar' if self.connected
+ else 'foo')
else:
raise ValueError('Invalid request_type %s' % request_type)
@@ -219,11 +220,15 @@
w.detach_wpa_control()
# pylint: disable=protected-access
w._initially_connected = True
+ w._initialized = False
w.attach_wpa_control(wpa_path)
wpa_control = w._wpa_control
# wpa_supplicant was already connected when we attached.
wvtest.WVPASS(w.wpa_supplicant)
+ wvtest.WVPASSEQ(w.initial_ssid, 'my ssid')
+ w.initialize()
+ wvtest.WVPASSEQ(w.initial_ssid, None)
# The wpa_supplicant process disconnects and terminates.
wpa_control.add_event(Wifi.DISCONNECTED_EVENT)
diff --git a/taxonomy/ethernet.py b/taxonomy/ethernet.py
index f8966f3..d0aaf45 100644
--- a/taxonomy/ethernet.py
+++ b/taxonomy/ethernet.py
@@ -61,6 +61,7 @@
'7c:61:93': ['htc'],
'84:7a:88': ['htc'],
'90:e7:c4': ['htc'],
+ 'a0:f4:50': ['htc'],
'b4:ce:f6': ['htc'],
'd8:b3:77': ['htc'],
'e8:99:c4': ['htc'],
@@ -110,6 +111,7 @@
'14:7d:c5': ['murata'],
'1c:99:4c': ['murata'],
'20:02:af': ['murata'],
+ '40:f3:08': ['murata'],
'44:a7:cf': ['murata'],
'5c:da:d4': ['murata'],
'78:4b:87': ['murata'],
diff --git a/taxonomy/pcaptest.py b/taxonomy/pcaptest.py
index a44a7b6..c7863fb 100644
--- a/taxonomy/pcaptest.py
+++ b/taxonomy/pcaptest.py
@@ -25,6 +25,9 @@
('Unknown', './testdata/pcaps/HTC Evo 2.4GHz.pcap'),
('Unknown', './testdata/pcaps/HTC Incredible 2.4GHz.pcap'),
('Unknown', './testdata/pcaps/HTC Inspire 2.4GHz.pcap'),
+ ('Unknown', './testdata/pcaps/HTC One V 2.4GHz.pcap'),
+ ('Unknown', './testdata/pcaps/HTC One X 2.4GHz.pcap'),
+ ('Unknown', './testdata/pcaps/HTC One X 5GHz.pcap'),
('Unknown', './testdata/pcaps/HTC Sensation 2.4GHz.pcap'),
('Unknown', './testdata/pcaps/HTC Thunderbolt 2.4GHz.pcap'),
('Unknown', './testdata/pcaps/HTC Titan 2.4GHz.pcap'),
@@ -46,7 +49,6 @@
('Unknown', './testdata/pcaps/Samsung Exhibit 2.4GHz.pcap'),
('Unknown', './testdata/pcaps/Samsung Fascinate 2.4GHz.pcap'),
('Unknown', './testdata/pcaps/Samsung Galaxy Tab 2 2.4GHz.pcap'),
- ('Unknown', './testdata/pcaps/Samsung Infuse 2.4GHz.pcap'),
('Unknown', './testdata/pcaps/Samsung Infuse 5GHz.pcap'),
('Unknown', './testdata/pcaps/Samsung Vibrant 2.4GHz.pcap'),
('Unknown', './testdata/pcaps/Sony Xperia Z5 2.4GHz.pcap'),
@@ -57,6 +59,10 @@
# work for these, instead we add them explicitly.
('iPad (1st/2nd gen)', './testdata/pcaps/iPad 1st gen 5GHz.pcap'),
('iPad (1st/2nd gen)', './testdata/pcaps/iPad 2nd gen 5GHz.pcap'),
+ ('iPad (4th gen or Air)', './testdata/pcaps/iPad (4th gen) 5GHz.pcap'),
+ ('iPad (4th gen or Air)', './testdata/pcaps/iPad (4th gen) 2.4GHz.pcap'),
+ ('iPad (4th gen or Air)', './testdata/pcaps/iPad Air 5GHz.pcap'),
+ ('iPad (4th gen or Air)', './testdata/pcaps/iPad Air 2.4GHz.pcap'),
('iPhone 6/6+', './testdata/pcaps/iPhone 6 5GHz.pcap'),
('iPhone 6/6+', './testdata/pcaps/iPhone 6+ 5GHz.pcap'),
('iPhone 6s/6s+', './testdata/pcaps/iPhone 6s 2.4GHz.pcap'),
@@ -65,6 +71,8 @@
('iPhone 6s/6s+', './testdata/pcaps/iPhone 6s+ 5GHz.pcap'),
('iPod Touch 1st/2nd gen', './testdata/pcaps/iPod Touch 1st gen 2.4GHz.pcap'),
('Nest Thermostat v1/v2', './testdata/pcaps/Nest Thermostat 2.4GHz.pcap'),
+ ('Samsung Galaxy S2 or Infuse', './testdata/pcaps/Samsung Galaxy S2 2.4GHz.pcap'),
+ ('Samsung Galaxy S2 or Infuse', './testdata/pcaps/Samsung Infuse 2.4GHz.pcap'),
]
diff --git a/taxonomy/testdata/dhcp.leases b/taxonomy/testdata/dhcp.leases
index 4bbfb3d..64aa1ca 100644
--- a/taxonomy/testdata/dhcp.leases
+++ b/taxonomy/testdata/dhcp.leases
@@ -45,3 +45,4 @@
1432237016 04:0c:ce:cf:40:2c 192.168.42.35 MacbookAir2010
1432237016 8c:2d:aa:9c:ce:0f 192.168.42.36 iPood-5
1432237016 dc:86:d8:a0:c8:de 192.168.42.37 iPhoone-5c
+1432237016 54:ae:27:32:ef:7f 192.168.42.38 iPaad-Air-1
diff --git a/taxonomy/testdata/dhcp.signatures b/taxonomy/testdata/dhcp.signatures
index 5a1ef1d..4831315 100644
--- a/taxonomy/testdata/dhcp.signatures
+++ b/taxonomy/testdata/dhcp.signatures
@@ -37,3 +37,4 @@
04:0c:ce:cf:40:2c 1,3,6,15,119,95,252,44,46
8c:2d:aa:9c:ce:0f 1,3,6,15,119,252
dc:86:d8:a0:c8:de 1,3,6,15,119,252
+54:ae:27:32:ef:7f 1,3,6,15,119,252
diff --git a/taxonomy/testdata/pcaps/HTC One V 2.4GHz.pcap b/taxonomy/testdata/pcaps/HTC One V 2.4GHz.pcap
new file mode 100644
index 0000000..5efec50
--- /dev/null
+++ b/taxonomy/testdata/pcaps/HTC One V 2.4GHz.pcap
Binary files differ
diff --git a/taxonomy/testdata/pcaps/HTC One X 2.4GHz.pcap b/taxonomy/testdata/pcaps/HTC One X 2.4GHz.pcap
new file mode 100644
index 0000000..e57a6b2
--- /dev/null
+++ b/taxonomy/testdata/pcaps/HTC One X 2.4GHz.pcap
Binary files differ
diff --git a/taxonomy/testdata/pcaps/HTC One X 5GHz.pcap b/taxonomy/testdata/pcaps/HTC One X 5GHz.pcap
new file mode 100644
index 0000000..9a25012
--- /dev/null
+++ b/taxonomy/testdata/pcaps/HTC One X 5GHz.pcap
Binary files differ
diff --git a/taxonomy/testdata/pcaps/Moto X 2.4GHz Broadcast.pcap b/taxonomy/testdata/pcaps/Moto X 2.4GHz Broadcast.pcap
new file mode 100644
index 0000000..045ec57
--- /dev/null
+++ b/taxonomy/testdata/pcaps/Moto X 2.4GHz Broadcast.pcap
Binary files differ
diff --git a/taxonomy/testdata/pcaps/Moto X 2.4GHz Specific.pcap b/taxonomy/testdata/pcaps/Moto X 2.4GHz Specific.pcap
new file mode 100644
index 0000000..0399b6c
--- /dev/null
+++ b/taxonomy/testdata/pcaps/Moto X 2.4GHz Specific.pcap
Binary files differ
diff --git a/taxonomy/testdata/pcaps/Moto X 2.4GHz.pcap b/taxonomy/testdata/pcaps/Moto X 2.4GHz.pcap
new file mode 100644
index 0000000..40e0ca1
--- /dev/null
+++ b/taxonomy/testdata/pcaps/Moto X 2.4GHz.pcap
Binary files differ
diff --git a/taxonomy/testdata/pcaps/Moto X 5GHz.pcap b/taxonomy/testdata/pcaps/Moto X 5GHz.pcap
new file mode 100644
index 0000000..dffcc63
--- /dev/null
+++ b/taxonomy/testdata/pcaps/Moto X 5GHz.pcap
Binary files differ
diff --git a/taxonomy/testdata/pcaps/Samsung Galaxy S2 2.4GHz.pcap b/taxonomy/testdata/pcaps/Samsung Galaxy S2 2.4GHz.pcap
new file mode 100644
index 0000000..e772fa8
--- /dev/null
+++ b/taxonomy/testdata/pcaps/Samsung Galaxy S2 2.4GHz.pcap
Binary files differ
diff --git a/taxonomy/testdata/pcaps/Samsung Galaxy S2 5GHz.pcap b/taxonomy/testdata/pcaps/Samsung Galaxy S2 5GHz.pcap
new file mode 100644
index 0000000..035fc85
--- /dev/null
+++ b/taxonomy/testdata/pcaps/Samsung Galaxy S2 5GHz.pcap
Binary files differ
diff --git a/taxonomy/testdata/pcaps/Samsung Galaxy S4 2.4GHz I9505.pcap b/taxonomy/testdata/pcaps/Samsung Galaxy S4 2.4GHz I9505.pcap
new file mode 100644
index 0000000..83832ba
--- /dev/null
+++ b/taxonomy/testdata/pcaps/Samsung Galaxy S4 2.4GHz I9505.pcap
Binary files differ
diff --git a/taxonomy/testdata/pcaps/Samsung Galaxy S4 5GHz I9505.pcap b/taxonomy/testdata/pcaps/Samsung Galaxy S4 5GHz I9505.pcap
new file mode 100644
index 0000000..ed78fc2
--- /dev/null
+++ b/taxonomy/testdata/pcaps/Samsung Galaxy S4 5GHz I9505.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/iPad \0504th gen\051 2.4GHz.pcap" "b/taxonomy/testdata/pcaps/iPad \0504th gen\051 2.4GHz.pcap"
new file mode 100644
index 0000000..7eb0924
--- /dev/null
+++ "b/taxonomy/testdata/pcaps/iPad \0504th gen\051 2.4GHz.pcap"
Binary files differ
diff --git a/taxonomy/testdata/pcaps/iPad Air 2.4GHz.pcap b/taxonomy/testdata/pcaps/iPad Air 2.4GHz.pcap
new file mode 100644
index 0000000..6d6fabb
--- /dev/null
+++ b/taxonomy/testdata/pcaps/iPad Air 2.4GHz.pcap
Binary files differ
diff --git a/taxonomy/testdata/pcaps/iPad Air 5GHz.pcap b/taxonomy/testdata/pcaps/iPad Air 5GHz.pcap
new file mode 100644
index 0000000..fac188d
--- /dev/null
+++ b/taxonomy/testdata/pcaps/iPad Air 5GHz.pcap
Binary files differ
diff --git a/taxonomy/wifi.py b/taxonomy/wifi.py
index b7cfaa6..c312c05 100644
--- a/taxonomy/wifi.py
+++ b/taxonomy/wifi.py
@@ -179,21 +179,21 @@
('BCM4330', 'iPad (3rd gen)', '2.4GHz'),
'wifi3|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01fe,htagg:1b,htmcs:0000ffff,intwrk:0f,extcap:00000804|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),cap:0011,htcap:01fe,htagg:1b,htmcs:0000ffff,txpow:e708|os:ios':
- ('BCM4334', 'iPad (4th gen)', '5GHz'),
+ ('BCM4334', 'iPad (4th gen or Air)', '5GHz'),
'wifi3|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01fe,htagg:1b,htmcs:0000ffff,intwrk:0f,extcap:00000804|assoc:0,1,33,36,48,45,70,221(001018,2),221(00904c,51),221(0050f2,2),cap:0011,htcap:01fe,htagg:1b,htmcs:0000ffff,txpow:e708|os:ios':
- ('BCM4334', 'iPad (4th gen)', '5GHz'),
+ ('BCM4334', 'iPad (4th gen or Air)', '5GHz'),
'wifi3|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01fe,htagg:1b,htmcs:0000ffff,intwrk:ff,extcap:00000804|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),cap:0011,htcap:01fe,htagg:1b,htmcs:0000ffff,txpow:e708|os:ios':
- ('BCM4334', 'iPad (4th gen)', '5GHz'),
+ ('BCM4334', 'iPad (4th gen or Air)', '5GHz'),
'wifi3|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01fe,htagg:1b,htmcs:0000ffff,intwrk:ff,extcap:00000804|assoc:0,1,33,36,48,45,70,221(001018,2),221(00904c,51),221(0050f2,2),cap:0011,htcap:01fe,htagg:1b,htmcs:0000ffff,txpow:e708|os:ios':
- ('BCM4334', 'iPad (4th gen)', '5GHz'),
+ ('BCM4334', 'iPad (4th gen or Air)', '5GHz'),
'wifi3|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01bc,htagg:1b,htmcs:0000ffff,intwrk:0f,extcap:00000804|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),cap:0431,htcap:01bc,htagg:1b,htmcs:0000ffff,txpow:1805|os:ios':
- ('BCM4334', 'iPad (4th gen)', '2.4GHz'),
+ ('BCM4334', 'iPad (4th gen or Air)', '2.4GHz'),
'wifi3|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01bc,htagg:1b,htmcs:0000ffff,intwrk:0f,extcap:00000804|assoc:0,1,33,36,48,50,45,70,221(001018,2),221(00904c,51),221(0050f2,2),cap:0431,htcap:01bc,htagg:1b,htmcs:0000ffff,txpow:1805|os:ios':
- ('BCM4334', 'iPad (4th gen)', '2.4GHz'),
+ ('BCM4334', 'iPad (4th gen or Air)', '2.4GHz'),
'wifi3|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01bc,htagg:1b,htmcs:0000ffff,intwrk:ff,extcap:00000804|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),cap:0431,htcap:01bc,htagg:1b,htmcs:0000ffff,txpow:1805|os:ios':
- ('BCM4334', 'iPad (4th gen)', '2.4GHz'),
+ ('BCM4334', 'iPad (4th gen or Air)', '2.4GHz'),
'wifi3|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01bc,htagg:1b,htmcs:0000ffff,intwrk:ff,extcap:00000804|assoc:0,1,33,36,48,50,45,70,221(001018,2),221(00904c,51),221(0050f2,2),cap:0431,htcap:01bc,htagg:1b,htmcs:0000ffff,txpow:1805|os:ios':
- ('BCM4334', 'iPad (4th gen)', '2.4GHz'),
+ ('BCM4334', 'iPad (4th gen or Air)', '2.4GHz'),
'wifi|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01fe|assoc:0,1,33,36,48,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:01fe|os:ios':
('BCM43241', 'iPad Air (1st gen)', '5GHz'),
@@ -382,6 +382,8 @@
'wifi3|probe:0,1,45,221(00904c,51),htcap:09ef,htagg:1b,htmcs:0000ffff|assoc:0,1,33,36,48,45,221(00904c,51),221(0050f2,2),cap:0011,htcap:09ef,htagg:1b,htmcs:0000ffff,txpow:0005|os:macos':
('BCM4331', 'MacBook Pro 17" late 2011 (A1297)', '5GHz'),
+ 'wifi3|probe:0,1,3,45,221(00904c,51),htcap:09ef,htagg:1b,htmcs:0000ffff|assoc:0,1,33,36,48,45,221(00904c,51),221(0050f2,2),cap:0011,htcap:09ef,htagg:1b,htmcs:0000ffff,txpow:0005|os:macos':
+ ('BCM4331', 'MacBook Pro 17" late 2011 (A1297)', '5GHz'),
'wifi3|probe:0,1,50,3,45,221(00904c,51),htcap:19ad,htagg:1b,htmcs:0000ffff|assoc:0,1,33,36,48,50,45,221(00904c,51),221(0050f2,2),cap:0431,htcap:19ad,htagg:1b,htmcs:0000ffff,txpow:1305|os:macos':
('BCM4331', 'MacBook Pro 17" late 2011 (A1297)', '2.4GHz'),
@@ -413,9 +415,11 @@
'wifi3|probe:0,1,50,3,45,221(0050f2,8),htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),127,cap:8431,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02|oui:motorola':
('QCA_WCN3620', 'Moto G or Moto X', '2.4GHz'),
- 'wifi|probe:0,1,45,221(0050f2,8),191,htcap:016e,vhtcap:31800120|assoc:0,1,33,36,48,45,221(0050f2,2),191,127,htcap:016e,vhtcap:31800120|oui:motorola':
+ 'wifi3|probe:0,1,45,221(0050f2,8),191,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31800120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe|assoc:0,1,48,45,221(0050f2,2),191,127,127,cap:0431,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31800120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:00000a02|oui:motorola':
('QCA_WCN3680', 'Moto X', '5GHz'),
- 'wifi|probe:0,1,50,3,45,221(0050f2,8),191,htcap:012c,vhtcap:31800120|assoc:0,1,50,48,45,221(0050f2,2),htcap:012c|oui:motorola':
+ 'wifi3|probe:0,1,50,3,45,221(0050f2,8),htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),127,cap:0431,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02|oui:motorola':
+ ('QCA_WCN3680', 'Moto X', '2.4GHz'),
+ 'wifi3|probe:0,1,50,3,45,221(0050f2,8),191,htcap:012c,htagg:03,htmcs:000000ff,vhtcap:31800120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe|assoc:0,1,50,48,45,221(0050f2,2),127,cap:0431,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02|oui:motorola':
('QCA_WCN3680', 'Moto X', '2.4GHz'),
'wifi3|probe:0,1,3,45,221(0050f2,8),191,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31805120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe|assoc:0,1,48,45,221(0050f2,2),191,127,127,cap:8431,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31805120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:00000a02|oui:motorola':
@@ -658,6 +662,23 @@
'wifi3|probe:0,1,50,3,45,127,107,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:01ad,htagg:17,htmcs:0000ffff,intwrk:0f,extcap:00080f8401400040|assoc:0,1,50,33,36,48,45,221(001018,2),221(0050f2,2),cap:0431,htcap:01ad,htagg:17,htmcs:0000ffff,txpow:1202|oui:murata':
('BCM4359', 'Samsung Galaxy Note 5', '2.4GHz'),
+ 'wifi3|probe:0,1,45,221(001018,2),221(00904c,51),htcap:000c,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),cap:0011,htcap:000c,htagg:19,htmcs:000000ff,txpow:0f0a|oui:samsung':
+ ('', 'Samsung Galaxy S2', '5GHz'),
+ 'wifi3|probe:0,1,45,221(001018,2),221(00904c,51),htcap:000c,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),cap:0011,htcap:000c,htagg:19,htmcs:000000ff,txpow:0f0a|oui:murata':
+ ('', 'Samsung Galaxy S2', '5GHz'),
+ 'wifi3|probe:0,1,45,3,221(001018,2),221(00904c,51),htcap:000c,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),cap:0011,htcap:000c,htagg:19,htmcs:000000ff,txpow:0f0a|oui:samsung':
+ ('', 'Samsung Galaxy S2', '5GHz'),
+ 'wifi3|probe:0,1,45,3,221(001018,2),221(00904c,51),htcap:000c,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),cap:0011,htcap:000c,htagg:19,htmcs:000000ff,txpow:0f0a|oui:murata':
+ ('', 'Samsung Galaxy S2', '5GHz'),
+ 'wifi3|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:100c,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),cap:0431,htcap:100c,htagg:19,htmcs:000000ff,txpow:120a|oui:samsung':
+ ('', 'Samsung Galaxy S2 or Infuse','2.4GHz'),
+ 'wifi3|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:100c,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),cap:0431,htcap:100c,htagg:19,htmcs:000000ff,txpow:120a|oui:murata':
+ ('', 'Samsung Galaxy S2 or Infuse','2.4GHz'),
+ 'wifi3|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:100c,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),cap:0431,htcap:100c,htagg:19,htmcs:000000ff,txpow:120a|oui:samsung':
+ ('', 'Samsung Galaxy S2 or Infuse','2.4GHz'),
+ 'wifi3|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:100c,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),cap:0431,htcap:100c,htagg:19,htmcs:000000ff,txpow:120a|oui:murata':
+ ('', 'Samsung Galaxy S2 or Infuse','2.4GHz'),
+
'wifi3|probe:0,1,45,3,221(001018,2),221(00904c,51),htcap:000c,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),cap:0011,htcap:000c,htagg:19,htmcs:000000ff,txpow:0f09|oui:samsung':
('', 'Samsung Galaxy S2+', '5GHz'),
'wifi3|probe:0,1,45,3,221(001018,2),221(00904c,51),htcap:000c,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),cap:0011,htcap:000c,htagg:19,htmcs:000000ff,txpow:0f09|oui:murata':
@@ -712,6 +733,10 @@
('BCM4335', 'Samsung Galaxy S4', '2.4GHz'),
'wifi3|probe:0,1,50,45,127,221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:102d,htagg:17,htmcs:000000ff,extcap:0000080000000040|assoc:0,1,33,36,48,50,45,221(001018,2),221(0050f2,2),cap:0431,htcap:102d,htagg:17,htmcs:000000ff,txpow:1201|oui:murata':
('BCM4335', 'Samsung Galaxy S4', '2.4GHz'),
+ 'wifi3|probe:0,1,50,45,127,107,221(506f9a,16),221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:102d,htagg:17,htmcs:000000ff,intwrk:0f,extcap:0000088000400040|assoc:0,1,33,36,48,50,45,127,107,221(001018,2),221(0050f2,2),cap:0431,htcap:102d,htagg:17,htmcs:000000ff,txpow:1201,intwrk:0f,extcap:000000800040|oui:samsung':
+ ('BCM4335', 'Samsung Galaxy S4', '2.4GHz'),
+ 'wifi3|probe:0,1,50,45,127,107,221(506f9a,16),221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:102d,htagg:17,htmcs:000000ff,intwrk:0f,extcap:0000088000400040|assoc:0,1,33,36,48,50,45,127,107,221(001018,2),221(0050f2,2),cap:0431,htcap:102d,htagg:17,htmcs:000000ff,txpow:1201,intwrk:0f,extcap:000000800040|oui:murata':
+ ('BCM4335', 'Samsung Galaxy S4', '2.4GHz'),
'wifi3|probe:0,1,45,127,107,191,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,intwrk:0f,extcap:0000088001400040|assoc:0,1,33,36,48,45,127,107,191,221(00904c,4),221(001018,2),221(0050f2,2),cap:0011,htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e20b,intwrk:0f,extcap:0000088001400040|oui:samsung':
('BCM4354', 'Samsung Galaxy S5', '5GHz'),
diff --git a/waveguide/fake/taxonomy/9c:d9:17:00:00:02 b/waveguide/fake/taxonomy/9c:d9:17:00:00:02
index 43be77d..8d6402c 100644
--- a/waveguide/fake/taxonomy/9c:d9:17:00:00:02
+++ b/waveguide/fake/taxonomy/9c:d9:17:00:00:02
@@ -1 +1 @@
-wifi|probe:0,1,45,221(0050f2,8),191,htcap:016e,vhtcap:31800120|assoc:0,1,33,36,48,45,221(0050f2,2),191,127,htcap:016e,vhtcap:31800120
+wifi3|probe:0,1,50,3,45,221(0050f2,8),htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),127,cap:0431,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02
diff --git a/wifi/quantenna.py b/wifi/quantenna.py
index 7ad4079..10af967 100755
--- a/wifi/quantenna.py
+++ b/wifi/quantenna.py
@@ -9,29 +9,52 @@
import utils
+ALREADY_MEMBER_FMT = ('device %s is already a member of a bridge; '
+ "can't enslave it to bridge %s.")
+NOT_MEMBER_FMT = 'device %s is not a slave of %s'
+
+
def _get_interface():
- return subprocess.check_output(['get-quantenna-interface']).strip() or None
+ return subprocess.check_output(['get-quantenna-interface']).strip()
-def _get_qcsapi():
- # qcsapi_pcie_static runs on PCIe hosts, e.g. GFRG250.
- # call_qcsapi runs on the LHOST, e.g. GFEX250.
- return next((qcsapi for qcsapi in ['qcsapi_pcie_static', 'call_qcsapi']
- if utils.subprocess_quiet(['runnable', qcsapi]) == 0), None)
-
-
-def _get_mac_address():
- var = {'wlan0': 'MAC_ADDR_WIFI', 'wlan1': 'MAC_ADDR_WIFI2'}[_get_interface()]
+def _get_mac_address(interface):
+ try:
+ var = {'wlan0': 'MAC_ADDR_WIFI', 'wlan1': 'MAC_ADDR_WIFI2'}[interface]
+ except KeyError:
+ raise utils.BinWifiException('no MAC address for %s in hnvram' % interface)
return subprocess.check_output(['hnvram', '-rq', var]).strip()
def _qcsapi(*args):
- return subprocess.check_output([_get_qcsapi()] + list(args)).strip()
+ return subprocess.check_output(['qcsapi'] + list(args)).strip()
+
+
+def _brctl(*args):
+ return subprocess.check_output(['brctl'] + list(args),
+ stderr=subprocess.STDOUT).strip()
+
+
+def _set_interface_in_bridge(bridge, interface, want_in_bridge):
+ """Add/remove Quantenna interface from/to the bridge."""
+ if want_in_bridge:
+ command = 'addif'
+ error_fmt = ALREADY_MEMBER_FMT
+ else:
+ command = 'delif'
+ error_fmt = NOT_MEMBER_FMT
+
+ try:
+ _brctl(command, bridge, interface)
+ except subprocess.CalledProcessError as e:
+ if error_fmt % (interface, bridge) not in e.output:
+ raise utils.BinWifiException(e.output)
def _set(mode, opt):
"""Enable wifi."""
- if not _get_interface() or not _get_qcsapi():
+ interface = _get_interface()
+ if not interface:
return False
_qcsapi('rfenable', '0')
@@ -47,7 +70,7 @@
for param, value in config.iteritems():
_qcsapi('update_config_param', 'wifi0', param, value)
- _qcsapi('set_mac_addr', 'wifi0', _get_mac_address())
+ _qcsapi('set_mac_addr', 'wifi0', _get_mac_address(interface))
if int(_qcsapi('is_startprod_done')):
_qcsapi('reload_in_mode', 'wifi0', mode)
@@ -61,12 +84,14 @@
raise utils.BinWifiException('startprod timed out')
if mode == 'ap':
+ _set_interface_in_bridge(opt.bridge, interface, True)
_qcsapi('set_ssid', 'wifi0', opt.ssid)
_qcsapi('set_passphrase', 'wifi0', '0', os.environ['WIFI_PSK'])
_qcsapi('set_option', 'wifi0', 'ssid_broadcast',
'0' if opt.hidden_mode else '1')
_qcsapi('rfenable', '1')
elif mode == 'sta':
+ _set_interface_in_bridge(opt.bridge, interface, False)
_qcsapi('create_ssid', 'wifi0', opt.ssid)
_qcsapi('ssid_set_passphrase', 'wifi0', opt.ssid, '0',
os.environ['WIFI_CLIENT_PSK'])
@@ -79,7 +104,7 @@
def _stop(_):
"""Disable wifi."""
- if not _get_interface() or not _get_qcsapi():
+ if not _get_interface():
return False
_qcsapi('rfenable', '0')
diff --git a/wifi/quantenna_test.py b/wifi/quantenna_test.py
index 1f99d41..72f0333 100755
--- a/wifi/quantenna_test.py
+++ b/wifi/quantenna_test.py
@@ -3,6 +3,8 @@
"""Tests for quantenna.py."""
import os
+from subprocess import CalledProcessError
+
from configs_test import FakeOptDict
import quantenna
from wvtest import wvtest
@@ -17,14 +19,39 @@
return '1\n' if ['startprod', 'wifi0'] in calls else '0\n'
-def set_fakes(interface='wlan1', qcsapi='qcsapi_pcie_static'):
+bridge_interfaces = set()
+
+
+def fake_brctl(*args):
+ bridge = args[-2]
+ wvtest.WVPASS(bridge == 'br0')
+ interface = args[-1]
+ if 'addif' in args:
+ if interface in bridge_interfaces:
+ raise CalledProcessError(
+ returncode=1, cmd=['brctl'] + list(args),
+ output=quantenna.ALREADY_MEMBER_FMT % (interface, bridge))
+ bridge_interfaces.add(interface)
+ return
+
+ if 'delif' in args:
+ if interface not in bridge_interfaces:
+ raise CalledProcessError(
+ returncode=1, cmd=['brctl'] + list(args),
+ output=quantenna.NOT_MEMBER_FMT % (interface, bridge))
+ bridge_interfaces.remove(interface)
+ return
+
+
+def set_fakes(interface='wlan1'):
del calls[:]
+ bridge_interfaces.clear()
os.environ['WIFI_PSK'] = 'wifi_psk'
os.environ['WIFI_CLIENT_PSK'] = 'wifi_client_psk'
quantenna._get_interface = lambda: interface
- quantenna._get_qcsapi = lambda: qcsapi
- quantenna._get_mac_address = lambda: '00:11:22:33:44:55'
+ quantenna._get_mac_address = lambda _: '00:11:22:33:44:55'
quantenna._qcsapi = fake_qcsapi
+ quantenna._brctl = fake_brctl
def matching_calls_indices(accept):
@@ -40,13 +67,12 @@
wvtest.WVFAIL(quantenna.stop_ap_wifi(opt))
wvtest.WVFAIL(quantenna.stop_client_wifi(opt))
wvtest.WVPASSEQ(calls, [])
- set_fakes(qcsapi='')
wvtest.WVFAIL(quantenna.set_wifi(opt))
wvtest.WVFAIL(quantenna.set_client_wifi(opt))
wvtest.WVFAIL(quantenna.stop_ap_wifi(opt))
wvtest.WVFAIL(quantenna.stop_client_wifi(opt))
wvtest.WVPASSEQ(calls, [])
- set_fakes(interface='', qcsapi='')
+ set_fakes(interface='')
wvtest.WVFAIL(quantenna.set_wifi(opt))
wvtest.WVFAIL(quantenna.set_client_wifi(opt))
wvtest.WVFAIL(quantenna.stop_ap_wifi(opt))
@@ -57,10 +83,12 @@
@wvtest.wvtest
def set_wifi_test():
opt = FakeOptDict()
+ opt.bridge = 'br0'
set_fakes()
# Run set_wifi for the first time.
wvtest.WVPASS(quantenna.set_wifi(opt))
+ wvtest.WVPASS('wlan1' in bridge_interfaces)
# 'rfenable 0' must be run first so that a live interface is not being
# modified.
@@ -104,6 +132,7 @@
opt.width = '80'
new_calls_start = len(calls)
wvtest.WVPASS(quantenna.set_client_wifi(opt))
+ wvtest.WVFAIL('wlan1' in bridge_interfaces)
# Clear old calls.
del calls[:new_calls_start]
@@ -143,6 +172,13 @@
wvtest.WVPASSLT(rim, i[0])
wvtest.WVPASSLT(i[-1], calls.index(['apply_security_config', 'wifi0']))
+ # Make sure subsequent equivalent calls don't fail despite the redundant
+ # bridge changes.
+ wvtest.WVPASS(quantenna.set_client_wifi(opt))
+ wvtest.WVPASS(quantenna.set_client_wifi(opt))
+ wvtest.WVPASS(quantenna.set_wifi(opt))
+ wvtest.WVPASS(quantenna.set_wifi(opt))
+
@wvtest.wvtest
def stop_wifi_test():