def __init__(self): self.usb_bus = UsbBus.Instance() self.request_buffer = RequestBuffer()
def __init__(self): self.router = None self.poller = None self.transmitter_applications = dict() self.request_buffer = RequestBuffer()
class UsbPortController: def __init__(self): self.usb_bus = UsbBus.Instance() self.request_buffer = RequestBuffer() def handle_event(self, action, device): """ action: the action that caused this event (eg add, remove) device: the usb device that prompted the event """ operation = Operation(action) if not device.attributes: usb_device = self.usb_bus.find_with(path=device.device_path) new_op = UsbOperation(operation=operation, usb_device=usb_device) message = DocumentMessage(document=new_op.to_json()) request = Request( id=message.id, dispatcher=self.usb_monitor_pair.send_string, args=message.serialize(), hop_limit=10 ) self.request_buffer.append(request) self.usb_bus.remove(usb_device) else: usb_device = UsbDevice(device) self.usb_bus.add(usb_device) new_op = UsbOperation(operation=operation, usb_device=usb_device) message = DocumentMessage(document=new_op.to_json()) request = Request( id=message.id, dispatcher=self.usb_monitor_pair.send_string, args=message.serialize(), hop_limit=10 ) self.request_buffer.append(message) def run(self): logger.info("USB Port Controller starting") context = pyudev.Context() monitor = pyudev.Monitor.from_netlink(context) monitor.filter_by(subsystem="usb", device_type="usb_device") observer = pyudev.MonitorObserver(monitor, self.handle_event) observer.start() kbsubscriber = NetworkingManager.KillBroadcastSubscriber() usb_monitor_pair = NetworkingManager.UsbMonitorPairServer() poller = NetworkingManager.Poller() poller.register(kbsubscriber, NetworkingManager.POLLIN) poller.register(usb_monitor_pair, NetworkingManager.POLLIN) for device in self.usb_bus.devices: new_op = UsbOperation(usb_device=device, operation=Operation("add")) message = DocumentMessage(document=new_op.to_json()) request = Request( id=message.id, dispatcher=usb_monitor_pair.send_string, args=message.serialize(), hop_limit=10 ) self.request_buffer.append(request) while True: self.request_buffer.dispatch_all() socks = dict(poller.poll(50)) if usb_monitor_pair.contained_in(socks): reply = CommandMessage.deserialize(usb_monitor_pair.recv_string()) self.request_buffer.process_reply(reply) if kbsubscriber.contained_in(socks): message = CommandMessage.deserialize(kbsubscriber.recv_string()) reply_structure = None try: command = Command(message.command) command_processor = CommandProcessor(self) reply_structure = command_processor.process(command) except ExitProcess: observer.stop() usb_monitor_pair.unbind() logger.info("USB Port Controller stopping") break finally: # send message if applicable if reply_structure: pass
class TransmitterApplicationController: def __init__(self): self.router = None self.poller = None self.transmitter_applications = dict() self.request_buffer = RequestBuffer() def process_usb_operation(self, usb_operation): transmitter = TransmitterIndex.find_matching(usb_operation.usb_device) if transmitter: if usb_operation.operation is Operation.ADD: self.start_transmitter_application(transmitter) elif usb_operation.operation is Operation.REMOVE: self.stop_transmitter_application(transmitter) def start_transmitter_application(self, transmitter): for child_id, app in self.transmitter_applications.items(): if app.transmitter == transmitter: logger.error( "Process using "+repr(transmitter)+" already running" ) return child_id = NEXT_CHILD_ID() controller = TransmitterController(transmitter, child_id) process = Process(target=controller.run) process.daemon = True process.start() app = _TransmitterApplication(controller, process) self.transmitter_applications[child_id] = app def stop_transmitter_application(self, transmitter): for child_id, app in self.transmitter_applications.items(): if app.transmitter == transmitter: message = CommandMessage(command=Command.SHUTDOWN) request = Request( id=message.id, dispatcher=self.router.send_string, args=[child_id, message.serialize], hop_limit=-1, splat_args=True ) self.request_buffer.append(request) def stop_all_transmitter_applications(self): for child_id, app in self.transmitter_applications: message = CommandMessage(command=Command.SHUTDOWN) request = Request( id=message.id, dispatcher=self.router.send_string, args=[child_id, message.serialize], hop_limit=-1, splat_args=True ) self.request_buffer.append(request) app.last_request = message def run(self): logger.info("Transmitter Application Controller starting") # Kill broadcast subscriber kbsubscriber = NetworkingManager.KillBroadcastSubscriber() usb_monitor_pair = NetworkingManager.UsbMonitorPairClient() self.router = NetworkingManager.TACParent() self.poller = NetworkingManager.Poller() self.poller.register(kbsubscriber, NetworkingManager.POLLIN) self.poller.register(usb_monitor_pair, NetworkingManager.POLLIN) self.poller.register(self.router, NetworkingManager.POLLIN) while True: self.request_buffer.dispatch_all() socks = dict(self.poller.poll(50)) if self.router.contained_in(socks): child_id, string = self.router.recv_string() # do some stuff with reply app = self.transmitter_applications[child_id] if app.last_request == Command.SHUTDOWN: reply = CommandMessage.deserialize(string) self.request_buffer.process_reply(reply) if app.process.is_alive(): app.process.terminate() del self.transmitter_applications[child_id] if usb_monitor_pair.contained_in(socks): # a message from the usb port controller indicates # a usb device has been added or removed from the system request = DocumentMessage.deserialize( usb_monitor_pair.recv_string() ) logger.info("Request received: " + request.serialize()) usb_operation = UsbOperation.from_json(request.contents) self.process_usb_operation(usb_operation) # send a void reply to confirm receipt reply = CommandMessage.VoidReply(request) usb_monitor_pair.send_string(reply.serialize()) if kbsubscriber.contained_in(socks): message = CommandMessage.deserialize( kbsubscriber.recv_string() ) reply_structure = None try: command = Command(message.command) command_processor = CommandProcessor(self) reply_structure = command_processor.process(command) except ExitProcess: self.request_buffer.clear() self.stop_all_transmitter_applications() self.request_buffer.dispatch_all() logger.info("Transmitter Application Controller stopping") break finally: if reply_structure: pass