conman: Handle missing wifi interface.
In b/27328894, there was no reported 5 GHz wifi interface. conman
will now not crash when this happens, but log an error and proceed as
normal with other interfaces.
Change-Id: I1a82f75b95376d4208aa395bac5d9e2ff01836df
diff --git a/conman/connection_manager.py b/conman/connection_manager.py
index abfcb36..eaaf7cf 100755
--- a/conman/connection_manager.py
+++ b/conman/connection_manager.py
@@ -147,7 +147,7 @@
try:
subprocess.check_output(self.WIFI_STOPCLIENT + ['-b', self.band],
- stderr=subprocess.STDOUT)
+ stderr=subprocess.STDOUT)
self.client_up = False
logging.debug('Stopped wifi client on %s GHz', self.band)
except subprocess.CalledProcessError as e:
@@ -483,15 +483,16 @@
match = re.match(self.COMMAND_FILE_REGEXP, filename)
if match:
band = match.group('band')
- wifi = next(w for w in self.wifi if band in w.bands)
- self._update_wlan_configuration(
- self.WLANConfiguration(band, wifi, contents))
+ wifi = self.wifi_for_band(band)
+ if wifi:
+ self._update_wlan_configuration(
+ self.WLANConfiguration(band, wifi, contents))
elif filename.startswith(self.ACCESS_POINT_FILE_PREFIX):
match = re.match(self.ACCESS_POINT_FILE_REGEXP, filename)
if match:
band = match.group('band')
- wifi = next(w for w in self.wifi if band in w.bands)
- if band in self._wlan_configuration:
+ wifi = self.wifi_for_band(band)
+ if wifi and band in self._wlan_configuration:
self._wlan_configuration[band].access_point = True
logging.debug('AP enabled for %s GHz', band)
@@ -527,6 +528,15 @@
if ifc.name == interface_name:
return ifc
+ def wifi_for_band(self, band):
+ for wifi in self.wifi:
+ if band in wifi.bands:
+ return wifi
+
+ logging.error('No wifi interface for %s GHz. wlan interfaces:\n%s',
+ band, '\n'.join('%s: %r' %
+ (w.name, w.bands) for w in self.wifi))
+
def ifplugd_action(self, interface_name, up):
subprocess.call(self.IFPLUGD_ACTION + [interface_name,
'up' if up else 'down'])
diff --git a/conman/connection_manager_test.py b/conman/connection_manager_test.py
index 19264f7..4ebd48b 100755
--- a/conman/connection_manager_test.py
+++ b/conman/connection_manager_test.py
@@ -76,6 +76,21 @@
Client BSSID: f4:f5:e8:81:1b:a1
"""
+# See b/27328894.
+WIFI_SHOW_OUTPUT_ONE_RADIO_NO_5GHZ = """Band: 2.4
+RegDomain: 00
+Interface: wlan0 # 2.4 GHz ap
+BSSID: 00:50:43:02:fe:01
+AutoChannel: False
+Station List for band: 2.4
+
+Client Interface: wcli0 # 2.4 GHz client
+Client BSSID: 00:50:43:02:fe:02
+
+Band: 5
+RegDomain: 00
+"""
+
IW_SCAN_OUTPUT = """BSS 00:11:22:33:44:55(on wcli0)
SSID: s1
Vendor specific: OUI f4:f5:e8, data: 01
@@ -265,11 +280,6 @@
# Non-overrides
- def wifi_for_band(self, band):
- for wifi in self.wifi:
- if band in wifi.bands:
- return wifi
-
def access_point_up(self, band):
if band not in self._wlan_configuration:
return False
@@ -710,5 +720,42 @@
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):
+ """Test ConnectionManager for the case documented in b/27328894.
+
+ conman should be able to handle the lack of 5 GHz without actually
+ crashing. Wired connections should not be affected.
+
+ Args:
+ c: The ConnectionManager set up by @connection_manager_test.
+ """
+ # Make sure we've correctly set up the test; that there is no 5 GHz wifi
+ # interface.
+ wvtest.WVPASSEQ(c.wifi_for_band('5'), None)
+
+ c.set_ethernet(True)
+ wvtest.WVPASS(c.acs())
+ wvtest.WVPASS(c.internet())
+
+ # Make sure this doesn't crash.
+ c.write_wlan_config('5', 'my ssid', 'my psk')
+ c.run_once()
+ c.enable_access_point('5')
+ c.run_once()
+ c.disable_access_point('5')
+ c.run_once()
+ c.delete_wlan_config('5')
+ c.run_once()
+
+ # Make sure 2.4 still works.
+ c.write_wlan_config('2.4', 'my ssid', 'my psk')
+ c.run_once()
+ wvtest.WVPASS(c.wifi_for_band('2.4').acs())
+ wvtest.WVPASS(c.wifi_for_band('2.4').internet())
+ wvtest.WVPASS(c.wifi_for_band('2.4').current_route())
+
+
if __name__ == '__main__':
wvtest.wvtest_main()