# 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 logging
import time

from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
from autotest_lib.server.cros.network import hostap_config
from autotest_lib.server.cros.network import wifi_cell_test_base


class network_WiFi_VerifyRouter(wifi_cell_test_base.WiFiCellTestBase):
    """Test that a dual radio router can use both radios."""
    version = 1
    MAX_ASSOCIATION_RETRIES = 8  # Super lucky number.  Not science.

    # We don't want to accept really low signal strength, so we pick an
    # arbitrary threshold.
    SIGNAL_THRESHOLD = -60


    def _connect(self, wifi_params):
        assoc_result = xmlrpc_datatypes.deserialize(
                self.context.client.shill.connect_wifi(wifi_params))
        logging.info('Finished connection attempt to %s with times: '
                     'discovery=%.2f, association=%.2f, configuration=%.2f.',
                     wifi_params.ssid,
                     assoc_result.discovery_time,
                     assoc_result.association_time,
                     assoc_result.configuration_time)
        return assoc_result.success


    def _antenna_test(self, bitmap, channel):
        """Test that we can connect on |channel|, with given antenna |bitmap|.

        Sets up two radios on |channel|, configures both radios with the
        given antenna |bitmap|, and then verifies that a client can connect
        to the AP on each radio and that the DUT doesn't report unreasonably
        low signal strength.

        Why do we run the two radios concurrently, instead of iterating over
        them? That's simply because our lower-layer code doesn't provide an
        interface for specifiying which PHY to run an AP on.

        To work around the API limitaiton, we bring up multiple APs, and let
        the lower-layer code spread them across radios. For stumpy/panther,
        this works in an obvious way. That is, each call to this method
        exercises phy0 and phy1.

        For whirlwind, we do not cover the 3rd radio. phy0 is 2.4 GHz, phy1 is
        5 GHz, and phy2 is a 1x1 radio that covers both. Because phy2 isn't
        normally used (and validated) as a transmitter, and because our
        conductive setups don't even wire up its antennas, we try not to use it
        in practice. So in effect, this test will be double-testing phy0 and
        phy1 with the 2.4 GHz and 5 GHz portions of the test, respectively.

        Gale is similar to whirlwind, except that it has no phy2 radio.

        @param bitmap: int bitmask controlling which antennas to enable.
        @param channel: int Wifi channel to conduct test on

        """
        # Antenna can only be configured when the wireless interface is down.
        self.context.router.deconfig()
        self.context.router.disable_antennas_except(bitmap)
        # This seems to increase the probability that our association
        # attempts pass.  It is the very definition of a dark incantation.
        time.sleep(5)
        # Setup two APs on |channel|. configure() will spread these across
        # radios.
        n_mode = hostap_config.HostapConfig.MODE_11N_MIXED
        ap_config = hostap_config.HostapConfig(channel=channel, mode=n_mode)
        self.context.configure(ap_config)
        self.context.configure(ap_config, multi_interface=True)
        failures = []
        # Verify connectivity to both APs. As the APs are spread
        # across radios, this exercises multiple radios.
        for instance in range(2):
            context_message = ('bitmap=%d, ap_instance=%d, channel=%d' %
                               (bitmap, instance, channel))
            logging.info('Connecting to AP with settings %s.',
                         context_message)
            client_conf = xmlrpc_datatypes.AssociationParameters(
                    ssid=self.context.router.get_ssid(instance=instance))
            if self._connect(client_conf):
                signal_level = self.context.client.wifi_signal_level
                logging.info('Signal level for AP %d with bitmap %d is %d',
                             instance, bitmap, signal_level)
                self.write_perf_keyval(
                        {'signal_for_ap_%d_bm_%d_ch_%d' %
                                 (instance, bitmap, channel):
                         signal_level})
                # Don't accept very low signal strength.
                if signal_level < self.SIGNAL_THRESHOLD:
                    failures.append(context_message)
            else:
                failures.append(context_message)
            # Don't automatically reconnect to this AP.
            self.context.client.shill.disconnect(
                    self.context.router.get_ssid(instance=instance))
        return failures


    def cleanup(self):
        """Clean up after the test is completed

        Perform additional cleanups after the test, the important thing is
        to re-enable all antennas.
        """
        self.context.router.deconfig()
        self.context.router.enable_all_antennas()
        super(network_WiFi_VerifyRouter, self).cleanup()


    def run_once(self):
        """Verify that all radios on this router are functional."""
        all_failures = []

        # ath10k doesn't support support non-contiguous antenna masks. The
        # driver complains:
        #   ath10k_ahb a000000.wifi: mac tx antenna chainmask may be invalid:
        #   0x2.  Suggested values: 15, 7, 3, 1 or 0.
        # And on gale, the firmware crashes eventually. Whirlwind seems OK for
        # now.
        # TODO: communicate this back from the driver better, so we don't have
        # to build an exception list.
        if self.context.router.board == "gale":
            bitmaps = (3, 1)
        else:
            bitmaps = (3, 1, 2)

        # Run antenna test for 2GHz band and 5GHz band
        for channel in (6, 149):
            # First connect with both antennas enabled. Then connect with just
            # one antenna enabled at a time.
            for bitmap in bitmaps:
                failures = set()
                for _ in range(self.MAX_ASSOCIATION_RETRIES):
                    new_failures = self._antenna_test(bitmap, channel)
                    if not new_failures:
                        break
                    failures.update(new_failures)
                else:
                    all_failures += failures

        if all_failures:
            failure_message = ', '.join(
                    ['(' + message + ')' for message in all_failures])
            raise error.TestFail('Failed to connect when %s.' % failure_message)
