# 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 ping_runner
from autotest_lib.client.common_lib.cros.network import tcpdump_analyzer
from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
from autotest_lib.server import site_linux_system
from autotest_lib.server.cros.network import hostap_config
from autotest_lib.server.cros.network import wifi_cell_test_base


class network_WiFi_TDLSPing(wifi_cell_test_base.WiFiCellTestBase):
    """Tests that the DUT can establish a TDLS link to a connected peer.

    This test associates the DUT with an AP, then attaches a peer
    client to the same AP.  After enabling a TDLS link from the DUT
    to the attached peer, we should see in the over-the-air packets
    that a ping between these devices does not use the AP as a relay
    any more.

    """

    version = 1

    def ping_and_check_for_tdls(self, frequency, expected):
        """
        Use an over-the-air packet capture to check whether we see
        ICMP packets from the DUT that indicate it is using a TDLS
        link to transmit its requests.  Raise an exception if this
        was not what was |expected|.

        @param frequency: int frequency on which to perform the packet capture.
        @param expected: bool set to true if we expect the sender to use TDLS.

        """
        self.context.router.start_capture(frequency)

        # Since we don't wait for the TDLS link to come up, it's possible
        # that we'll have some fairly drastic packet loss as the link is
        # being established.  We don't care about that in this test, except
        # that we should see at least a few packets by the end of the ping
        # we can use to test for TDLS.  Therefore we ignore the statistical
        # result of the ping.
        ping_config = ping_runner.PingConfig(
                self.context.router.local_peer_ip_address(0),
                ignore_result=True)
        self.context.assert_ping_from_dut(ping_config=ping_config)

        results = self.context.router.stop_capture()
        if len(results) != 1:
            raise error.TestError('Expected to generate one packet '
                                  'capture but got %d captures instead.' %
                                  len(results))
        pcap_result = results[0]

        logging.info('Analyzing packet capture...')

        # Filter for packets from the DUT.
        client_mac_filter = 'ether src host %s' % self.context.client.wifi_mac

        # In this test we only care that the outgoing ICMP requests are
        # sent over IBSS, so we filter for ICMP echo requests explicitly.
        icmp_filter = 'icmp[icmptype] = icmp-echo'

        # This filter requires a little explaining.  The "link[1]" identifier
        # tells tcpdump to provide the second byte of the link header, which
        # in the case of a received 802.11 frame is the second byte of the
        # frame control field.  This field contains the "tods" and "fromds"
        # bits in bit 0 and 1 respsectively.  These bits have the following
        # interpretation:
        #
        #   ToDS  FromDS
        #     0     0      Ad-Hoc (IBSS)
        #     0     1      Traffic from client to the AP
        #     1     0      Traffic from AP to the client
        #     1     1      4-address mode for wireless distribution system
        #
        # TDLS co-opts the ToDS=0, FromDS=0 (IBSS) mode when transferring
        # data directly between peers.  Therefore, to detect TDLS, we mask
        # the ToDS and FromDS bits out of the second byte of the frame control
        # and compare it with 0.
        tdls_filter = 'link[1] & 0x3 == 0'

        dut_icmp_pcap_filter = ' and '.join(
                [client_mac_filter, icmp_filter, tdls_filter])
        frames = tcpdump_analyzer.get_frames(
                pcap_result.pcap_path,
                remote_host=self.context.router.host,
                pcap_filter=dut_icmp_pcap_filter)
        if expected and not frames:
            raise error.TestFail('Packet capture did not contain a IBSS '
                                 'frames from the DUT!')
        elif not expected and frames:
            raise error.TestFail('Packet capture contain a IBSS frames '
                                 'from the DUT, but we did not expect them!')


    def run_once(self):
        """Test body."""
        client_caps = self.context.client.capabilities
        if site_linux_system.LinuxSystem.CAPABILITY_TDLS not in client_caps:
            raise error.TestNAError('DUT is incapable of TDLS')

        # Configure the AP.
        frequency = 2412
        self.context.configure(hostap_config.HostapConfig(
                frequency=frequency, force_wmm=True))
        router_ssid = self.context.router.get_ssid()

        # Connect the DUT to the AP.
        self.context.assert_connect_wifi(
                xmlrpc_datatypes.AssociationParameters(ssid=router_ssid))

        # Connect a client instance to the AP so the DUT has a peer to which
        # it can send TDLS traffic.
        self.context.router.add_connected_peer()

        # Test for TDLS connectivity to the peer, using the IP address.
        # We expect the first attempt to fail since the client does not
        # have the IP address of the peer in its ARP cache.
        peer_ip = self.context.router.local_peer_ip_address(0)
        link_state = self.context.client.query_tdls_link(peer_ip)
        if link_state is not False:
            raise error.TestError(
                    'First query of TDLS link succeeded: %r' % link_state)

        # Wait a reasonable time for the ARP triggered by the first TDLS
        # command to succeed.
        time.sleep(1)

        # A second attempt should succeed, since by now the ARP cache should
        # be populated.  However at this time there should be no link.
        link_state = self.context.client.query_tdls_link(peer_ip)
        if link_state != 'Nonexistent':
            raise error.TestError(
                    'DUT does not report a missing TDLS link: %r' % link_state)

        # Ping from DUT to the associated peer without TDLS.
        self.ping_and_check_for_tdls(frequency, expected=False)

        # Ping from DUT to the associated peer with TDLS.
        self.context.client.establish_tdls_link(peer_ip)
        self.ping_and_check_for_tdls(frequency, expected=True)

        # Ensure that the DUT reports the TDLS link as being active.
        # Use the MAC address to ensure we can perform TDLS requests
        # against either IP or MAC addresses.
        peer_mac = self.context.router.local_peer_mac_address()
        link_state = self.context.client.query_tdls_link(peer_mac)
        if link_state != 'Connected':
            raise error.TestError(
                    'DUT does not report TDLS link is active: %r' % link_state)
