# 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 = params.get("cmd_iw", "/usr/sbin/iw")
        self.cmd_ip = params.get("cmd_ip", "/usr/sbin/ip")
        self.cmd_dhcpd = params.get("cmd_dhcpd", "/usr/sbin/dhcpd")
        self.cmd_tcpdump = params.get("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.phy_for_frequency = {}

        # 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
                wiphyname = 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.phy_for_frequency[mhz] = wiphyname
                else:
                    in_phy = False
        self.phydev2 = params.get('phydev2', None)
        self.phydev5 = params.get('phydev5', None)


    def _remove_interfaces(self):
        self.wlanifs = {}
        # Remove all wifi devices.
        output = self.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)
                self.host.run("%s link set %s down" % (self.cmd_ip, device))
                self.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.phy_for_frequency:
            phy = self.phy_for_frequency[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
