# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import collections
import copy
import logging

from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros.network import xmlrpc_security_types
from autotest_lib.server.cros.network import packet_capturer


class HostapConfig(object):
    """Parameters for router configuration."""

    # A mapping of frequency to channel number.  This includes some
    # frequencies used outside the US.
    CHANNEL_MAP = {2412: 1,
                   2417: 2,
                   2422: 3,
                   2427: 4,
                   2432: 5,
                   2437: 6,
                   2442: 7,
                   2447: 8,
                   2452: 9,
                   2457: 10,
                   2462: 11,
                   # 12, 13 are only legitimate outside the US.
                   2467: 12,
                   2472: 13,
                   # 14 is for Japan, DSSS and CCK only.
                   2484: 14,
                   # 32 valid in Europe.
                   5160: 32,
                   # 34 valid in Europe.
                   5170: 34,
                   # 36-116 valid in the US, except 38, 42, and 46, which have
                   # mixed international support.
                   5180: 36,
                   5190: 38,
                   5200: 40,
                   5210: 42,
                   5220: 44,
                   5230: 46,
                   5240: 48,
                   5260: 52,
                   5280: 56,
                   5300: 60,
                   5320: 64,
                   5500: 100,
                   5520: 104,
                   5540: 108,
                   5560: 112,
                   5580: 116,
                   # 120, 124, 128 valid in Europe/Japan.
                   5600: 120,
                   5620: 124,
                   5640: 128,
                   # 132+ valid in US.
                   5660: 132,
                   5680: 136,
                   5700: 140,
                   5710: 142,
                   # 144 is supported by a subset of WiFi chips
                   # (e.g. bcm4354, but not ath9k).
                   5720: 144,
                   5745: 149,
                   5755: 151,
                   5765: 153,
                   5785: 157,
                   5805: 161,
                   5825: 165}

    MODE_11A = 'a'
    MODE_11B = 'b'
    MODE_11G = 'g'
    MODE_11N_MIXED = 'n-mixed'
    MODE_11N_PURE = 'n-only'
    MODE_11AC_MIXED = 'ac-mixed'
    MODE_11AC_PURE = 'ac-only'

    N_CAPABILITY_HT20 = object()
    N_CAPABILITY_HT40 = object()
    N_CAPABILITY_HT40_PLUS = object()
    N_CAPABILITY_HT40_MINUS = object()
    N_CAPABILITY_GREENFIELD = object()
    N_CAPABILITY_SGI20 = object()
    N_CAPABILITY_SGI40 = object()
    ALL_N_CAPABILITIES = [N_CAPABILITY_HT20,
                          N_CAPABILITY_HT40,
                          N_CAPABILITY_HT40_PLUS,
                          N_CAPABILITY_HT40_MINUS,
                          N_CAPABILITY_GREENFIELD,
                          N_CAPABILITY_SGI20,
                          N_CAPABILITY_SGI40]

    AC_CAPABILITY_VHT160 = object()
    AC_CAPABILITY_VHT160_80PLUS80 = object()
    AC_CAPABILITY_RXLDPC = object()
    AC_CAPABILITY_SHORT_GI_80 = object()
    AC_CAPABILITY_SHORT_GI_160 = object()
    AC_CAPABILITY_TX_STBC_2BY1 = object()
    AC_CAPABILITY_RX_STBC_1 = object()
    AC_CAPABILITY_RX_STBC_12 = object()
    AC_CAPABILITY_RX_STBC_123 = object()
    AC_CAPABILITY_RX_STBC_1234 = object()
    AC_CAPABILITY_SU_BEAMFORMER = object()
    AC_CAPABILITY_SU_BEAMFORMEE = object()
    AC_CAPABILITY_BF_ANTENNA_2 = object()
    AC_CAPABILITY_SOUNDING_DIMENSION_2 = object()
    AC_CAPABILITY_MU_BEAMFORMER = object()
    AC_CAPABILITY_MU_BEAMFORMEE = object()
    AC_CAPABILITY_VHT_TXOP_PS = object()
    AC_CAPABILITY_HTC_VHT = object()
    AC_CAPABILITY_MAX_A_MPDU_LEN_EXP0 = object()
    AC_CAPABILITY_MAX_A_MPDU_LEN_EXP1 = object()
    AC_CAPABILITY_MAX_A_MPDU_LEN_EXP2 = object()
    AC_CAPABILITY_MAX_A_MPDU_LEN_EXP3 = object()
    AC_CAPABILITY_MAX_A_MPDU_LEN_EXP4 = object()
    AC_CAPABILITY_MAX_A_MPDU_LEN_EXP5 = object()
    AC_CAPABILITY_MAX_A_MPDU_LEN_EXP6 = object()
    AC_CAPABILITY_MAX_A_MPDU_LEN_EXP7 = object()
    AC_CAPABILITY_VHT_LINK_ADAPT2 = object()
    AC_CAPABILITY_VHT_LINK_ADAPT3 = object()
    AC_CAPABILITY_RX_ANTENNA_PATTERN = object()
    AC_CAPABILITY_TX_ANTENNA_PATTERN = object()
    AC_CAPABILITIES_MAPPING = {
            AC_CAPABILITY_VHT160: '[VHT160]',
            AC_CAPABILITY_VHT160_80PLUS80: '[VHT160-80PLUS80]',
            AC_CAPABILITY_RXLDPC: '[RXLDPC]',
            AC_CAPABILITY_SHORT_GI_80: '[SHORT-GI-80]',
            AC_CAPABILITY_SHORT_GI_160: '[SHORT-GI-160]',
            AC_CAPABILITY_TX_STBC_2BY1: '[TX-STBC-2BY1]',
            AC_CAPABILITY_RX_STBC_1: '[RX-STBC-1]',
            AC_CAPABILITY_RX_STBC_12: '[RX-STBC-12]',
            AC_CAPABILITY_RX_STBC_123: '[RX-STBC-123]',
            AC_CAPABILITY_RX_STBC_1234: '[RX-STBC-1234]',
            AC_CAPABILITY_SU_BEAMFORMER: '[SU-BEAMFORMER]',
            AC_CAPABILITY_SU_BEAMFORMEE: '[SU-BEAMFORMEE]',
            AC_CAPABILITY_BF_ANTENNA_2: '[BF-ANTENNA-2]',
            AC_CAPABILITY_SOUNDING_DIMENSION_2: '[SOUNDING-DIMENSION-2]',
            AC_CAPABILITY_MU_BEAMFORMER: '[MU-BEAMFORMER]',
            AC_CAPABILITY_MU_BEAMFORMEE: '[MU-BEAMFORMEE]',
            AC_CAPABILITY_VHT_TXOP_PS: '[VHT-TXOP-PS]',
            AC_CAPABILITY_HTC_VHT: '[HTC-VHT]',
            AC_CAPABILITY_MAX_A_MPDU_LEN_EXP0: '[MAX-A-MPDU-LEN-EXP0]',
            AC_CAPABILITY_MAX_A_MPDU_LEN_EXP1: '[MAX-A-MPDU-LEN-EXP1]',
            AC_CAPABILITY_MAX_A_MPDU_LEN_EXP2: '[MAX-A-MPDU-LEN-EXP2]',
            AC_CAPABILITY_MAX_A_MPDU_LEN_EXP3: '[MAX-A-MPDU-LEN-EXP3]',
            AC_CAPABILITY_MAX_A_MPDU_LEN_EXP4: '[MAX-A-MPDU-LEN-EXP4]',
            AC_CAPABILITY_MAX_A_MPDU_LEN_EXP5: '[MAX-A-MPDU-LEN-EXP5]',
            AC_CAPABILITY_MAX_A_MPDU_LEN_EXP6: '[MAX-A-MPDU-LEN-EXP6]',
            AC_CAPABILITY_MAX_A_MPDU_LEN_EXP7: '[MAX-A-MPDU-LEN-EXP7]',
            AC_CAPABILITY_VHT_LINK_ADAPT2: '[VHT-LINK-ADAPT2]',
            AC_CAPABILITY_VHT_LINK_ADAPT3: '[VHT-LINK-ADAPT3]',
            AC_CAPABILITY_RX_ANTENNA_PATTERN: '[RX-ANTENNA-PATTERN]',
            AC_CAPABILITY_TX_ANTENNA_PATTERN: '[TX-ANTENNA-PATTERN]'}

    HT_CHANNEL_WIDTH_20 = object()
    HT_CHANNEL_WIDTH_40_PLUS = object()
    HT_CHANNEL_WIDTH_40_MINUS = object()

    HT_NAMES = {
        HT_CHANNEL_WIDTH_20: 'HT20',
        HT_CHANNEL_WIDTH_40_PLUS: 'HT40+',
        HT_CHANNEL_WIDTH_40_MINUS: 'HT40-',
    }

    VHT_CHANNEL_WIDTH_40 = object()
    VHT_CHANNEL_WIDTH_80 = object()
    VHT_CHANNEL_WIDTH_160 = object()
    VHT_CHANNEL_WIDTH_80_80 = object()

    # Human readable names for these channel widths.
    VHT_NAMES = {
        VHT_CHANNEL_WIDTH_40: 'VHT40',
        VHT_CHANNEL_WIDTH_80: 'VHT80',
        VHT_CHANNEL_WIDTH_160: 'VHT160',
        VHT_CHANNEL_WIDTH_80_80: 'VHT80+80',
    }

    # This is a loose merging of the rules for US and EU regulatory
    # domains as taken from IEEE Std 802.11-2016 Appendix E.  For instance,
    # we tolerate HT40 in channels 149-161 (not allowed in EU), but also
    # tolerate HT40+ on channel 7 (not allowed in the US).  We take the loose
    # definition so that we don't prohibit testing in either domain.
    HT40_ALLOW_MAP = {N_CAPABILITY_HT40_MINUS: range(5, 14) +
                                           range(40, 65, 8) +
                                           range(104, 145, 8) +
                                           [153, 161],
                  N_CAPABILITY_HT40_PLUS: range(1, 10) +
                                           range(36, 61, 8) +
                                           range(100, 141, 8) +
                                           [149, 157]}

    PMF_SUPPORT_DISABLED = 0
    PMF_SUPPORT_ENABLED = 1
    PMF_SUPPORT_REQUIRED = 2
    PMF_SUPPORT_VALUES = (PMF_SUPPORT_DISABLED,
                          PMF_SUPPORT_ENABLED,
                          PMF_SUPPORT_REQUIRED)

    DRIVER_NAME = 'nl80211'


    @staticmethod
    def get_channel_for_frequency(frequency):
        """Returns the channel number associated with a given frequency.

        @param value: int frequency in MHz.

        @return int frequency associated with the channel.

        """
        return HostapConfig.CHANNEL_MAP[frequency]


    @staticmethod
    def get_frequency_for_channel(channel):
        """Returns the frequency associated with a given channel number.

        @param value: int channel number.

        @return int frequency in MHz associated with the channel.

        """
        for frequency, channel_iter in HostapConfig.CHANNEL_MAP.iteritems():
            if channel == channel_iter:
                return frequency
        else:
            raise error.TestFail('Unknown channel value: %r.' % channel)


    @property
    def _get_default_config(self):
        """@return dict of default options for hostapd."""
        return collections.OrderedDict([
                ('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 _hostapd_vht_capabilities(self):
        """@return string suitable for the vht_capab= line in a hostapd config.
        """
        ret = []
        for cap in self.AC_CAPABILITIES_MAPPING.keys():
            if cap in self._ac_capabilities:
                ret.append(self.AC_CAPABILITIES_MAPPING[cap])
        return ''.join(ret)


    @property
    def _require_ht(self):
        """@return True iff clients should be required to support HT."""
        return self._mode == self.MODE_11N_PURE


    @property
    def require_vht(self):
        """@return True iff clients should be required to support VHT."""
        return self._mode == self.MODE_11AC_PURE


    @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._is_11n or self.is_11ac:
            # 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 is_11ac(self):
        """@return True iff we're trying to host an 802.11ac network."""
        return self._mode in (self.MODE_11AC_MIXED, self.MODE_11AC_PURE)


    @property
    def channel(self):
        """@return int channel number for self.frequency."""
        return self.get_channel_for_frequency(self.frequency)


    @channel.setter
    def channel(self, value):
        """Sets the channel number to configure hostapd to listen on.

        @param value: int channel number.

        """
        self.frequency = self.get_frequency_for_channel(value)


    @property
    def frequency(self):
        """@return int frequency for hostapd to listen on."""
        return self._frequency


    @frequency.setter
    def frequency(self, value):
        """Sets the frequency for hostapd to listen on.

        @param value: int frequency in MHz.

        """
        if value not in self.CHANNEL_MAP or not self.supports_frequency(value):
            raise error.TestFail('Tried to set an invalid frequency: %r.' %
                                 value)

        self._frequency = value


    @property
    def ssid(self):
        """@return string SSID."""
        return self._ssid


    @ssid.setter
    def ssid(self, value):
        """Sets the ssid for the hostapd.

        @param value: string ssid name.

        """
        self._ssid = value


    @property
    def _ht_mode(self):
        """
        @return object one of ( None,
                                HT_CHANNEL_WIDTH_40_PLUS,
                                HT_CHANNEL_WIDTH_40_MINUS,
                                HT_CHANNEL_WIDTH_20)
        """
        if self._is_11n or self.is_11ac:
            if self._ht40_plus_allowed:
                return self.HT_CHANNEL_WIDTH_40_PLUS
            if self._ht40_minus_allowed:
                return self.HT_CHANNEL_WIDTH_40_MINUS
            return self.HT_CHANNEL_WIDTH_20
        return None


    @property
    def packet_capture_mode(self):
        """Get an appropriate packet capture HT/VHT parameter.

        When we go to configure a raw monitor we need to configure
        the phy to listen on the correct channel.  Part of doing
        so is to specify the channel width for HT/VHT channels.  In the
        case that the AP is configured to be either HT40+ or HT40-,
        we could return the wrong parameter because we don't know which
        configuration will be chosen by hostap.

        @return object width_type parameter from packet_capturer.

        """

        if (not self.vht_channel_width or
                self.vht_channel_width == self.VHT_CHANNEL_WIDTH_40):
            # if it is VHT40, capture packets on the correct 40MHz band since
            # for packet capturing purposes, only the channel width matters
            ht_mode = self._ht_mode
            if ht_mode == self.HT_CHANNEL_WIDTH_40_PLUS:
                return packet_capturer.WIDTH_HT40_PLUS
            if ht_mode == self.HT_CHANNEL_WIDTH_40_MINUS:
                return packet_capturer.WIDTH_HT40_MINUS
            if ht_mode == self.HT_CHANNEL_WIDTH_20:
                return packet_capturer.WIDTH_HT20

        if self.vht_channel_width == self.VHT_CHANNEL_WIDTH_80:
            return packet_capturer.WIDTH_VHT80
        if self.vht_channel_width == self.VHT_CHANNEL_WIDTH_160:
            return packet_capturer.WIDTH_VHT160
        if self.vht_channel_width == self.VHT_CHANNEL_WIDTH_80_80:
            return packet_capturer.WIDTH_VHT80_80
        return None


    @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])


    @property
    def printable_mode(self):
        """@return human readable mode string."""

        if self.vht_channel_width is not None:
            return self.VHT_NAMES[self.vht_channel_width]

        ht_mode = self._ht_mode
        if ht_mode:
            return self.HT_NAMES[ht_mode]

        return '11' + self._hw_mode.upper()


    @property
    def ssid_suffix(self):
        """@return meaningful suffix for SSID."""
        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


    @property
    def scenario_name(self):
        """@return string _scenario_name value, or None."""
        return self._scenario_name


    @property
    def min_streams(self):
        """@return int _min_streams value, or None."""
        return self._min_streams


    @property
    def frag_threshold(self):
        """@return int frag threshold value, or None."""
        return self._frag_threshold

    @property
    def bridge(self):
        """@return string _bridge value, or None."""
        return self._bridge

    @property
    def max_stas(self):
        """@return int _max_stas value, or None."""
        return self._max_stas

    @property
    def supported_rates(self):
        """@return list of supported bitrates (in Mbps, or None if not
           specified.
        """
        return self._supported_rates

    def __init__(self, mode=MODE_11B, channel=None, frequency=None,
                 n_capabilities=None, hide_ssid=None, beacon_interval=None,
                 dtim_period=None, frag_threshold=None, ssid=None, bssid=None,
                 force_wmm=None, security_config=None,
                 pmf_support=PMF_SUPPORT_DISABLED,
                 obss_interval=None,
                 vht_channel_width=None,
                 vht_center_channel=None,
                 ac_capabilities=None,
                 spectrum_mgmt_required=None,
                 scenario_name=None,
                 supported_rates=None,
                 basic_rates=None,
                 min_streams=None,
                 nas_id=None,
                 mdid=None,
                 r1kh_id=None,
                 r0kh=None,
                 r1kh=None,
                 bridge=None,
                 max_stas=None):
        """Construct a HostapConfig.

        You may specify channel or frequency, but not both.  Both options
        are checked for validity (i.e. you can't specify an invalid channel
        or a frequency that will not be accepted).

        @param mode string MODE_11x defined above.
        @param channel int channel number.
        @param frequency int frequency of channel.
        @param n_capabilities list of N_CAPABILITY_x defined above.
        @param hide_ssid True if we should set up a hidden SSID.
        @param beacon_interval int beacon interval of AP.
        @param dtim_period int include a DTIM every |dtim_period| beacons.
        @param frag_threshold int maximum outgoing data frame size.
        @param ssid string up to 32 byte SSID overriding the router default.
        @param bssid string like 00:11:22:33:44:55.
        @param force_wmm True if we should force WMM on, False if we should
            force it off, None if we shouldn't force anything.
        @param security_config SecurityConfig object.
        @param pmf_support one of PMF_SUPPORT_* above.  Controls whether the
            client supports/must support 802.11w.
        @param obss_interval int interval in seconds that client should be
            required to do background scans for overlapping BSSes.
        @param vht_channel_width object channel width
        @param vht_center_channel int center channel of segment 0.
        @param ac_capabilities list of AC_CAPABILITY_x defined above.
        @param spectrum_mgmt_required True if we require the DUT to support
            spectrum management.
        @param scenario_name string to be included in file names, instead
            of the interface name.
        @param supported_rates list of rates (in Mbps) that the AP should
             advertise.
        @param basic_rates list of basic rates (in Mbps) that the AP should
            advertise.
        @param min_streams int number of spatial streams required.
        @param nas_id string for RADIUS messages (needed for 802.11r)
        @param mdid string used to indicate a group of APs for FT
        @param r1kh_id string PMK-R1 key holder id for FT
        @param r0kh string R0KHs in the same mobility domain
        @param r1kh string R1KHs in the same mobility domain
        @param bridge string bridge interface to use, if any
        @param max_stas int maximum number of STAs allowed to connect to AP.

        """
        super(HostapConfig, self).__init__()
        if channel is not None and frequency is not None:
            raise error.TestError('Specify either frequency or channel '
                                  'but not both.')

        if n_capabilities is None:
            n_capabilities = []
        if ac_capabilities is None:
            ac_capabilities = []
        self._wmm_enabled = False
        unknown_caps = [cap for cap in n_capabilities
                        if cap not in self.ALL_N_CAPABILITIES]
        if unknown_caps:
            raise error.TestError('Unknown capabilities: %r' % unknown_caps)

        self._n_capabilities = set(n_capabilities)
        if self._n_capabilities:
            self._wmm_enabled = True
        if self._n_capabilities and mode is None:
            mode = self.MODE_11N_PURE
        self._mode = mode

        self._frequency = None
        if channel:
            self.channel = channel
        elif frequency:
            self.frequency = frequency
        else:
            raise error.TestError('Specify either frequency or channel.')

        if not self.supports_frequency(self.frequency):
            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
        if ssid and len(ssid) > 32:
            raise error.TestFail('Tried to specify SSID that was too long.')

        self._ssid = ssid
        self._bssid = bssid
        if force_wmm is not None:
            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
                                xmlrpc_security_types.SecurityConfig())
        self._obss_interval = obss_interval
        if vht_channel_width == self.VHT_CHANNEL_WIDTH_40:
            self._vht_oper_chwidth = 0
        elif vht_channel_width == self.VHT_CHANNEL_WIDTH_80:
            self._vht_oper_chwidth = 1
        elif vht_channel_width == self.VHT_CHANNEL_WIDTH_160:
            self._vht_oper_chwidth = 2
        elif vht_channel_width == self.VHT_CHANNEL_WIDTH_80_80:
            self._vht_oper_chwidth = 3
        elif vht_channel_width is not None:
            raise error.TestFail('Invalid channel width')
        self.vht_channel_width = vht_channel_width
        # TODO(zqiu) Add checking for center channel based on the channel width
        # and operating channel.
        self._vht_oper_centr_freq_seg0_idx = vht_center_channel
        self._ac_capabilities = set(ac_capabilities)
        self._spectrum_mgmt_required = spectrum_mgmt_required
        self._scenario_name = scenario_name
        self._supported_rates = supported_rates
        self._basic_rates = basic_rates
        self._min_streams = min_streams
        self._nas_id = nas_id
        self._mdid = mdid
        self._r1kh_id = r1kh_id
        self._r0kh = r0kh
        self._r1kh = r1kh
        self._bridge = bridge
        # keep _max_stas in [0, 2007], as valid AIDs must be in [1, 2007]
        if max_stas is None:
            self._max_stas = None
        else:
            self._max_stas = max(0, min(max_stas, 2007))


    def __repr__(self):
        return ('%s(mode=%r, channel=%r, frequency=%r, '
                'n_capabilities=%r, hide_ssid=%r, beacon_interval=%r, '
                'dtim_period=%r, frag_threshold=%r, ssid=%r, bssid=%r, '
                'wmm_enabled=%r, security_config=%r, '
                'spectrum_mgmt_required=%r)' % (
                        self.__class__.__name__,
                        self._mode,
                        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,
                        self._spectrum_mgmt_required))


    def supports_channel(self, value):
        """Check whether channel is supported by the current hardware mode.

        @param value: int channel to check.
        @return True iff the current mode supports the band of the channel.

        """
        for freq, channel in self.CHANNEL_MAP.iteritems():
            if channel == value:
                return self.supports_frequency(freq)

        return False


    def supports_frequency(self, frequency):
        """Check whether frequency is supported by the current hardware mode.

        @param frequency: int frequency to check.
        @return True iff the current mode supports the band of the frequency.

        """
        if self._mode == self.MODE_11A and frequency < 5000:
            return False

        if self._mode in (self.MODE_11B, self.MODE_11G) and frequency > 5000:
            return False

        if frequency not in self.CHANNEL_MAP:
            return False

        channel = self.CHANNEL_MAP[frequency]
        supports_plus = (channel in
                         self.HT40_ALLOW_MAP[self.N_CAPABILITY_HT40_PLUS])
        supports_minus = (channel in
                          self.HT40_ALLOW_MAP[self.N_CAPABILITY_HT40_MINUS])
        if (self.N_CAPABILITY_HT40_PLUS in self._n_capabilities and
                not supports_plus):
            return False

        if (self.N_CAPABILITY_HT40_MINUS in self._n_capabilities and
                not supports_minus):
            return False

        if (self.N_CAPABILITY_HT40 in self._n_capabilities and
                not supports_plus and not supports_minus):
            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

        # hostapd specifies rates in units of 100Kbps.
        rate_to_100kbps = lambda rate: str(int(rate * 10))
        if self._supported_rates:
            conf['supported_rates'] = ' '.join(map(rate_to_100kbps,
                                                   self._supported_rates))
        if self._basic_rates:
            conf['basic_rates'] = ' '.join(map(rate_to_100kbps,
                                               self._basic_rates))

        if self._hide_ssid:
            conf['ignore_broadcast_ssid'] = 1
        if self._is_11n or self.is_11ac:
            conf['ieee80211n'] = 1
            conf['ht_capab'] = self._hostapd_ht_capabilities
        if self.is_11ac:
            conf['ieee80211ac'] = 1
            conf['vht_oper_chwidth'] = self._vht_oper_chwidth
            if self._vht_oper_centr_freq_seg0_idx is not None:
                conf['vht_oper_centr_freq_seg0_idx'] = \
                        self._vht_oper_centr_freq_seg0_idx
            conf['vht_capab'] = self._hostapd_vht_capabilities
        if self._wmm_enabled:
            conf['wmm_enabled'] = 1
        if self._require_ht:
            conf['require_ht'] = 1
        if self.require_vht:
            conf['require_vht'] = 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
        if self._nas_id:
            conf['nas_identifier'] = self._nas_id
        if self._mdid:
            conf['mobility_domain'] = self._mdid
        if self._r1kh_id:
            conf['r1_key_holder'] = self._r1kh_id
        if self._r0kh:
            conf['r0kh'] = self._r0kh
        if self._r1kh:
            conf['r1kh'] = self._r1kh
        if self._bridge:
            conf['bridge'] = self._bridge
        if self._max_stas is not None:
            conf['max_num_sta'] = self._max_stas
        conf['interface'] = interface
        conf['ctrl_interface'] = control_interface
        if self._spectrum_mgmt_required:
            # To set spectrum_mgmt_required, we must first set
            # local_pwr_constraint. And to set local_pwr_constraint,
            # we must first set ieee80211d. And to set ieee80211d, ...
            # Point being: order matters here.
            conf['country_code'] = 'US'  # Required for local_pwr_constraint
            conf['ieee80211d'] = 1  # Required for local_pwr_constraint
            conf['local_pwr_constraint'] = 0  # No local constraint
            conf['spectrum_mgmt_required'] = 1  # Requires local_pwr_constraint
        conf.update(self._security_config.get_hostapd_config())
        return conf
