Skip to content
This repository has been archived by the owner on Jan 10, 2022. It is now read-only.

Added an error message if a repeated USB address is seen #31

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 41 additions & 10 deletions src/device-lister.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ export default class DeviceLister extends EventEmitter {
// Caches
this._currentDevices = new Map();
this._currentErrors = new Set();
this._seenUsbAdresses = new Set();

// State for throttling down reenumerations
this._activeReenumeration = false; // Promise or false
this._queuedReenumeration = false; // Boolean


this._backends = [];

const {
Expand Down Expand Up @@ -92,14 +92,15 @@ export default class DeviceLister extends EventEmitter {
if (serialport) { this._backends.push(new SerialPortBackend()); }
if (jlink) { this._backends.push(new JlinkBackend()); }

this._boundReenumerate = this._triggerReenumeration.bind(this);
this._boundOnAttach = this._onUsbAttach.bind(this);
this._boundOnDetach = this._onUsbDetach.bind(this);
}

start() {
debug('Attaching event listeners for USB attach/detach');

Usb.on('attach', this._boundReenumerate);
Usb.on('detach', this._boundReenumerate);
Usb.on('attach', this._boundOnAttach);
Usb.on('detach', this._boundOnDetach);

this._backends.forEach(backend => backend.start());

Expand All @@ -113,8 +114,8 @@ export default class DeviceLister extends EventEmitter {

this._backends.forEach(backend => backend.stop());

Usb.removeListener('attach', this._boundReenumerate);
Usb.removeListener('detach', this._boundReenumerate);
Usb.removeListener('attach', this._boundOnAttach);
Usb.removeListener('detach', this._boundOnDetach);
}

static get devices() {
Expand All @@ -137,16 +138,36 @@ export default class DeviceLister extends EventEmitter {
});
}

_onUsbDetach(usbDevice) {
debug(`Called _triggerReenumeration because of detached USB device VID/PID 0x${
usbDevice.deviceDescriptor.idVendor.toString(16).padStart(4, '0')}/0x${
usbDevice.deviceDescriptor.idProduct.toString(16).padStart(4, '0')}`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could consider using one of the hexpad4() or getDeviceId() functions from util/usb.js.


this._triggerReenumeration(usbDevice)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon here. Looks like a npm run lintfix is needed.

}

_onUsbAttach(usbDevice) {
debug(`Called _triggerReenumeration because of attached USB device VID/PID 0x${
usbDevice.deviceDescriptor.idVendor.toString(16).padStart(4, '0')}/0x${
usbDevice.deviceDescriptor.idProduct.toString(16).padStart(4, '0')}`);

const usbAddress = usbDevice.busNumber + '.' + usbDevice.deviceAddress;

if (this._seenUsbAdresses.has(usbAddress)) {
this.emit('error', new Error('A USB device has been given a USB address seen before; this might lead to problems. See https://github.com/NordicSemiconductor/pc-nrfconnect-core/blob/master/doc/repeated-usb-address-troubleshoot.md'));
} else {
this._seenUsbAdresses.add(usbAddress);
}

this._triggerReenumeration(usbDevice)
}

// Called on the USB attach/detach events, throttles down calls to reenumerate()
// Only one reenumeration will be active at any one time - if any reenumerations
// are triggered by events when there is one already active, the first one
// will be queued and delayed until the active one is finished, the rest
// will be silently ignored.
_triggerReenumeration(usbDevice) {
debug(`Called _triggerReenumeration because of added/removed USB device VID/PID 0x${
usbDevice.deviceDescriptor.idVendor.toString(16).padStart(4, '0')}/0x${
usbDevice.deviceDescriptor.idProduct.toString(16).padStart(4, '0')}`);
_triggerReenumeration() {

if (!this._activeReenumeration) {
debug('Calling reenumerate().');
Expand Down Expand Up @@ -187,8 +208,18 @@ export default class DeviceLister extends EventEmitter {
device = Object.assign({}, device, result);
if (traits) {
device.traits = result.traits.concat(traits);

if (traits.indexOf('usb') !== -1) {
// This just fills up this._seenUsbAdresses on the
// first run, without needing to receive an
// 'attach' event for the offending USB peripheral
const usbAddress = device.usb.device.busNumber + '.' + device.usb.device.deviceAddress;
this._seenUsbAdresses.add(usbAddress);
}
}
deviceMap.set(serialNumber, device);


} else if (result.errorSource) {
if (!this._currentErrors.has(result.errorSource)) {
this.emit('error', result.error);
Expand Down