Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

node-raspberrypi-usbboot

Package Overview
Dependencies
Maintainers
1
Versions
86
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-raspberrypi-usbboot - npm Package Compare versions

Comparing version 0.2.7 to 0.2.8-fix-device-not-detaching-4e44ad6ddf66c8d00c9611d5e85bdeccc5baa1c0

8

build/index.d.ts

@@ -0,1 +1,2 @@

/// <reference types="node" />
import { EventEmitter } from 'events';

@@ -5,7 +6,8 @@ export declare const isUsbBootCapableUSBDevice: (idVendor: number, idProduct: number) => boolean;

portId: string;
static readonly LAST_STEP: number;
static readonly LAST_STEP = 41;
private _step;
constructor(portId: string);
readonly progress: number;
step: number;
get progress(): number;
get step(): number;
set step(step: number);
}

@@ -12,0 +14,0 @@ export declare class UsbbootScanner extends EventEmitter {

@@ -6,11 +6,4 @@ "use strict";

*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UsbbootScanner = exports.UsbbootDevice = exports.isUsbBootCapableUSBDevice = void 0;
// tslint:disable:no-bitwise

@@ -26,3 +19,3 @@ const usb = require("@balena.io/usb");

const POLLING_INTERVAL_MS = 2000;
const TRANSFER_BLOCK_SIZE = Math.pow(1024, 2);
const TRANSFER_BLOCK_SIZE = 1024 ** 2;
// The equivalent of a NULL buffer, given that node-usb complains

@@ -145,6 +138,6 @@ // if the data argument is not an instance of Buffer

*/
const performControlTransfer = (device, bmRequestType, bRequest, wValue, wIndex, dataOrLength) => __awaiter(this, void 0, void 0, function* () {
const performControlTransfer = async (device, bmRequestType, bRequest, wValue, wIndex, dataOrLength) => {
const previousTimeout = device.timeout;
device.timeout = USB_CONTROL_TRANSFER_TIMEOUT_MS;
const result = yield bluebird_1.fromCallback((callback) => {
const result = await bluebird_1.fromCallback((callback) => {
device.controlTransfer(bmRequestType, bRequest, wValue, wIndex, dataOrLength, callback);

@@ -154,3 +147,3 @@ });

return result;
});
};
exports.isUsbBootCapableUSBDevice = (idVendor, idProduct) => {

@@ -193,5 +186,5 @@ return (idVendor === USB_VENDOR_ID_BROADCOM_CORPORATION &&

};
const sendSize = (device, size) => __awaiter(this, void 0, void 0, function* () {
yield performControlTransfer(device, usb.LIBUSB_REQUEST_TYPE_VENDOR, USB_REQUEST_CODE_GET_STATUS, size & USBBOOT_MESSAGE_MAX_BUFFER_LENGTH, size >> CONTROL_TRANSFER_INDEX_RIGHT_BIT_SHIFT, NULL_BUFFER);
});
const sendSize = async (device, size) => {
await performControlTransfer(device, usb.LIBUSB_REQUEST_TYPE_VENDOR, USB_REQUEST_CODE_GET_STATUS, size & USBBOOT_MESSAGE_MAX_BUFFER_LENGTH, size >> CONTROL_TRANSFER_INDEX_RIGHT_BIT_SHIFT, NULL_BUFFER);
};
function* chunks(buffer, size) {

@@ -202,3 +195,3 @@ for (let start = 0; start < buffer.length; start += size) {

}
const transfer = (endpoint, chunk) => __awaiter(this, void 0, void 0, function* () {
const transfer = async (endpoint, chunk) => {
endpoint.timeout = USB_BULK_TRANSFER_TIMEOUT_MS;

@@ -210,3 +203,3 @@ for (let tries = 0; tries < 3; tries++) {

try {
yield bluebird_1.fromCallback(callback => {
await bluebird_1.fromCallback((callback) => {
endpoint.transfer(chunk, callback);

@@ -223,22 +216,22 @@ });

}
});
const epWrite = (buffer, device, endpoint) => __awaiter(this, void 0, void 0, function* () {
};
const epWrite = async (buffer, device, endpoint) => {
debug('Sending buffer size', buffer.length);
yield sendSize(device, buffer.length);
await sendSize(device, buffer.length);
if (buffer.length > 0) {
for (const chunk of chunks(buffer, TRANSFER_BLOCK_SIZE)) {
debug('Sending chunk of size', chunk.length);
yield transfer(endpoint, chunk);
await transfer(endpoint, chunk);
}
}
});
const epRead = (device, bytesToRead) => __awaiter(this, void 0, void 0, function* () {
return yield performControlTransfer(device, usb.LIBUSB_REQUEST_TYPE_VENDOR | usb.LIBUSB_ENDPOINT_IN, USB_REQUEST_CODE_GET_STATUS, bytesToRead & USBBOOT_MESSAGE_MAX_BUFFER_LENGTH, bytesToRead >> CONTROL_TRANSFER_INDEX_RIGHT_BIT_SHIFT, bytesToRead);
});
};
const epRead = async (device, bytesToRead) => {
return await performControlTransfer(device, usb.LIBUSB_REQUEST_TYPE_VENDOR | usb.LIBUSB_ENDPOINT_IN, USB_REQUEST_CODE_GET_STATUS, bytesToRead & USBBOOT_MESSAGE_MAX_BUFFER_LENGTH, bytesToRead >> CONTROL_TRANSFER_INDEX_RIGHT_BIT_SHIFT, bytesToRead);
};
const getDeviceId = (device) => {
return `${device.busNumber}:${device.deviceAddress}`;
};
const safeReadFile = (filename) => __awaiter(this, void 0, void 0, function* () {
const safeReadFile = async (filename) => {
try {
return yield readFile(Path.join(__dirname, '..', 'blobs', filename));
return await readFile(Path.join(__dirname, '..', 'blobs', filename));
}

@@ -248,7 +241,7 @@ catch (e) {

}
});
const getFileBuffer = (filename) => __awaiter(this, void 0, void 0, function* () {
let buffer = yield safeReadFile(filename);
};
const getFileBuffer = async (filename) => {
let buffer = await safeReadFile(filename);
if (buffer === undefined) {
buffer = yield safeReadFile(Path.join('raspberrypi', filename));
buffer = await safeReadFile(Path.join('raspberrypi', filename));
}

@@ -259,3 +252,3 @@ if (buffer === undefined) {

return buffer;
});
};
/**

@@ -287,4 +280,4 @@ * @summary Create a boot message buffer

};
const secondStageBoot = (device, endpoint) => __awaiter(this, void 0, void 0, function* () {
const bootcodeBuffer = yield getFileBuffer('bootcode.bin');
const secondStageBoot = async (device, endpoint) => {
const bootcodeBuffer = await getFileBuffer('bootcode.bin');
if (bootcodeBuffer === undefined) {

@@ -294,7 +287,7 @@ throw new Error("Can't find bootcode.bin");

const bootMessage = createBootMessageBuffer(bootcodeBuffer.length);
yield epWrite(bootMessage, device, endpoint);
await epWrite(bootMessage, device, endpoint);
debug(`Writing ${bootMessage.length} bytes`, devicePortId(device));
yield epWrite(bootcodeBuffer, device, endpoint);
await epWrite(bootcodeBuffer, device, endpoint);
// raspberrypi's sample code has a sleep(1) here, but it looks like it isn't required.
const data = yield epRead(device, RETURN_CODE_LENGTH);
const data = await epRead(device, RETURN_CODE_LENGTH);
const returnCode = data.readInt32LE(0);

@@ -304,3 +297,3 @@ if (returnCode !== RETURN_CODE_SUCCESS) {

}
});
};
class UsbbootDevice extends events_1.EventEmitter {

@@ -323,2 +316,3 @@ constructor(portId) {

}
exports.UsbbootDevice = UsbbootDevice;
// LAST_STEP is hardcoded here as it is depends on the bootcode.bin file we send to the pi.

@@ -332,3 +326,2 @@ // List of steps:

UsbbootDevice.LAST_STEP = 41;
exports.UsbbootDevice = UsbbootDevice;
class UsbbootScanner extends events_1.EventEmitter {

@@ -397,38 +390,36 @@ constructor() {

}
attachDevice(device) {
return __awaiter(this, void 0, void 0, function* () {
if (this.attachedDeviceIds.has(getDeviceId(device))) {
return;
async attachDevice(device) {
if (this.attachedDeviceIds.has(getDeviceId(device))) {
return;
}
this.attachedDeviceIds.add(getDeviceId(device));
if (isRaspberryPiInMassStorageMode(device) &&
this.usbbootDevices.has(devicePortId(device))) {
this.step(device, 41);
return;
}
if (!isUsbBootCapableUSBDevice$(device)) {
return;
}
debug('Found serial number', device.deviceDescriptor.iSerialNumber);
debug('port id', devicePortId(device));
try {
const { endpoint } = initializeDevice(device);
if (device.deviceDescriptor.iSerialNumber === 0) {
debug('Sending bootcode.bin', devicePortId(device));
this.step(device, 0);
await secondStageBoot(device, endpoint);
// The device will now detach and reattach with iSerialNumber 1.
// This takes approximately 1.5 seconds
}
this.attachedDeviceIds.add(getDeviceId(device));
if (isRaspberryPiInMassStorageMode(device) &&
this.usbbootDevices.has(devicePortId(device))) {
this.step(device, 41);
return;
else {
debug('Second stage boot server', devicePortId(device));
await this.fileServer(device, endpoint, 2);
}
if (!isUsbBootCapableUSBDevice$(device)) {
return;
}
debug('Found serial number', device.deviceDescriptor.iSerialNumber);
debug('port id', devicePortId(device));
try {
const { endpoint } = initializeDevice(device);
if (device.deviceDescriptor.iSerialNumber === 0) {
debug('Sending bootcode.bin', devicePortId(device));
this.step(device, 0);
yield secondStageBoot(device, endpoint);
// The device will now detach and reattach with iSerialNumber 1.
// This takes approximately 1.5 seconds
}
else {
debug('Second stage boot server', devicePortId(device));
yield this.fileServer(device, endpoint, 2);
}
device.close();
}
catch (error) {
debug('error', error, devicePortId(device));
this.remove(device);
}
});
device.close();
}
catch (error) {
debug('error', error, devicePortId(device));
this.remove(device);
}
}

@@ -453,44 +444,51 @@ detachDevice(device) {

}
fileServer(device, endpoint, step) {
return __awaiter(this, void 0, void 0, function* () {
while (true) {
this.step(device, step);
step += 1;
let data;
try {
data = yield epRead(device, FILE_MESSAGE_SIZE);
async fileServer(device, endpoint, step) {
while (true) {
this.step(device, step);
step += 1;
let data;
try {
data = await epRead(device, FILE_MESSAGE_SIZE);
}
catch (error) {
if (error.message === 'LIBUSB_ERROR_NO_DEVICE' ||
error.message === 'LIBUSB_ERROR_IO') {
// Drop out if the device goes away
break;
}
catch (error) {
if (error.message === 'LIBUSB_ERROR_NO_DEVICE' ||
error.message === 'LIBUSB_ERROR_IO') {
// Drop out if the device goes away
break;
}
yield bluebird_1.delay(READ_ERROR_DELAY);
continue;
await bluebird_1.delay(READ_ERROR_DELAY);
continue;
}
const message = parseFileMessageBuffer(data);
debug('Received message', FileMessageCommand[message.command], message.filename, devicePortId(device));
if (message.command === FileMessageCommand.GetFileSize ||
message.command === FileMessageCommand.ReadFile) {
const buffer = await getFileBuffer(message.filename);
if (buffer === undefined) {
debug(`Couldn't find ${message.filename}`, devicePortId(device));
await sendSize(device, 0);
}
const message = parseFileMessageBuffer(data);
debug('Received message', FileMessageCommand[message.command], message.filename, devicePortId(device));
if (message.command === FileMessageCommand.GetFileSize ||
message.command === FileMessageCommand.ReadFile) {
const buffer = yield getFileBuffer(message.filename);
if (buffer === undefined) {
debug(`Couldn't find ${message.filename}`, devicePortId(device));
yield sendSize(device, 0);
else {
if (message.command === FileMessageCommand.GetFileSize) {
await sendSize(device, buffer.length);
}
else {
if (message.command === FileMessageCommand.GetFileSize) {
yield sendSize(device, buffer.length);
}
else {
yield epWrite(buffer, device, endpoint);
}
await epWrite(buffer, device, endpoint);
}
}
else if (message.command === FileMessageCommand.Done) {
break;
}
}
debug('File server done', devicePortId(device));
});
else if (message.command === FileMessageCommand.Done) {
break;
}
}
debug('File server done', devicePortId(device));
// On some computers, the rpi won't detach at this point.
// If you try communicating with it, it will error, detach and reattach as expected.
await bluebird_1.delay(2000);
try {
device.open();
}
catch (_a) {
// We expect LIBUSB_ERROR_IO here
}
}

@@ -497,0 +495,0 @@ }

@@ -7,2 +7,9 @@ # Change Log

# v0.2.8
## (2020-06-11)
* Update dependencies, target es2018 [Alexis Svinartchouk]
* Update resin-lint to @balena/lint [Alexis Svinartchouk]
* Fix fin not detaching after receiving files on some computers [Alexis Svinartchouk]
## 0.2.7 - 2019-10-15

@@ -9,0 +16,0 @@

{
"name": "node-raspberrypi-usbboot",
"version": "0.2.7",
"version": "0.2.8-fix-device-not-detaching-4e44ad6ddf66c8d00c9611d5e85bdeccc5baa1c0",
"description": "Transforms Raspberry Pi Compute Modules and Zeros to mass storage devices.",

@@ -8,4 +8,4 @@ "main": "build/index.js",

"scripts": {
"prettier": "prettier --config ./node_modules/resin-lint/config/.prettierrc --write \"lib/**/*.ts\"",
"lint": "resin-lint --typescript lib/*.ts",
"prettier": "balena-lint --fix --typescript lib/*.ts",
"lint": "balena-lint --typescript lib/*.ts",
"build": "npm run lint && rimraf build && tsc",

@@ -30,14 +30,15 @@ "prepublish": "npm run build"

"@balena.io/usb": "^1.3.12",
"@types/node": "^6.0.112",
"@types/usb": "^1.5.1",
"debug": "^3.1.0"
"bluebird": "^3.7.2",
"debug": "^4.1.1"
},
"devDependencies": {
"@types/bluebird": "^3.5.20",
"@types/debug": "0.0.30",
"resin-lint": "^3.0.1",
"rimraf": "^2.6.2",
"ts-node": "^6.0.3",
"typescript": "^2.9.1"
"@balena/lint": "^5.1.0",
"@types/bluebird": "^3.5.32",
"@types/debug": "^4.1.5",
"@types/node": "^8.10.61",
"@types/usb": "^1.5.1",
"rimraf": "^3.0.2",
"ts-node": "^8.10.2",
"typescript": "^3.9.5"
}
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc