Socket
Socket
Sign inDemoInstall

modbus-serial

Package Overview
Dependencies
Maintainers
1
Versions
123
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

modbus-serial - npm Package Compare versions

Comparing version 7.4.2 to 7.4.3-no-serial-port

6

.eslintrc.json

@@ -6,2 +6,5 @@ {

},
"parserOptions": {
"ecmaVersion": 2017
},
"extends": "eslint:recommended",

@@ -59,2 +62,3 @@ "rules": {

"func-style": "off",
"for-direction": "error",
"generator-star-spacing": "error",

@@ -143,3 +147,3 @@ "global-require": "off",

"no-multi-assign": "error",
"no-multi-spaces": "error",
"no-multi-spaces": "off",
"no-multi-str": "off",

@@ -146,0 +150,0 @@ "no-multiple-empty-lines": "off",

@@ -43,2 +43,16 @@ /* eslint-disable no-console, no-unused-vars, spaced-comment */

return;
},
readDeviceIdentification: function(addr) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve({
0x00: "MyVendorName",
0x01: "MyProductCode",
0x02: "MyMajorMinorRevision",
0x05: "MyModelName",
0x97: "MyExtendedObject1",
0xAB: "MyExtendedObject2"
});
}, 10);
});
}

@@ -45,0 +59,0 @@ };

2

examples/debug.js

@@ -37,3 +37,3 @@ /* eslint-disable no-console, spaced-comment */

