#!/usr/bin/python2
# 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.

"""Wrapper for an RF switch built on an Elexol EtherIO24.

The EtherIO is documented at
        http://www.elexol.com/IO_Modules/Ether_IO_24_Dip_R.php

This file is both a python module and a command line utility to speak
to the module
"""

import cellular_logging
import collections
import socket
import struct
import sys

log = cellular_logging.SetupCellularLogging('ether_io_rf_switch')


class Error(Exception):
    pass


class EtherIo24(object):
    """Encapsulates an EtherIO24 UDP-GPIO bridge."""

    def __init__(self, hostname, port=2424):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.socket.bind(('', 0))
        self.destination = (hostname, port)
        self.socket.settimeout(3)   # In seconds

    def SendPayload(self, payload):
        self.socket.sendto(payload, self.destination)

    def SendOperation(self, opcode, list_bytes):
        """Sends the specified opcode with [list_bytes] as an argument."""
        payload = opcode + struct.pack(('=%dB' % len(list_bytes)), *list_bytes)
        self.SendPayload(payload)
        return payload

    def SendCommandVerify(self, write_opcode, list_bytes, read_opcode=None):
        """Sends opcode and bytes,
        then reads to make sure command was executed."""
        if read_opcode is None:
            read_opcode = write_opcode.lower()
        for _ in xrange(3):
            write_sent = self.SendOperation(write_opcode, list_bytes)
            self.SendOperation(read_opcode, list_bytes)
            try:
                response = self.AwaitResponse()
                if response == write_sent:
                    return
                else:
                    log.warning('Unexpected reply:  sent %s, got %s',
                                write_sent.encode('hex_codec'),
                                response.encode('hex_codec'))
            except socket.timeout:
                log.warning('Timed out awaiting reply for %s', write_opcode)
                continue
        raise Error('Failed to execute %s' % write_sent.encode('hex_codec'))

    def AwaitResponse(self):
        (response, address) = self.socket.recvfrom(65536)
        if (socket.gethostbyname(address[0]) !=
                socket.gethostbyname(self.destination[0])):
            log.warning('Unexpected reply source: %s (expected %s)',
                        address, self.destination)
        return response


class RfSwitch(object):
    """An RF switch hooked to an Elexol EtherIO24."""

    def __init__(self, ip):
        self.io = EtherIo24(ip)
        # Must run on pythons without 0bxxx notation.  These are 1110,
        # 1101, 1011, 0111
        decode = [0xe, 0xd, 0xb, 0x7]

        self.port_mapping = []
        for upper in xrange(3):
            for lower in xrange(4):
                self.port_mapping.append(decode[upper] << 4 | decode[lower])

    def SelectPort(self, n):
        """Connects port n to the RF generator."""
        # Set all pins to output

        # !A0:  all pins output
        self.io.SendCommandVerify('!A', [0])
        self.io.SendCommandVerify('A', [self.port_mapping[n]])

    def Query(self):
        """Returns (binary port status, selected port, port direction)."""
        self.io.SendOperation('!a', [])
        raw_direction = self.io.AwaitResponse()
        direction = ord(raw_direction[2])

        self.io.SendOperation('a', [])
        status = ord(self.io.AwaitResponse()[1])
        try:
            port = self.port_mapping.index(status)
        except ValueError:
            port = None

        return status, port, direction


def CommandLineUtility(arguments):
    """Command line utility to control a switch."""

    def Select(switch, remaining_args):
        switch.SelectPort(int(remaining_args.popleft()))

    def Query(switch, unused_remaining_args):
        (raw_status, port, direction) = switch.Query()
        if direction != 0x00:
            print 'Warning: Direction register is %x, should be 0x00' % \
                  direction
        if port is None:
            port_str = 'Invalid'
        else:
            port_str = str(port)
        print 'Port %s  (0x%x)' % (port_str, raw_status)

    def Usage():
        print 'usage:  %s hostname {query|select portnumber}' % sys.argv[0]
        exit(1)

    try:
        hostname = arguments.popleft()
        operation = arguments.popleft()

        switch = RfSwitch(hostname)

        if operation == 'query':
            Query(switch, arguments)
        elif operation == 'select':
            Select(switch, arguments)
        else:
            Usage()
    except IndexError:
        Usage()

if __name__ == '__main__':
    CommandLineUtility(collections.deque(sys.argv[1:]))
