@rakwireless/linbus
Version:
LinBUS module able to parse and create LinBUS-compatible frames to be forwarded using a serial connection, created for RAK13005 LIN transceiver module, which uses the TLE7259-3 chip from Infineon
97 lines (84 loc) • 2.61 kB
JavaScript
module.exports = function(RED) {
"use strict";
const headerLength = 3;
const checkSumLength = 1;
const sync = 0x55;
function protectID(ident) {
var pid = ident & 0x3F;
var tmp = (pid ^ (pid>>1) ^ (pid>>2) ^ (pid>>4)) & 0x01;
pid |= tmp << 6;
tmp = ~((pid>>1) ^ (pid>>3) ^ (pid>>4) ^ (pid>>5)) & 0x01;
pid |= tmp << 7;
return pid;
}
function calculateChecksum(data) {
var chk = 0;
for(var i = 0; i < data.length; i++) {
chk += data[i];
if (chk > 255) {
chk -= 255;
}
}
chk = 255 - chk;
return chk;
}
function validateChecksum(data, checkSum) {
return calculateChecksum(data) == checkSum;
}
function linBusParseNode(config) {
RED.nodes.createNode(this,config);
this.on("input", function(msg) {
//clear status icon every new trigger input
this.status({});
var newMsg = {};
newMsg.payload = [];
var rawData = msg.payload;
var payloadLength = parseInt(config.length);
var frameLength = headerLength + payloadLength + checkSumLength;
while (rawData.length >= frameLength) {
if (rawData[0] == 0 && rawData[1] == sync && rawData[2] == protectID(config.ID)) {
var payloadData = rawData.slice(headerLength, headerLength+payloadLength);
var checkSum = rawData[headerLength+payloadLength];
if (validateChecksum(payloadData, checkSum)) {
var tmp = {ID:parseInt(config.ID), length:payloadLength, data:payloadData};
newMsg.payload.push(tmp);
}
rawData = rawData.slice(frameLength, rawData.length);
}
else {
rawData = rawData.slice(1, rawData.length);
}
}
this.send(newMsg);
});
this.on('close', function() {
this.status({fill:"grey", shape:"ring", text:"linbus.status.closed"});
this.cb.cancel();
if (done) { done(); }
});
}
RED.nodes.registerType("linbus-parse", linBusParseNode);
function linBusBuilderNode(config) {
RED.nodes.createNode(this,config);
this.on("input", function(msg) {
this.status({});
var newMsg = {};
var length = msg.payload.length;
if (length == 2 || length == 4 || length == 8 ) {
var pid = protectID(config.ID);
var header = Buffer.from([0, sync, pid]);
var checkSum = calculateChecksum(msg.payload);
checkSum = Buffer.from([checkSum]);
var frame = Buffer.concat([header, msg.payload, checkSum]);
newMsg.payload = frame;
this.send(newMsg);
}
});
this.on('close', function() {
this.status({fill:"grey", shape:"ring", text:"linbus.status.closed"});
this.cb.cancel();
if (done) { done(); }
});
}
RED.nodes.registerType("linbus-builder", linBusBuilderNode);
}