# Copyright (c) 2011 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 re, logging
from autotest_lib.client.common_lib import error

class LinuxSystem(object):
    """ This is a superclass for test machines running Linux.  It provides
        a common point for routines that use the cfg80211 users space tools
        to manipulate the wireless stack, regardless of the role they play.
        Currently the commands shared are the init, which queries for wireless
        devices, along with start_capture and stop_capture.  More commands
        may migrate from site_linux_router as appropriate to share.
    """
    def __init__(self, host, params, role):
        # Command locations.
        self.cmd_iw = "/usr/sbin/iw"
        self.cmd_ip = "/usr/sbin/ip"
        self.cmd_dhcpd = "/usr/sbin/dhcpd"
        self.cmd_tcpdump = "/usr/sbin/tcpdump"

        self.capture_file = "/tmp/dump.cap"
        self.capture_logfile = "/tmp/dump.log"
        self.capture_count = 0
        self.capture_running = False
        self.capture_channel = None

        self.host = host
        self.role = role

        setattr(self, '%s_netdump_start' % role, self.start_capture)
        setattr(self, '%s_netdump_stop' % role, self.stop_capture)

        # Network interfaces.
        self.frequency_support = {}
        self.wlanifs = {}

        # Parse the output of 'iw phy' and find a device for each frequency
        output = host.run("%s list" % self.cmd_iw).stdout
        re_wiphy = re.compile("Wiphy (.*)")
        re_mhz = re.compile("(\d+) MHz")
        in_phy = False
        for line in output.splitlines():
            match_wiphy = re_wiphy.match(line)
            if match_wiphy:
                in_phy = True
                widevname = match_wiphy.group(1)
            elif in_phy:
                if line[0] == '\t':
                    match_mhz = re_mhz.search(line)
                    if match_mhz:
                        mhz = int(match_mhz.group(1))
                        self.frequency_support[mhz] = widevname
                else:
                    in_phy = False
        self.phydev2 = params.get('phydev2', None)
        self.phydev5 = params.get('phydev5', None)

        # Remove all wifi devices.
        output = host.run("%s dev" % self.cmd_iw).stdout
        test = re.compile("[\s]*Interface (.*)")
        for line in output.splitlines():
            m = test.match(line)
            if m:
                device = m.group(1)
                host.run("%s link set %s down" % (self.cmd_ip, device))
                host.run("%s dev %s del" % (self.cmd_iw, device))


    def start_capture(self, params):
        if self.capture_running:
            self.stop_capture({})

        if 'channel' in params:
            channel = int(params['channel'])
            channel_args = "%s" % channel
            for arg in ('ht20', 'ht40+', 'ht40-'):
                if arg in params:
                    channel_args = "%s %s" % (channel_args, arg.upper())
            self.capture_channel = channel
            self.channel_args = channel_args
        else:
            channel = self.capture_channel
            channel_args = self.channel_args
        self.capture_interface = self._get_wlanif(channel, "monitor")

        self.host.run("%s dev %s set freq %s" %
            (self.cmd_iw, self.capture_interface, channel_args))

        self.host.run("%s link set %s up" % (self.cmd_ip,
                                             self.capture_interface))

        self.host.run("%s -i %s -w %s -s %s >%s 2>&1 &" %
                      (self.cmd_tcpdump,
                       self.capture_interface,
                       self.capture_file,
                       params.get('snaplen', '2048'),
                       self.capture_logfile))
        self.capture_running = True


    def stop_capture(self, params):
        if not self.capture_running:
            return
        self.host.run("pkill -INT tcpdump >/dev/null 2>&1", ignore_status=True)
        self.host.run("%s link set %s down" % (self.cmd_ip,
                                               self.capture_interface))

        self.host.get_file(self.capture_file,
                             'debug/tcpdump_%s_%d.cap' %
                             (self.role, self.capture_count))
        self.capture_count += 1
        self.capture_running = False


    def _get_wlanif(self, frequency, phytype, mode = None):
        """ This function is used to inherited classes, so we use the
            single '_' convention rather than the '__' we usually use for
            non-scriptable commands, since these cannot be inherited by
            subclasses.

            We still support the old "phydevN" parameters, but
            this code is smart enough to do without it.
        """
        if mode in ('b', 'g') and self.phydev2 is not None:
            phy = self.phydev2
        elif mode == 'a' and self.phydev5 is not None:
            phy = self.phydev5
        elif frequency in self.frequency_support:
            phy = self.frequency_support[frequency]
        else:
            raise error.TestFail("Unable to find phy for frequency %d mode %s" %
                                 (frequency, mode))

        if phytype not in self.wlanifs:
            self.wlanifs[phytype] = {}
        elif phy in self.wlanifs[phytype]:
            return self.wlanifs[phytype][phy]

        wlanif = "%s%d" % (phytype, len(self.wlanifs[phytype].keys()))
        self.wlanifs[phytype][phy] = wlanif

        self.host.run("%s phy %s interface add %s type %s" %
            (self.cmd_iw, phy, wlanif, phytype))

        return wlanif
