Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / tools / usb_gadget / echo_gadget.py
blob98d625a204eb3e7e97a601c18fd729a25ac1391e
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.
5 """USB echo gadget module.
7 This gadget has pairs of IN/OUT endpoints that echo packets back to the host.
8 """
10 import uuid
12 import composite_gadget
13 import usb_constants
14 import usb_descriptors
17 class EchoCompositeFeature(composite_gadget.CompositeFeature):
18 """Composite device feature that echos data back to the host.
19 """
21 def __init__(self, endpoints):
22 """Create an echo gadget.
23 """
24 fs_interfaces = []
25 hs_interfaces = []
27 if len(endpoints) >= 1:
28 iface_num, iface_string, in_endpoint, out_endpoint = endpoints[0]
29 fs_intr_interface_desc = usb_descriptors.InterfaceDescriptor(
30 bInterfaceNumber=iface_num,
31 bInterfaceClass=usb_constants.DeviceClass.VENDOR,
32 bInterfaceSubClass=0,
33 bInterfaceProtocol=0,
34 iInterface=iface_string,
36 fs_intr_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
37 bEndpointAddress=out_endpoint,
38 bmAttributes=usb_constants.TransferType.INTERRUPT,
39 wMaxPacketSize=64,
40 bInterval=1 # 1ms
42 fs_intr_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
43 bEndpointAddress=in_endpoint,
44 bmAttributes=usb_constants.TransferType.INTERRUPT,
45 wMaxPacketSize=64,
46 bInterval=1 # 1ms
48 fs_interfaces.append(fs_intr_interface_desc)
50 hs_intr_interface_desc = usb_descriptors.InterfaceDescriptor(
51 bInterfaceNumber=iface_num,
52 bInterfaceClass=usb_constants.DeviceClass.VENDOR,
53 bInterfaceSubClass=0,
54 bInterfaceProtocol=0,
55 iInterface=iface_string
57 hs_intr_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
58 bEndpointAddress=out_endpoint,
59 bmAttributes=usb_constants.TransferType.INTERRUPT,
60 wMaxPacketSize=64,
61 bInterval=4 # 1ms
63 hs_intr_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
64 bEndpointAddress=in_endpoint,
65 bmAttributes=usb_constants.TransferType.INTERRUPT,
66 wMaxPacketSize=64,
67 bInterval=4 # 1ms
69 hs_interfaces.append(hs_intr_interface_desc)
71 if len(endpoints) >= 2:
72 iface_num, iface_string, in_endpoint, out_endpoint = endpoints[1]
73 fs_bulk_interface_desc = usb_descriptors.InterfaceDescriptor(
74 bInterfaceNumber=iface_num,
75 bInterfaceClass=usb_constants.DeviceClass.VENDOR,
76 bInterfaceSubClass=0,
77 bInterfaceProtocol=0,
78 iInterface=iface_string
80 fs_bulk_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
81 bEndpointAddress=out_endpoint,
82 bmAttributes=usb_constants.TransferType.BULK,
83 wMaxPacketSize=64,
84 bInterval=0
86 fs_bulk_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
87 bEndpointAddress=in_endpoint,
88 bmAttributes=usb_constants.TransferType.BULK,
89 wMaxPacketSize=64,
90 bInterval=0
92 fs_interfaces.append(fs_bulk_interface_desc)
94 hs_bulk_interface_desc = usb_descriptors.InterfaceDescriptor(
95 bInterfaceNumber=iface_num,
96 bInterfaceClass=usb_constants.DeviceClass.VENDOR,
97 bInterfaceSubClass=0,
98 bInterfaceProtocol=0,
99 iInterface=iface_string
101 hs_bulk_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
102 bEndpointAddress=out_endpoint,
103 bmAttributes=usb_constants.TransferType.BULK,
104 wMaxPacketSize=512,
105 bInterval=0
107 hs_bulk_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
108 bEndpointAddress=in_endpoint,
109 bmAttributes=usb_constants.TransferType.BULK,
110 wMaxPacketSize=512,
111 bInterval=0
113 hs_interfaces.append(hs_bulk_interface_desc)
115 if len(endpoints) >= 3:
116 iface_num, iface_string, in_endpoint, out_endpoint = endpoints[2]
117 fs_interfaces.append(usb_descriptors.InterfaceDescriptor(
118 bInterfaceNumber=iface_num,
119 bInterfaceClass=usb_constants.DeviceClass.VENDOR,
120 bInterfaceSubClass=0,
121 bInterfaceProtocol=0,
122 iInterface=iface_string
124 fs_isoc_interface_desc = usb_descriptors.InterfaceDescriptor(
125 bInterfaceNumber=iface_num,
126 bAlternateSetting=1,
127 bInterfaceClass=usb_constants.DeviceClass.VENDOR,
128 bInterfaceSubClass=0,
129 bInterfaceProtocol=0,
130 iInterface=iface_string
132 fs_isoc_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
133 bEndpointAddress=out_endpoint,
134 bmAttributes=usb_constants.TransferType.ISOCHRONOUS,
135 wMaxPacketSize=1023,
136 bInterval=1 # 1ms
138 fs_isoc_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
139 bEndpointAddress=in_endpoint,
140 bmAttributes=usb_constants.TransferType.ISOCHRONOUS,
141 wMaxPacketSize=1023,
142 bInterval=1 # 1ms
144 fs_interfaces.append(fs_isoc_interface_desc)
146 hs_interfaces.append(usb_descriptors.InterfaceDescriptor(
147 bInterfaceNumber=iface_num,
148 bInterfaceClass=usb_constants.DeviceClass.VENDOR,
149 bInterfaceSubClass=0,
150 bInterfaceProtocol=0,
151 iInterface=iface_string
153 hs_isoc_interface_desc = usb_descriptors.InterfaceDescriptor(
154 bInterfaceNumber=iface_num,
155 bAlternateSetting=1,
156 bInterfaceClass=usb_constants.DeviceClass.VENDOR,
157 bInterfaceSubClass=0,
158 bInterfaceProtocol=0,
159 iInterface=iface_string
161 hs_isoc_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
162 bEndpointAddress=out_endpoint,
163 bmAttributes=usb_constants.TransferType.ISOCHRONOUS,
164 wMaxPacketSize=512,
165 bInterval=4 # 1ms
167 hs_isoc_interface_desc.AddEndpoint(usb_descriptors.EndpointDescriptor(
168 bEndpointAddress=in_endpoint,
169 bmAttributes=usb_constants.TransferType.ISOCHRONOUS,
170 wMaxPacketSize=512,
171 bInterval=4 # 1ms
173 hs_interfaces.append(hs_isoc_interface_desc)
175 super(EchoCompositeFeature, self).__init__(fs_interfaces, hs_interfaces)
177 def ReceivePacket(self, endpoint, data):
178 """Echo a packet back to the host.
180 Args:
181 endpoint: Incoming endpoint (must be an OUT pipe).
182 data: Packet data.
184 assert endpoint & usb_constants.Dir.IN == 0
186 self.SendPacket(endpoint | usb_constants.Dir.IN, data)
189 class EchoGadget(composite_gadget.CompositeGadget):
190 """Echo gadget.
193 def __init__(self):
194 """Create an echo gadget.
196 device_desc = usb_descriptors.DeviceDescriptor(
197 idVendor=usb_constants.VendorID.GOOGLE,
198 idProduct=usb_constants.ProductID.GOOGLE_ECHO_GADGET,
199 bcdUSB=0x0200,
200 iManufacturer=1,
201 iProduct=2,
202 iSerialNumber=3,
203 bcdDevice=0x0100)
205 feature = EchoCompositeFeature(
206 endpoints=[(0, 4, 0x81, 0x01), (1, 5, 0x82, 0x02), (2, 6, 0x83, 0x03)])
208 super(EchoGadget, self).__init__(device_desc, [feature])
209 self.AddStringDescriptor(1, 'Google Inc.')
210 self.AddStringDescriptor(2, 'Echo Gadget')
211 self.AddStringDescriptor(3, '{:06X}'.format(uuid.getnode()))
212 self.AddStringDescriptor(4, 'Interrupt Echo')
213 self.AddStringDescriptor(5, 'Bulk Echo')
214 self.AddStringDescriptor(6, 'Isochronous Echo')
216 # Enable Microsoft OS Descriptors for Windows 8 and above.
217 self.EnableMicrosoftOSDescriptorsV1(vendor_code=0x01)
218 # These are used to force Windows to load WINUSB.SYS for the echo functions.
219 self.SetMicrosoftCompatId(0, 'WINUSB')
220 self.SetMicrosoftCompatId(1, 'WINUSB')
221 self.SetMicrosoftCompatId(2, 'WINUSB')
223 self.AddDeviceCapabilityDescriptor(usb_descriptors.ContainerIdDescriptor(
224 ContainerID=uuid.uuid4().bytes_le))
226 def RegisterHandlers():
227 """Registers web request handlers with the application server."""
229 import server
230 from tornado import web
232 class WebConfigureHandler(web.RequestHandler):
234 def post(self):
235 server.SwitchGadget(EchoGadget())
237 server.app.add_handlers('.*$', [
238 (r'/echo/configure', WebConfigureHandler),