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

utilities.mddocs/

0

# Utilities

1

2

Helper functions for endpoint handling, interface management, descriptor parsing, and resource cleanup. The util module provides essential utilities for USB device operations and data interpretation.

3

4

## Capabilities

5

6

### Endpoint Operations

7

8

Parse and interpret endpoint addresses and attributes for proper communication setup.

9

10

```python { .api }

11

def endpoint_address(address):

12

"""

13

Return endpoint absolute address.

14

15

Parameters:

16

- address: int, endpoint address from descriptor

17

18

Returns:

19

int: absolute endpoint address (0-15)

20

"""

21

22

def endpoint_direction(address):

23

"""

24

Return endpoint transfer direction.

25

26

Parameters:

27

- address: int, endpoint address from descriptor

28

29

Returns:

30

int: ENDPOINT_OUT (0) or ENDPOINT_IN (128)

31

"""

32

33

def endpoint_type(bmAttributes):

34

"""

35

Return endpoint type from attributes.

36

37

Parameters:

38

- bmAttributes: int, endpoint attributes from descriptor

39

40

Returns:

41

int: endpoint type (ENDPOINT_TYPE_CTRL, ENDPOINT_TYPE_ISO,

42

ENDPOINT_TYPE_BULK, ENDPOINT_TYPE_INTR)

43

"""

44

```

45

46

### Control Transfer Utilities

47

48

Build control transfer parameters and interpret transfer directions.

49

50

```python { .api }

51

def ctrl_direction(bmRequestType):

52

"""

53

Return direction of control transfer.

54

55

Parameters:

56

- bmRequestType: int, request type field

57

58

Returns:

59

int: CTRL_OUT (0) or CTRL_IN (128)

60

"""

61

62

def build_request_type(direction, type, recipient):

63

"""

64

Build bmRequestType field for control transfer.

65

66

Parameters:

67

- direction: int, transfer direction (CTRL_OUT or CTRL_IN)

68

- type: int, request type (CTRL_TYPE_STANDARD, CTRL_TYPE_CLASS, CTRL_TYPE_VENDOR)

69

- recipient: int, recipient (CTRL_RECIPIENT_DEVICE, CTRL_RECIPIENT_INTERFACE, etc.)

70

71

Returns:

72

int: bmRequestType value

73

"""

74

```

75

76

### Buffer Management

77

78

Create and manage buffers for USB data operations.

79

80

```python { .api }

81

def create_buffer(length):

82

"""

83

Create buffer for USB operations.

84

85

Parameters:

86

- length: int, buffer size in bytes

87

88

Returns:

89

array.array: buffer suitable for USB operations

90

"""

91

```

92

93

### Descriptor Search

94

95

Find specific descriptors within device configuration hierarchies.

96

97

```python { .api }

98

def find_descriptor(desc, find_all=False, custom_match=None, **args):

99

"""

100

Find inner descriptor within a configuration/interface/endpoint hierarchy.

101

102

Parameters:

103

- desc: descriptor object to search within

104

- find_all: bool, return all matches instead of first match

105

- custom_match: callable taking descriptor as argument, return True for matches

106

- **args: descriptor fields to match

107

108

Returns:

109

Descriptor object or list of descriptors, None if not found

110

"""

111

```

112

113

### Interface Management

114

115

Claim and release interfaces for exclusive device access.

116

117

```python { .api }

118

def claim_interface(device, interface):

119

"""

120

Explicitly claim an interface.

121

122

Parameters:

123

- device: Device object

124

- interface: int or Interface object, interface to claim

125

126

Raises:

127

- USBError: Interface claim failed

128

"""

129

130

def release_interface(device, interface):

131

"""

132

Explicitly release an interface.

133

134

Parameters:

135

- device: Device object

136

- interface: int or Interface object, interface to release

137

138

Raises:

139

- USBError: Interface release failed

140

"""

141

```

142

143

### Resource Management

144

145

Clean up device resources and handle proper disposal.

146

147

```python { .api }

148

def dispose_resources(device):

149

"""

150

Release internal resources allocated by the device object.

151

152

Parameters:

153

- device: Device object to clean up

154

"""

155

```

156

157

### String Descriptors

158

159

Retrieve and decode string descriptors with language support.

160

161

