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 """A composite USB gadget is built from multiple USB features.
10 import usb_descriptors
13 class CompositeGadget(gadget
.Gadget
):
14 """Basic functionality for a composite USB device.
16 Composes multiple USB features into a single device.
19 def __init__(self
, device_desc
, features
):
20 """Create a USB gadget device.
23 device_desc: USB device descriptor.
24 features: USB device features.
26 # dicts mapping interface numbers to features for FS and HS configurations
27 self
._fs
_interface
_feature
_map
= {}
28 self
._hs
_interface
_feature
_map
= {}
30 fs_config_desc
= usb_descriptors
.ConfigurationDescriptor(
33 hs_config_desc
= usb_descriptors
.ConfigurationDescriptor(
36 for feature
in features
:
37 for fs_interface
in feature
.GetFullSpeedInterfaces():
38 fs_config_desc
.AddInterface(fs_interface
)
39 self
._fs
_interface
_feature
_map
[fs_interface
.bInterfaceNumber
] = feature
40 for hs_interface
in feature
.GetHighSpeedInterfaces():
41 hs_config_desc
.AddInterface(hs_interface
)
42 self
._hs
_interface
_feature
_map
[hs_interface
.bInterfaceNumber
] = feature
44 super(CompositeGadget
, self
).__init
__(
45 device_desc
, fs_config_desc
, hs_config_desc
)
46 self
._features
= features
48 def Connected(self
, chip
, speed
):
49 super(CompositeGadget
, self
).Connected(chip
, speed
)
50 for feature
in self
._features
:
51 feature
.Connected(self
)
53 def Disconnected(self
):
54 super(CompositeGadget
, self
).Disconnected()
55 for feature
in self
._features
:
56 feature
.Disconnected()
58 def _GetInterfaceFeatureMap(self
):
59 if self
.GetSpeed() == usb_constants
.Speed
.FULL
:
60 return self
._fs
_interface
_feature
_map
61 elif self
.GetSpeed() == usb_constants
.Speed
.HIGH
:
62 return self
._hs
_interface
_feature
_map
64 raise RuntimeError('Device is not connected.')
66 def ReceivePacket(self
, endpoint
, data
):
67 interface
= self
.GetInterfaceForEndpoint(endpoint
)
68 feature
= self
._GetInterfaceFeatureMap
()[interface
]
69 feature
.ReceivePacket(endpoint
, data
)
71 def _GetFeatureForIndex(self
, recipient
, index
):
73 if recipient
== usb_constants
.Recipient
.INTERFACE
:
75 elif recipient
== usb_constants
.Recipient
.ENDPOINT
:
76 interface
= self
.GetInterfaceForEndpoint(index
)
78 if interface
is not None:
79 return self
._GetInterfaceFeatureMap
().get(interface
)
82 def StandardControlRead(self
, recipient
, request
, value
, index
, length
):
83 response
= super(CompositeGadget
, self
).StandardControlRead(
84 recipient
, request
, value
, index
, length
)
85 if response
is not None:
88 feature
= self
._GetFeatureForIndex
(recipient
, index
)
90 return feature
.StandardControlRead(
91 recipient
, request
, value
, index
, length
)
93 def StandardControlWrite(self
, recipient
, request
, value
, index
, data
):
94 response
= super(CompositeGadget
, self
).StandardControlWrite(
95 recipient
, request
, value
, index
, data
)
96 if response
is not None:
99 feature
= self
._GetFeatureForIndex
(recipient
, index
)
101 return feature
.StandardControlWrite(
102 recipient
, request
, value
, index
, data
)
104 def ClassControlRead(self
, recipient
, request
, value
, index
, length
):
105 response
= super(CompositeGadget
, self
).ClassControlRead(
106 recipient
, request
, value
, index
, length
)
107 if response
is not None:
110 feature
= self
._GetFeatureForIndex
(recipient
, index
)
112 return feature
.ClassControlRead(recipient
, request
, value
, index
, length
)
114 def ClassControlWrite(self
, recipient
, request
, value
, index
, data
):
115 response
= super(CompositeGadget
, self
).ClassControlWrite(
116 recipient
, request
, value
, index
, data
)
117 if response
is not None:
120 feature
= self
._GetFeatureForIndex
(recipient
, index
)
122 return feature
.ClassControlWrite(recipient
, request
, value
, index
, data
)
124 def VendorControlRead(self
, recipient
, request
, value
, index
, length
):
125 response
= super(CompositeGadget
, self
).VendorControlRead(
126 recipient
, request
, value
, index
, length
)
127 if response
is not None:
130 feature
= self
._GetFeatureForIndex
(recipient
, index
)
132 return feature
.VendorControlRead(recipient
, request
, value
, index
, length
)
134 def VendorControlWrite(self
, recipient
, request
, value
, index
, data
):
135 response
= super(CompositeGadget
, self
).VendorControlWrite(
136 recipient
, request
, value
, index
, data
)
137 if response
is not None:
140 feature
= self
._GetFeatureForIndex
(recipient
, index
)
142 return feature
.VendorControlWrite(recipient
, request
, value
, index
, data
)
145 class CompositeFeature(object):
146 def __init__(self
, fs_interface_descs
, hs_interface_descs
):
148 self
._fs
_interface
_descs
= fs_interface_descs
149 self
._hs
_interface
_descs
= hs_interface_descs
151 def GetFullSpeedInterfaces(self
):
152 return self
._fs
_interface
_descs
154 def GetHighSpeedInterfaces(self
):
155 return self
._hs
_interface
_descs
157 def Connected(self
, my_gadget
):
158 self
._gadget
= my_gadget
160 def Disconnected(self
):
163 def IsConnected(self
):
164 return self
._gadget
is not None
166 def SendPacket(self
, endpoint
, data
):
167 if self
._gadget
is None:
168 raise RuntimeError('Device is not connected.')
169 self
._gadget
.SendPacket(endpoint
, data
)
171 def HaltEndpoint(self
, endpoint
):
172 if self
._gadget
is None:
173 raise RuntimeError('Device is not connected.')
174 self
._gadget
.HaltEndpoint(endpoint
)
176 def GetDescriptor(self
, recipient
, typ
, index
, lang
, length
):
177 _
= recipient
, typ
, index
, lang
, length
180 def StandardControlRead(self
, recipient
, request
, value
, index
, length
):
181 """Handle standard USB control transfers.
184 recipient: Request recipient (interface or endpoint)
185 request: bRequest field of the setup packet.
186 value: wValue field of the setup packet.
187 index: wIndex field of the setup packet.
188 length: Maximum amount of data the host expects the device to return.
191 A buffer to return to the USB host with len <= length on success or
192 None to stall the pipe.
194 _
= recipient
, request
, value
, index
, length
197 def ClassControlRead(self
, recipient
, request
, value
, index
, length
):
198 """Handle class-specific control transfers.
201 recipient: Request recipient (interface or endpoint)
202 request: bRequest field of the setup packet.
203 value: wValue field of the setup packet.
204 index: wIndex field of the setup packet.
205 length: Maximum amount of data the host expects the device to return.
208 A buffer to return to the USB host with len <= length on success or
209 None to stall the pipe.
211 _
= recipient
, request
, value
, index
, length
214 def VendorControlRead(self
, recipient
, request
, value
, index
, length
):
215 """Handle vendor-specific control transfers.
218 recipient: Request recipient (interface or endpoint)
219 request: bRequest field of the setup packet.
220 value: wValue field of the setup packet.
221 index: wIndex field of the setup packet.
222 length: Maximum amount of data the host expects the device to return.
225 A buffer to return to the USB host with len <= length on success or
226 None to stall the pipe.
228 _
= recipient
, request
, value
, index
, length
231 def StandardControlWrite(self
, recipient
, request
, value
, index
, data
):
232 """Handle standard USB control transfers.
235 recipient: Request recipient (interface or endpoint)
236 request: bRequest field of the setup packet.
237 value: wValue field of the setup packet.
238 index: wIndex field of the setup packet.
239 data: Data stage of the request.
242 True on success, None to stall the pipe.
244 _
= recipient
, request
, value
, index
, data
247 def ClassControlWrite(self
, recipient
, request
, value
, index
, data
):
248 """Handle class-specific control transfers.
251 recipient: Request recipient (interface or endpoint)
252 request: bRequest field of the setup packet.
253 value: wValue field of the setup packet.
254 index: wIndex field of the setup packet.
255 data: Data stage of the request.
258 True on success, None to stall the pipe.
260 _
= recipient
, request
, value
, index
, data
263 def VendorControlWrite(self
, recipient
, request
, value
, index
, data
):
264 """Handle vendor-specific control transfers.
267 recipient: Request recipient (interface or endpoint)
268 request: bRequest field of the setup packet.
269 value: wValue field of the setup packet.
270 index: wIndex field of the setup packet.
271 data: Data stage of the request.
274 True on success, None to stall the pipe.
276 _
= recipient
, request
, value
, index
, data