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 """A HID-class echo device.
      6 
      7 This module provides a HID feature and HID device that can be used as an
      8 echo test for HID drivers. The device exposes vendor-specific input, output
      9 and feature usages that transmit 8 bytes of data. Data written sent as an
     10 output report is echoed as an input report. The value of the feature report
     11 can be written and read with control transfers.
     12 """
     13 
     14 import struct
     15 
     16 import hid_constants
     17 import hid_descriptors
     18 import hid_gadget
     19 import usb_constants
     20 
     21 
     22 class EchoFeature(hid_gadget.HidFeature):
     23 
     24   REPORT_DESC = hid_descriptors.ReportDescriptor(
     25       hid_descriptors.UsagePage(0xFF00),  # Vendor Defined
     26       hid_descriptors.Usage(0),
     27       hid_descriptors.Collection(
     28           hid_constants.CollectionType.APPLICATION,
     29           hid_descriptors.LogicalMinimum(0, force_length=1),
     30           hid_descriptors.LogicalMaximum(255, force_length=2),
     31           hid_descriptors.ReportSize(8),
     32           hid_descriptors.ReportCount(8),
     33           hid_descriptors.Usage(0),
     34           hid_descriptors.Input(hid_descriptors.Data,
     35                                 hid_descriptors.Variable,
     36                                 hid_descriptors.Absolute),
     37           hid_descriptors.Usage(0),
     38           hid_descriptors.Output(hid_descriptors.Data,
     39                                  hid_descriptors.Variable,
     40                                  hid_descriptors.Absolute),
     41           hid_descriptors.Usage(0),
     42           hid_descriptors.Feature(hid_descriptors.Data,
     43                                   hid_descriptors.Variable,
     44                                   hid_descriptors.Absolute)
     45       )
     46   )
     47 
     48   def __init__(self):
     49     super(EchoFeature, self).__init__()
     50     self._input_output_report = 0
     51     self._feature_report = 0
     52 
     53   def SetInputReport(self, data):
     54     self._input_output_report, = struct.unpack('<Q', data)
     55     self.SendReport(struct.pack('<Q', self._input_output_report))
     56     return True
     57 
     58   def SetOutputReport(self, data):
     59     self._input_output_report, = struct.unpack('<Q', data)
     60     self.SendReport(struct.pack('<Q', self._input_output_report))
     61     return True
     62 
     63   def SetFeatureReport(self, data):
     64     self._feature_report, = struct.unpack('<Q', data)
     65     return True
     66 
     67   def GetInputReport(self):
     68     return struct.pack('<Q', self._input_output_report)
     69 
     70   def GetOutputReport(self):
     71     return struct.pack('<Q', self._input_output_report)
     72 
     73   def GetFeatureReport(self):
     74     return struct.pack('<Q', self._feature_report)
     75 
     76 
     77 class EchoGadget(hid_gadget.HidGadget):
     78 
     79   def __init__(self):
     80     self._feature = EchoFeature()
     81     super(EchoGadget, self).__init__(
     82         report_desc=EchoFeature.REPORT_DESC,
     83         features={0: self._feature},
     84         packet_size=8,
     85         interval_ms=1,
     86         out_endpoint=True,
     87         vendor_id=usb_constants.VendorID.GOOGLE,
     88         product_id=usb_constants.ProductID.GOOGLE_HID_ECHO_GADGET,
     89         device_version=0x0100)
     90     self.AddStringDescriptor(1, 'Google Inc.')
     91     self.AddStringDescriptor(2, 'HID Echo Gadget')
     92 
     93 
     94 def RegisterHandlers():
     95   from tornado import web
     96 
     97   class WebConfigureHandler(web.RequestHandler):
     98 
     99     def post(self):
    100       server.SwitchGadget(EchoGadget())
    101 
    102   import server
    103   server.app.add_handlers('.*$', [
    104       (r'/hid_echo/configure', WebConfigureHandler),
    105   ])
    106