Skip to content

Commit

Permalink
🤖 Merge PR DefinitelyTyped#47007 [usb] minor fixes by @mildsunrise
Browse files Browse the repository at this point in the history
* [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 <[email protected]>

* Update index.d.ts

* make callback error parameter non-optional

* more consistency fixes

Co-authored-by: Rob Moran <[email protected]>
  • Loading branch information
mildsunrise and thegecko authored Sep 3, 2020
1 parent 3bf9694 commit 9a5105e
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 37 deletions.
86 changes: 63 additions & 23 deletions types/usb/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) */
Expand All @@ -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.
Expand All @@ -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.
*
Expand All @@ -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
Expand All @@ -89,41 +94,41 @@ 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.
*
* 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.
*
* 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),
* then before claiming an interface, call this method.
*
* 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.
*
* 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 */
Expand Down Expand Up @@ -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.
Expand All @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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. */
Expand All @@ -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);

Expand All @@ -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.
Expand All @@ -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. */
Expand All @@ -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);

Expand All @@ -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 */
Expand Down Expand Up @@ -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
Expand Down
40 changes: 26 additions & 14 deletions types/usb/usb-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -55,19 +59,20 @@ 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);

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();

Expand Down Expand Up @@ -105,22 +110,29 @@ 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";
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];

Expand Down

0 comments on commit 9a5105e

Please sign in to comment.