autotest: Refactor router configuration

1) Add new HostapConfig object which abstracts and aids router
    configuration.
2) Change new WiFi tests to configure routers through a configure()
    method on the WiFiTestContextManager.  This facillitates packet
    captures since we start the captures at configuration time.  Routing
    this call through the context lets us share a common point to
    start client/server/router captures, similar to site_wifitest.

TEST=network_WiFi_SimpleConnect/control.* pass.  Manually inspected the
802.11n parameters for correctness.
BUG=chromium:231429

Change-Id: Ifa4b92ce96094451864769bb5b3df806017773a1
Reviewed-on: https://gerrit.chromium.org/gerrit/48668
Tested-by: Christopher Wiley <wiley@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Commit-Queue: Christopher Wiley <wiley@chromium.org>
diff --git a/server/site_linux_router.py b/server/site_linux_router.py
index da0f85e..4065644 100644
--- a/server/site_linux_router.py
+++ b/server/site_linux_router.py
@@ -160,6 +160,7 @@
         @param params dict of site_wifitest parameters.
 
         """
+        logging.info('Starting hostapd with parameters: %r', conf)
         # Figure out the correct interface.
         interface = self._get_wlanif(self.hostapd['frequency'],
                                      self.phytype,
@@ -225,6 +226,57 @@
         """Kill all hostapd instances."""
         self.kill_hostapd_instance(None)
 
+
+    def __get_default_hostap_config(self):
+        """@return dict of default options for hostapd."""
+        conf = self.hostapd['conf']
+        # default RTS and frag threshold to ``off''
+        conf['rts_threshold'] = '2347'
+        conf['fragm_threshold'] = '2346'
+        conf['driver'] = self.hostapd['driver']
+        return conf
+
+
+    def hostap_configure(self, configuration, multi_interface=None):
+        """Build up a hostapd configuration file and start hostapd.
+
+        Also setup a local server if this router supports them.
+
+        @param configuration HosetapConfig object.
+        @param multi_interface bool True iff multiple interfaces allowed.
+
+        """
+        if multi_interface is None and (self.hostapd['configured'] or
+                                        self.station['configured']):
+            self.deconfig()
+        # Start with the default hostapd config parameters.
+        conf = self.__get_default_hostap_config()
+        conf['ssid'] = (self.defssid + configuration.ssid_suffix)[-32:]
+        conf['channel'] = configuration.channel
+        self.hostapd['frequency'] = configuration.frequency
+        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'] = ''.join(configuration.n_capabilities)
+        if configuration.wmm_enabled:
+            conf['wmm_enabled'] = 1
+        if configuration.require_ht:
+            conf['require_ht'] = 1
+        # TODO(wiley) beacon interval support
+        self.start_hostapd(conf, {})
+        # Configure transmit power
+        tx_power_params = {'interface': conf['interface']}
+        # TODO(wiley) support for setting transmit power
+        self.set_txpower(tx_power_params)
+        if self.force_local_server:
+            self.start_local_server(conf['interface'])
+        self._post_start_hook({})
+        logging.info('AP configured.')
+        self.hostapd['configured'] = True
+
+
     def hostap_config(self, params):
         """Configure the AP per test requirements.
 
@@ -244,18 +296,10 @@
 
         local_server = params.pop('local_server', False)
 
-        # Construct the hostapd.conf file and start hostapd.
-        conf = self.hostapd['conf']
-        # default RTS and frag threshold to ``off''
-        conf['rts_threshold'] = '2347'
-        conf['fragm_threshold'] = '2346'
-
+        conf = self.__get_default_hostap_config()
         tx_power_params = {}
         htcaps = set()
 
-        conf['driver'] = params.get('hostapd_driver',
-            self.hostapd['driver'])
-
         for k, v in params.iteritems():
             if k == 'ssid':
                 conf['ssid'] = v