# Copyright 2014 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """USB echo gadget module. This gadget has pairs of IN/OUT endpoints that echo packets back to the host. """ import math import struct import uuid import gadget import usb_constants import usb_descriptors class EchoGadget(gadget.Gadget): """Echo gadget. """ def __init__(self): """Create an echo gadget. """ device_desc = usb_descriptors.DeviceDescriptor( idVendor=usb_constants.VendorID.GOOGLE, idProduct=usb_constants.ProductID.GOOGLE_ECHO_GADGET, bcdUSB=0x0200, iManufacturer=1, iProduct=2, iSerialNumber=3, bcdDevice=0x0100) fs_config_desc = usb_descriptors.ConfigurationDescriptor( bmAttributes=0x80, MaxPower=50) fs_intr_interface_desc = usb_descriptors.InterfaceDescriptor( bInterfaceNumber=0, bInterfaceClass=usb_constants.DeviceClass.VENDOR, bInterfaceSubClass=0, bInterfaceProtocol=0, iInterface=4, ) fs_intr_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor( bEndpointAddress=0x01, bmAttributes=usb_constants.TransferType.INTERRUPT, wMaxPacketSize=64, bInterval=1 # 1ms )) fs_intr_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor( bEndpointAddress=0x81, bmAttributes=usb_constants.TransferType.INTERRUPT, wMaxPacketSize=64, bInterval=1 # 1ms )) fs_config_desc.AddInterface(fs_intr_interface_desc) fs_bulk_interface_desc = usb_descriptors.InterfaceDescriptor( bInterfaceNumber=1, bInterfaceClass=usb_constants.DeviceClass.VENDOR, bInterfaceSubClass=0, bInterfaceProtocol=0, iInterface=5 ) fs_bulk_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor( bEndpointAddress=0x02, bmAttributes=usb_constants.TransferType.BULK, wMaxPacketSize=64, bInterval=0 )) fs_bulk_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor( bEndpointAddress=0x82, bmAttributes=usb_constants.TransferType.BULK, wMaxPacketSize=64, bInterval=0 )) fs_config_desc.AddInterface(fs_bulk_interface_desc) fs_config_desc.AddInterface(usb_descriptors.InterfaceDescriptor( bInterfaceNumber=2, bInterfaceClass=usb_constants.DeviceClass.VENDOR, bInterfaceSubClass=0, bInterfaceProtocol=0, iInterface=6 )) fs_isoc_interface_desc = usb_descriptors.InterfaceDescriptor( bInterfaceNumber=2, bAlternateSetting=1, bInterfaceClass=usb_constants.DeviceClass.VENDOR, bInterfaceSubClass=0, bInterfaceProtocol=0, iInterface=6 ) fs_isoc_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor( bEndpointAddress=0x03, bmAttributes=usb_constants.TransferType.ISOCHRONOUS, wMaxPacketSize=1023, bInterval=1 # 1ms )) fs_isoc_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor( bEndpointAddress=0x83, bmAttributes=usb_constants.TransferType.ISOCHRONOUS, wMaxPacketSize=1023, bInterval=1 # 1ms )) fs_config_desc.AddInterface(fs_isoc_interface_desc) hs_config_desc = usb_descriptors.ConfigurationDescriptor( bmAttributes=0x80, MaxPower=50) hs_intr_interface_desc = usb_descriptors.InterfaceDescriptor( bInterfaceNumber=0, bInterfaceClass=usb_constants.DeviceClass.VENDOR, bInterfaceSubClass=0, bInterfaceProtocol=0, iInterface=4 ) hs_intr_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor( bEndpointAddress=0x01, bmAttributes=usb_constants.TransferType.INTERRUPT, wMaxPacketSize=64, bInterval=4 # 1ms )) hs_intr_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor( bEndpointAddress=0x81, bmAttributes=usb_constants.TransferType.INTERRUPT, wMaxPacketSize=64, bInterval=4 # 1ms )) hs_config_desc.AddInterface(hs_intr_interface_desc) hs_bulk_interface_desc = usb_descriptors.InterfaceDescriptor( bInterfaceNumber=1, bInterfaceClass=usb_constants.DeviceClass.VENDOR, bInterfaceSubClass=0, bInterfaceProtocol=0, iInterface=5 ) hs_bulk_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor( bEndpointAddress=0x02, bmAttributes=usb_constants.TransferType.BULK, wMaxPacketSize=512, bInterval=0 )) hs_bulk_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor( bEndpointAddress=0x82, bmAttributes=usb_constants.TransferType.BULK, wMaxPacketSize=512, bInterval=0 )) hs_config_desc.AddInterface(hs_bulk_interface_desc) hs_config_desc.AddInterface(usb_descriptors.InterfaceDescriptor( bInterfaceNumber=2, bInterfaceClass=usb_constants.DeviceClass.VENDOR, bInterfaceSubClass=0, bInterfaceProtocol=0, iInterface=6 )) hs_isoc_interface_desc = usb_descriptors.InterfaceDescriptor( bInterfaceNumber=2, bAlternateSetting=1, bInterfaceClass=usb_constants.DeviceClass.VENDOR, bInterfaceSubClass=0, bInterfaceProtocol=0, iInterface=6 ) hs_isoc_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor( bEndpointAddress=0x03, bmAttributes=usb_constants.TransferType.ISOCHRONOUS, wMaxPacketSize=1024, bInterval=4 # 1ms )) hs_isoc_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor( bEndpointAddress=0x83, bmAttributes=usb_constants.TransferType.ISOCHRONOUS, wMaxPacketSize=1024, bInterval=4 # 1ms )) hs_config_desc.AddInterface(hs_isoc_interface_desc) super(EchoGadget, self).__init__( device_desc, fs_config_desc, hs_config_desc) self.AddStringDescriptor(1, 'Google Inc.') self.AddStringDescriptor(2, 'Echo Gadget') self.AddStringDescriptor(3, '{:06X}'.format(uuid.getnode())) self.AddStringDescriptor(4, 'Interrupt Echo') self.AddStringDescriptor(5, 'Bulk Echo') self.AddStringDescriptor(6, 'Isochronous Echo') def ReceivePacket(self, endpoint, data): """Echo a packet back to the host. Args: endpoint: Incoming endpoint (must be an OUT pipe). data: Packet data. """ assert endpoint & usb_constants.Dir.IN == 0 self.SendPacket(endpoint | usb_constants.Dir.IN, data) def RegisterHandlers(): """Registers web request handlers with the application server.""" import server from tornado import web class WebConfigureHandler(web.RequestHandler): def post(self): server.SwitchGadget(EchoGadget()) server.app.add_handlers('.*$', [ (r'/echo/configure', WebConfigureHandler), ])