2 # Copyright 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
12 import usb_descriptors
15 device_desc
= usb_descriptors
.DeviceDescriptor(
16 idVendor
=0x18D1, # Google Inc.
25 fs_config_desc
= usb_descriptors
.ConfigurationDescriptor(
29 fs_interface_desc
= usb_descriptors
.InterfaceDescriptor(
32 fs_config_desc
.AddInterface(fs_interface_desc
)
34 fs_bulk_in_endpoint_desc
= usb_descriptors
.EndpointDescriptor(
35 bEndpointAddress
=0x01,
36 bmAttributes
=usb_constants
.TransferType
.BULK
,
40 fs_interface_desc
.AddEndpoint(fs_bulk_in_endpoint_desc
)
42 fs_bulk_out_endpoint_desc
= usb_descriptors
.EndpointDescriptor(
43 bEndpointAddress
=0x81,
44 bmAttributes
=usb_constants
.TransferType
.BULK
,
48 fs_interface_desc
.AddEndpoint(fs_bulk_out_endpoint_desc
)
50 fs_alt_interface_desc
= usb_descriptors
.InterfaceDescriptor(
54 fs_config_desc
.AddInterface(fs_alt_interface_desc
)
56 fs_interrupt_in_endpoint_desc
= usb_descriptors
.EndpointDescriptor(
57 bEndpointAddress
=0x01,
58 bmAttributes
=usb_constants
.TransferType
.INTERRUPT
,
62 fs_alt_interface_desc
.AddEndpoint(fs_interrupt_in_endpoint_desc
)
64 fs_interrupt_out_endpoint_desc
= usb_descriptors
.EndpointDescriptor(
65 bEndpointAddress
=0x81,
66 bmAttributes
=usb_constants
.TransferType
.INTERRUPT
,
70 fs_alt_interface_desc
.AddEndpoint(fs_interrupt_out_endpoint_desc
)
72 hs_config_desc
= usb_descriptors
.ConfigurationDescriptor(
76 hs_interface_desc
= usb_descriptors
.InterfaceDescriptor(
79 hs_config_desc
.AddInterface(hs_interface_desc
)
81 hs_bulk_in_endpoint_desc
= usb_descriptors
.EndpointDescriptor(
82 bEndpointAddress
=0x01,
83 bmAttributes
=usb_constants
.TransferType
.BULK
,
87 hs_interface_desc
.AddEndpoint(hs_bulk_in_endpoint_desc
)
89 hs_bulk_out_endpoint_desc
= usb_descriptors
.EndpointDescriptor(
90 bEndpointAddress
=0x81,
91 bmAttributes
=usb_constants
.TransferType
.BULK
,
95 hs_interface_desc
.AddEndpoint(hs_bulk_out_endpoint_desc
)
97 hs_alt_interface_desc
= usb_descriptors
.InterfaceDescriptor(
101 hs_config_desc
.AddInterface(hs_alt_interface_desc
)
103 hs_interrupt_in_endpoint_desc
= usb_descriptors
.EndpointDescriptor(
104 bEndpointAddress
=0x01,
105 bmAttributes
=usb_constants
.TransferType
.INTERRUPT
,
109 hs_alt_interface_desc
.AddEndpoint(hs_interrupt_in_endpoint_desc
)
111 hs_interrupt_out_endpoint_desc
= usb_descriptors
.EndpointDescriptor(
112 bEndpointAddress
=0x81,
113 bmAttributes
=usb_constants
.TransferType
.INTERRUPT
,
117 hs_alt_interface_desc
.AddEndpoint(hs_interrupt_out_endpoint_desc
)
120 class GadgetTest(unittest
.TestCase
):
122 def test_get_descriptors(self
):
123 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
124 self
.assertEquals(g
.GetDeviceDescriptor(), device_desc
)
125 self
.assertEquals(g
.GetFullSpeedConfigurationDescriptor(), fs_config_desc
)
126 self
.assertEquals(g
.GetHighSpeedConfigurationDescriptor(), hs_config_desc
)
127 with self
.assertRaisesRegexp(RuntimeError, 'not connected'):
128 g
.GetConfigurationDescriptor()
130 def test_connect_full_speed(self
):
131 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
132 g
.Connected(mock
.Mock(), usb_constants
.Speed
.FULL
)
133 self
.assertTrue(g
.IsConnected())
134 self
.assertEquals(g
.GetSpeed(), usb_constants
.Speed
.FULL
)
135 self
.assertEquals(g
.GetConfigurationDescriptor(), fs_config_desc
)
137 self
.assertFalse(g
.IsConnected())
139 def test_connect_high_speed(self
):
140 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
141 g
.Connected(mock
.Mock(), usb_constants
.Speed
.HIGH
)
142 self
.assertTrue(g
.IsConnected())
143 self
.assertEquals(g
.GetSpeed(), usb_constants
.Speed
.HIGH
)
144 self
.assertEquals(g
.GetConfigurationDescriptor(), hs_config_desc
)
146 self
.assertFalse(g
.IsConnected())
148 def test_string_index_out_of_range(self
):
149 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
150 with self
.assertRaisesRegexp(ValueError, 'index out of range'):
151 g
.AddStringDescriptor(0, 'Hello world!')
153 def test_language_id_out_of_range(self
):
154 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
155 with self
.assertRaisesRegexp(ValueError, 'language code out of range'):
156 g
.AddStringDescriptor(1, 'Hello world!', lang
=-1)
158 def test_get_languages(self
):
159 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
160 g
.AddStringDescriptor(1, 'Hello world!')
161 desc
= g
.ControlRead(0x80, 6, 0x0300, 0, 255)
162 self
.assertEquals(desc
, '\x04\x03\x09\x04')
164 def test_get_string_descriptor(self
):
165 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
166 g
.AddStringDescriptor(1, 'Hello world!')
167 desc
= g
.ControlRead(0x80, 6, 0x0301, 0x0409, 255)
168 self
.assertEquals(desc
, '\x1A\x03H\0e\0l\0l\0o\0 \0w\0o\0r\0l\0d\0!\0')
170 def test_get_missing_string_descriptor(self
):
171 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
172 g
.AddStringDescriptor(1, 'Hello world!')
173 desc
= g
.ControlRead(0x80, 6, 0x0302, 0x0409, 255)
174 self
.assertEquals(desc
, None)
176 def test_get_missing_string_language(self
):
177 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
178 g
.AddStringDescriptor(1, 'Hello world!')
179 desc
= g
.ControlRead(0x80, 6, 0x0301, 0x040C, 255)
180 self
.assertEquals(desc
, None)
182 def test_class_and_vendor_transfers(self
):
183 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
184 self
.assertIsNone(g
.ControlRead(0xA0, 0, 0, 0, 0))
185 self
.assertIsNone(g
.ControlRead(0xC0, 0, 0, 0, 0))
186 self
.assertIsNone(g
.ControlWrite(0x20, 0, 0, 0, ''))
187 self
.assertIsNone(g
.ControlWrite(0x40, 0, 0, 0, ''))
189 def test_set_configuration(self
):
190 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
192 g
.Connected(chip
, usb_constants
.Speed
.HIGH
)
193 g
.ControlWrite(0, 9, 1, 0, 0)
194 chip
.StartEndpoint
.assert_has_calls([
195 mock
.call(hs_bulk_in_endpoint_desc
),
196 mock
.call(hs_bulk_out_endpoint_desc
)
199 def test_set_configuration_zero(self
):
200 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
202 g
.Connected(chip
, usb_constants
.Speed
.HIGH
)
203 g
.ControlWrite(0, 9, 1, 0, 0)
204 chip
.StartEndpoint
.reset_mock()
205 g
.ControlWrite(0, 9, 0, 0, 0)
206 chip
.StopEndpoint
.assert_has_calls([
211 def test_set_bad_configuration(self
):
212 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
213 g
.Connected(mock
.Mock(), usb_constants
.Speed
.HIGH
)
214 self
.assertIsNone(g
.ControlWrite(0, 9, 2, 0, 0))
216 def test_set_interface(self
):
217 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
219 g
.Connected(chip
, usb_constants
.Speed
.HIGH
)
220 self
.assertTrue(g
.ControlWrite(0, 9, 1, 0, 0))
222 self
.assertTrue(g
.ControlWrite(1, 11, 1, 0, 0))
223 chip
.StopEndpoint
.assert_has_calls([
227 chip
.StartEndpoint
.assert_has_calls([
228 mock
.call(hs_interrupt_in_endpoint_desc
),
229 mock
.call(hs_interrupt_out_endpoint_desc
)
232 self
.assertTrue(g
.ControlWrite(1, 11, 0, 0, 0))
233 chip
.StopEndpoint
.assert_has_calls([
237 chip
.StartEndpoint
.assert_has_calls([
238 mock
.call(hs_bulk_in_endpoint_desc
),
239 mock
.call(hs_bulk_out_endpoint_desc
)
242 def test_set_bad_interface(self
):
243 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
244 g
.Connected(mock
.Mock(), usb_constants
.Speed
.HIGH
)
245 self
.assertTrue(g
.ControlWrite(0, 9, 1, 0, 0))
246 self
.assertIsNone(g
.ControlWrite(1, 11, 0, 1, 0))
248 def test_send_packet(self
):
249 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
251 g
.Connected(chip
, usb_constants
.Speed
.HIGH
)
252 g
.SendPacket(0x81, 'Hello world!')
253 chip
.SendPacket
.assert_called_once_with(0x81, 'Hello world!')
255 def test_send_packet_disconnected(self
):
256 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
257 with self
.assertRaisesRegexp(RuntimeError, 'not connected'):
258 g
.SendPacket(0x81, 'Hello world!')
259 g
.Connected(mock
.Mock(), usb_constants
.Speed
.HIGH
)
260 g
.SendPacket(0x81, 'Hello world!')
262 with self
.assertRaisesRegexp(RuntimeError, 'not connected'):
263 g
.SendPacket(0x81, 'Hello world!')
265 def test_send_invalid_endpoint(self
):
266 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
268 g
.Connected(chip
, usb_constants
.Speed
.HIGH
)
269 with self
.assertRaisesRegexp(ValueError, 'non-input endpoint'):
270 g
.SendPacket(0x01, 'Hello world!')
272 def test_receive_packet(self
):
273 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
274 self
.assertIsNone(g
.ReceivePacket(0x01, 'Hello world!'))
276 def test_halt_endpoint(self
):
277 g
= gadget
.Gadget(device_desc
, fs_config_desc
, hs_config_desc
)
279 g
.Connected(chip
, usb_constants
.Speed
.HIGH
)
281 chip
.HaltEndpoint
.assert_called_once_with(0x01)
284 if __name__
== '__main__':