HostapConfig refactor
Refactor HostapConfig class to have it generate config dictionary. Updated variables' name scope to internal when possible.
BUG=chromium:347346
TEST=Run full wifi_matfunc test suite.
Change-Id: Ibbfce87fc25b57da3e411517d5da7a0e9e77aa73
Reviewed-on: https://chromium-review.googlesource.com/188169
Tested-by: Peter Qiu <zqiu@chromium.org>
Reviewed-by: Christopher Wiley <wiley@chromium.org>
Commit-Queue: Peter Qiu <zqiu@chromium.org>
diff --git a/server/cros/network/hostap_config.py b/server/cros/network/hostap_config.py
index cf87bc3..2848274 100644
--- a/server/cros/network/hostap_config.py
+++ b/server/cros/network/hostap_config.py
@@ -104,6 +104,8 @@
PMF_SUPPORT_ENABLED,
PMF_SUPPORT_REQUIRED)
+ DRIVER_NAME = 'nl80211'
+
@staticmethod
def get_channel_for_frequency(frequency):
@@ -134,6 +136,89 @@
@property
+ def _get_default_config(self):
+ """@return dict of default options for hostapd."""
+ return {'hw_mode': 'g',
+ 'logger_syslog': '-1',
+ 'logger_syslog_level': '0',
+ # default RTS and frag threshold to ``off''
+ 'rts_threshold': '2347',
+ 'fragm_threshold': '2346',
+ 'driver': self.DRIVER_NAME }
+
+
+ @property
+ def _ht40_plus_allowed(self):
+ """@return True iff HT40+ is enabled for this configuration."""
+ channel_supported = (self.channel in
+ self.HT40_ALLOW_MAP[self.N_CAPABILITY_HT40_PLUS])
+ return ((self.N_CAPABILITY_HT40_PLUS in self._n_capabilities or
+ self.N_CAPABILITY_HT40 in self._n_capabilities) and
+ channel_supported)
+
+
+ @property
+ def _ht40_minus_allowed(self):
+ """@return True iff HT40- is enabled for this configuration."""
+ channel_supported = (self.channel in
+ self.HT40_ALLOW_MAP[self.N_CAPABILITY_HT40_MINUS])
+ return ((self.N_CAPABILITY_HT40_MINUS in self._n_capabilities or
+ self.N_CAPABILITY_HT40 in self._n_capabilities) and
+ channel_supported)
+
+
+ @property
+ def _hostapd_ht_capabilities(self):
+ """@return string suitable for the ht_capab= line in a hostapd config"""
+ ret = []
+ if self._ht40_plus_allowed:
+ ret.append('[HT40+]')
+ elif self._ht40_minus_allowed:
+ ret.append('[HT40-]')
+ if self.N_CAPABILITY_GREENFIELD in self._n_capabilities:
+ logging.warning('Greenfield flag is ignored for hostap...')
+ if self.N_CAPABILITY_SGI20 in self._n_capabilities:
+ ret.append('[SHORT-GI-20]')
+ if self.N_CAPABILITY_SGI40 in self._n_capabilities:
+ ret.append('[SHORT-GI-40]')
+ return ''.join(ret)
+
+
+ @property
+ def _require_ht(self):
+ """@return True iff clients should be required to support HT."""
+ # TODO(wiley) Why? (crbug.com/237370)
+ logging.warning('Not enforcing pure N mode because Snow does '
+ 'not seem to support it...')
+ return False
+
+
+ @property
+ def _hw_mode(self):
+ """@return string hardware mode understood by hostapd."""
+ if self._mode == self.MODE_11A:
+ return self.MODE_11A
+ if self._mode == self.MODE_11B:
+ return self.MODE_11B
+ if self._mode == self.MODE_11G:
+ return self.MODE_11G
+ if self._mode in (self.MODE_11N_MIXED, self.MODE_11N_PURE):
+ # For their own historical reasons, hostapd wants it this way.
+ if self._frequency > 5000:
+ return self.MODE_11A
+
+ return self.MODE_11G
+
+ raise error.TestFail('Invalid mode.')
+
+
+ @property
+ def _is_11n(self):
+ """@return True iff we're trying to host an 802.11n network."""
+ return self._mode in (self.MODE_11N_MIXED, self.MODE_11N_PURE)
+
+
+ @property
def channel(self):
"""@return int channel number for self.frequency."""
return self.get_channel_for_frequency(self.frequency)
@@ -170,40 +255,19 @@
@property
- def hostapd_ht_capabilities(self):
- """@return string suitable for the ht_capab= line in a hostapd config"""
- ret = []
- if self.ht40_plus_allowed:
- ret.append('[HT40+]')
- elif self.ht40_minus_allowed:
- ret.append('[HT40-]')
- if self.N_CAPABILITY_GREENFIELD in self._n_capabilities:
- logging.warning('Greenfield flag is ignored for hostap...')
- if self.N_CAPABILITY_SGI20 in self._n_capabilities:
- ret.append('[SHORT-GI-20]')
- if self.N_CAPABILITY_SGI40 in self._n_capabilities:
- ret.append('[SHORT-GI-40]')
- return ''.join(ret)
+ def ssid(self):
+ """@return string SSID."""
+ return self._ssid
- @property
- def ht40_plus_allowed(self):
- """@return True iff HT40+ is enabled for this configuration."""
- channel_supported = (self.channel in
- self.HT40_ALLOW_MAP[self.N_CAPABILITY_HT40_PLUS])
- return ((self.N_CAPABILITY_HT40_PLUS in self._n_capabilities or
- self.N_CAPABILITY_HT40 in self._n_capabilities) and
- channel_supported)
+ @ssid.setter
+ def ssid(self, value):
+ """Sets the ssid for the hostapd.
+ @param value: string ssid name.
- @property
- def ht40_minus_allowed(self):
- """@return True iff HT40- is enabled for this configuration."""
- channel_supported = (self.channel in
- self.HT40_ALLOW_MAP[self.N_CAPABILITY_HT40_MINUS])
- return ((self.N_CAPABILITY_HT40_MINUS in self._n_capabilities or
- self.N_CAPABILITY_HT40 in self._n_capabilities) and
- channel_supported)
+ """
+ self._ssid = value
@property
@@ -220,68 +284,34 @@
@return string HT parameter for frequency configuration.
"""
- if not self.is_11n:
+ if not self._is_11n:
return None
- if self.ht40_plus_allowed:
+ if self._ht40_plus_allowed:
return 'HT40+'
- if self.ht40_minus_allowed:
+ if self._ht40_minus_allowed:
return 'HT40-'
return 'HT20'
@property
- def hw_mode(self):
- """@return string hardware mode understood by hostapd."""
- if self._mode == self.MODE_11A:
- return self.MODE_11A
- if self._mode == self.MODE_11B:
- return self.MODE_11B
- if self._mode == self.MODE_11G:
- return self.MODE_11G
- if self._mode in (self.MODE_11N_MIXED, self.MODE_11N_PURE):
- # For their own historical reasons, hostapd wants it this way.
- if self.frequency > 5000:
- return self.MODE_11A
-
- return self.MODE_11G
-
- raise error.TestFail('Invalid mode.')
-
-
- @property
- def is_11n(self):
- """@return True iff we're trying to host an 802.11n network."""
- return self._mode in (self.MODE_11N_MIXED, self.MODE_11N_PURE)
-
-
- @property
def perf_loggable_description(self):
"""@return string test description suitable for performance logging."""
mode = 'mode%s' % (
self.printable_mode.replace('+', 'p').replace('-', 'm'))
channel = 'ch%03d' % self.channel
- return '_'.join([channel, mode, self.security_config.security])
+ return '_'.join([channel, mode, self._security_config.security])
@property
def printable_mode(self):
"""@return human readable mode string."""
- if self.is_11n:
+ if self._is_11n:
return self.ht_packet_capture_mode
- return '11' + self.hw_mode.upper()
-
-
- @property
- def require_ht(self):
- """@return True iff clients should be required to support HT."""
- # TODO(wiley) Why? (crbug.com/237370)
- logging.warning('Not enforcing pure N mode because Snow does '
- 'not seem to support it...')
- return False
+ return '11' + self._hw_mode.upper()
@property
@@ -290,6 +320,18 @@
return '_ch%d' % self.channel
+ @property
+ def security_config(self):
+ """@return SecurityConfig security config object"""
+ return self._security_config
+
+
+ @property
+ def hide_ssid(self):
+ """@return bool _hide_ssid flag."""
+ return self._hide_ssid
+
+
def __init__(self, mode=MODE_11B, channel=None, frequency=None,
n_capabilities=[], hide_ssid=None, beacon_interval=None,
dtim_period=None, frag_threshold=None, ssid=None, bssid=None,
@@ -326,7 +368,7 @@
raise error.TestError('Specify either frequency or channel '
'but not both.')
- self.wmm_enabled = False
+ self._wmm_enabled = False
unknown_caps = [cap for cap in n_capabilities
if cap not in self.ALL_N_CAPABILITIES]
if unknown_caps:
@@ -334,7 +376,7 @@
self._n_capabilities = set(n_capabilities)
if self._n_capabilities:
- self.wmm_enabled = True
+ self._wmm_enabled = True
if self._n_capabilities and mode is None:
mode = self.MODE_11N_PURE
self._mode = mode
@@ -351,25 +393,25 @@
raise error.TestFail('Configured a mode %s that does not support '
'frequency %d' % (self._mode, self.frequency))
- self.hide_ssid = hide_ssid
- self.beacon_interval = beacon_interval
- self.dtim_period = dtim_period
- self.frag_threshold = frag_threshold
+ self._hide_ssid = hide_ssid
+ self._beacon_interval = beacon_interval
+ self._dtim_period = dtim_period
+ self._frag_threshold = frag_threshold
if ssid and len(ssid) > 32:
raise error.TestFail('Tried to specify SSID that was too long.')
- self.ssid = ssid
- self.bssid = bssid
+ self._ssid = ssid
+ self._bssid = bssid
if force_wmm is not None:
- self.wmm_enabled = force_wmm
+ self._wmm_enabled = force_wmm
if pmf_support not in self.PMF_SUPPORT_VALUES:
raise error.TestFail('Invalid value for pmf_support: %r' %
pmf_support)
- self.pmf_support = pmf_support
- self.security_config = (copy.copy(security_config) or
+ self._pmf_support = pmf_support
+ self._security_config = (copy.copy(security_config) or
xmlrpc_security_types.SecurityConfig())
- self.obss_interval = obss_interval
+ self._obss_interval = obss_interval
def __repr__(self):
@@ -382,19 +424,14 @@
self.channel,
self.frequency,
self._n_capabilities,
- self.hide_ssid,
- self.beacon_interval,
- self.dtim_period,
- self.frag_threshold,
- self.ssid,
- self.bssid,
- self.wmm_enabled,
- self.security_config))
-
-
- def get_security_hostapd_conf(self):
- """@return dict of hostapd settings related to security."""
- return self.security_config.get_hostapd_config()
+ self._hide_ssid,
+ self._beacon_interval,
+ self._dtim_period,
+ self._frag_threshold,
+ self._ssid,
+ self._bssid,
+ self._wmm_enabled,
+ self._security_config))
def supports_channel(self, value):
@@ -445,3 +482,46 @@
return False
return True
+
+
+ def generate_dict(self, interface, control_interface, ssid):
+ """Generate config dictionary.
+
+ Generate config dictionary for the given |interface|.
+
+ @param interface: string interface to generate config dict for.
+ @param control_interface: string control interface
+ @param ssid: string SSID of the AP.
+ @return dict of hostap configurations.
+
+ """
+ # Start with the default config parameters.
+ conf = self._get_default_config
+ conf['ssid'] = (self._ssid or ssid)
+ if self._bssid:
+ conf['bssid'] = self._bssid
+ conf['channel'] = self.channel
+ conf['hw_mode'] = self._hw_mode
+ if self._hide_ssid:
+ conf['ignore_broadcast_ssid'] = 1
+ if self._is_11n:
+ conf['ieee80211n'] = 1
+ conf['ht_capab'] = self._hostapd_ht_capabilities
+ if self._wmm_enabled:
+ conf['wmm_enabled'] = 1
+ if self._require_ht:
+ conf['require_ht'] = 1
+ if self._beacon_interval:
+ conf['beacon_int'] = self._beacon_interval
+ if self._dtim_period:
+ conf['dtim_period'] = self._dtim_period
+ if self._frag_threshold:
+ conf['fragm_threshold'] = self._frag_threshold
+ if self._pmf_support:
+ conf['ieee80211w'] = self._pmf_support
+ if self._obss_interval:
+ conf['obss_interval'] = self._obss_interval
+ conf['interface'] = interface
+ conf['ctrl_interface'] = control_interface
+ conf.update(self._security_config.get_hostapd_config())
+ return conf
diff --git a/server/site_linux_router.py b/server/site_linux_router.py
index 4e64a8c..3670479 100644
--- a/server/site_linux_router.py
+++ b/server/site_linux_router.py
@@ -126,15 +126,12 @@
return bool(self.local_servers)
- def start_hostapd(self, hostapd_conf_dict, configuration):
+ def start_hostapd(self, configuration):
"""Start a hostapd instance described by conf.
- @param hostapd_conf_dict dict of hostapd configuration parameters.
@param configuration HostapConfig object.
"""
- logging.info('Starting hostapd with parameters: %r',
- hostapd_conf_dict)
# Figure out the correct interface.
interface = self.get_wlanif(configuration.frequency, 'managed')
@@ -142,8 +139,10 @@
log_file = self.HOSTAPD_LOG_FILE_PATTERN % interface
pid_file = self.HOSTAPD_PID_FILE_PATTERN % interface
control_interface = self.HOSTAPD_CONTROL_INTERFACE_PATTERN % interface
- hostapd_conf_dict['interface'] = interface
- hostapd_conf_dict['ctrl_interface'] = control_interface
+ hostapd_conf_dict = configuration.generate_dict(
+ interface, control_interface,
+ self._build_ssid(configuration.ssid_suffix))
+ logging.info('Starting hostapd with parameters: %r', hostapd_conf_dict)
# Generate hostapd.conf.
self.router.run("cat <<EOF >%s\n%s\nEOF\n" %
@@ -240,18 +239,6 @@
self.kill_hostapd_instance(None)
- def __get_default_hostap_config(self):
- """@return dict of default options for hostapd."""
- return {'hw_mode': 'g',
- 'logger_syslog': '-1',
- 'logger_syslog_level': '0',
- # default RTS and frag threshold to ``off''
- 'rts_threshold': '2347',
- 'fragm_threshold': '2346',
- 'driver': self.HOSTAPD_DRIVER_NAME,
- 'ssid': self._build_ssid('') }
-
-
def _build_ssid(self, suffix):
unique_salt = ''.join([random.choice(self.SUFFIX_LETTERS)
for x in range(5)])
@@ -270,35 +257,7 @@
if multi_interface is None and (self.hostapd_instances or
self.station_instances):
self.deconfig()
- # Start with the default hostapd config parameters.
- conf = self.__get_default_hostap_config()
- conf['ssid'] = (configuration.ssid or
- self._build_ssid(configuration.ssid_suffix))
- if configuration.bssid:
- conf['bssid'] = configuration.bssid
- conf['channel'] = configuration.channel
- conf['hw_mode'] = configuration.hw_mode
- if configuration.hide_ssid:
- conf['ignore_broadcast_ssid'] = 1
- if configuration.is_11n:
- conf['ieee80211n'] = 1
- conf['ht_capab'] = configuration.hostapd_ht_capabilities
- if configuration.wmm_enabled:
- conf['wmm_enabled'] = 1
- if configuration.require_ht:
- conf['require_ht'] = 1
- if configuration.beacon_interval:
- conf['beacon_int'] = configuration.beacon_interval
- if configuration.dtim_period:
- conf['dtim_period'] = configuration.dtim_period
- if configuration.frag_threshold:
- conf['fragm_threshold'] = configuration.frag_threshold
- if configuration.pmf_support:
- conf['ieee80211w'] = configuration.pmf_support
- if configuration.obss_interval:
- conf['obss_interval'] = configuration.obss_interval
- conf.update(configuration.get_security_hostapd_conf())
- self.start_hostapd(conf, configuration)
+ self.start_hostapd(configuration)
interface = self.hostapd_instances[-1]['interface']
self.iw_runner.set_tx_power(interface, 'auto')
self.start_local_server(interface)