or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

constants-errors.mddata-transfers.mddescriptors.mddevice-communication.mddevice-management.mdevent-handling.mdindex.mdinterfaces-endpoints.mdwebusb-api.md

device-communication.mddocs/

0

# Device Communication

1

2

Device communication provides methods to open USB devices and perform control transfers for device configuration and data exchange. This includes device initialization, configuration management, and low-level control operations.

3

4

## Capabilities

5

6

### Device Opening and Closing

7

8

Open and close USB devices for communication.

9

10

```typescript { .api }

11

/**

12

* Open the device for communication

13

* @param defaultConfig - Whether to automatically configure the device with the default configuration (default: true)

14

*/

15

open(defaultConfig?: boolean): void;

16

17

/**

18

* Close the device

19

* The device must be open to use other methods

20

*/

21

close(): void;

22

```

23

24

**Usage Examples:**

25

26

```typescript

27

import { findByIds } from 'usb';

28

29

const device = findByIds(0x1234, 0x5678);

30

if (device) {

31

// Open with default configuration

32

device.open();

33

console.log('Device opened with default configuration');

34

35

// Access interfaces after opening

36

console.log(`Device has ${device.interfaces?.length || 0} interfaces`);

37

38

// Close when done

39

device.close();

40

console.log('Device closed');

41

}

42

43

// Open without default configuration (for manual configuration)

44

if (device) {

45

device.open(false);

46

console.log('Device opened without auto-configuration');

47

48

// You can now manually set configuration before using interfaces

49

device.setConfiguration(1, (error) => {

50

if (!error) {

51

console.log('Configuration set successfully');

52

// Now interfaces are available

53

}

54

});

55

56

device.close();

57

}

58

```

59

60

### Device Configuration

61

62

Set the device configuration to something other than the default.

63

64

```typescript { .api }

65

/**

66

* Set the device configuration

67

* To use this, first call .open(false), then before claiming an interface, call this method

68

* @param desired - Configuration value to set

69

* @param callback - Optional callback called when complete

70

*/

71

setConfiguration(desired: number, callback?: (error?: LibUSBException) => void): void;

72

```

73

74

**Usage Examples:**

75

76

```typescript

77

import { findByIds } from 'usb';

78

79

const device = findByIds(0x1234, 0x5678);

80

if (device) {

81

// Open without default configuration

82

device.open(false);

83

84

// Set specific configuration

85

device.setConfiguration(2, (error) => {

86

if (error) {

87

console.error('Failed to set configuration:', error.message);

88

return;

89

}

90

91

console.log('Configuration 2 set successfully');

92

console.log(`Device now has ${device.interfaces?.length || 0} interfaces`);

93

94

// Now you can claim interfaces and use endpoints

95

if (device.interfaces && device.interfaces.length > 0) {

96

const interface0 = device.interfaces[0];

97

interface0.claim();

98

console.log('Interface 0 claimed');

99

100

// Use interface...

101

102

interface0.release((error) => {

103

if (!error) console.log('Interface released');

104

device.close();

105

});

106

}

107

});

108

}

109

```

110

111

### Control Transfers

112

113

Perform control transfers for device configuration and vendor-specific commands.

114

115

```typescript { .api }

116

/**

117

* Perform a control transfer with libusb_control_transfer

118

* Parameter data_or_length can be an integer length for an IN transfer, or a Buffer for an OUT transfer

119

* The type must match the direction specified in the MSB of bmRequestType

120

* @param bmRequestType - Request type (direction, type, recipient)

121

* @param bRequest - Specific request

122

* @param wValue - Request-specific value

123

* @param wIndex - Request-specific index

124

* @param data_or_length - Buffer for OUT transfer or length for IN transfer

125

* @param callback - Completion callback

126

* @returns Device instance for chaining

127

*/

128

controlTransfer(

129

bmRequestType: number,

130

bRequest: number,

131

wValue: number,

132

wIndex: number,

133

data_or_length: number | Buffer,

134

callback?: (error?: LibUSBException, buffer?: Buffer | number) => void

135

): Device;

136

```

137

138

**Usage Examples:**

139

140

```typescript

141

import { findByIds, LIBUSB_ENDPOINT_IN, LIBUSB_ENDPOINT_OUT, LIBUSB_REQUEST_TYPE_VENDOR, LIBUSB_RECIPIENT_DEVICE } from 'usb';

142

143

const device = findByIds(0x1234, 0x5678);

144

if (device) {

145

device.open();

146

147

// Vendor-specific IN control transfer

148

const bmRequestType = LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE;

149

device.controlTransfer(bmRequestType, 0x01, 0x0000, 0x0000, 64, (error, data) => {

150

if (error) {

151

console.error('Control transfer failed:', error.message);

152

return;

153

}

154

155

console.log('Received data:', data);

156

if (data instanceof Buffer) {

157

console.log('Data length:', data.length);

158

console.log('Data hex:', data.toString('hex'));

159

}

160

});

161

162

// Vendor-specific OUT control transfer

163

const outData = Buffer.from([0x01, 0x02, 0x03, 0x04]);

164

const bmRequestTypeOut = LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE;

165

device.controlTransfer(bmRequestTypeOut, 0x02, 0x1234, 0x0000, outData, (error, bytesWritten) => {

166

if (error) {

167

console.error('Control transfer failed:', error.message);

168

return;

169

}

170

171

console.log('Bytes written:', bytesWritten);

172

});

173

174

device.close();

175

}

176

```

177

178

### String Descriptor Access

179

180

Retrieve string descriptors from the device.

181

182

```typescript { .api }

183

/**

184

* Perform a control transfer to retrieve a string descriptor

185

* @param desc_index - String descriptor index

186

* @param callback - Callback with error and string value

187

*/

188

getStringDescriptor(desc_index: number, callback: (error?: LibUSBException, value?: string) => void): void;

189

```

190

191

**Usage Examples:**

192

193

```typescript

194

import { findByIds } from 'usb';

195

196

const device = findByIds(0x1234, 0x5678);

197

if (device) {

198

device.open();

199

200

const descriptor = device.deviceDescriptor;

201

202

// Get manufacturer string

203

if (descriptor.iManufacturer > 0) {

204

device.getStringDescriptor(descriptor.iManufacturer, (error, manufacturer) => {

205

if (!error && manufacturer) {

206

console.log('Manufacturer:', manufacturer);

207

}

208

});

209

}

210

211

// Get product string

212

if (descriptor.iProduct > 0) {

213

device.getStringDescriptor(descriptor.iProduct, (error, product) => {

214

if (!error && product) {

215

console.log('Product:', product);

216

}

217

});

218

}

219

220

// Get serial number string

221

if (descriptor.iSerialNumber > 0) {

222

device.getStringDescriptor(descriptor.iSerialNumber, (error, serial) => {

223

if (!error && serial) {

224

console.log('Serial Number:', serial);

225

}

226

});

227

}

228

229

device.close();

230

}

231

```

232

233

### Kernel Driver Management

234

235

Manage automatic kernel driver detachment for device access.

236

237

```typescript { .api }

238

/**

239

* Enable/disable libusb's automatic kernel driver detachment

240

* When enabled, libusb will automatically detach the kernel driver on an interface

241

* when claiming the interface, and attach it when releasing the interface

242

* @param enable - Whether to enable automatic detachment

243

*/

244

setAutoDetachKernelDriver(enable: boolean): void;

245

```

246

247

**Usage Examples:**

248

249

