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

@betaflight/msp

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@betaflight/msp - npm Package Compare versions

Comparing version 0.3.0 to 0.4.0

21

CHANGELOG.md

@@ -6,2 +6,23 @@ # Change Log

# [0.4.0](https://github.com/freshollie/fresh-configurator/compare/@betaflight/msp@0.3.0...@betaflight/msp@0.4.0) (2021-11-11)
### Bug Fixes
* **msp:** improved code ([e824965](https://github.com/freshollie/fresh-configurator/commit/e82496550ec86ed684dc90c119757afbfabea177))
### Features
* **api:** added mixer config api ([50b0c19](https://github.com/freshollie/fresh-configurator/commit/50b0c1923d5f125d7d4359228853448c9b1c04c5))
* **api:** include info in ports api ([5478100](https://github.com/freshollie/fresh-configurator/commit/5478100e46a23af1ce991ce2e24b10de4cf020e7))
* **api:** provide baudRate for connection ([c27a9d0](https://github.com/freshollie/fresh-configurator/commit/c27a9d0ef8fa4265075ea206253003e4db41132a))
* **api:** start writing blackbox api ([bbd3926](https://github.com/freshollie/fresh-configurator/commit/bbd39266348b26610898dad304b1388a1304639f))
* **configurator:** use web serial when run in browser ([#61](https://github.com/freshollie/fresh-configurator/issues/61)) ([9e88ec0](https://github.com/freshollie/fresh-configurator/commit/9e88ec04e4dea8d8686d273357545cb586060901))
* **msp:** allow responses to be checked for match ([88970a1](https://github.com/freshollie/fresh-configurator/commit/88970a12b7fefdca3d0d4af754997da3fb4c589c))
# [0.3.0](https://github.com/freshollie/fresh-configurator/tree/master/packages/msp/compare/@betaflight/msp@0.2.0...@betaflight/msp@0.3.0) (2020-06-05)

@@ -8,0 +29,0 @@

9

dist/cjs/connection.d.ts

@@ -9,6 +9,6 @@ /**

*/
/// <reference types="serialport" />
import SerialPort from "@serialport/stream";
import MspDataView from "./dataview";
import { MspCommand, OpenConnectionFunction } from "./types";
import { MspCommand, OpenConnectionFunction, PortInfo } from "./types";
export declare const initialiseSerialBackend: (bindings?: typeof import("serialport").BaseBinding | undefined) => Promise<void>;
/**

@@ -19,4 +19,4 @@ * Execute the given MspCommand on the given port.

*/
export declare const execute: (port: string, { code, data, timeout }: MspCommand) => Promise<MspDataView>;
export declare const ports: () => Promise<string[]>;
export declare const execute: (port: string, { code, data, timeout, match }: MspCommand) => Promise<MspDataView>;
export declare const ports: () => Promise<PortInfo[]>;
/**

@@ -38,2 +38,3 @@ * Close the given port

export declare const apiVersion: (port: string) => string;
export declare const baudRate: (port: string) => number;
/**

@@ -40,0 +41,0 @@ * Private, used for testing

@@ -10,2 +10,21 @@ "use strict";

*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -15,2 +34,3 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

Object.defineProperty(exports, "__esModule", { value: true });
exports.reset = exports.raw = exports.baudRate = exports.apiVersion = exports.packetErrors = exports.bytesWritten = exports.bytesRead = exports.isOpen = exports.connections = exports.open = exports.close = exports.ports = exports.execute = exports.initialiseSerialBackend = void 0;
const stream_1 = __importDefault(require("@serialport/stream"));

@@ -24,8 +44,10 @@ const debug_1 = __importDefault(require("debug"));

// at import time
const initialiseBindings = () => {
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires, global-require
const Binding = require("@serialport/bindings");
const initialiseSerialBackend = async (bindings) => {
const { default: Binding } = !bindings
? await Promise.resolve().then(() => __importStar(require("@serialport/bindings")))
: { default: bindings };
stream_1.default.Binding = Binding;
};
const log = debug_1.default("connection");
exports.initialiseSerialBackend = initialiseSerialBackend;
const log = (0, debug_1.default)("msp:connection");
const connectionsMap = {};

@@ -37,3 +59,3 @@ /**

*/
exports.execute = async (port, { code, data, timeout = 2500 }) => {
const execute = async (port, { code, data, timeout = 100, match }) => {
const connection = connectionsMap[port];

@@ -46,5 +68,5 @@ if (!connection) {

const request = code > 254
? encoders_1.encodeMessageV2(code, sendData)
: encoders_1.encodeMessageV1(code, sendData);
const requestKey = request.toString("utf-8");
? (0, encoders_1.encodeMessageV2)(code, sendData)
: (0, encoders_1.encodeMessageV1)(code, sendData);
const requestKey = request.toString("base64");
let mspRequest = requests[requestKey];

@@ -54,5 +76,4 @@ // Prevent FC lockup by checking if this request is currently being performed

if (mspRequest === undefined) {
let rejector;
let onError;
const response = new Promise((resolve, reject) => {
rejector = reject;
// Throw an error if timeout is reached

@@ -65,2 +86,7 @@ const timeoutId = setTimeout(() => {

}, timeout);
onError = (e) => {
reject(e);
clearTimeout(timeoutId);
delete requests[requestKey];
};
function onData(message) {

@@ -72,3 +98,6 @@ if (message.code === code) {

}
log(`${request.toJSON().data} response: ${Buffer.from(message.data).toJSON().data}, byteLength: ${message.data.byteLength}`);
if (match && !match(new dataview_1.default(message.data))) {
return;
}
log(`request: ${request.toJSON().data}, response: ${Buffer.from(message.data).toJSON().data}, byteLength: ${message.data.byteLength}`);
delete requests[requestKey];

@@ -84,8 +113,15 @@ clearTimeout(timeoutId);

response,
close: () => rejector === null || rejector === void 0 ? void 0 : rejector(new Error("Connection closed")),
close: () => onError(new Error("Connection closed")),
};
requests[requestKey] = mspRequest;
log(`Writing ${request.toJSON().data} to ${port}`);
serial.write(request);
connection.bytesWritten += Buffer.byteLength(request);
serial.write(request, (error) => {
if (error) {
log(`Error writing to serial port ${error.message}, rejecting execution`);
onError(new Error(`Could not write to serial port: ${error.message}`));
}
else {
connection.bytesWritten += Buffer.byteLength(request);
}
});
}

@@ -96,12 +132,15 @@ // make every DataView unique to each request, even though

};
exports.ports = async () => {
exports.execute = execute;
const ports = async () => {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!stream_1.default.Binding) {
initialiseBindings();
await (0, exports.initialiseSerialBackend)();
}
return stream_1.default.list().then((data) => data.map(({ path }) => path));
return stream_1.default.list();
};
exports.ports = ports;
/**
* Close the given port
*/
exports.close = async (port) => {
const close = async (port) => {
const connection = connectionsMap[port];

@@ -118,6 +157,7 @@ if (!connection) {

Object.values(connection.requests).forEach((request) => {
request === null || request === void 0 ? void 0 : request.close();
request.close();
});
await closePromise;
};
exports.close = close;
/**

@@ -128,3 +168,3 @@ * Open a serial connection on the given

*/
exports.open = async (port, options, onClose) => {
const open = async (port, options, onClose) => {
if (connectionsMap[port]) {

@@ -141,6 +181,11 @@ throw new Error(`${port} is already open`);

}
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!stream_1.default.Binding) {
initialiseBindings();
await (0, exports.initialiseSerialBackend)();
}
const serial = new stream_1.default(port, Object.assign(Object.assign({ baudRate: 115200 }, connectionOptions), { autoOpen: false }));
const serial = new stream_1.default(port, {
baudRate: 115200,
...connectionOptions,
autoOpen: false,
});
await new Promise((resolve, reject) => {

@@ -174,3 +219,3 @@ serial.open((err) => {

try {
const response = await exports.execute(port, { code: 1 });
const response = await (0, exports.execute)(port, { code: 1 });
connection.mspInfo = {

@@ -184,3 +229,3 @@ mspProtocolVersion: response.readU8(),

log(`failed to read MSP info from ${port}, failed to open`);
await exports.close(port);
await (0, exports.close)(port);
throw new Error(`Could not read MSP version from ${port}`);

@@ -193,5 +238,5 @@ }

const disconnectMonitor = setInterval(async () => {
const list = await exports.ports();
if (!list.includes(port) && serial.isOpen) {
exports.close(port);
const list = await (0, exports.ports)();
if (!list.find(({ path }) => port === path) && serial.isOpen) {
(0, exports.close)(port);
}

@@ -203,4 +248,4 @@ }, 250);

});
serial.on("error", () => {
log(`${port} on error received`);
serial.on("error", (e) => {
log(`${port} on error received: ${e === null || e === void 0 ? void 0 : e.message}`);
// Don't trigger close if this serial port is already

@@ -210,3 +255,3 @@ // closed, as it means that the closing

if (serial.isOpen) {
exports.close(port);
(0, exports.close)(port);
}

@@ -217,3 +262,3 @@ });

clearInterval(disconnectMonitor);
await exports.close(port);
await (0, exports.close)(port);
onCloseCallback === null || onCloseCallback === void 0 ? void 0 : onCloseCallback();

@@ -225,18 +270,35 @@ });

};
exports.connections = () => Object.keys(connectionsMap);
exports.isOpen = (port) => !!connectionsMap[port];
exports.bytesRead = (port) => { var _a, _b; return (_b = (_a = connectionsMap[port]) === null || _a === void 0 ? void 0 : _a.bytesRead) !== null && _b !== void 0 ? _b : 0; };
exports.bytesWritten = (port) => { var _a, _b; return (_b = (_a = connectionsMap[port]) === null || _a === void 0 ? void 0 : _a.bytesWritten) !== null && _b !== void 0 ? _b : 0; };
exports.packetErrors = (port) => { var _a, _b; return (_b = (_a = connectionsMap[port]) === null || _a === void 0 ? void 0 : _a.packetErrors) !== null && _b !== void 0 ? _b : 0; };
exports.apiVersion = (port) => { var _a, _b; return (_b = (_a = connectionsMap[port]) === null || _a === void 0 ? void 0 : _a.mspInfo.apiVersion) !== null && _b !== void 0 ? _b : "0.0.0"; };
exports.open = open;
const connections = () => Object.keys(connectionsMap);
exports.connections = connections;
const isOpen = (port) => !!connectionsMap[port];
exports.isOpen = isOpen;
const bytesRead = (port) => { var _a, _b; return (_b = (_a = connectionsMap[port]) === null || _a === void 0 ? void 0 : _a.bytesRead) !== null && _b !== void 0 ? _b : 0; };
exports.bytesRead = bytesRead;
const bytesWritten = (port) => { var _a, _b; return (_b = (_a = connectionsMap[port]) === null || _a === void 0 ? void 0 : _a.bytesWritten) !== null && _b !== void 0 ? _b : 0; };
exports.bytesWritten = bytesWritten;
const packetErrors = (port) => { var _a, _b; return (_b = (_a = connectionsMap[port]) === null || _a === void 0 ? void 0 : _a.packetErrors) !== null && _b !== void 0 ? _b : 0; };
exports.packetErrors = packetErrors;
const apiVersion = (port) => { var _a, _b; return (_b = (_a = connectionsMap[port]) === null || _a === void 0 ? void 0 : _a.mspInfo.apiVersion) !== null && _b !== void 0 ? _b : "0.0.0"; };
exports.apiVersion = apiVersion;
const baudRate = (port) => {
const connection = connectionsMap[port];
if (!connection) {
throw new Error("Port is not open");
}
return connection.serial.baudRate;
};
exports.baudRate = baudRate;
/**
* Private, used for testing
*/
exports.raw = (port) => { var _a; return (_a = connectionsMap[port]) === null || _a === void 0 ? void 0 : _a.serial; };
const raw = (port) => { var _a; return (_a = connectionsMap[port]) === null || _a === void 0 ? void 0 : _a.serial; };
exports.raw = raw;
/**
* Private, used for testing
*/
exports.reset = async () => {
await Promise.all(Object.keys(connectionsMap).map((port) => exports.close(port)));
const reset = async () => {
await Promise.all(Object.keys(connectionsMap).map((port) => (0, exports.close)(port)));
};
exports.reset = reset;
//# sourceMappingURL=connection.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.encodeMessageV2 = exports.encodeMessageV1 = void 0;
const utils_1 = require("./utils");
exports.encodeMessageV1 = (code, data) => {
const encodeMessageV1 = (code, data) => {
let bufferOut;

@@ -36,3 +37,4 @@ // always reserve 6 bytes for protocol overhead !

};
exports.encodeMessageV2 = (code, data) => {
exports.encodeMessageV1 = encodeMessageV1;
const encodeMessageV2 = (code, data) => {
const dataLength = data ? data.length : 0;

@@ -54,5 +56,6 @@ // 9 bytes for protocol overhead

}
bufView[bufferSize - 1] = utils_1.crc8DvbS2Data(bufView, 3, bufferSize - 1);
bufView[bufferSize - 1] = (0, utils_1.crc8DvbS2Data)(bufView, 3, bufferSize - 1);
return Buffer.from(bufferOut);
};
exports.encodeMessageV2 = encodeMessageV2;
//# sourceMappingURL=encoders.js.map

@@ -1,3 +0,3 @@

export { ports, connections, isOpen, open, close, bytesRead, bytesWritten, packetErrors, apiVersion, execute, } from "./connection";
export { ports, connections, isOpen, open, close, bytesRead, bytesWritten, packetErrors, apiVersion, execute, baudRate, initialiseSerialBackend, } from "./connection";
export { default as WriteBuffer } from "./writebuffer";
export { default as MspDataView } from "./dataview";
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MspDataView = exports.WriteBuffer = exports.initialiseSerialBackend = exports.baudRate = exports.execute = exports.apiVersion = exports.packetErrors = exports.bytesWritten = exports.bytesRead = exports.close = exports.open = exports.isOpen = exports.connections = exports.ports = void 0;
/* eslint-disable import/first */
var connection_1 = require("./connection");
exports.ports = connection_1.ports;
exports.connections = connection_1.connections;
exports.isOpen = connection_1.isOpen;
exports.open = connection_1.open;
exports.close = connection_1.close;
exports.bytesRead = connection_1.bytesRead;
exports.bytesWritten = connection_1.bytesWritten;
exports.packetErrors = connection_1.packetErrors;
exports.apiVersion = connection_1.apiVersion;
exports.execute = connection_1.execute;
Object.defineProperty(exports, "ports", { enumerable: true, get: function () { return connection_1.ports; } });
Object.defineProperty(exports, "connections", { enumerable: true, get: function () { return connection_1.connections; } });
Object.defineProperty(exports, "isOpen", { enumerable: true, get: function () { return connection_1.isOpen; } });
Object.defineProperty(exports, "open", { enumerable: true, get: function () { return connection_1.open; } });
Object.defineProperty(exports, "close", { enumerable: true, get: function () { return connection_1.close; } });
Object.defineProperty(exports, "bytesRead", { enumerable: true, get: function () { return connection_1.bytesRead; } });
Object.defineProperty(exports, "bytesWritten", { enumerable: true, get: function () { return connection_1.bytesWritten; } });
Object.defineProperty(exports, "packetErrors", { enumerable: true, get: function () { return connection_1.packetErrors; } });
Object.defineProperty(exports, "apiVersion", { enumerable: true, get: function () { return connection_1.apiVersion; } });
Object.defineProperty(exports, "execute", { enumerable: true, get: function () { return connection_1.execute; } });
Object.defineProperty(exports, "baudRate", { enumerable: true, get: function () { return connection_1.baudRate; } });
Object.defineProperty(exports, "initialiseSerialBackend", { enumerable: true, get: function () { return connection_1.initialiseSerialBackend; } });
var writebuffer_1 = require("./writebuffer");
exports.WriteBuffer = writebuffer_1.default;
Object.defineProperty(exports, "WriteBuffer", { enumerable: true, get: function () { return __importDefault(writebuffer_1).default; } });
var dataview_1 = require("./dataview");
exports.MspDataView = dataview_1.default;
Object.defineProperty(exports, "MspDataView", { enumerable: true, get: function () { return __importDefault(dataview_1).default; } });
//# sourceMappingURL=index.js.map

@@ -18,7 +18,8 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.MspParser = void 0;
const stream_1 = require("stream");
const debug_1 = __importDefault(require("debug"));
const utils_1 = require("./utils");
const log = debug_1.default("parser");
const SYMBOLS = {
const log = (0, debug_1.default)("msp:parser");
const Symbols = {
BEGIN: "$".charCodeAt(0),

@@ -31,29 +32,29 @@ PROTO_V1: "M".charCodeAt(0),

};
var CONSTANTS;
(function (CONSTANTS) {
CONSTANTS[CONSTANTS["PROTOCOL_V1"] = 1] = "PROTOCOL_V1";
CONSTANTS[CONSTANTS["PROTOCOL_V2"] = 2] = "PROTOCOL_V2";
CONSTANTS[CONSTANTS["JUMBO_FRAME_MIN_SIZE"] = 255] = "JUMBO_FRAME_MIN_SIZE";
})(CONSTANTS || (CONSTANTS = {}));
var DECODER_STATES;
(function (DECODER_STATES) {
DECODER_STATES[DECODER_STATES["IDLE"] = 0] = "IDLE";
DECODER_STATES[DECODER_STATES["PROTO_IDENTIFIER"] = 1] = "PROTO_IDENTIFIER";
DECODER_STATES[DECODER_STATES["DIRECTION_V1"] = 2] = "DIRECTION_V1";
DECODER_STATES[DECODER_STATES["DIRECTION_V2"] = 3] = "DIRECTION_V2";
DECODER_STATES[DECODER_STATES["FLAG_V2"] = 4] = "FLAG_V2";
DECODER_STATES[DECODER_STATES["PAYLOAD_LENGTH_V1"] = 5] = "PAYLOAD_LENGTH_V1";
DECODER_STATES[DECODER_STATES["PAYLOAD_LENGTH_JUMBO_LOW"] = 6] = "PAYLOAD_LENGTH_JUMBO_LOW";
DECODER_STATES[DECODER_STATES["PAYLOAD_LENGTH_JUMBO_HIGH"] = 7] = "PAYLOAD_LENGTH_JUMBO_HIGH";
DECODER_STATES[DECODER_STATES["PAYLOAD_LENGTH_V2_LOW"] = 8] = "PAYLOAD_LENGTH_V2_LOW";
DECODER_STATES[DECODER_STATES["PAYLOAD_LENGTH_V2_HIGH"] = 9] = "PAYLOAD_LENGTH_V2_HIGH";
DECODER_STATES[DECODER_STATES["CODE_V1"] = 10] = "CODE_V1";
DECODER_STATES[DECODER_STATES["CODE_JUMBO_V1"] = 11] = "CODE_JUMBO_V1";
DECODER_STATES[DECODER_STATES["CODE_V2_LOW"] = 12] = "CODE_V2_LOW";
DECODER_STATES[DECODER_STATES["CODE_V2_HIGH"] = 13] = "CODE_V2_HIGH";
DECODER_STATES[DECODER_STATES["PAYLOAD_V1"] = 14] = "PAYLOAD_V1";
DECODER_STATES[DECODER_STATES["PAYLOAD_V2"] = 15] = "PAYLOAD_V2";
DECODER_STATES[DECODER_STATES["CHECKSUM_V1"] = 16] = "CHECKSUM_V1";
DECODER_STATES[DECODER_STATES["CHECKSUM_V2"] = 17] = "CHECKSUM_V2";
})(DECODER_STATES || (DECODER_STATES = {}));
var Constants;
(function (Constants) {
Constants[Constants["PROTOCOL_V1"] = 1] = "PROTOCOL_V1";
Constants[Constants["PROTOCOL_V2"] = 2] = "PROTOCOL_V2";
Constants[Constants["JUMBO_FRAME_MIN_SIZE"] = 255] = "JUMBO_FRAME_MIN_SIZE";
})(Constants || (Constants = {}));
var DecoderStates;
(function (DecoderStates) {
DecoderStates[DecoderStates["IDLE"] = 0] = "IDLE";
DecoderStates[DecoderStates["PROTO_IDENTIFIER"] = 1] = "PROTO_IDENTIFIER";
DecoderStates[DecoderStates["DIRECTION_V1"] = 2] = "DIRECTION_V1";
DecoderStates[DecoderStates["DIRECTION_V2"] = 3] = "DIRECTION_V2";
DecoderStates[DecoderStates["FLAG_V2"] = 4] = "FLAG_V2";
DecoderStates[DecoderStates["PAYLOAD_LENGTH_V1"] = 5] = "PAYLOAD_LENGTH_V1";
DecoderStates[DecoderStates["PAYLOAD_LENGTH_JUMBO_LOW"] = 6] = "PAYLOAD_LENGTH_JUMBO_LOW";
DecoderStates[DecoderStates["PAYLOAD_LENGTH_JUMBO_HIGH"] = 7] = "PAYLOAD_LENGTH_JUMBO_HIGH";
DecoderStates[DecoderStates["PAYLOAD_LENGTH_V2_LOW"] = 8] = "PAYLOAD_LENGTH_V2_LOW";
DecoderStates[DecoderStates["PAYLOAD_LENGTH_V2_HIGH"] = 9] = "PAYLOAD_LENGTH_V2_HIGH";
DecoderStates[DecoderStates["CODE_V1"] = 10] = "CODE_V1";
DecoderStates[DecoderStates["CODE_JUMBO_V1"] = 11] = "CODE_JUMBO_V1";
DecoderStates[DecoderStates["CODE_V2_LOW"] = 12] = "CODE_V2_LOW";
DecoderStates[DecoderStates["CODE_V2_HIGH"] = 13] = "CODE_V2_HIGH";
DecoderStates[DecoderStates["PAYLOAD_V1"] = 14] = "PAYLOAD_V1";
DecoderStates[DecoderStates["PAYLOAD_V2"] = 15] = "PAYLOAD_V2";
DecoderStates[DecoderStates["CHECKSUM_V1"] = 16] = "CHECKSUM_V1";
DecoderStates[DecoderStates["CHECKSUM_V2"] = 17] = "CHECKSUM_V2";
})(DecoderStates || (DecoderStates = {}));
class MspParser extends stream_1.Transform {

@@ -77,33 +78,33 @@ constructor() {

const data = new Uint8Array(chunk);
for (let i = 0; i < data.length; i += 1) {
data.forEach((byte) => {
switch (this.state) {
case DECODER_STATES.IDLE: // sync char 1
if (data[i] === SYMBOLS.BEGIN) {
this.state = DECODER_STATES.PROTO_IDENTIFIER;
case DecoderStates.IDLE: // sync char 1
if (byte === Symbols.BEGIN) {
this.state = DecoderStates.PROTO_IDENTIFIER;
}
break;
case DECODER_STATES.PROTO_IDENTIFIER: // sync char 2
switch (data[i]) {
case SYMBOLS.PROTO_V1:
this.state = DECODER_STATES.DIRECTION_V1;
case DecoderStates.PROTO_IDENTIFIER: // sync char 2
switch (byte) {
case Symbols.PROTO_V1:
this.state = DecoderStates.DIRECTION_V1;
break;
case SYMBOLS.PROTO_V2:
this.state = DECODER_STATES.DIRECTION_V2;
case Symbols.PROTO_V2:
this.state = DecoderStates.DIRECTION_V2;
break;
default:
log(`Unknown protocol char ${String.fromCharCode(data[i])}`);
this.state = DECODER_STATES.IDLE;
log(`Unknown protocol char ${String.fromCharCode(byte)}`);
this.state = DecoderStates.IDLE;
}
break;
case DECODER_STATES.DIRECTION_V1: // direction (should be >)
case DECODER_STATES.DIRECTION_V2:
case DecoderStates.DIRECTION_V1: // direction (should be >)
case DecoderStates.DIRECTION_V2:
this.unsupported = 0;
switch (data[i]) {
case SYMBOLS.FROM_MWC:
switch (byte) {
case Symbols.FROM_MWC:
this.messageDirection = 1;
break;
case SYMBOLS.TO_MWC:
case Symbols.TO_MWC:
this.messageDirection = 0;
break;
case SYMBOLS.UNSUPPORTED:
case Symbols.UNSUPPORTED:
this.unsupported = 1;

@@ -114,42 +115,42 @@ break;

this.state =
this.state === DECODER_STATES.DIRECTION_V1
? DECODER_STATES.PAYLOAD_LENGTH_V1
: DECODER_STATES.FLAG_V2;
this.state === DecoderStates.DIRECTION_V1
? DecoderStates.PAYLOAD_LENGTH_V1
: DecoderStates.FLAG_V2;
break;
case DECODER_STATES.FLAG_V2:
case DecoderStates.FLAG_V2:
// Ignored for now
this.state = DECODER_STATES.CODE_V2_LOW;
this.state = DecoderStates.CODE_V2_LOW;
break;
case DECODER_STATES.PAYLOAD_LENGTH_V1:
this.message_length_expected = data[i];
if (this.message_length_expected === CONSTANTS.JUMBO_FRAME_MIN_SIZE) {
this.state = DECODER_STATES.CODE_JUMBO_V1;
case DecoderStates.PAYLOAD_LENGTH_V1:
this.message_length_expected = byte;
if (this.message_length_expected === Constants.JUMBO_FRAME_MIN_SIZE) {
this.state = DecoderStates.CODE_JUMBO_V1;
}
else {
this.initializeReadBuffer();
this.state = DECODER_STATES.CODE_V1;
this.state = DecoderStates.CODE_V1;
}
break;
case DECODER_STATES.PAYLOAD_LENGTH_V2_LOW:
this.message_length_expected = data[i];
this.state = DECODER_STATES.PAYLOAD_LENGTH_V2_HIGH;
case DecoderStates.PAYLOAD_LENGTH_V2_LOW:
this.message_length_expected = byte;
this.state = DecoderStates.PAYLOAD_LENGTH_V2_HIGH;
break;
case DECODER_STATES.PAYLOAD_LENGTH_V2_HIGH:
this.message_length_expected |= data[i] << 8;
case DecoderStates.PAYLOAD_LENGTH_V2_HIGH:
this.message_length_expected |= byte << 8;
this.initializeReadBuffer();
this.state =
this.message_length_expected > 0
? DECODER_STATES.PAYLOAD_V2
: DECODER_STATES.CHECKSUM_V2;
? DecoderStates.PAYLOAD_V2
: DecoderStates.CHECKSUM_V2;
break;
case DECODER_STATES.CODE_V1:
case DECODER_STATES.CODE_JUMBO_V1:
this.code = data[i];
case DecoderStates.CODE_V1:
case DecoderStates.CODE_JUMBO_V1:
this.code = byte;
if (this.message_length_expected > 0) {
// process payload
if (this.state === DECODER_STATES.CODE_JUMBO_V1) {
this.state = DECODER_STATES.PAYLOAD_LENGTH_JUMBO_LOW;
if (this.state === DecoderStates.CODE_JUMBO_V1) {
this.state = DecoderStates.PAYLOAD_LENGTH_JUMBO_LOW;
}
else {
this.state = DECODER_STATES.PAYLOAD_V1;
this.state = DecoderStates.PAYLOAD_V1;
}

@@ -159,37 +160,36 @@ }

// no payload
this.state = DECODER_STATES.CHECKSUM_V1;
this.state = DecoderStates.CHECKSUM_V1;
}
break;
case DECODER_STATES.CODE_V2_LOW:
this.code = data[i];
this.state = DECODER_STATES.CODE_V2_HIGH;
case DecoderStates.CODE_V2_LOW:
this.code = byte;
this.state = DecoderStates.CODE_V2_HIGH;
break;
case DECODER_STATES.CODE_V2_HIGH:
this.code |= data[i] << 8;
this.state = DECODER_STATES.PAYLOAD_LENGTH_V2_LOW;
case DecoderStates.CODE_V2_HIGH:
this.code |= byte << 8;
this.state = DecoderStates.PAYLOAD_LENGTH_V2_LOW;
break;
case DECODER_STATES.PAYLOAD_LENGTH_JUMBO_LOW:
this.message_length_expected = data[i];
this.state = DECODER_STATES.PAYLOAD_LENGTH_JUMBO_HIGH;
case DecoderStates.PAYLOAD_LENGTH_JUMBO_LOW:
this.message_length_expected = byte;
this.state = DecoderStates.PAYLOAD_LENGTH_JUMBO_HIGH;
break;
case DECODER_STATES.PAYLOAD_LENGTH_JUMBO_HIGH:
this.message_length_expected |= data[i] << 8;
case DecoderStates.PAYLOAD_LENGTH_JUMBO_HIGH:
this.message_length_expected |= byte << 8;
this.initializeReadBuffer();
this.state = DECODER_STATES.PAYLOAD_V1;
this.state = DecoderStates.PAYLOAD_V1;
break;
case DECODER_STATES.PAYLOAD_V1:
case DECODER_STATES.PAYLOAD_V2:
this.message_buffer_uint8_view[this.message_length_received] =
data[i];
case DecoderStates.PAYLOAD_V1:
case DecoderStates.PAYLOAD_V2:
this.message_buffer_uint8_view[this.message_length_received] = byte;
this.message_length_received += 1;
if (this.message_length_received >= this.message_length_expected) {
this.state =
this.state === DECODER_STATES.PAYLOAD_V1
? DECODER_STATES.CHECKSUM_V1
: DECODER_STATES.CHECKSUM_V2;
this.state === DecoderStates.PAYLOAD_V1
? DecoderStates.CHECKSUM_V1
: DecoderStates.CHECKSUM_V2;
}
break;
case DECODER_STATES.CHECKSUM_V1:
if (this.message_length_expected >= CONSTANTS.JUMBO_FRAME_MIN_SIZE) {
this.message_checksum = CONSTANTS.JUMBO_FRAME_MIN_SIZE;
case DecoderStates.CHECKSUM_V1:
if (this.message_length_expected >= Constants.JUMBO_FRAME_MIN_SIZE) {
this.message_checksum = Constants.JUMBO_FRAME_MIN_SIZE;
}

@@ -200,3 +200,3 @@ else {

this.message_checksum ^= this.code;
if (this.message_length_expected >= CONSTANTS.JUMBO_FRAME_MIN_SIZE) {
if (this.message_length_expected >= Constants.JUMBO_FRAME_MIN_SIZE) {
this.message_checksum ^= this.message_length_expected & 0xff;

@@ -206,18 +206,22 @@ this.message_checksum ^=

}
for (let ii = 0; ii < this.message_length_received; ii += 1) {
this.message_checksum ^= this.message_buffer_uint8_view[ii];
}
this.dispatchMessage(data[i]);
this.message_buffer_uint8_view
.slice(0, this.message_length_received)
.forEach((messageByte) => {
this.message_checksum ^= messageByte;
});
this.dispatchMessage(byte);
break;
case DECODER_STATES.CHECKSUM_V2:
case DecoderStates.CHECKSUM_V2:
this.message_checksum = 0;
this.message_checksum = utils_1.crc8DvbS2(this.message_checksum, 0); // flag
this.message_checksum = utils_1.crc8DvbS2(this.message_checksum, this.code & 0xff);
this.message_checksum = utils_1.crc8DvbS2(this.message_checksum, (this.code & 0xff00) >> 8);
this.message_checksum = utils_1.crc8DvbS2(this.message_checksum, this.message_length_expected & 0xff);
this.message_checksum = utils_1.crc8DvbS2(this.message_checksum, (this.message_length_expected & 0xff00) >> 8);
for (let ii = 0; ii < this.message_length_received; ii += 1) {
this.message_checksum = utils_1.crc8DvbS2(this.message_checksum, this.message_buffer_uint8_view[ii]);
}
this.dispatchMessage(data[i]);
this.message_checksum = (0, utils_1.crc8DvbS2)(this.message_checksum, 0); // flag
this.message_checksum = (0, utils_1.crc8DvbS2)(this.message_checksum, this.code & 0xff);
this.message_checksum = (0, utils_1.crc8DvbS2)(this.message_checksum, (this.code & 0xff00) >> 8);
this.message_checksum = (0, utils_1.crc8DvbS2)(this.message_checksum, this.message_length_expected & 0xff);
this.message_checksum = (0, utils_1.crc8DvbS2)(this.message_checksum, (this.message_length_expected & 0xff00) >> 8);
this.message_buffer_uint8_view
.slice(0, this.message_length_received)
.forEach((messageByte) => {
this.message_checksum = (0, utils_1.crc8DvbS2)(this.message_checksum, messageByte);
});
this.dispatchMessage(byte);
break;

@@ -227,3 +231,3 @@ default:

}
}
});
cb();

@@ -243,3 +247,3 @@ }

else {
log(`code: ${this.code} - crc failed`);
log(`code: ${this.code} - crc failed, expectedChecksum=${expectedChecksum}, checksum=${this.message_checksum}`);
this.crcError = true;

@@ -260,3 +264,3 @@ data = new ArrayBuffer(0);

this.message_length_received = 0;
this.state = DECODER_STATES.IDLE;
this.state = DecoderStates.IDLE;
this.crcError = false;

@@ -263,0 +267,0 @@ }

@@ -1,6 +0,5 @@

/// <reference types="serialport" />
/// <reference types="node" />
import SerialPort from "@serialport/stream";
import MspDataView from "./dataview";
import { MspParser } from "./parser";
import WriteBuffer from "./writebuffer";
export declare type MspInfo = {

@@ -10,3 +9,3 @@ mspProtocolVersion: number;

};
export declare type ExecutionLocks = Record<number, Promise<void> | undefined>;
export declare type ExecutionLocks = Record<number, Promise<void>>;
export declare type MspRequest = {

@@ -19,3 +18,3 @@ close: () => void;

parser: MspParser;
requests: Record<string, MspRequest | undefined>;
requests: Record<string, MspRequest>;
bytesWritten: number;

@@ -36,4 +35,14 @@ bytesRead: number;

code: number;
data?: WriteBuffer | Buffer;
data?: number[] | Buffer;
timeout?: number;
match?: (data: MspDataView) => boolean;
};
export declare type PortInfo = {
path: string;
manufacturer?: string;
serialNumber?: string;
pnpId?: string;
locationId?: string;
productId?: string;
vendorId?: string;
};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.crc8DvbS2 = (currCRC, ch) => {
exports.crc8DvbS2Data = exports.crc8DvbS2 = void 0;
const crc8DvbS2 = (currCRC, ch) => {
let crc = currCRC;

@@ -16,9 +17,7 @@ crc ^= ch;

};
exports.crc8DvbS2Data = (data, start, end) => {
let crc = 0;
for (let i = start; i < end; i += 1) {
crc = exports.crc8DvbS2(crc, data[i]);
}
return crc;
};
exports.crc8DvbS2 = crc8DvbS2;
const crc8DvbS2Data = (data, start, end) => data
.slice(start, end)
.reduce((computed, byte) => (0, exports.crc8DvbS2)(computed, byte), 0);
exports.crc8DvbS2Data = crc8DvbS2Data;
//# sourceMappingURL=utils.js.map

@@ -9,6 +9,6 @@ /**

*/
/// <reference types="serialport" />
import SerialPort from "@serialport/stream";
import MspDataView from "./dataview";
import { MspCommand, OpenConnectionFunction } from "./types";
import { MspCommand, OpenConnectionFunction, PortInfo } from "./types";
export declare const initialiseSerialBackend: (bindings?: typeof import("serialport").BaseBinding | undefined) => Promise<void>;
/**

@@ -19,4 +19,4 @@ * Execute the given MspCommand on the given port.

*/
export declare const execute: (port: string, { code, data, timeout }: MspCommand) => Promise<MspDataView>;
export declare const ports: () => Promise<string[]>;
export declare const execute: (port: string, { code, data, timeout, match }: MspCommand) => Promise<MspDataView>;
export declare const ports: () => Promise<PortInfo[]>;
/**

@@ -38,2 +38,3 @@ * Close the given port

export declare const apiVersion: (port: string) => string;
export declare const baudRate: (port: string) => number;
/**

@@ -40,0 +41,0 @@ * Private, used for testing

@@ -17,8 +17,9 @@ /**

// at import time
const initialiseBindings = () => {
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires, global-require
const Binding = require("@serialport/bindings");
export const initialiseSerialBackend = async (bindings) => {
const { default: Binding } = !bindings
? await import("@serialport/bindings")
: { default: bindings };
SerialPort.Binding = Binding;
};
const log = debug("connection");
const log = debug("msp:connection");
const connectionsMap = {};

@@ -30,3 +31,3 @@ /**

*/
export const execute = async (port, { code, data, timeout = 2500 }) => {
export const execute = async (port, { code, data, timeout = 100, match }) => {
const connection = connectionsMap[port];

@@ -41,3 +42,3 @@ if (!connection) {

: encodeMessageV1(code, sendData);
const requestKey = request.toString("utf-8");
const requestKey = request.toString("base64");
let mspRequest = requests[requestKey];

@@ -47,5 +48,4 @@ // Prevent FC lockup by checking if this request is currently being performed

if (mspRequest === undefined) {
let rejector;
let onError;
const response = new Promise((resolve, reject) => {
rejector = reject;
// Throw an error if timeout is reached

@@ -58,2 +58,7 @@ const timeoutId = setTimeout(() => {

}, timeout);
onError = (e) => {
reject(e);
clearTimeout(timeoutId);
delete requests[requestKey];
};
function onData(message) {

@@ -65,3 +70,6 @@ if (message.code === code) {

}
log(`${request.toJSON().data} response: ${Buffer.from(message.data).toJSON().data}, byteLength: ${message.data.byteLength}`);
if (match && !match(new MspDataView(message.data))) {
return;
}
log(`request: ${request.toJSON().data}, response: ${Buffer.from(message.data).toJSON().data}, byteLength: ${message.data.byteLength}`);
delete requests[requestKey];

@@ -77,8 +85,15 @@ clearTimeout(timeoutId);

response,
close: () => rejector === null || rejector === void 0 ? void 0 : rejector(new Error("Connection closed")),
close: () => onError(new Error("Connection closed")),
};
requests[requestKey] = mspRequest;
log(`Writing ${request.toJSON().data} to ${port}`);
serial.write(request);
connection.bytesWritten += Buffer.byteLength(request);
serial.write(request, (error) => {
if (error) {
log(`Error writing to serial port ${error.message}, rejecting execution`);
onError(new Error(`Could not write to serial port: ${error.message}`));
}
else {
connection.bytesWritten += Buffer.byteLength(request);
}
});
}

@@ -90,6 +105,7 @@ // make every DataView unique to each request, even though

export const ports = async () => {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!SerialPort.Binding) {
initialiseBindings();
await initialiseSerialBackend();
}
return SerialPort.list().then((data) => data.map(({ path }) => path));
return SerialPort.list();
};

@@ -111,3 +127,3 @@ /**

Object.values(connection.requests).forEach((request) => {
request === null || request === void 0 ? void 0 : request.close();
request.close();
});

@@ -133,6 +149,11 @@ await closePromise;

}
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!SerialPort.Binding) {
initialiseBindings();
await initialiseSerialBackend();
}
const serial = new SerialPort(port, Object.assign(Object.assign({ baudRate: 115200 }, connectionOptions), { autoOpen: false }));
const serial = new SerialPort(port, {
baudRate: 115200,
...connectionOptions,
autoOpen: false,
});
await new Promise((resolve, reject) => {

@@ -184,3 +205,3 @@ serial.open((err) => {

const list = await ports();
if (!list.includes(port) && serial.isOpen) {
if (!list.find(({ path }) => port === path) && serial.isOpen) {
close(port);

@@ -193,4 +214,4 @@ }

});
serial.on("error", () => {
log(`${port} on error received`);
serial.on("error", (e) => {
log(`${port} on error received: ${e === null || e === void 0 ? void 0 : e.message}`);
// Don't trigger close if this serial port is already

@@ -219,2 +240,9 @@ // closed, as it means that the closing

export const apiVersion = (port) => { var _a, _b; return (_b = (_a = connectionsMap[port]) === null || _a === void 0 ? void 0 : _a.mspInfo.apiVersion) !== null && _b !== void 0 ? _b : "0.0.0"; };
export const baudRate = (port) => {
const connection = connectionsMap[port];
if (!connection) {
throw new Error("Port is not open");
}
return connection.serial.baudRate;
};
/**

@@ -221,0 +249,0 @@ * Private, used for testing

@@ -1,3 +0,3 @@

export { ports, connections, isOpen, open, close, bytesRead, bytesWritten, packetErrors, apiVersion, execute, } from "./connection";
export { ports, connections, isOpen, open, close, bytesRead, bytesWritten, packetErrors, apiVersion, execute, baudRate, initialiseSerialBackend, } from "./connection";
export { default as WriteBuffer } from "./writebuffer";
export { default as MspDataView } from "./dataview";
/* eslint-disable import/first */
export { ports, connections, isOpen, open, close, bytesRead, bytesWritten, packetErrors, apiVersion, execute, } from "./connection";
export { ports, connections, isOpen, open, close, bytesRead, bytesWritten, packetErrors, apiVersion, execute, baudRate, initialiseSerialBackend, } from "./connection";
export { default as WriteBuffer } from "./writebuffer";
export { default as MspDataView } from "./dataview";
//# sourceMappingURL=index.js.map

@@ -16,4 +16,4 @@ /**

import { crc8DvbS2 } from "./utils";
const log = debug("parser");
const SYMBOLS = {
const log = debug("msp:parser");
const Symbols = {
BEGIN: "$".charCodeAt(0),

@@ -26,29 +26,29 @@ PROTO_V1: "M".charCodeAt(0),

};
var CONSTANTS;
(function (CONSTANTS) {
CONSTANTS[CONSTANTS["PROTOCOL_V1"] = 1] = "PROTOCOL_V1";
CONSTANTS[CONSTANTS["PROTOCOL_V2"] = 2] = "PROTOCOL_V2";
CONSTANTS[CONSTANTS["JUMBO_FRAME_MIN_SIZE"] = 255] = "JUMBO_FRAME_MIN_SIZE";
})(CONSTANTS || (CONSTANTS = {}));
var DECODER_STATES;
(function (DECODER_STATES) {
DECODER_STATES[DECODER_STATES["IDLE"] = 0] = "IDLE";
DECODER_STATES[DECODER_STATES["PROTO_IDENTIFIER"] = 1] = "PROTO_IDENTIFIER";
DECODER_STATES[DECODER_STATES["DIRECTION_V1"] = 2] = "DIRECTION_V1";
DECODER_STATES[DECODER_STATES["DIRECTION_V2"] = 3] = "DIRECTION_V2";
DECODER_STATES[DECODER_STATES["FLAG_V2"] = 4] = "FLAG_V2";
DECODER_STATES[DECODER_STATES["PAYLOAD_LENGTH_V1"] = 5] = "PAYLOAD_LENGTH_V1";
DECODER_STATES[DECODER_STATES["PAYLOAD_LENGTH_JUMBO_LOW"] = 6] = "PAYLOAD_LENGTH_JUMBO_LOW";
DECODER_STATES[DECODER_STATES["PAYLOAD_LENGTH_JUMBO_HIGH"] = 7] = "PAYLOAD_LENGTH_JUMBO_HIGH";
DECODER_STATES[DECODER_STATES["PAYLOAD_LENGTH_V2_LOW"] = 8] = "PAYLOAD_LENGTH_V2_LOW";
DECODER_STATES[DECODER_STATES["PAYLOAD_LENGTH_V2_HIGH"] = 9] = "PAYLOAD_LENGTH_V2_HIGH";
DECODER_STATES[DECODER_STATES["CODE_V1"] = 10] = "CODE_V1";
DECODER_STATES[DECODER_STATES["CODE_JUMBO_V1"] = 11] = "CODE_JUMBO_V1";
DECODER_STATES[DECODER_STATES["CODE_V2_LOW"] = 12] = "CODE_V2_LOW";
DECODER_STATES[DECODER_STATES["CODE_V2_HIGH"] = 13] = "CODE_V2_HIGH";
DECODER_STATES[DECODER_STATES["PAYLOAD_V1"] = 14] = "PAYLOAD_V1";
DECODER_STATES[DECODER_STATES["PAYLOAD_V2"] = 15] = "PAYLOAD_V2";
DECODER_STATES[DECODER_STATES["CHECKSUM_V1"] = 16] = "CHECKSUM_V1";
DECODER_STATES[DECODER_STATES["CHECKSUM_V2"] = 17] = "CHECKSUM_V2";
})(DECODER_STATES || (DECODER_STATES = {}));
var Constants;
(function (Constants) {
Constants[Constants["PROTOCOL_V1"] = 1] = "PROTOCOL_V1";
Constants[Constants["PROTOCOL_V2"] = 2] = "PROTOCOL_V2";
Constants[Constants["JUMBO_FRAME_MIN_SIZE"] = 255] = "JUMBO_FRAME_MIN_SIZE";
})(Constants || (Constants = {}));
var DecoderStates;
(function (DecoderStates) {
DecoderStates[DecoderStates["IDLE"] = 0] = "IDLE";
DecoderStates[DecoderStates["PROTO_IDENTIFIER"] = 1] = "PROTO_IDENTIFIER";
DecoderStates[DecoderStates["DIRECTION_V1"] = 2] = "DIRECTION_V1";
DecoderStates[DecoderStates["DIRECTION_V2"] = 3] = "DIRECTION_V2";
DecoderStates[DecoderStates["FLAG_V2"] = 4] = "FLAG_V2";
DecoderStates[DecoderStates["PAYLOAD_LENGTH_V1"] = 5] = "PAYLOAD_LENGTH_V1";
DecoderStates[DecoderStates["PAYLOAD_LENGTH_JUMBO_LOW"] = 6] = "PAYLOAD_LENGTH_JUMBO_LOW";
DecoderStates[DecoderStates["PAYLOAD_LENGTH_JUMBO_HIGH"] = 7] = "PAYLOAD_LENGTH_JUMBO_HIGH";
DecoderStates[DecoderStates["PAYLOAD_LENGTH_V2_LOW"] = 8] = "PAYLOAD_LENGTH_V2_LOW";
DecoderStates[DecoderStates["PAYLOAD_LENGTH_V2_HIGH"] = 9] = "PAYLOAD_LENGTH_V2_HIGH";
DecoderStates[DecoderStates["CODE_V1"] = 10] = "CODE_V1";
DecoderStates[DecoderStates["CODE_JUMBO_V1"] = 11] = "CODE_JUMBO_V1";
DecoderStates[DecoderStates["CODE_V2_LOW"] = 12] = "CODE_V2_LOW";
DecoderStates[DecoderStates["CODE_V2_HIGH"] = 13] = "CODE_V2_HIGH";
DecoderStates[DecoderStates["PAYLOAD_V1"] = 14] = "PAYLOAD_V1";
DecoderStates[DecoderStates["PAYLOAD_V2"] = 15] = "PAYLOAD_V2";
DecoderStates[DecoderStates["CHECKSUM_V1"] = 16] = "CHECKSUM_V1";
DecoderStates[DecoderStates["CHECKSUM_V2"] = 17] = "CHECKSUM_V2";
})(DecoderStates || (DecoderStates = {}));
export class MspParser extends Transform {

@@ -72,33 +72,33 @@ constructor() {

const data = new Uint8Array(chunk);
for (let i = 0; i < data.length; i += 1) {
data.forEach((byte) => {
switch (this.state) {
case DECODER_STATES.IDLE: // sync char 1
if (data[i] === SYMBOLS.BEGIN) {
this.state = DECODER_STATES.PROTO_IDENTIFIER;
case DecoderStates.IDLE: // sync char 1
if (byte === Symbols.BEGIN) {
this.state = DecoderStates.PROTO_IDENTIFIER;
}
break;
case DECODER_STATES.PROTO_IDENTIFIER: // sync char 2
switch (data[i]) {
case SYMBOLS.PROTO_V1:
this.state = DECODER_STATES.DIRECTION_V1;
case DecoderStates.PROTO_IDENTIFIER: // sync char 2
switch (byte) {
case Symbols.PROTO_V1:
this.state = DecoderStates.DIRECTION_V1;
break;
case SYMBOLS.PROTO_V2:
this.state = DECODER_STATES.DIRECTION_V2;
case Symbols.PROTO_V2:
this.state = DecoderStates.DIRECTION_V2;
break;
default:
log(`Unknown protocol char ${String.fromCharCode(data[i])}`);
this.state = DECODER_STATES.IDLE;
log(`Unknown protocol char ${String.fromCharCode(byte)}`);
this.state = DecoderStates.IDLE;
}
break;
case DECODER_STATES.DIRECTION_V1: // direction (should be >)
case DECODER_STATES.DIRECTION_V2:
case DecoderStates.DIRECTION_V1: // direction (should be >)
case DecoderStates.DIRECTION_V2:
this.unsupported = 0;
switch (data[i]) {
case SYMBOLS.FROM_MWC:
switch (byte) {
case Symbols.FROM_MWC:
this.messageDirection = 1;
break;
case SYMBOLS.TO_MWC:
case Symbols.TO_MWC:
this.messageDirection = 0;
break;
case SYMBOLS.UNSUPPORTED:
case Symbols.UNSUPPORTED:
this.unsupported = 1;

@@ -109,42 +109,42 @@ break;

this.state =
this.state === DECODER_STATES.DIRECTION_V1
? DECODER_STATES.PAYLOAD_LENGTH_V1
: DECODER_STATES.FLAG_V2;
this.state === DecoderStates.DIRECTION_V1
? DecoderStates.PAYLOAD_LENGTH_V1
: DecoderStates.FLAG_V2;
break;
case DECODER_STATES.FLAG_V2:
case DecoderStates.FLAG_V2:
// Ignored for now
this.state = DECODER_STATES.CODE_V2_LOW;
this.state = DecoderStates.CODE_V2_LOW;
break;
case DECODER_STATES.PAYLOAD_LENGTH_V1:
this.message_length_expected = data[i];
if (this.message_length_expected === CONSTANTS.JUMBO_FRAME_MIN_SIZE) {
this.state = DECODER_STATES.CODE_JUMBO_V1;
case DecoderStates.PAYLOAD_LENGTH_V1:
this.message_length_expected = byte;
if (this.message_length_expected === Constants.JUMBO_FRAME_MIN_SIZE) {
this.state = DecoderStates.CODE_JUMBO_V1;
}
else {
this.initializeReadBuffer();
this.state = DECODER_STATES.CODE_V1;
this.state = DecoderStates.CODE_V1;
}
break;
case DECODER_STATES.PAYLOAD_LENGTH_V2_LOW:
this.message_length_expected = data[i];
this.state = DECODER_STATES.PAYLOAD_LENGTH_V2_HIGH;
case DecoderStates.PAYLOAD_LENGTH_V2_LOW:
this.message_length_expected = byte;
this.state = DecoderStates.PAYLOAD_LENGTH_V2_HIGH;
break;
case DECODER_STATES.PAYLOAD_LENGTH_V2_HIGH:
this.message_length_expected |= data[i] << 8;
case DecoderStates.PAYLOAD_LENGTH_V2_HIGH:
this.message_length_expected |= byte << 8;
this.initializeReadBuffer();
this.state =
this.message_length_expected > 0
? DECODER_STATES.PAYLOAD_V2
: DECODER_STATES.CHECKSUM_V2;
? DecoderStates.PAYLOAD_V2
: DecoderStates.CHECKSUM_V2;
break;
case DECODER_STATES.CODE_V1:
case DECODER_STATES.CODE_JUMBO_V1:
this.code = data[i];
case DecoderStates.CODE_V1:
case DecoderStates.CODE_JUMBO_V1:
this.code = byte;
if (this.message_length_expected > 0) {
// process payload
if (this.state === DECODER_STATES.CODE_JUMBO_V1) {
this.state = DECODER_STATES.PAYLOAD_LENGTH_JUMBO_LOW;
if (this.state === DecoderStates.CODE_JUMBO_V1) {
this.state = DecoderStates.PAYLOAD_LENGTH_JUMBO_LOW;
}
else {
this.state = DECODER_STATES.PAYLOAD_V1;
this.state = DecoderStates.PAYLOAD_V1;
}

@@ -154,37 +154,36 @@ }

// no payload
this.state = DECODER_STATES.CHECKSUM_V1;
this.state = DecoderStates.CHECKSUM_V1;
}
break;
case DECODER_STATES.CODE_V2_LOW:
this.code = data[i];
this.state = DECODER_STATES.CODE_V2_HIGH;
case DecoderStates.CODE_V2_LOW:
this.code = byte;
this.state = DecoderStates.CODE_V2_HIGH;
break;
case DECODER_STATES.CODE_V2_HIGH:
this.code |= data[i] << 8;
this.state = DECODER_STATES.PAYLOAD_LENGTH_V2_LOW;
case DecoderStates.CODE_V2_HIGH:
this.code |= byte << 8;
this.state = DecoderStates.PAYLOAD_LENGTH_V2_LOW;
break;
case DECODER_STATES.PAYLOAD_LENGTH_JUMBO_LOW:
this.message_length_expected = data[i];
this.state = DECODER_STATES.PAYLOAD_LENGTH_JUMBO_HIGH;
case DecoderStates.PAYLOAD_LENGTH_JUMBO_LOW:
this.message_length_expected = byte;
this.state = DecoderStates.PAYLOAD_LENGTH_JUMBO_HIGH;
break;
case DECODER_STATES.PAYLOAD_LENGTH_JUMBO_HIGH:
this.message_length_expected |= data[i] << 8;
case DecoderStates.PAYLOAD_LENGTH_JUMBO_HIGH:
this.message_length_expected |= byte << 8;
this.initializeReadBuffer();
this.state = DECODER_STATES.PAYLOAD_V1;
this.state = DecoderStates.PAYLOAD_V1;
break;
case DECODER_STATES.PAYLOAD_V1:
case DECODER_STATES.PAYLOAD_V2:
this.message_buffer_uint8_view[this.message_length_received] =
data[i];
case DecoderStates.PAYLOAD_V1:
case DecoderStates.PAYLOAD_V2:
this.message_buffer_uint8_view[this.message_length_received] = byte;
this.message_length_received += 1;
if (this.message_length_received >= this.message_length_expected) {
this.state =
this.state === DECODER_STATES.PAYLOAD_V1
? DECODER_STATES.CHECKSUM_V1
: DECODER_STATES.CHECKSUM_V2;
this.state === DecoderStates.PAYLOAD_V1
? DecoderStates.CHECKSUM_V1
: DecoderStates.CHECKSUM_V2;
}
break;
case DECODER_STATES.CHECKSUM_V1:
if (this.message_length_expected >= CONSTANTS.JUMBO_FRAME_MIN_SIZE) {
this.message_checksum = CONSTANTS.JUMBO_FRAME_MIN_SIZE;
case DecoderStates.CHECKSUM_V1:
if (this.message_length_expected >= Constants.JUMBO_FRAME_MIN_SIZE) {
this.message_checksum = Constants.JUMBO_FRAME_MIN_SIZE;
}

@@ -195,3 +194,3 @@ else {

this.message_checksum ^= this.code;
if (this.message_length_expected >= CONSTANTS.JUMBO_FRAME_MIN_SIZE) {
if (this.message_length_expected >= Constants.JUMBO_FRAME_MIN_SIZE) {
this.message_checksum ^= this.message_length_expected & 0xff;

@@ -201,8 +200,10 @@ this.message_checksum ^=

}
for (let ii = 0; ii < this.message_length_received; ii += 1) {
this.message_checksum ^= this.message_buffer_uint8_view[ii];
}
this.dispatchMessage(data[i]);
this.message_buffer_uint8_view
.slice(0, this.message_length_received)
.forEach((messageByte) => {
this.message_checksum ^= messageByte;
});
this.dispatchMessage(byte);
break;
case DECODER_STATES.CHECKSUM_V2:
case DecoderStates.CHECKSUM_V2:
this.message_checksum = 0;

@@ -214,6 +215,8 @@ this.message_checksum = crc8DvbS2(this.message_checksum, 0); // flag

this.message_checksum = crc8DvbS2(this.message_checksum, (this.message_length_expected & 0xff00) >> 8);
for (let ii = 0; ii < this.message_length_received; ii += 1) {
this.message_checksum = crc8DvbS2(this.message_checksum, this.message_buffer_uint8_view[ii]);
}
this.dispatchMessage(data[i]);
this.message_buffer_uint8_view
.slice(0, this.message_length_received)
.forEach((messageByte) => {
this.message_checksum = crc8DvbS2(this.message_checksum, messageByte);
});
this.dispatchMessage(byte);
break;

@@ -223,3 +226,3 @@ default:

}
}
});
cb();

@@ -239,3 +242,3 @@ }

else {
log(`code: ${this.code} - crc failed`);
log(`code: ${this.code} - crc failed, expectedChecksum=${expectedChecksum}, checksum=${this.message_checksum}`);
this.crcError = true;

@@ -256,3 +259,3 @@ data = new ArrayBuffer(0);

this.message_length_received = 0;
this.state = DECODER_STATES.IDLE;
this.state = DecoderStates.IDLE;
this.crcError = false;

@@ -259,0 +262,0 @@ }

@@ -1,6 +0,5 @@

/// <reference types="serialport" />
/// <reference types="node" />
import SerialPort from "@serialport/stream";
import MspDataView from "./dataview";
import { MspParser } from "./parser";
import WriteBuffer from "./writebuffer";
export declare type MspInfo = {

@@ -10,3 +9,3 @@ mspProtocolVersion: number;

};
export declare type ExecutionLocks = Record<number, Promise<void> | undefined>;
export declare type ExecutionLocks = Record<number, Promise<void>>;
export declare type MspRequest = {

@@ -19,3 +18,3 @@ close: () => void;

parser: MspParser;
requests: Record<string, MspRequest | undefined>;
requests: Record<string, MspRequest>;
bytesWritten: number;

@@ -36,4 +35,14 @@ bytesRead: number;

code: number;
data?: WriteBuffer | Buffer;
data?: number[] | Buffer;
timeout?: number;
match?: (data: MspDataView) => boolean;
};
export declare type PortInfo = {
path: string;
manufacturer?: string;
serialNumber?: string;
pnpId?: string;
locationId?: string;
productId?: string;
vendorId?: string;
};

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

export {};
//# sourceMappingURL=types.js.map

@@ -14,9 +14,5 @@ export const crc8DvbS2 = (currCRC, ch) => {

};
export const crc8DvbS2Data = (data, start, end) => {
let crc = 0;
for (let i = start; i < end; i += 1) {
crc = crc8DvbS2(crc, data[i]);
}
return crc;
};
export const crc8DvbS2Data = (data, start, end) => data
.slice(start, end)
.reduce((computed, byte) => crc8DvbS2(computed, byte), 0);
//# sourceMappingURL=utils.js.map
{
"name": "@betaflight/msp",
"version": "0.3.0",
"version": "0.4.0",
"description": "A MultiWii Serial Protocol library to connect and communicate with flight controllers",

@@ -8,4 +8,7 @@ "license": "MIT",

"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
"typings": "./dist/cjs/index.d.ts",
"publishConfig": {
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
"typings": "./dist/cjs/index.d.ts"
},
"sideEffects": false,

@@ -26,12 +29,14 @@ "repository": "https://github.com/freshollie/fresh-configurator/tree/master/packages/msp",

"scripts": {
"testscript": "ts-node -T test-script.ts"
"testscript": "ts-node --project tsconfig.cjs.build.json test-script.ts"
},
"dependencies": {
"@serialport/bindings": "^8.0.7",
"@serialport/stream": "^8.0.6",
"debug": "^4.1.1"
"@serialport/bindings": "^9.2.1",
"@serialport/stream": "^9.0.7",
"debug": "^4.3.2"
},
"devDependencies": {
"@serialport/binding-mock": "^8.0.6",
"@types/debug": "^4.1.5",
"@serialport/binding-mock": "^9.0.7",
"@types/debug": "^4.1.7",
"@types/jest": "^27.0.1",
"@types/node": "^14.17.14",
"@types/serialport__binding-mock": "^8.0.0",

@@ -41,6 +46,6 @@ "@types/serialport__bindings": "^8.0.0",

"flush-promises": "^1.0.2",
"rimraf": "^3.0.2",
"typescript": ">=3.7"
"ts-jest": "^27.0.5",
"typescript": "^4.4.2"
},
"gitHead": "688344fb75f271b76389d903f2ab1373f5916b28"
}
"module": "./dist/esm/index.js"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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