function run() {
// read the 4 registers starting at address 5
// read the 4 registers starting at address 5
client.readHoldingRegisters(5, 4)

@@ -40,0 +40,0 @@ .then(function(d) {

@@ -25,3 +25,13 @@ /* eslint-disable no-console, no-unused-vars, spaced-comment */

setRegister: function(addr, value) { console.log("set register", addr, value); return; },
setCoil: function(addr, value) { console.log("set coil", addr, value); return; }
setCoil: function(addr, value) { console.log("set coil", addr, value); return; },
readDeviceIdentification: function(addr) {
return {
0x00: "MyVendorName",
0x01: "MyProductCode",
0x02: "MyMajorMinorRevision",
0x05: "MyModelName",
0x97: "MyExtendedObject1",
0xAB: "MyExtendedObject2"
};
}
};

@@ -28,0 +38,0 @@

@@ -18,8 +18,8 @@ /* eslint-disable no-console, spaced-comment */

function setClient() {
// set the client's unit id
// set a timout for requests default is null (no timeout)
// set the client's unit id
// set a timout for requests default is null (no timeout)
client.setID(1);
client.setTimeout(2000);
// run program
// run program
run();

@@ -29,3 +29,3 @@ }

function run() {
// write to coil
// write to coil
client.writeCoils(1, [true, false, true, false, true, true, false, true])

@@ -70,3 +70,3 @@ .then(function(d) {

function writeRegisters() {
// write 5 registers statrting at input registers
// write 5 registers statrting at input registers
client.writeRegisters(1, [100, 90, 80, -200 + 65535, -100 + 65535])

@@ -73,0 +73,0 @@ .then(function(d) {

@@ -1,64 +0,64 @@

'use strict';
"use strict";
var gulp = require('gulp');
var pump = require('pump');
const jsdoc = require('gulp-jsdoc3');
const clean = require('gulp-clean');
var gulp = require("gulp");
var pump = require("pump");
const jsdoc = require("gulp-jsdoc3");
const clean = require("gulp-clean");
gulp.task('default', function() {
gulp.task("default", function() {
// place code for your default task here
});
gulp.task('docs', ['doc', 'docExamples']);
gulp.task('build', ['apis', 'ports', 'servers', 'utils']);
gulp.task('publish', ['build', 'docs']);
gulp.task("docs", ["doc", "docExamples"]);
gulp.task("build", ["apis", "ports", "servers", "utils"]);
gulp.task("publish", ["build", "docs"]);
gulp.task('clean', function() {
return gulp.src(['modbus-serial', 'docs/gen'])
.pipe(clean({force: true}))
gulp.task("clean", function() {
return gulp.src(["modbus-serial", "docs/gen"])
.pipe(clean({ force: true }));
});
gulp.task('doc', function(cb) {
gulp.src(['README.md', 'apis/**/*.js', 'ports/**/*.js', 'servers/**/*.js', 'utils/**/*.js'], {read: false})
.pipe(jsdoc(cb))
gulp.task("doc", function(cb) {
gulp.src(["README.md", "apis/**/*.js", "ports/**/*.js", "servers/**/*.js", "utils/**/*.js"], { read: false })
.pipe(jsdoc(cb));
});
gulp.task('docExamples', function() {
return gulp.src('examples/**/*').pipe(gulp.dest('docs/gen/examples'))
gulp.task("docExamples", function() {
return gulp.src("examples/**/*").pipe(gulp.dest("docs/gen/examples"));
});
gulp.task('apis', function(cb) {
gulp.task("apis", function(cb) {
pump([
gulp.src('apis/**/*.js'),
gulp.dest('modbus-serial/apis')
gulp.src("apis/**/*.js"),
gulp.dest("modbus-serial/apis")
],
cb
)
);
});
gulp.task('ports', function(cb) {
gulp.task("ports", function(cb) {
pump([
gulp.src('ports/**/*.js'),
gulp.dest('modbus-serial/ports')
gulp.src("ports/**/*.js"),
gulp.dest("modbus-serial/ports")
],
cb
)
);
});
gulp.task('servers', function(cb) {
gulp.task("servers", function(cb) {
pump([
gulp.src('servers/**/*.js'),
gulp.dest('modbus-serial/servers')
gulp.src("servers/**/*.js"),
gulp.dest("modbus-serial/servers")
],
cb
)
);
});
gulp.task('utils', function(cb) {
gulp.task("utils", function(cb) {
pump([
gulp.src('utils/**/*.js'),
gulp.dest('modbus-serial/utils')
gulp.src("utils/**/*.js"),
gulp.dest("modbus-serial/utils")
],
cb
)
);
});

@@ -650,3 +650,3 @@ "use strict";

var codeLength = 7 + dataBytes;
var buf = Buffer.alloc(codeLength + 2); // add 2 crc bytes
var buf = Buffer.alloc(codeLength + 2); // add 2 crc bytes

@@ -653,0 +653,0 @@ buf.writeUInt8(address, 0);

{
"name": "modbus-serial",
"version": "7.4.2",
"version": "7.4.3-no-serial-port",
"description": "A pure JavaScript implemetation of MODBUS-RTU (Serial and TCP) for NodeJS.",

@@ -28,17 +28,17 @@ "main": "index.js",

"devDependencies": {
"chai": "^3.5.0",
"eslint": "^3.16.1",
"gulp": "^3.9.1",
"gulp-clean": "^0.3.2",
"gulp-jsdoc3": "^1.0.1",
"mocha": "^3.2.0",
"mocha-eslint": "^3.0.1",
"mockery": "^2.0.0",
"pump": "^1.0.2",
"sinon": "^1.17.7"
"chai": "^4.2.0",
"eslint": "^5.12.1",
"gulp": "^4.0.0",
"gulp-clean": "^0.4.0",
"gulp-jsdoc3": "^2.0.0",
"mocha": "^5.2.0",
"mocha-eslint": "^5.0.0",
"mockery": "^2.1.0",
"pump": "^3.0.0",
"serialport": "^7.1.3",
"sinon": "^7.2.2"
},
"dependencies": {
"debug": "^3.0.1",
"serialport": "^6.1.1"
"debug": "^4.1.1"
}
}

@@ -68,2 +68,3 @@ # modbus-serial

* FC16 "Preset Multiple Registers"
* FC43/14 "Read Device Identification" (server only)

@@ -242,2 +243,12 @@ ###### Client Serial:

return;
},
readDeviceIdentification: function(addr) {
return {
0x00: "MyVendorName",
0x01: "MyProductCode",
0x02: "MyMajorMinorRevision",
0x05: "MyModelName",
0x97: "MyExtendedObject1",
0xAB: "MyExtendedObject2"
};
}

@@ -244,0 +255,0 @@ };

@@ -47,12 +47,10 @@ "use strict";

if (promiseOrValue && promiseOrValue.then && typeof promiseOrValue.then === "function") {
promiseOrValue.then(function(value) {
cb(null, value);
});
if (promiseOrValue.catch && typeof promiseOrValue.catch === "function") {
promiseOrValue.catch(function(err) {
promiseOrValue
.then(function(value) {
cb(null, value);
})
.catch(function(err) {
cb(err);
});
}
}
else {
} else {
cb(null, promiseOrValue);

@@ -672,2 +670,200 @@ }

/**
* Function to handle FC43 request.
*
* @param requestBuffer - request Buffer from client
* @param vector - vector of functions for read and write
* @param unitID - Id of the requesting unit
* @param {function} callback - callback to be invoked passing {Buffer} response
* @returns undefined
* @private
*/
function _handleMEI(requestBuffer, vector, unitID, callback) {
var MEIType = requestBuffer[2];
switch(parseInt(MEIType)) {
case 14:
_handleReadDeviceIdentification(requestBuffer, vector, unitID, callback);
break;
default:
callback({ modbusErrorCode: 0x01 }); // illegal MEI type
}
}
/**
* Function to handle FC43/14 MEI request.
*
* @param requestBuffer - request Buffer from client
* @param vector - vector of functions for read and write
* @param unitID - Id of the requesting unit
* @param {function} callback - callback to be invoked passing {Buffer} response
* @returns undefined
* @private
*/
async function _handleReadDeviceIdentification(requestBuffer, vector, unitID, callback) {
const PDULenMax = 253;
const MEI14HeaderLen = 6;
const stringLengthMax = PDULenMax - MEI14HeaderLen - 2;
if(!vector.readDeviceIdentification) {
callback({ modbusErrorCode: 0x01 });
return;
}
var readDeviceIDCode = requestBuffer.readUInt8(3);
var objectID = requestBuffer.readUInt8(4);
// Basic request parameters checks
switch(readDeviceIDCode) {
case 0x01:
if(objectID > 0x02 || (objectID > 0x06 && objectID < 0x80))
objectID = 0x00;
break;
case 0x02:
if(objectID >= 0x80 || (objectID > 0x06 && objectID < 0x80))
objectID = 0x00;
break;
case 0x03:
if(objectID > 0x06 && objectID < 0x80)
objectID = 0x00;
break;
case 0x04:
if(objectID > 0x06 && objectID < 0x80) {
callback({ modbusErrorCode: 0x02 });
return;
}
break;
default:
callback({ modbusErrorCode: 0x03 });
return;
}
// Filling mandatory basic device identification objects
var objects = {
0x00: "undefined",
0x01: "undefined",
0x02: "undefined"
};
const pkg = require("../package.json");
if(pkg) {
if(pkg.author)
objects[0x00] = pkg.author;
if(pkg.name)
objects[0x01] = pkg.name;
if(pkg.version)
objects[0x02] = pkg.version;
}
var promiseOrValue = vector.readDeviceIdentification(unitID);
try {
var userObjects = await new Promise((resolve, reject) => {
_handlePromiseOrValue(promiseOrValue, (err, value) => {
if(err)
reject(err);
else
resolve(value);
});
});
}
catch(error) {
callback(error);
return;
}
for(var o of Object.keys(userObjects)) {
const i = parseInt(o);
if(!isNaN(i) && i >= 0 && i <= 255)
objects[i] = userObjects[o];
}
// Checking the existence of the requested objectID
if(!objects[objectID]) {
if(readDeviceIDCode === 0x04) {
callback({ modbusErrorCode: 0x02 });
return;
}
objectID = 0x00;
}
var ids = [];
var totalLength = 2 + MEI14HeaderLen + 2; // UnitID + FC + MEI14Header + CRC
var lastID = 0;
var conformityLevel = 0x81;
var supportedIDs = Object.keys(objects);
// Filtering of objects and Conformity level determination
for(var id of supportedIDs) {
id = parseInt(id);
if(isNaN(id))
continue;
// Enforcing valid object IDs from the user
if(id < 0x00 || (id > 0x06 && id < 0x80) || id > 0xFF) {
callback({ modbusErrorCode: 0x04 });
throw new Error("Invalid Object ID provided for Read Device Identification: " + id);
}
if(id > 0x02)
conformityLevel = 0x82;
if(id > 0x80)
conformityLevel = 0x83;
// Starting from requested object ID
if(objectID > id)
continue;
// Enforcing maximum string length
if(objects[id].length > stringLengthMax) {
callback({ modbusErrorCode: 0x04 });
throw new Error("Read Device Identification string size can be maximum " + stringLengthMax);
}
if(lastID !== 0)
continue;
if(objects[id].length + 2 > PDULenMax - totalLength) {
if(lastID === 0)
lastID = id;
}
else {
totalLength += objects[id].length + 2;
ids.push(id);
// Requested a single object
if(readDeviceIDCode === 0x04)
break;
}
}
ids.sort((a, b) => parseInt(a) - parseInt(b));
var responseBuffer = Buffer.alloc(totalLength);
var i = 2;
i = responseBuffer.writeUInt8(14, i); // MEI type
i = responseBuffer.writeUInt8(readDeviceIDCode, i);
i = responseBuffer.writeUInt8(conformityLevel, i);
if(lastID === 0) // More follows
i = responseBuffer.writeUInt8(0x00, i);
else
i = responseBuffer.writeUInt8(0xFF, i);
i = responseBuffer.writeUInt8(lastID, i); // Next Object Id
i = responseBuffer.writeUInt8(ids.length, i); // Number of objects
for(id of ids) {
i = responseBuffer.writeUInt8(id, i); // Object id
i = responseBuffer.writeUInt8(objects[id].length, i); // Object length
i += responseBuffer.write(objects[id], i, objects[id].length); // Object value
}
callback(null, responseBuffer);
}
/**
* Exports

@@ -682,3 +878,4 @@ */

forceMultipleCoils: _handleForceMultipleCoils,
writeMultipleRegisters: _handleWriteMultipleRegisters
writeMultipleRegisters: _handleWriteMultipleRegisters,
handleMEI: _handleMEI
};

@@ -26,3 +26,4 @@ "use strict";

var MODBUS_PORT = 502;
// Not really its official length, but we parse UnitID as part of PDU
// Not really its official length, but we parse UnitID as part of PDU
const MBAP_LEN = 6;

@@ -177,2 +178,5 @@

break;
case 43:
handlers.handleMEI(requestBuffer, vector, unitID, cb);
break;
default:

@@ -213,3 +217,8 @@ var errorCode = 0x01; // illegal function

// remember open sockets
modbus.socks = new Map();
modbus._server.on("connection", function(sock) {
modbus.socks.set(sock, 0);
modbusSerialDebug({

@@ -219,5 +228,12 @@ action: "connected",

remoteAddress: sock.remoteAddress,
remotePort: sock.remotePort
localPort: sock.localPort
});
sock.once("close", function() {
modbusSerialDebug({
action: "closed"
});
modbus.socks.delete(sock);
});
sock.on("data", function(data) {

@@ -300,7 +316,13 @@ modbusSerialDebug({ action: "socket data", data: data });

ServerTCP.prototype.close = function(callback) {
const modbus = this;
// close the net port if exist
if (this._server) {
this._server.removeAllListeners("data");
this._server.close(callback);
if (modbus._server) {
modbus._server.removeAllListeners("data");
modbus._server.close(callback);
modbus.socks.forEach(function(e, sock) {
sock.destroy();
});
modbusSerialDebug({ action: "close server" });

@@ -307,0 +329,0 @@ } else {

@@ -20,3 +20,3 @@ "use strict";

console.log("Holding register: ", addr);
console.log("\tHolding register: ", addr);

@@ -26,11 +26,11 @@ return addr + 8000;

getCoil: function(addr) {
console.log("Holding register: ", addr);
console.log("\tHolding register: ", addr);
return (addr % 2) === 0;
},
setRegister: function(addr, value) {
console.log("set register", addr, value);
console.log("\tset register", addr, value);
return;
},
setCoil: function(addr, value) {
console.log("set coil", addr, value);
console.log("\tset coil", addr, value);
return;

@@ -56,2 +56,4 @@ }

expect(data.toString("hex")).to.equal("00010000000601050005ff00");
client.end();
done();

@@ -74,2 +76,4 @@ });

expect(data.toString("hex")).to.equal("000100000003018701");
client.end();
done();

@@ -88,2 +92,4 @@ });

expect(data.toString("hex")).to.equal("000100000003018304");
client.end();
done();

@@ -106,2 +112,3 @@ });

// Error handled correctly
client.end();
done();

@@ -124,2 +131,4 @@ });

expect(data.toString("hex")).to.equal("000100000003018104");
client.end();
done();

@@ -138,2 +147,4 @@ });

expect(data.toString("hex")).to.equal("000100000003018304");
client.end();
done();

@@ -152,2 +163,4 @@ });

expect(data.toString("hex")).to.equal("000100000003018404");
client.end();
done();

@@ -167,3 +180,3 @@ });

setCoil: function(addr, value) {
console.log("set coil", addr, value);
console.log("\tset coil", addr, value);
return;

@@ -189,2 +202,4 @@ }

expect(data.toString("hex")).to.equal("00010000000604050005ff00");
client.end();
done();

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

setCoil: function(addr, value) {
console.log("set coil", addr, value);
console.log("\tset coil", addr, value);
return;

@@ -230,2 +245,4 @@ }

expect(data.toString("hex")).to.equal("NO DATA");
client.end();
done();

@@ -232,0 +249,0 @@ });

@@ -40,3 +40,3 @@ "use strict";

setCoil: function(addr, value, unit, callback) {
setTimeout(function() {console.log("set coil", addr, value);
setTimeout(function() {console.log("\tset coil", addr, value);
callback(null);

@@ -43,0 +43,0 @@ }, 50);

@@ -40,3 +40,3 @@ "use strict";

setTimeout(function() {
console.log("set register", addr, value);
console.log("\tset register", addr, value);
resolve();

@@ -49,3 +49,3 @@ }, 50);

setTimeout(function() {
console.log("set coil", addr, value);
console.log("\tset coil", addr, value);
resolve();

@@ -52,0 +52,0 @@ }, 50);

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