# Copyright (c) 2015 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.

AUTHOR = 'pstew, quiche'
NAME = 'network_WiFi_RegDomain'
TIME = 'MEDIUM'
TEST_TYPE = 'Server'
ATTRIBUTES = "suite:wifi_matfunc_bcm4356"
DEPENDENCIES = 'wificell'

DOC = """
This test verifies that a DUT can, or cannot, connect on given
channels, in given regions.

This test exercises:
- parsing of VPD data
- mapping of VPD data to ISO country code
- communication of country code from user-space to kernel
- communication of country code / rules from kernel to driver
- communication of country code / rules from driver to firmware

This test is an aid to identify changes in behavior. It does not
provide advice on regulatory requirements.
"""

import logging

from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros.network import interface


# When adding a negative rule ('expect': 'no-connect'), be sure to add
# a case with a positive rule ('expect': 'connect', or 'expect':
# 'passive-scan'). Otherwise, we haven't ruled out the possibility
# that the test itself prevents the DUT from connecting.
#
# Note:
# - 'passive-scan' implies 'connect'
# - 'no-connect' implies no probes
DEVTYPE_TO_REGION_INFOS = {
    # TODO(quiche): Add ath9k expectations for channels 52 and 120.
    'ath9k':
        [
         # This first set of expectations is based on
         # ath_world_regdom_63_65 in ath/regd.c. We may need to change
         # or remove these, if it turns out that some DUTs have other
         # ath9k SKUs.
         {'region_name': '',
          'country_code': '00',
          'channel_infos': [
              {'chnum': 13, 'expect': 'passive-scan'},
              {'chnum': 36, 'expect': 'passive-scan'},
              {'chnum': 149, 'expect': 'passive-scan'}]},
         # Many of the 'passive-scan' expectations for the remaining
         # regions seem to arise from ath_world_regdom_63_65. (Or, at
         # least, not all of the passive scanning expectations can be
         # attributed to data in wireless-regdb.)
         {'region_name': 'ar',
          'country_code': 'AR',
          'channel_infos': [
              {'chnum': 13, 'expect': 'passive-scan'},
              {'chnum': 36, 'expect': 'passive-scan'},
              {'chnum': 149, 'expect': 'passive-scan'}]},
         {'region_name': 'id',
          'country_code': 'ID',
          'channel_infos': [
              {'chnum': 13, 'expect': 'passive-scan'},
              {'chnum': 36, 'expect': 'no-connect'},
              {'chnum': 149, 'expect': 'passive-scan'}]},
         {'region_name': 'ru',
          'country_code': 'RU',
          'channel_infos': [
              {'chnum': 13, 'expect': 'passive-scan'},
              {'chnum': 36, 'expect': 'passive-scan'},
              {'chnum': 149, 'expect': 'passive-scan'}]},
         {'region_name': 'us',
          'country_code': 'US',
          'channel_infos': [
              {'chnum': 13, 'expect': 'no-connect'},
              {'chnum': 36, 'expect': 'passive-scan'},
              {'chnum': 149, 'expect': 'passive-scan'}]}],
    'bcm435x':
        [{'region_name': 'ca.hybrid',  # <country code>.<extra>
          'country_code': 'CA',
          'channel_infos': [
              {'chnum': 13, 'expect': 'no-connect'},
              {'chnum': 36, 'expect': 'connect'},
              {'chnum': 52, 'expect': 'passive-scan'},
              {'chnum': 120, 'expect': 'passive-scan'},
              {'chnum': 149, 'expect': 'connect'},
              {'chnum': 165, 'expect': 'connect'}]},
         {'region_name': 'nordic',  # virtual set
          'country_code': 'SE',
          'channel_infos': [
              {'chnum': 13, 'expect': 'connect'},
              {'chnum': 36, 'expect': 'connect'},
              {'chnum': 52, 'expect': 'passive-scan'},
              {'chnum': 120, 'expect': 'passive-scan'},
              {'chnum': 149, 'expect': 'no-connect'},
              {'chnum': 165, 'expect': 'no-connect'}]},
         {'region_name': 'us',
          'country_code': 'US',
          'channel_infos': [
              {'chnum': 13, 'expect': 'no-connect'},
              {'chnum': 36, 'expect': 'connect'},
              {'chnum': 52, 'expect': 'passive-scan'},
              {'chnum': 120, 'expect': 'no-connect'},
              {'chnum': 149, 'expect': 'connect'},
              {'chnum': 165, 'expect': 'connect'}]}],
    'intel_wp2':
    # TODO(quiche): Add wp2 expectations for channels 52 and 120. If
    # those expectations match the (to-be-added) expectations for
    # ath9k, then collapse both configs into a 'cfg80211' config.
        [
         {'region_name': '',
          'country_code': '00',
          'channel_infos': [
              {'chnum': 13, 'expect': 'passive-scan'},
              {'chnum': 36, 'expect': 'passive-scan'},
              {'chnum': 149, 'expect': 'passive-scan'}]},
         # Many of the 'passive-scan' expectations seem to follow from
         # the initial world rules above. (Or, at least, not all of
         # the passive scanning expectations can be attributed to
         # country-speific data in wireless-regdb. We haven't
         # investigated if the 'passive-scan' expectations are due to
         # rules in the driver.)
         {'region_name': 'ar',
          'country_code': 'AR',
          'channel_infos': [
              {'chnum': 13, 'expect': 'passive-scan'},
              {'chnum': 36, 'expect': 'passive-scan'},
              {'chnum': 149, 'expect': 'passive-scan'}]},
         {'region_name': 'id',
          'country_code': 'ID',
          'channel_infos': [
              {'chnum': 13, 'expect': 'passive-scan'},
              {'chnum': 36, 'expect': 'no-connect'},
              {'chnum': 149, 'expect': 'passive-scan'}]},
         {'region_name': 'ru',
          'country_code': 'RU',
          'channel_infos': [
              {'chnum': 13, 'expect': 'passive-scan'},
              {'chnum': 36, 'expect': 'passive-scan'},
              {'chnum': 149, 'expect': 'passive-scan'}]},
         {'region_name': 'us',
          'country_code': 'US',
          'channel_infos': [
              {'chnum': 13, 'expect': 'no-connect'},
              {'chnum': 36, 'expect': 'passive-scan'},
              {'chnum': 149, 'expect': 'passive-scan'}]}]}
