Home | History | Annotate | Download | only in usb_gadget
      1 # Copyright 2014 The Chromium Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 """USB echo gadget module.
      6 
      7 This gadget has pairs of IN/OUT endpoints that echo packets back to the host.
      8 """
      9 
     10 import math
     11 import struct
     12 import uuid
     13 
     14 import gadget
     15 import usb_constants
     16 import usb_descriptors
     17 
     18 
     19 class EchoGadget(gadget.Gadget):
     20   """Echo gadget.
     21   """
     22 
     23   def __init__(self):
     24     """Create an echo gadget.
     25     """
     26     device_desc = usb_descriptors.DeviceDescriptor(
     27         idVendor=usb_constants.VendorID.GOOGLE,
     28         idProduct=usb_constants.ProductID.GOOGLE_ECHO_GADGET,
     29         bcdUSB=0x0200,
     30         iManufacturer=1,
     31         iProduct=2,
     32         iSerialNumber=3,
     33         bcdDevice=0x0100)
     34 
     35     fs_config_desc = usb_descriptors.ConfigurationDescriptor(
     36         bmAttributes=0x80,
     37         MaxPower=50)
     38     fs_intr_interface_desc = usb_descriptors.InterfaceDescriptor(
     39         bInterfaceNumber=0,
     40         bInterfaceClass=usb_constants.DeviceClass.VENDOR,
     41         bInterfaceSubClass=0,
     42         bInterfaceProtocol=0,
     43         iInterface=4,
     44     )
     45     fs_intr_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
     46         bEndpointAddress=0x01,
     47         bmAttributes=usb_constants.TransferType.INTERRUPT,
     48         wMaxPacketSize=64,
     49         bInterval=1  # 1ms
     50     ))
     51     fs_intr_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
     52         bEndpointAddress=0x81,
     53         bmAttributes=usb_constants.TransferType.INTERRUPT,
     54         wMaxPacketSize=64,
     55         bInterval=1  # 1ms
     56     ))
     57     fs_config_desc.AddInterface(fs_intr_interface_desc)
     58 
     59     fs_bulk_interface_desc = usb_descriptors.InterfaceDescriptor(
     60         bInterfaceNumber=1,
     61         bInterfaceClass=usb_constants.DeviceClass.VENDOR,
     62         bInterfaceSubClass=0,
     63         bInterfaceProtocol=0,
     64         iInterface=5
     65     )
     66     fs_bulk_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
     67         bEndpointAddress=0x02,
     68         bmAttributes=usb_constants.TransferType.BULK,
     69         wMaxPacketSize=64,
     70         bInterval=0
     71     ))
     72     fs_bulk_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
     73         bEndpointAddress=0x82,
     74         bmAttributes=usb_constants.TransferType.BULK,
     75         wMaxPacketSize=64,
     76         bInterval=0
     77     ))
     78     fs_config_desc.AddInterface(fs_bulk_interface_desc)
     79 
     80     fs_config_desc.AddInterface(usb_descriptors.InterfaceDescriptor(
     81         bInterfaceNumber=2,
     82         bInterfaceClass=usb_constants.DeviceClass.VENDOR,
     83         bInterfaceSubClass=0,
     84         bInterfaceProtocol=0,
     85         iInterface=6
     86     ))
     87     fs_isoc_interface_desc = usb_descriptors.InterfaceDescriptor(
     88         bInterfaceNumber=2,
     89         bAlternateSetting=1,
     90         bInterfaceClass=usb_constants.DeviceClass.VENDOR,
     91         bInterfaceSubClass=0,
     92         bInterfaceProtocol=0,
     93         iInterface=6
     94     )
     95     fs_isoc_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
     96         bEndpointAddress=0x03,
     97         bmAttributes=usb_constants.TransferType.ISOCHRONOUS,
     98         wMaxPacketSize=1023,
     99         bInterval=1  # 1ms
    100     ))
    101     fs_isoc_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
    102         bEndpointAddress=0x83,
    103         bmAttributes=usb_constants.TransferType.ISOCHRONOUS,
    104         wMaxPacketSize=1023,
    105         bInterval=1  # 1ms
    106     ))
    107     fs_config_desc.AddInterface(fs_isoc_interface_desc)
    108 
    109     hs_config_desc = usb_descriptors.ConfigurationDescriptor(
    110         bmAttributes=0x80,
    111         MaxPower=50)
    112 
    113     hs_intr_interface_desc = usb_descriptors.InterfaceDescriptor(
    114         bInterfaceNumber=0,
    115         bInterfaceClass=usb_constants.DeviceClass.VENDOR,
    116         bInterfaceSubClass=0,
    117         bInterfaceProtocol=0,
    118         iInterface=4
    119     )
    120     hs_intr_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
    121         bEndpointAddress=0x01,
    122         bmAttributes=usb_constants.TransferType.INTERRUPT,
    123         wMaxPacketSize=64,
    124         bInterval=4  # 1ms
    125     ))
    126     hs_intr_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
    127         bEndpointAddress=0x81,
    128         bmAttributes=usb_constants.TransferType.INTERRUPT,
    129         wMaxPacketSize=64,
    130         bInterval=4  # 1ms
    131     ))
    132     hs_config_desc.AddInterface(hs_intr_interface_desc)
    133 
    134     hs_bulk_interface_desc = usb_descriptors.InterfaceDescriptor(
    135         bInterfaceNumber=1,
    136         bInterfaceClass=usb_constants.DeviceClass.VENDOR,
    137         bInterfaceSubClass=0,
    138         bInterfaceProtocol=0,
    139         iInterface=5
    140     )
    141     hs_bulk_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
    142         bEndpointAddress=0x02,
    143         bmAttributes=usb_constants.TransferType.BULK,
    144         wMaxPacketSize=512,
    145         bInterval=0
    146     ))
    147     hs_bulk_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
    148         bEndpointAddress=0x82,
    149         bmAttributes=usb_constants.TransferType.BULK,
    150         wMaxPacketSize=512,
    151         bInterval=0
    152     ))
    153     hs_config_desc.AddInterface(hs_bulk_interface_desc)
    154 
    155     hs_config_desc.AddInterface(usb_descriptors.InterfaceDescriptor(
    156         bInterfaceNumber=2,
    157         bInterfaceClass=usb_constants.DeviceClass.VENDOR,
    158         bInterfaceSubClass=0,
    159         bInterfaceProtocol=0,
    160         iInterface=6
    161     ))
    162     hs_isoc_interface_desc = usb_descriptors.InterfaceDescriptor(
    163         bInterfaceNumber=2,
    164         bAlternateSetting=1,
    165         bInterfaceClass=usb_constants.DeviceClass.VENDOR,
    166         bInterfaceSubClass=0,
    167         bInterfaceProtocol=0,
    168         iInterface=6
    169     )
    170     hs_isoc_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
    171         bEndpointAddress=0x03,
    172         bmAttributes=usb_constants.TransferType.ISOCHRONOUS,
    173         wMaxPacketSize=1024,
    174         bInterval=4  # 1ms
    175     ))
    176     hs_isoc_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
    177         bEndpointAddress=0x83,
    178         bmAttributes=usb_constants.TransferType.ISOCHRONOUS,
    179         wMaxPacketSize=1024,
    180         bInterval=4  # 1ms
    181     ))
    182     hs_config_desc.AddInterface(hs_isoc_interface_desc)
    183 
    184     super(EchoGadget, self).__init__(
    185         device_desc, fs_config_desc, hs_config_desc)
    186     self.AddStringDescriptor(1, 'Google Inc.')
    187     self.AddStringDescriptor(2, 'Echo Gadget')
    188     self.AddStringDescriptor(3, '{:06X}'.format(uuid.getnode()))
    189     self.AddStringDescriptor(4, 'Interrupt Echo')
    190     self.AddStringDescriptor(5, 'Bulk Echo')
    191     self.AddStringDescriptor(6, 'Isochronous Echo')
    192 
    193   def ReceivePacket(self, endpoint, data):
    194     """Echo a packet back to the host.
    195 
    196     Args:
    197       endpoint: Incoming endpoint (must be an OUT pipe).
    198       data: Packet data.
    199     """
    200     assert endpoint & usb_constants.Dir.IN == 0
    201 
    202     self.SendPacket(endpoint | usb_constants.Dir.IN, data)
    203 
    204 def RegisterHandlers():
    205   """Registers web request handlers with the application server."""
    206 
    207   import server
    208   from tornado import web
    209 
    210   class WebConfigureHandler(web.RequestHandler):
    211 
    212     def post(self):
    213       server.SwitchGadget(EchoGadget())
    214 
    215   server.app.add_handlers('.*$', [
    216       (r'/echo/configure', WebConfigureHandler),
    217   ])
    218