普通文本  |  218行  |  6.86 KB

# 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),
  ])