```python { .api }

162

def get_langids(dev):

163

"""

164

Retrieve list of supported string languages from device.

165

166

Parameters:

167

- dev: Device object

168

169

Returns:

170

list: language ID codes supported by device

171

172

Raises:

173

- USBError: Language ID retrieval failed

174

"""

175

176

def get_string(dev, index, langid=None):

177

"""

178

Retrieve string descriptor from device.

179

180

Parameters:

181

- dev: Device object

182

- index: int, string descriptor index

183

- langid: int, language ID (default: first supported language)

184

185

Returns:

186

str: decoded string descriptor

187

188

Raises:

189

- USBError: String retrieval failed

190

"""

191

```

192

193

### USB Constants

194

195

Direction and type constants for endpoint and control operations.

196

197

```python { .api }

198

# Descriptor types

199

DESC_TYPE_DEVICE = 0x01

200

DESC_TYPE_CONFIG = 0x02

201

DESC_TYPE_STRING = 0x03

202

DESC_TYPE_INTERFACE = 0x04

203

DESC_TYPE_ENDPOINT = 0x05

204

205

# Endpoint directions

206

ENDPOINT_IN = 0x80

207

ENDPOINT_OUT = 0x00

208

209

# Endpoint types

210

ENDPOINT_TYPE_CTRL = 0x00

211

ENDPOINT_TYPE_ISO = 0x01

212

ENDPOINT_TYPE_BULK = 0x02

213

ENDPOINT_TYPE_INTR = 0x03

214

215

# Control transfer directions

216

CTRL_OUT = 0x00

217

CTRL_IN = 0x80

218

219

# Control transfer types

220

CTRL_TYPE_STANDARD = 0x00

221

CTRL_TYPE_CLASS = 0x20

222

CTRL_TYPE_VENDOR = 0x40

223

CTRL_TYPE_RESERVED = 0x60

224

225

# Control transfer recipients

226

CTRL_RECIPIENT_DEVICE = 0x00

227

CTRL_RECIPIENT_INTERFACE = 0x01

228

CTRL_RECIPIENT_ENDPOINT = 0x02

229

CTRL_RECIPIENT_OTHER = 0x03

230

231

# USB speeds

232

SPEED_UNKNOWN = 0

233

SPEED_LOW = 1

234

SPEED_FULL = 2

235

SPEED_HIGH = 3

236

SPEED_SUPER = 4

237

```

238

239

## Usage Examples

240

241

### Endpoint Analysis

242

243

```python

244

import usb.core

245

import usb.util

246

247

device = usb.core.find(idVendor=0x1234, idProduct=0x5678)

248

device.set_configuration()

249

250

config = device.get_active_configuration()

251

interface = config.interfaces()[0]

252

253

for endpoint in interface.endpoints():

254

addr = endpoint.bEndpointAddress

255

attrs = endpoint.bmAttributes

256

257

print(f"Endpoint address: 0x{addr:02x}")

258

print(f" Absolute address: {usb.util.endpoint_address(addr)}")

259

260

direction = usb.util.endpoint_direction(addr)

261

if direction == usb.util.ENDPOINT_IN:

262

print(" Direction: IN")

263

else:

264

print(" Direction: OUT")

265

266

ep_type = usb.util.endpoint_type(attrs)

267

type_names = {

268

usb.util.ENDPOINT_TYPE_CTRL: "Control",

269

usb.util.ENDPOINT_TYPE_ISO: "Isochronous",

270

usb.util.ENDPOINT_TYPE_BULK: "Bulk",

271

usb.util.ENDPOINT_TYPE_INTR: "Interrupt"

272

}

273

print(f" Type: {type_names[ep_type]}")

274

print(f" Max packet size: {endpoint.wMaxPacketSize}")

275

```

276

277

### Interface Management

278

279

```python

280

import usb.core

281

import usb.util

282

283

device = usb.core.find(idVendor=0x1234, idProduct=0x5678)

284

device.set_configuration()

285

286

interface_num = 0

287

288

try:

289

# Claim interface for exclusive access

290

usb.util.claim_interface(device, interface_num)

291

print(f"Interface {interface_num} claimed")

292

293

# Perform device operations...

294

295

finally:

296

# Always release interface when done

297

usb.util.release_interface(device, interface_num)

298

print(f"Interface {interface_num} released")

299

```

