0
# Legacy API
1
2
Backward-compatible API matching PyUSB 0.x interface patterns with extensive USB constants and legacy device handling. This module provides compatibility for applications written against PyUSB 0.x versions.
3
4
## Capabilities
5
6
### Device Hierarchy
7
8
Legacy device representation using bus/device hierarchy similar to PyUSB 0.x.
9
10
```python { .api }
11
class Bus:
12
"""Legacy bus representation."""
13
dirname: str # Bus directory name
14
location: int # Bus location
15
16
def devices(self):
17
"""Return list of devices on this bus."""
18
19
class Device:
20
"""Legacy device representation."""
21
deviceClass: int # Device class
22
deviceSubClass: int # Device sub-class
23
deviceProtocol: int # Device protocol
24
maxPacketSize: int # Maximum packet size
25
idVendor: int # Vendor ID
26
idProduct: int # Product ID
27
bcdDevice: int # Device version
28
iManufacturer: int # Manufacturer string index
29
iProduct: int # Product string index
30
iSerialNumber: int # Serial number string index
31
32
def configurations(self):
33
"""Return list of configurations."""
34
35
def open(self):
36
"""Open device and return DeviceHandle."""
37
38
class Configuration:
39
"""Legacy configuration representation."""
40
value: int # Configuration value
41
iConfiguration: int # Configuration string index
42
attributes: int # Configuration attributes
43
maxPower: int # Maximum power consumption
44
45
def interfaces(self):
46
"""Return list of interfaces."""
47
48
class Interface:
49
"""Legacy interface representation."""
50
interfaceNumber: int # Interface number
51
alternateSetting: int # Alternate setting
52
interfaceClass: int # Interface class
53
interfaceSubClass: int # Interface sub-class
54
interfaceProtocol: int # Interface protocol
55
iInterface: int # Interface string index
56
57
def endpoints(self):
58
"""Return list of endpoints."""
59
60
class Endpoint:
61
"""Legacy endpoint representation."""
62
address: int # Endpoint address
63
type: int # Endpoint type
64
maxPacketSize: int # Maximum packet size
65
interval: int # Polling interval
66
67
class DeviceHandle:
68
"""Legacy device handle for communication."""
69
70
def bulkWrite(self, endpoint, buffer, timeout=100):
71
"""Write data via bulk transfer."""
72
73
def bulkRead(self, endpoint, size, timeout=100):
74
"""Read data via bulk transfer."""
75
76
def interruptWrite(self, endpoint, buffer, timeout=100):
77
"""Write data via interrupt transfer."""
78
79
def interruptRead(self, endpoint, size, timeout=100):
80
"""Read data via interrupt transfer."""
81
82
def controlMsg(self, requestType, request, buffer, value=0, index=0, timeout=100):
83
"""Send control message."""
84
85
def setConfiguration(self, configuration):
86
"""Set device configuration."""
87
88
def claimInterface(self, interface):
89
"""Claim interface."""
90
91
def releaseInterface(self, interface):
92
"""Release interface."""
93
94
def setAltInterface(self, alt):
95
"""Set alternate interface."""
96
```
97
98
### Device Enumeration
99
100
Legacy device enumeration following PyUSB 0.x patterns.
101
102
```python { .api }
103
def busses():
104
"""
105
Return list of USB buses.
106
107
Returns:
108
list: Bus objects representing system USB buses
109
"""
110
```
111
112
### USB Constants
113
114
Comprehensive set of USB constants for device classes, descriptor types, endpoints, and requests.
115
116
```python { .api }
117
# Device Classes
118
CLASS_AUDIO = 1
119
CLASS_COMM = 2
120
CLASS_HID = 3
121
CLASS_PRINTER = 7
122
CLASS_MASS_STORAGE = 8
123
CLASS_HUB = 9
124
CLASS_DATA = 10
125
CLASS_WIRELESS_CONTROLLER = 224
126
CLASS_VENDOR_SPEC = 255
127
CLASS_PER_INTERFACE = 0
128
129
# Descriptor Types
130
DT_DEVICE = 1
131
DT_CONFIG = 2
132
DT_STRING = 3
133
DT_INTERFACE = 4
134
DT_ENDPOINT = 5
135
DT_HID = 33
136
DT_HUB = 41
137
DT_PHYSICAL = 35
138
DT_REPORT = 34
139
140
# Descriptor Sizes
141
DT_DEVICE_SIZE = 18
142
DT_CONFIG_SIZE = 9
143
DT_INTERFACE_SIZE = 9
144
DT_ENDPOINT_SIZE = 7
145
DT_ENDPOINT_AUDIO_SIZE = 9
146
DT_HUB_NONVAR_SIZE = 7
147
148
# Endpoint Directions
149
ENDPOINT_IN = 128
150
ENDPOINT_OUT = 0
151
ENDPOINT_ADDRESS_MASK = 15
152
ENDPOINT_DIR_MASK = 128
153
154
# Endpoint Types
155
ENDPOINT_TYPE_CONTROL = 0
156
ENDPOINT_TYPE_ISOCHRONOUS = 1
157
ENDPOINT_TYPE_BULK = 2
158
ENDPOINT_TYPE_INTERRUPT = 3
159
ENDPOINT_TYPE_MASK = 3
160
161
# Request Types
162
TYPE_STANDARD = 0
163
TYPE_CLASS = 32
164
TYPE_VENDOR = 64
165
TYPE_RESERVED = 96
166
167
# Recipients
168
RECIP_DEVICE = 0
169
RECIP_INTERFACE = 1
170
RECIP_ENDPOINT = 2
171
RECIP_OTHER = 3
172
173
# Standard Requests
174
REQ_GET_STATUS = 0
175
REQ_CLEAR_FEATURE = 1
176
REQ_SET_FEATURE = 3
177
REQ_SET_ADDRESS = 5
178
REQ_GET_DESCRIPTOR = 6
179
REQ_SET_DESCRIPTOR = 7
180
REQ_GET_CONFIGURATION = 8
181
REQ_SET_CONFIGURATION = 9
182
REQ_GET_INTERFACE = 10
183
REQ_SET_INTERFACE = 11
184
REQ_SYNCH_FRAME = 12
185
186
# Configuration Limits
187
MAXCONFIG = 8
188
MAXINTERFACES = 32
189
MAXALTSETTING = 128
190
MAXENDPOINTS = 32
191
192
# Error Codes
193
ERROR_BEGIN = 500000
194
195
# Protocol Codes
196
PROTOCOL_BLUETOOTH_PRIMARY_CONTROLLER = 1
197
SUBCLASS_RF_CONTROLLER = 1
198
```
199
200
## Usage Examples
201
202
### Legacy Device Enumeration
203
204
```python
205
import usb
206
207
# Get all USB buses
208
buses = usb.busses()
209
print(f"Found {len(buses)} USB buses")
210
211
# Enumerate all devices
212
for bus in buses:
213
devices = bus.devices()
214
print(f"Bus {bus.dirname}: {len(devices)} devices")
215
216
for device in devices:
217
print(f" Device {device.idVendor:04x}:{device.idProduct:04x}")
218
print(f" Class: {device.deviceClass}")
219
print(f" Max packet size: {device.maxPacketSize}")
220
```
221
222
### Legacy Device Communication
223
224
```python
225
import usb
226
227
# Find device (legacy style)
228
def find_device(vendor_id, product_id):
229
"""Find device using legacy enumeration."""
230
for bus in usb.busses():
231
for device in bus.devices():
232
if device.idVendor == vendor_id and device.idProduct == product_id:
233
return device
234
return None
235
236
device = find_device(0x1234, 0x5678)
237
238
if device:
239
print("Device found!")
240
241
# Open device handle
242
handle = device.open()
243
244
try:
245
# Set configuration
246
handle.setConfiguration(1)
247
248
# Claim interface
249
handle.claimInterface(0)
250
251
# Bulk write
252
data = b"Hello USB device!"
253
bytes_written = handle.bulkWrite(0x01, data, timeout=1000)
254
print(f"Wrote {bytes_written} bytes")
255
256
# Bulk read
257
read_data = handle.bulkRead(0x81, 64, timeout=1000)
258
print(f"Read {len(read_data)} bytes: {read_data}")
259
260
finally:
261
# Clean up
262
handle.releaseInterface(0)
263
264
else:
265
print("Device not found")
266
```
267
268
### Legacy Control Messages
269
270
```python
271
import usb
272
273
device = find_device(0x1234, 0x5678) # From previous example
274
handle = device.open()
275
276
try:
277
# Control message for getting device status
278
request_type = usb.TYPE_STANDARD | usb.RECIP_DEVICE | usb.ENDPOINT_IN
279
result = handle.controlMsg(
280
requestType=request_type,
281
request=usb.REQ_GET_STATUS,
282
buffer=2, # 2 bytes for status
283
value=0,
284
index=0,
285
timeout=1000
286
)
287
288
print(f"Device status: {result}")
289
290
# Vendor-specific control message
291
vendor_request_type = usb.TYPE_VENDOR | usb.RECIP_DEVICE | usb.ENDPOINT_IN
292
vendor_result = handle.controlMsg(
293
requestType=vendor_request_type,
294
request=0x01, # Vendor-specific request
295
buffer=64,
296
value=0x1234,
297
index=0x5678,
298
timeout=1000
299
)
300
301
print(f"Vendor response: {vendor_result}")
302
303
finally:
304
handle.releaseInterface(0)
305
```
306
307
### Legacy Configuration Inspection
308
309
```python
310
import usb
311
312
device = find_device(0x1234, 0x5678) # From previous example
313
314
print(f"Device {device.idVendor:04x}:{device.idProduct:04x}")
315
print(f"Device class: {device.deviceClass}")
316
print(f"Device sub-class: {device.deviceSubClass}")
317
print(f"Device protocol: {device.deviceProtocol}")
318
319
# Enumerate configurations
320
configurations = device.configurations()
321
print(f"Configurations: {len(configurations)}")
322
323
for config in configurations:
324
print(f" Configuration {config.value}:")
325
print(f" Max power: {config.maxPower * 2}mA") # maxPower is in 2mA units
326
print(f" Attributes: 0x{config.attributes:02x}")
327
328
# Enumerate interfaces
329
interfaces = config.interfaces()
330
print(f" Interfaces: {len(interfaces)}")
331
332
for interface in interfaces:
333
print(f" Interface {interface.interfaceNumber}:")
334
print(f" Class: {interface.interfaceClass}")
335
print(f" Sub-class: {interface.interfaceSubClass}")
336
print(f" Protocol: {interface.interfaceProtocol}")
337
338
# Enumerate endpoints
339
endpoints = interface.endpoints()
340
print(f" Endpoints: {len(endpoints)}")
341
342
for endpoint in endpoints:
343
direction = "IN" if endpoint.address & usb.ENDPOINT_IN else "OUT"
344
ep_type = endpoint.type & usb.ENDPOINT_TYPE_MASK
345
346
type_names = {
347
usb.ENDPOINT_TYPE_CONTROL: "Control",
348
usb.ENDPOINT_TYPE_ISOCHRONOUS: "Isochronous",
349
usb.ENDPOINT_TYPE_BULK: "Bulk",
350
usb.ENDPOINT_TYPE_INTERRUPT: "Interrupt"
351
}
352
353
print(f" Endpoint 0x{endpoint.address:02x} ({direction} {type_names[ep_type]})")
354
print(f" Max packet: {endpoint.maxPacketSize}")
355
print(f" Interval: {endpoint.interval}")
356
```
357
358
### Legacy Interrupt Transfers
359
360
```python
361
import usb
362
import time
363
364
device = find_device(0x1234, 0x5678) # From previous example
365
handle = device.open()
366
367
try:
368
handle.setConfiguration(1)
369
handle.claimInterface(0)
370
371
# Interrupt read loop
372
interrupt_endpoint = 0x83 # IN endpoint 3
373
374
print("Starting interrupt read loop...")
375
for i in range(10):
376
try:
377
data = handle.interruptRead(interrupt_endpoint, 8, timeout=1000)
378
print(f"Interrupt data [{i}]: {data}")
379
380
except usb.USBError as e:
381
print(f"Interrupt read error: {e}")
382
break
383
384
time.sleep(0.1)
385
386
# Interrupt write (if supported)
387
interrupt_out_endpoint = 0x03 # OUT endpoint 3
388
try:
389
bytes_written = handle.interruptWrite(
390
interrupt_out_endpoint,
391
b'\x01\x02\x03\x04',
392
timeout=1000
393
)
394
print(f"Interrupt write: {bytes_written} bytes")
395
396
except usb.USBError as e:
397
print(f"Interrupt write not supported: {e}")
398
399
finally:
400
handle.releaseInterface(0)
401
```
402
403
### Legacy Error Handling
404
405
```python
406
import usb
407
408
try:
409
device = find_device(0x1234, 0x5678)
410
411
if device is None:
412
raise usb.USBError("Device not found")
413
414
handle = device.open()
415
416
try:
417
handle.setConfiguration(1)
418
handle.claimInterface(0)
419
420
# Operations that might fail
421
data = handle.bulkRead(0x81, 64, timeout=100)
422
423
except usb.USBError as e:
424
print(f"USB operation failed: {e}")
425
# Handle specific error conditions based on error message or code
426
427
finally:
428
# Always clean up
429
try:
430
handle.releaseInterface(0)
431
except:
432
pass # Ignore cleanup errors
433
434
except usb.USBError as e:
435
print(f"USB error: {e}")
436
except Exception as e:
437
print(f"Unexpected error: {e}")
438
```