# 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_flaky"
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)
