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

Only poll USB devices list when a change is detected #191

Merged
merged 17 commits into from
Jul 31, 2018
Merged
Show file tree
Hide file tree
Changes from 15 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
4 changes: 3 additions & 1 deletion packages/hw-transport-node-hid/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
"license": "Apache-2.0",
"dependencies": {
"@ledgerhq/hw-transport": "^4.21.0",
"node-hid": "^0.7.2"
"lodash": "^4.17.10",
"node-hid": "^0.7.2",
"usb": "^1.3.2"
},
"devDependencies": {
"flow-bin": "^0.68.0",
Expand Down
13 changes: 12 additions & 1 deletion packages/hw-transport-node-hid/src/TransportNodeHid.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ function defer<T>(): Defer<T> {

let listenDevicesPollingInterval = 500;
let listenDevicesPollingSkip = () => false;
let listenDevicesDebug = () => {};

/**
* node-hid Transport implementation
Expand Down Expand Up @@ -68,6 +69,15 @@ export default class TransportNodeHid extends Transport<string> {
listenDevicesPollingSkip = conditionToSkip;
};

static setListenDevicesDebug = (debug: boolean | ((log: string) => void)) => {
listenDevicesDebug =
typeof debug === "function"
? debug
: debug
? (...log) => console.log("[listenDevices]", ...log)
: () => {};
};

/**
*/
static listen = (
Expand All @@ -85,7 +95,8 @@ export default class TransportNodeHid extends Transport<string> {
});
const { events, stop } = listenDevices(
listenDevicesPollingInterval,
listenDevicesPollingSkip
listenDevicesPollingSkip,
listenDevicesDebug
);

const onAdd = device => {
Expand Down
4 changes: 2 additions & 2 deletions packages/hw-transport-node-hid/src/getDevices.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @flow
import HID from "node-hid";
import isLedgerDevice from "./isLedgerDevice";

export default function getDevices(): Array<*> {
return HID.devices().filter(isLedgerDevice);
return HID.devices(0x2c97, 0x0);
}
6 changes: 0 additions & 6 deletions packages/hw-transport-node-hid/src/isLedgerDevice.js

This file was deleted.

64 changes: 53 additions & 11 deletions packages/hw-transport-node-hid/src/listenDevices.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
// @flow

import EventEmitter from "events";
import usb from "usb";
import debounce from "lodash/debounce";
import getDevices from "./getDevices";

export default (
delay: number,
listenDevicesPollingSkip: () => boolean
listenDevicesPollingSkip: () => boolean,
debug: (...any) => void
): {
events: EventEmitter,
stop: () => void
} => {
const events = new EventEmitter();
events.setMaxListeners(0);

let timeoutDetection;
let listDevices = getDevices();

const flatDevice = d => d.path;
Expand All @@ -27,37 +29,77 @@ export default (

let lastDevices = getFlatDevices();

const checkDevices = () => {
const poll = () => {
if (!listenDevicesPollingSkip()) {
const currentDevices = getFlatDevices();
debug("Polling for added or removed devices");

let changeFound = false;
const currentDevices = getFlatDevices();
const newDevices = currentDevices.filter(d => !lastDevices.includes(d));
const removeDevices = lastDevices.filter(
d => !currentDevices.includes(d)
);

if (newDevices.length > 0) {
debug("New device found:", newDevices);

listDevices = getDevices();
events.emit("add", getDeviceByPaths(newDevices));

changeFound = true;
} else {
debug("No new device found");
}

const removeDevices = lastDevices.filter(
d => !currentDevices.includes(d)
);

if (removeDevices.length > 0) {
debug("Removed device found:", removeDevices);

events.emit("remove", getDeviceByPaths(removeDevices));
listDevices = listDevices.filter(
d => !removeDevices.includes(flatDevice(d))
);

changeFound = true;
} else {
debug("No removed device found");
}

lastDevices = currentDevices;
if (changeFound) {
lastDevices = currentDevices;
}
} else {
debug("Polling skipped, re-debouncing");
debouncedPoll();
}
setTimeout(checkDevices, delay);
};

timeoutDetection = setTimeout(checkDevices, delay);
const debouncedPoll = debounce(poll, delay);

const attachDetected = device => {
debug("Device add detected:", device);

debouncedPoll();
};
usb.on("attach", attachDetected);
debug("attach listener added");

const detachDetected = device => {
debug("Device removal detected:", device);

debouncedPoll();
};
usb.on("detach", detachDetected);
debug("detach listener added");

return {
stop: () => {
clearTimeout(timeoutDetection);
debug(
"Stop received, removing listeners and cancelling pending debounced polls"
);
debouncedPoll.cancel();
usb.removeListener("attach", attachDetected);
usb.removeListener("detach", detachDetected);
},
events
};
Expand Down
36 changes: 33 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6761,7 +6761,7 @@ lodash.uniq@^4.5.0:
version "4.17.5"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"

lodash@^4.15.0, lodash@^4.17.4, lodash@^4.2.0:
lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.2.0:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"

Expand Down Expand Up @@ -7289,7 +7289,7 @@ mute-stream@0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"

nan@^2.0.5, nan@^2.0.7, nan@^2.10.0, nan@^2.2.1, nan@^2.3.0, nan@^2.9.2:
nan@^2.0.5, nan@^2.0.7, nan@^2.10.0, nan@^2.2.1, nan@^2.3.0, nan@^2.8.0, nan@^2.9.2:
version "2.10.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f"

Expand Down Expand Up @@ -7322,6 +7322,14 @@ needle@^2.2.0:
iconv-lite "^0.4.4"
sax "^1.2.4"

needle@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.1.tgz#b5e325bd3aae8c2678902fa296f729455d1d3a7d"
dependencies:
debug "^2.1.2"
iconv-lite "^0.4.4"
sax "^1.2.4"

negotiator@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
Expand Down Expand Up @@ -7418,6 +7426,21 @@ node-notifier@^5.0.2:
shellwords "^0.1.1"
which "^1.3.0"

node-pre-gyp@^0.10.0:
version "0.10.3"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc"
dependencies:
detect-libc "^1.0.2"
mkdirp "^0.5.1"
needle "^2.2.1"
nopt "^4.0.1"
npm-packlist "^1.1.6"
npmlog "^4.0.2"
rc "^1.2.7"
rimraf "^2.6.1"
semver "^5.3.0"
tar "^4"

node-pre-gyp@^0.6.39:
version "0.6.39"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649"
Expand Down Expand Up @@ -8752,7 +8775,7 @@ rc@^1.0.1, rc@^1.1.7:
minimist "^1.2.0"
strip-json-comments "~2.0.1"

rc@^1.1.6:
rc@^1.1.6, rc@^1.2.7:
version "1.2.8"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
dependencies:
Expand Down Expand Up @@ -10929,6 +10952,13 @@ url@^0.11.0, url@~0.11.0:
punycode "1.3.2"
querystring "0.2.0"

usb@^1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/usb/-/usb-1.3.2.tgz#4563a32323856e26c97dae374b34c66c3d83b5f4"
dependencies:
nan "^2.8.0"
node-pre-gyp "^0.10.0"

use@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/use/-/use-3.1.0.tgz#14716bf03fdfefd03040aef58d8b4b85f3a7c544"
Expand Down