@sdr.cool/rtlsdrjs
Version:
Turn your Realtek RTL2832U based device into an SDR receiver using JavaScript
153 lines (124 loc) • 3.81 kB
JavaScript
// Copyright 2018 Sandeep Mistry All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
const usb = require('usb');
function USB(device) {
this._device = device;
}
USB.prototype.open = async function() {
return new Promise((resolve) => {
this._device.open();
for (let i = 0; i < 2; i++) {
if (this._device.interfaces[i].isKernelDriverActive()) {
this._device.interfaces[i].detachKernelDriver();
}
}
resolve();
});
};
USB.prototype.selectConfiguration = async function(configuration) {
return new Promise((resolve, reject) => {
this._device.setConfiguration(configuration, (err) => {
if (err) {
return reject(err);
}
resolve();
});
});
};
USB.prototype.claimInterface = async function(iface) {
return new Promise((resolve) => {
this._device.interface(iface).claim();
this._interface = iface;
resolve();
});
};
USB.prototype.releaseInterface = async function(iface) {
return new Promise((resolve) => {
this._device.interface(iface).release((error) => {
if (error) {
return reject(error);
}
resolve();
});
});
};
USB.prototype.controlTransfer = async function(ti) {
return new Promise((resolve, reject) => {
let requestType = 0;
let lengthOrData = ti.length ? ti.length : Buffer.from(ti.data);
if (ti.requestType === 'vendor') {
requestType |= usb.LIBUSB_REQUEST_TYPE_VENDOR;
}
if (ti.recipient === 'device') {
requestType |= usb.LIBUSB_RECIPIENT_DEVICE;
}
if (ti.direction === 'out') {
requestType |= usb.LIBUSB_ENDPOINT_OUT;
} else if (ti.direction === 'in') {
requestType |= usb.LIBUSB_ENDPOINT_IN;
}
this._device.controlTransfer(requestType, ti.request, ti.value, ti.index, lengthOrData, (err, data) => {
if (err) {
return reject(err);
}
if (data) {
return resolve(Uint8Array.from(data).buffer);
}
resolve();
});
});
};
USB.prototype.bulkTransfer = async function(ti) {
return new Promise((resolve, reject) => {
this._device.interface(this._interface).endpoints[ti.endpoint - 1].transfer(ti.length, (err, data) => {
if (err) {
return reject(err);
}
resolve(data.buffer);
});
});
};
USB.prototype.close = async function() {
return new Promise((resolve) => {
this._device.close(resolve);
});
};
USB.requestDevice = async function(filters) {
return new Promise((resolve, reject) => {
for (let i = 0; i < filters.length; i++) {
const filter = filters[i];
const usbDevice = usb.findByIds(filter.vendorId, filter.productId);
if (usbDevice) {
return resolve(new USB(usbDevice));
}
}
reject(new Error('No devices found!'));
});
};
USB.getDevices = async function(filters) {
return new Promise((resolve) => {
const usbDevices = usb.getDeviceList();
const devices = [];
usbDevices.forEach((usbDevice) => {
filters.forEach((filter) => {
if (filter.vendorId === usbDevice.deviceDescriptor.idVendor &&
filter.productId === usbDevice.deviceDescriptor.idProduct) {
devices.push(new USB(usbDevice));
}
});
});
resolve(devices);
});
};
module.exports = USB;