```typescript

250

import { findByIds } from 'usb';

251

252

const device = findByIds(0x1234, 0x5678);

253

if (device) {

254

device.open();

255

256

// Enable automatic kernel driver detachment

257

device.setAutoDetachKernelDriver(true);

258

console.log('Auto kernel driver detach enabled');

259

260

// Now when you claim an interface, the kernel driver will be automatically detached

261

if (device.interfaces && device.interfaces.length > 0) {

262

const interface0 = device.interfaces[0];

263

264

// This will automatically detach kernel driver if needed

265

interface0.claim();

266

console.log('Interface claimed (kernel driver automatically detached if needed)');

267

268

// Use interface...

269

270

// This will automatically reattach kernel driver

271

interface0.release((error) => {

272

if (!error) {

273

console.log('Interface released (kernel driver automatically reattached)');

274

}

275

device.close();

276

});

277

}

278

}

279

280

// Disable automatic detachment for manual control

281

const device2 = findByIds(0x5678, 0x1234);

282

if (device2) {

283

device2.open();

284

device2.setAutoDetachKernelDriver(false);

285

286

if (device2.interfaces && device2.interfaces.length > 0) {

287

const interface0 = device2.interfaces[0];

288

289

// Manually check and detach kernel driver if needed

290

if (interface0.isKernelDriverActive()) {

291

console.log('Kernel driver is active, detaching...');

292

interface0.detachKernelDriver();

293

}

294

295

interface0.claim();

296

// Use interface...

297

298

// Manually reattach kernel driver

299

interface0.release((error) => {

300

if (!error) {

301

interface0.attachKernelDriver();

302

console.log('Kernel driver reattached');

303

}

304

device2.close();

305

});

306

}

307

}

308

```

309

310

### Device Reset

311

312

Reset the USB device.

313

314

```typescript { .api }

315

/**

316

* Performs a reset of the device. Callback is called when complete.

317

* The device must be open to use this method.

318

* @param callback - Completion callback

319

*/

320

reset(callback: (error?: LibUSBException) => void): void;

321

```

322

323

**Usage Examples:**

324

325

```typescript

326

import { findByIds } from 'usb';

327

328

const device = findByIds(0x1234, 0x5678);

329

if (device) {

330

device.open();

331

332

// Reset the device

333

device.reset((error) => {

334

if (error) {

335

console.error('Device reset failed:', error.message);

336

return;

337

}

338

339

console.log('Device reset successfully');

340

341

// Note: After reset, you may need to re-open the device

342

// as the device may re-enumerate with new addresses

343

device.close();

344

345

// Wait a moment for re-enumeration

346

setTimeout(() => {

347

// Find device again (it may have new bus/address)

348

const resetDevice = findByIds(0x1234, 0x5678);

349

if (resetDevice) {

350

resetDevice.open();

351

console.log('Device reconnected after reset');

352

resetDevice.close();

353

}

354

}, 1000);

355

});

356

}

357

```

358

359

### Timeout Configuration

360

361

Configure timeout for control transfers.

362

363

```typescript { .api }

364

/**

365

* Device timeout property

366

* Timeout in milliseconds to use for control transfers (default: 1000)

367

*/

368

timeout: number;

369

```

370

371

**Usage Examples:**

372

373

```typescript

374

import { findByIds } from 'usb';

375

376

const device = findByIds(0x1234, 0x5678);

377

if (device) {

378

device.open();

379

380

// Set custom timeout (5 seconds)

381

device.timeout = 5000;

382

console.log(`Device timeout set to ${device.timeout}ms`);

383

384

// Control transfers will now use the 5-second timeout

385

device.controlTransfer(0x80, 0x06, 0x0100, 0x0000, 18, (error, data) => {

386

if (error) {

387

console.error('Control transfer timed out or failed:', error.message);

388

} else {

389

console.log('Control transfer completed within timeout');

390

}

391

});

392

393

device.close();

394

}

395

```

396

397

### BOS Descriptor Access

398

399

Retrieve Binary Object Store (BOS) descriptors for USB 2.0.1+ devices.

400

401

