node-raspberrypi-usbboot
Advanced tools
Comparing version 0.2.0 to 0.2.1-usbboot-stalls-23feb062025537a6758192c0eb1fc6f31916a64e
@@ -16,2 +16,4 @@ /// <reference types="node" /> | ||
private boundDetachDevice; | ||
private interval; | ||
private attachedDeviceIds; | ||
constructor(); | ||
@@ -18,0 +20,0 @@ start(): void; |
@@ -24,2 +24,3 @@ "use strict"; | ||
const debug = _debug('node-raspberrypi-usbboot'); | ||
const POLLING_INTERVAL_MS = 2000; | ||
const TRANSFER_BLOCK_SIZE = Math.pow(1024, 2); | ||
@@ -86,4 +87,7 @@ // The equivalent of a NULL buffer, given that node-usb complains | ||
*/ | ||
// In node-usb, 0 means "infinite" timeout | ||
const USB_CONTROL_TRANSFER_TIMEOUT_MS = 0; | ||
const USB_CONTROL_TRANSFER_TIMEOUT_MS = 10000; | ||
/** | ||
* @summary The timeout for USB bulk transfers, in milliseconds | ||
*/ | ||
const USB_BULK_TRANSFER_TIMEOUT_MS = 10000; | ||
const USB_ENDPOINT_INTERFACES_SOC_BCM2835 = 1; | ||
@@ -195,9 +199,29 @@ const USB_VENDOR_ID_BROADCOM_CORPORATION = 0x0a5c; | ||
} | ||
const transfer = (endpoint, chunk) => __awaiter(this, void 0, void 0, function* () { | ||
endpoint.timeout = USB_BULK_TRANSFER_TIMEOUT_MS; | ||
for (let tries = 0; tries < 3; tries++) { | ||
if (tries > 0) { | ||
debug('Transfer stall, retrying'); | ||
} | ||
try { | ||
yield bluebird_1.fromCallback(callback => { | ||
endpoint.transfer(chunk, callback); | ||
}); | ||
return; | ||
} | ||
catch (error) { | ||
if (error.errno === usb.LIBUSB_TRANSFER_STALL) { | ||
continue; | ||
} | ||
throw error; | ||
} | ||
} | ||
}); | ||
const epWrite = (buffer, device, endpoint) => __awaiter(this, void 0, void 0, function* () { | ||
debug('Sending buffer size', buffer.length); | ||
yield sendSize(device, buffer.length); | ||
if (buffer.length > 0) { | ||
for (const chunk of chunks(buffer, TRANSFER_BLOCK_SIZE)) { | ||
yield bluebird_1.fromCallback(callback => { | ||
endpoint.transfer(chunk, callback); | ||
}); | ||
debug('Sending chunk of size', chunk.length); | ||
yield transfer(endpoint, chunk); | ||
} | ||
@@ -302,4 +326,15 @@ } | ||
this.usbbootDevices = new Map(); | ||
// We use both events ('attach' and 'detach') and polling getDeviceList() on usb. | ||
// We don't know which one will trigger the this.attachDevice call. | ||
// So we keep track of attached devices ids in attachedDeviceIds to not run it twice. | ||
this.attachedDeviceIds = new Set(); | ||
this.boundAttachDevice = this.attachDevice.bind(this); | ||
this.boundDetachDevice = this.detachDevice.bind(this); | ||
// This is an undocumented property | ||
// @ts-ignore | ||
if (usb.INIT_ERROR) { | ||
throw new Error( | ||
// @ts-ignore | ||
`USB failed to initialize, libusb_init returned ${usb.INIT_ERROR}`); | ||
} | ||
} | ||
@@ -317,2 +352,7 @@ start() { | ||
usb.on('detach', this.boundDetachDevice); | ||
// ts-ignore because of a confusion between NodeJS.Timer and number | ||
// @ts-ignore | ||
this.interval = setInterval(() => { | ||
usb.getDeviceList().forEach(this.boundAttachDevice); | ||
}, POLLING_INTERVAL_MS); | ||
} | ||
@@ -322,2 +362,3 @@ stop() { | ||
usb.removeListener('detach', this.boundDetachDevice); | ||
clearInterval(this.interval); | ||
this.usbbootDevices.clear(); | ||
@@ -356,2 +397,6 @@ } | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (this.attachedDeviceIds.has(getDeviceId(device))) { | ||
return; | ||
} | ||
this.attachedDeviceIds.add(getDeviceId(device)); | ||
if (isRaspberryPiInMassStorageMode(device) && | ||
@@ -368,3 +413,3 @@ this.usbbootDevices.has(devicePortId(device))) { | ||
try { | ||
const { iface, endpoint } = initializeDevice(device); | ||
const { endpoint } = initializeDevice(device); | ||
if (device.deviceDescriptor.iSerialNumber === 0) { | ||
@@ -390,2 +435,3 @@ debug('Sending bootcode.bin', devicePortId(device)); | ||
detachDevice(device) { | ||
this.attachedDeviceIds.delete(getDeviceId(device)); | ||
if (!isUsbBootCapableUSBDevice$(device)) { | ||
@@ -453,4 +499,8 @@ return; | ||
const devicePortId = (device) => { | ||
return `${device.busNumber}-${device.portNumbers.join('.')}`; | ||
let result = `${device.busNumber}`; | ||
if (device.portNumbers !== undefined) { | ||
result += `-${device.portNumbers.join('.')}`; | ||
} | ||
return result; | ||
}; | ||
//# sourceMappingURL=index.js.map |
@@ -7,2 +7,8 @@ # Change Log | ||
## 0.2.1 - 2019-03-19 | ||
* Add noUnusedLocals and noUnusedParameters to tsconfig.json [Alexis Svinartchouk] | ||
* Poll usb.getDeviceList() every 2 seconds. [Juan Cruz Viotti] | ||
* Improve USB boot stability [Juan Cruz Viotti] | ||
## 0.2.0 - 2019-03-18 | ||
@@ -9,0 +15,0 @@ |
{ | ||
"name": "node-raspberrypi-usbboot", | ||
"version": "0.2.0", | ||
"version": "0.2.1-usbboot-stalls-23feb062025537a6758192c0eb1fc6f31916a64e", | ||
"description": "Transforms Raspberry Pi Compute Modules and Zeros to mass storage devices.", | ||
@@ -5,0 +5,0 @@ "main": "build/index.js", |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
27828366
523