🤖 Merge PR #47007 [usb] minor fixes by @mildsunrise

* [usb] fix invalid return types

* [usb] fix callback types

* [usb] update tests

* [usb] add definition for clearHalt

* [usb] use consistent terms

* [usb] getStringDescriptor returns string

* [usb] fix type of data_or_length

* [usb] add __getConfigDescriptor

* [usb] expose Transfer API

* [usb] expose three more interface internals

* Update types/usb/index.d.ts

Co-authored-by: Rob Moran <github@thegecko.org>

* Update index.d.ts

* make callback error parameter non-optional

* more consistency fixes

Co-authored-by: Rob Moran <github@thegecko.org>
This commit is contained in:
Alba Mendez 2020-09-03 10:54:04 +02:00 committed by GitHub
parent 3bf969403b
commit 9a5105e065
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 89 additions and 37 deletions

86
types/usb/index.d.ts vendored
View File

@ -29,7 +29,7 @@ export class Device {
/** Object with properties for the fields of the device descriptor. */
deviceDescriptor: DeviceDescriptor;
/** Object with properties for the fields of the configuration descriptor. */
/** Object with properties for the fields of the active configuration descriptor. */
configDescriptor: ConfigDescriptor;
/** Contains all config descriptors of the device (same structure as .configDescriptor above) */
@ -42,7 +42,11 @@ export class Device {
interfaces: Interface[];
__open(): void;
__getConfigDescriptor(): ConfigDescriptor;
__claimInterface(addr: number): void;
__detachKernelDriver(addr: number): void;
__attachKernelDriver(addr: number): void;
__isKernelDriverActive(addr: number): boolean;
/**
* Open the device.
@ -68,7 +72,7 @@ export class Device {
/**
* Perform a control transfer with `libusb_control_transfer`.
*
* Parameter `data_or_length` can be a integer length for an IN transfer, or a Buffer for an out transfer. The type must match the direction specified in the MSB of bmRequestType.
* Parameter `data_or_length` can be an integer length for an IN transfer, or a `Buffer` for an OUT transfer. The type must match the direction specified in the MSB of bmRequestType.
*
* The `data` parameter of the callback is always undefined for OUT transfers, or will be passed a Buffer for IN transfers.
*
@ -80,7 +84,8 @@ export class Device {
* @param data_or_length
* @param callback
*/
controlTransfer(bmRequestType: number, bRequest: number, wValue: number, wIndex: number, data_or_length: any, callback: (error?: LibUSBException, buf?: Buffer) => void): Device;
controlTransfer(bmRequestType: number, bRequest: number, wValue: number, wIndex: number, data_or_length: number | Buffer,
callback: (error: undefined | LibUSBException, buffer?: Buffer) => void): Device;
/**
* Perform a control transfer to retrieve a string descriptor
@ -89,7 +94,7 @@ export class Device {
* @param desc_index
* @param callback
*/
getStringDescriptor(desc_index: number, callback: (error?: string, buf?: Buffer) => void): void;
getStringDescriptor(desc_index: number, callback: (error: undefined | LibUSBException, data?: string) => void): void;
/**
* Perform a control transfer to retrieve an object with properties for the fields of the Binary Object Store descriptor.
@ -97,7 +102,7 @@ export class Device {
* The device must be open to use this method.
* @param callback
*/
getBosDescriptor(callback: (error?: string, descriptor?: BosDescriptor) => void): void;
getBosDescriptor(callback: (error: undefined | LibUSBException, descriptor?: BosDescriptor) => void): void;
/**
* Retrieve a list of Capability objects for the Binary Object Store capabilities of the device.
@ -105,7 +110,7 @@ export class Device {
* The device must be open to use this method.
* @param callback
*/
getCapabilities(callback: (error?: string, capabilities?: Capability[]) => void): void;
getCapabilities(callback: (error: undefined | LibUSBException, capabilities?: Capability[]) => void): void;
/**
* Set the device configuration to something other than the default (0). To use this, first call `.open(false)` (which tells it not to auto configure),
@ -113,9 +118,9 @@ export class Device {
*
* The device must be open to use this method.
* @param desired
* @param cb
* @param callback
*/
setConfiguration(desired: number, cb: (err?: string) => void): void;
setConfiguration(desired: number, callback: (error: undefined | LibUSBException) => void): void;
/**
* Performs a reset of the device. Callback is called when complete.
@ -123,7 +128,7 @@ export class Device {
* The device must be open to use this method.
* @param callback
*/
reset(callback: (err?: string) => void): void;
reset(callback: (error: undefined | LibUSBException) => void): void;
}
/** A structure representing the standard USB device descriptor */
@ -276,9 +281,9 @@ export class Interface {
* It is an error to release an interface with pending transfers.
*
* The device must be open to use this method.
* @param cb
* @param callback
*/
release(cb?: (err?: string) => void): void;
release(callback?: (error: undefined | LibUSBException) => void): void;
/**
* Releases the interface and resets the alternate setting. Calls callback when complete.
@ -290,9 +295,9 @@ export class Interface {
*
* The device must be open to use this method.
* @param closeEndpoints
* @param cb
* @param callback
*/
release(closeEndpoints?: boolean, cb?: (err?: string) => void): void;
release(closeEndpoints?: boolean, callback?: (error: undefined | LibUSBException) => void): void;
/**
* Returns `false` if a kernel driver is not active; `true` if active.
@ -306,23 +311,23 @@ export class Interface {
*
* The device must be open to use this method.
*/
detachKernelDriver(): number;
detachKernelDriver(): void;
/**
* Re-attaches the kernel driver for the interface.
*
* The device must be open to use this method.
*/
attachKernelDriver(): number;
attachKernelDriver(): void;
/**
* Sets the alternate setting. It updates the `interface.endpoints` array to reflect the endpoints found in the alternate setting.
*
* The device must be open to use this method.
* @param altSetting
* @param cb
* @param callback
*/
setAltSetting(altSetting: number, cb: (err?: string) => void): void;
setAltSetting(altSetting: number, callback: (error: undefined | LibUSBException) => void): void;
/**
* Return the InEndpoint or OutEndpoint with the specified address.
@ -382,6 +387,20 @@ export interface Endpoint extends EventEmitter {
/** Object with fields from the endpoint descriptor -- see libusb documentation or USB spec. */
descriptor: EndpointDescriptor;
/** Clear the halt/stall condition for this endpoint. */
clearHalt(callback: (error: undefined | LibUSBException) => void): void;
/**
* Create a new `Transfer` object for this endpoint.
*
* The passed callback will be called when the transfer is submitted and finishes. Its arguments are the error (if any), the submitted buffer, and the amount of data actually written (for
* OUT transfers) or read (for IN transfers).
*
* @param timeout Timeout for the transfer (0 means unlimited).
* @param callback Transfer completion callback.
*/
makeTransfer(timeout: number, callback: (error: undefined | LibUSBException, buffer?: Buffer, actualLength?: number) => void): Transfer;
}
/** Endpoints in the IN direction (device->PC) have this type. */
@ -390,6 +409,8 @@ export class InEndpoint extends EventEmitter implements Endpoint {
transferType: number;
timeout: number;
descriptor: EndpointDescriptor;
clearHalt(callback: (error: undefined | LibUSBException) => void): void;
makeTransfer(timeout: number, callback: (error: undefined | LibUSBException, buffer?: Buffer, actualLength?: number) => void): Transfer;
constructor(device: Device, descriptor: EndpointDescriptor);
@ -404,7 +425,7 @@ export class InEndpoint extends EventEmitter implements Endpoint {
* @param length
* @param callback
*/
transfer(length: number, callback: (error: LibUSBException, data: Buffer) => void): InEndpoint;
transfer(length: number, callback: (error: undefined | LibUSBException, data?: Buffer) => void): InEndpoint;
/**
* Start polling the endpoint.
@ -424,9 +445,9 @@ export class InEndpoint extends EventEmitter implements Endpoint {
* Further data may still be received. The `end` event is emitted and the callback is called once all transfers have completed or canceled.
*
* The device must be open to use this method.
* @param cb
* @param callback
*/
stopPoll(cb?: () => void): void;
stopPoll(callback?: () => void): void;
}
/** Endpoints in the OUT direction (PC->device) have this type. */
@ -435,6 +456,8 @@ export class OutEndpoint extends EventEmitter implements Endpoint {
transferType: number;
timeout: number;
descriptor: EndpointDescriptor;
clearHalt(callback: (error: undefined | LibUSBException) => void): void;
makeTransfer(timeout: number, callback: (error: undefined | LibUSBException, buffer?: Buffer, actualLength?: number) => void): Transfer;
constructor(device: Device, descriptor: EndpointDescriptor);
@ -447,10 +470,10 @@ export class OutEndpoint extends EventEmitter implements Endpoint {
*
* The device must be open to use this method.
* @param buffer
* @param cb
* @param callback
*/
transfer(buffer: Buffer, cb: (err?: LibUSBException) => void): OutEndpoint;
transferWithZLP(buf: Buffer, cb: (err?: LibUSBException) => void): void;
transfer(buffer: Buffer, callback: (error: undefined | LibUSBException) => void): OutEndpoint;
transferWithZLP(buffer: Buffer, callback: (error: undefined | LibUSBException) => void): void;
}
/** A structure representing the standard USB endpoint descriptor */
@ -487,6 +510,23 @@ export class EndpointDescriptor {
extra: Buffer;
}
/** Represents a USB transfer */
export class Transfer {
/**
* (Re-)submit the transfer.
*
* @param buffer Buffer where data will be written (for IN transfers) or read from (for OUT transfers).
*/
submit(buffer: Buffer): Transfer;
/**
* Cancel the transfer.
*
* Returns `true` if the transfer was canceled, `false` if it wasn't in pending state.
*/
cancel(): boolean;
}
/**
* Convenience method to get the first device with the specified VID and PID, or `undefined` if no such device is present.
* @param vid

View File

@ -9,15 +9,19 @@ device.portNumbers = [1, 2, 3];
device.__open();
device.__claimInterface(0);
device.__attachKernelDriver(0);
device.__detachKernelDriver(0);
const isKernelActive: boolean = device.__isKernelDriverActive(0);
device.open(true);
device.close();
const xferDevice: usb.Device = device.controlTransfer(1, 1, 1, 1, 1, (error: usb.LibUSBException, buf: Buffer): usb.Device => new usb.Device());
device.getStringDescriptor(1, (error: string, buf: Buffer) => null);
device.getBosDescriptor((error: string, descriptor: usb.BosDescriptor) => null);
device.getCapabilities((error: string, capabilities: usb.Capability[]) => null);
device.setConfiguration(1, (error: string) => null);
device.reset((error: string) => null);
const xferDeviceIn: usb.Device = device.controlTransfer(1, 1, 1, 1, 1, (error?: usb.LibUSBException, buffer?: Buffer): usb.Device => new usb.Device());
const xferDeviceOut: usb.Device = device.controlTransfer(1, 1, 1, 1, Buffer.alloc(5), (error?: usb.LibUSBException): usb.Device => new usb.Device());
device.getStringDescriptor(1, (error?: usb.LibUSBException, data?: string) => null);
device.getBosDescriptor((error?: usb.LibUSBException, descriptor?: usb.BosDescriptor) => null);
device.getCapabilities((error?: usb.LibUSBException, capabilities?: usb.Capability[]) => null);
device.setConfiguration(1, (error?: usb.LibUSBException) => null);
device.reset((error?: usb.LibUSBException) => null);
const deviceDesc: usb.DeviceDescriptor = new usb.DeviceDescriptor();
@ -55,6 +59,7 @@ const deviceInterface: usb.Interface = device.interface(1);
device.interfaces = [deviceInterface];
device.parent = device;
device.configDescriptor = configDesc;
const configDesc2: usb.ConfigDescriptor = device.__getConfigDescriptor();
device.allConfigDescriptors = [configDesc];
const iface = new usb.Interface(device, 1);
@ -62,12 +67,12 @@ const iface = new usb.Interface(device, 1);
iface.interfaceNumber = 1;
iface.altSetting = 0;
iface.claim();
iface.release((error: string) => null);
iface.release(false, (error: string) => null);
iface.release((error?: usb.LibUSBException) => null);
iface.release(false, (error?: usb.LibUSBException) => null);
const kernelActive: boolean = iface.isKernelDriverActive();
const detachKernel: number = iface.detachKernelDriver();
const attachKernel: number = iface.attachKernelDriver();
iface.setAltSetting(1, (error: string) => null);
iface.detachKernelDriver();
iface.attachKernelDriver();
iface.setAltSetting(1, (error?: usb.LibUSBException) => null);
const ifaceDesc: usb.InterfaceDescriptor = new usb.InterfaceDescriptor();
@ -105,13 +110,17 @@ inEndpoint.direction = "in";
inEndpoint.transferType = 1;
inEndpoint.timeout = 1;
inEndpoint.descriptor = endpointDesc;
const xferInEndpoint: usb.InEndpoint = inEndpoint.transfer(1, (error: usb.LibUSBException, data: Buffer) => inEndpoint);
const xferInEndpoint: usb.InEndpoint = inEndpoint.transfer(1, (error?: usb.LibUSBException, data?: Buffer) => inEndpoint);
inEndpoint.on("data", (data) => null);
inEndpoint.startPoll(1, 1);
inEndpoint.startPoll(1);
inEndpoint.startPoll();
inEndpoint.stopPoll(() => null);
inEndpoint.stopPoll();
inEndpoint.clearHalt((error?: usb.LibUSBException) => null);
const transferIn: usb.Transfer = inEndpoint.makeTransfer(0, (error?: usb.LibUSBException, buffer?: Buffer, actualLength?: number) => null);
transferIn.submit(Buffer.alloc(0));
const transferInCancelResult: boolean = transferIn.cancel();
const outEndpoint: usb.OutEndpoint = new usb.OutEndpoint(device, endpointDesc);
outEndpoint.direction = "out";
@ -119,8 +128,11 @@ outEndpoint.transferType = 1;
outEndpoint.timeout = 1;
outEndpoint.descriptor = endpointDesc;
inEndpoint.on("error", (err) => null);
const xferOutEndpoint: usb.OutEndpoint = outEndpoint.transfer(new Buffer([]), (error: usb.LibUSBException) => null);
outEndpoint.transferWithZLP(new Buffer([]), (error: usb.LibUSBException) => null);
const xferOutEndpoint: usb.OutEndpoint = outEndpoint.transfer(new Buffer([]), (error?: usb.LibUSBException) => null);
outEndpoint.transferWithZLP(new Buffer([]), (error?: usb.LibUSBException) => null);
outEndpoint.clearHalt((error?: usb.LibUSBException) => null);
const transferOut: usb.Transfer = outEndpoint.makeTransfer(0, (error?: usb.LibUSBException, buffer?: Buffer, actualLength?: number) => null);
const transferOutCancelResult: boolean = transferOut.cancel();
iface.endpoints = [inEndpoint, outEndpoint];