or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

backends.mdcontrol-requests.mddevice-communication.mddevice-discovery.mdindex.mdlegacy-api.mdutilities.md

legacy-api.mddocs/

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

```