300

301

### String Descriptor Access

302

303

```python

304

import usb.core

305

import usb.util

306

307

device = usb.core.find(idVendor=0x1234, idProduct=0x5678)

308

309

try:

310

# Get supported languages

311

langids = usb.util.get_langids(device)

312

print(f"Supported languages: {[hex(lid) for lid in langids]}")

313

314

# Get device strings in first supported language

315

if langids and device.iManufacturer:

316

manufacturer = usb.util.get_string(device, device.iManufacturer, langids[0])

317

print(f"Manufacturer: {manufacturer}")

318

319

if langids and device.iProduct:

320

product = usb.util.get_string(device, device.iProduct, langids[0])

321

print(f"Product: {product}")

322

323

if langids and device.iSerialNumber:

324

serial = usb.util.get_string(device, device.iSerialNumber, langids[0])

325

print(f"Serial number: {serial}")

326

327

except usb.core.USBError as e:

328

print(f"String access failed: {e}")

329

```

330

331

### Descriptor Search

332

333

```python

334

import usb.core

335

import usb.util

336

337

device = usb.core.find(idVendor=0x1234, idProduct=0x5678)

338

device.set_configuration()

339

340

config = device.get_active_configuration()

341

342

# Find all bulk endpoints

343

bulk_endpoints = usb.util.find_descriptor(

344

config,

345

find_all=True,

346

custom_match=lambda e: usb.util.endpoint_type(e.bmAttributes) == usb.util.ENDPOINT_TYPE_BULK

347

)

348

349

print(f"Found {len(bulk_endpoints)} bulk endpoints:")

350

for ep in bulk_endpoints:

351

direction = "IN" if usb.util.endpoint_direction(ep.bEndpointAddress) == usb.util.ENDPOINT_IN else "OUT"

352

print(f" Endpoint 0x{ep.bEndpointAddress:02x} ({direction})")

353

354

# Find specific interface by class

355

hid_interface = usb.util.find_descriptor(

356

config,

357

bInterfaceClass=3 # HID class

358

)

359

360

if hid_interface:

361

print(f"Found HID interface: {hid_interface.bInterfaceNumber}")

362

```

363

364

### Control Transfer Setup

365

366

```python

367

import usb.core

368

import usb.util

369

370

device = usb.core.find(idVendor=0x1234, idProduct=0x5678)

371

372

# Build request type for vendor-specific IN request to device

373

request_type = usb.util.build_request_type(

374

usb.util.CTRL_IN,

375

usb.util.CTRL_TYPE_VENDOR,

376

usb.util.CTRL_RECIPIENT_DEVICE

377

)

378

379

print(f"Request type: 0x{request_type:02x}")

380

381

# Perform control transfer

382

try:

383

result = device.ctrl_transfer(

384

request_type,

385

0x01, # Vendor-specific request

386

0x0000, # wValue

387

0x0000, # wIndex

388

64 # Read 64 bytes

389

)

390

print(f"Control transfer result: {result}")

391

392

except usb.core.USBError as e:

393

print(f"Control transfer failed: {e}")

394

```

395

396

### Buffer Management

397

398

```python

399

import usb.core

400

import usb.util

401

402

device = usb.core.find(idVendor=0x1234, idProduct=0x5678)

403

device.set_configuration()

404

405

# Create buffer for reading data

406

buffer = usb.util.create_buffer(1024)

407

print(f"Created buffer of size {len(buffer)}")

408

409

# Use buffer with read operation

410

endpoint_addr = 0x81 # IN endpoint

411

try:

412

bytes_read = device.read(endpoint_addr, buffer, timeout=1000)

413

print(f"Read {bytes_read} bytes into buffer")

414

print(f"Data: {buffer[:bytes_read]}")

415

416

except usb.core.USBTimeoutError:

417

print("Read operation timed out")

418

```

419

420

### Resource Cleanup

421

422

```python

423

import usb.core

424

import usb.util

425

426

device = usb.core.find(idVendor=0x1234, idProduct=0x5678)

427

428

try:

429

# Perform device operations

430

device.set_configuration()

431

# ... communication ...

432

433

finally:

434

# Clean up device resources

435

usb.util.dispose_resources(device)

436

print("Device resources disposed")

437

```