```typescript { .api }

402

/**

403

* Perform a control transfer to retrieve BOS descriptor

404

* BOS is only supported from USB 2.0.1

405

* @param callback - Callback with error and BOS descriptor

406

*/

407

getBosDescriptor(callback: (error?: LibUSBException, descriptor?: BosDescriptor) => void): void;

408

409

/**

410

* Retrieve array of Capability objects for BOS capabilities

411

* @param callback - Callback with error and capabilities array

412

*/

413

getCapabilities(callback: (error?: LibUSBException, capabilities?: Capability[]) => void): void;

414

415

/**

416

* Binary Object Store (BOS) Descriptor

417

*/

418

interface BosDescriptor {

419

/** Size of this descriptor (in bytes) */

420

bLength: number;

421

422

/** Descriptor type */

423

bDescriptorType: number;

424

425

/** Length of this descriptor and all sub descriptors */

426

wTotalLength: number;

427

428

/** Number of separate device capability descriptors */

429

bNumDeviceCaps: number;

430

431

/** Device Capability Descriptors */

432

capabilities: CapabilityDescriptor[];

433

}

434

435

/**

436

* Device Capability Descriptor

437

*/

438

interface CapabilityDescriptor {

439

/** Size of this descriptor (in bytes) */

440

bLength: number;

441

442

/** Descriptor type */

443

bDescriptorType: number;

444

445

/** Device Capability type */

446

bDevCapabilityType: number;

447

448

/** Device Capability data */

449

dev_capability_data: Buffer;

450

}

451

452

/**

453

* Capability class for device capabilities

454

*/

455

class Capability {

456

/** Capability type */

457

readonly type: number;

458

459

/** Capability data buffer */

460

readonly data: Buffer;

461

462

/** Capability descriptor */

463

readonly descriptor: CapabilityDescriptor;

464

}

465

```

466

467

**Usage Examples:**

468

469

```typescript

470

import { findByIds } from 'usb';

471

472

const device = findByIds(0x1234, 0x5678);

473

if (device) {

474

device.open();

475

476

// Check USB version before attempting BOS

477

const usbVersion = device.deviceDescriptor.bcdUSB;

478

console.log(`USB Version: ${(usbVersion >> 8).toString(16)}.${((usbVersion & 0xFF) >> 4).toString(16)}.${(usbVersion & 0x0F).toString(16)}`);

479

480

if (usbVersion >= 0x0201) { // USB 2.0.1 or higher

481

// Get BOS descriptor

482

device.getBosDescriptor((error, bosDescriptor) => {

483

if (error) {

484

console.error('Failed to get BOS descriptor:', error.message);

485

device.close();

486

return;

487

}

488

489

if (!bosDescriptor) {

490

console.log('Device does not support BOS descriptor');

491

device.close();

492

return;

493

}

494

495

console.log('BOS Descriptor:');

496

console.log(` Total Length: ${bosDescriptor.wTotalLength}`);

497

console.log(` Number of Capabilities: ${bosDescriptor.bNumDeviceCaps}`);

498

499

// List capability types

500

bosDescriptor.capabilities.forEach((cap, index) => {

501

console.log(` Capability ${index}:`);

502

console.log(` Type: ${cap.bDevCapabilityType}`);

503

console.log(` Length: ${cap.bLength}`);

504

console.log(` Data: ${cap.dev_capability_data.toString('hex')}`);

505

});

506

507

device.close();

508

});

509

510

// Get device capabilities

511

device.getCapabilities((error, capabilities) => {

512

if (error) {

513

console.error('Failed to get capabilities:', error.message);

514

return;

515

}

516

517

if (capabilities && capabilities.length > 0) {

518

console.log(`Device has ${capabilities.length} capabilities:`);

519

capabilities.forEach((capability, index) => {

520

console.log(` Capability ${index}:`);

521

console.log(` Type: ${capability.type}`);

522

console.log(` Data Length: ${capability.data.length}`);

523

console.log(` Descriptor Type: ${capability.descriptor.bDevCapabilityType}`);

524

});

525

} else {

526

console.log('Device has no BOS capabilities');

527

}

528

});

529

530

} else {

531

console.log('Device USB version is below 2.0.1, BOS not supported');

532

device.close();

533

}

534

}

535

```