WLAN_DEV = 'wlan0'


def run(machine):
    host = hosts.create_host(machine)
    wlan_info = interface.Interface(WLAN_DEV, host=host).device_description
    if not wlan_info:
        raise error.TestFail('Couldn\'t find the WiFi device.')
    if wlan_info.name in (
        interface.NAME_ATHEROS_AR9280,
        interface.NAME_ATHEROS_AR9382,
        interface.NAME_ATHEROS_AR9462):
            devtype = 'ath9k'
    elif wlan_info.name in (
        interface.NAME_BROADCOM_BCM4354_SDIO,
        interface.NAME_BROADCOM_BCM4356_PCIE):
            devtype = 'bcm435x'
    elif wlan_info.name in (
        interface.NAME_INTEL_7260,
        interface.NAME_INTEL_7265):
            devtype = 'intel_wp2'
    else:
        raise error.TestNAError(
            'Unrecognized WiFi chip |%s|.' % wlan_info.name)

    logging.debug('Running test with devtype=%s', devtype)
    for region_info in DEVTYPE_TO_REGION_INFOS[devtype]:
        # Use a fresh |host| every time, as WiFiTestContextManager
        # cleans up |host| on context exit.
        host = hosts.create_host(machine)
        job.run_test(
            'network_WiFi_RegDomain',
            tag=region_info['region_name'] or 'default',
            host=host,
            raw_cmdline_args=args,
            additional_params=region_info)


parallel_simple(run, machines)
