#!/usr/bin/env python3

import socketserver
import subprocess
import syslog

def change_usb_state(action):
    global state
    if action == state: return
    if action == "toggle": action = "guest" if state == "host" else "host"
    syslog.syslog("Setting xHCI port routing mask to {:#x}".format(masks[action]))
    if subprocess.call(["setpci", "-s0:14.0", "0xd0.L=0x{:08x}".format(masks[action])]) == 0: state = action
    else: syslog.syslog("Calling setpci failed. Assuming routing is unchanged.")

class PCIHandler(socketserver.StreamRequestHandler):
    def handle(self):
        for line in self.rfile:
            action = line.strip().decode("utf-8")
            syslog.syslog("Got action request: {}".format(action))
            if action in ["guest", "host", "toggle"]: change_usb_state(action)

class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): pass

masks = { "guest": 0x0fc, "host": 0x0ff }
state = "host"
server = ThreadedTCPServer(("127.0.0.1", 10), PCIHandler)
server.serve_forever()
