njs-modbus 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -11
- package/dist/index.cjs +560 -476
- package/dist/index.d.ts +6 -0
- package/dist/index.mjs +560 -476
- package/dist/src/slave/slave.d.ts +6 -0
- package/package.json +2 -1
- package/dist/test/slave.d.ts +0 -1
- /package/dist/test/{master.d.ts → slave.test.d.ts} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -327,6 +327,7 @@ class TcpServerPhysicalLayer extends AbstractPhysicalLayer {
|
|
|
327
327
|
this._server.removeAllListeners();
|
|
328
328
|
for (const socket of this._sockets) {
|
|
329
329
|
socket.removeAllListeners();
|
|
330
|
+
socket.destroy();
|
|
330
331
|
}
|
|
331
332
|
this._server.close(() => {
|
|
332
333
|
resolve();
|
|
@@ -1111,31 +1112,47 @@ class ModbusMaster extends EventEmitter {
|
|
|
1111
1112
|
}
|
|
1112
1113
|
waitResponse(request, response, timeout) {
|
|
1113
1114
|
return new Promise((resolve, reject) => {
|
|
1115
|
+
let settled = false;
|
|
1116
|
+
const tid = setTimeout(() => {
|
|
1117
|
+
if (!settled) {
|
|
1118
|
+
settled = true;
|
|
1119
|
+
this.applicationLayer.stopWaitingResponse();
|
|
1120
|
+
reject(new Error('Timeout'));
|
|
1121
|
+
}
|
|
1122
|
+
}, timeout);
|
|
1114
1123
|
this.physicalLayer
|
|
1115
1124
|
.write(request.data)
|
|
1116
1125
|
.then(() => {
|
|
1117
|
-
if (
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
else {
|
|
1121
|
-
const tid = setTimeout(() => {
|
|
1122
|
-
this.applicationLayer.stopWaitingResponse();
|
|
1123
|
-
reject(new Error('Timeout'));
|
|
1124
|
-
}, timeout);
|
|
1125
|
-
this.applicationLayer.startWaitingResponse(response.preCheck, (error, frame) => {
|
|
1126
|
+
if (!settled) {
|
|
1127
|
+
if (request.broadcast) {
|
|
1128
|
+
settled = true;
|
|
1126
1129
|
clearTimeout(tid);
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1130
|
+
resolve();
|
|
1131
|
+
}
|
|
1132
|
+
else {
|
|
1133
|
+
this.applicationLayer.startWaitingResponse(response.preCheck, (error, frame) => {
|
|
1134
|
+
if (!settled) {
|
|
1135
|
+
settled = true;
|
|
1136
|
+
clearTimeout(tid);
|
|
1137
|
+
this.applicationLayer.stopWaitingResponse();
|
|
1138
|
+
if (error) {
|
|
1139
|
+
reject(error);
|
|
1140
|
+
}
|
|
1141
|
+
else {
|
|
1142
|
+
resolve(frame);
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1135
1147
|
}
|
|
1136
1148
|
})
|
|
1137
1149
|
.catch((error) => {
|
|
1138
|
-
|
|
1150
|
+
if (!settled) {
|
|
1151
|
+
settled = true;
|
|
1152
|
+
clearTimeout(tid);
|
|
1153
|
+
this.applicationLayer.stopWaitingResponse();
|
|
1154
|
+
reject(error);
|
|
1155
|
+
}
|
|
1139
1156
|
});
|
|
1140
1157
|
});
|
|
1141
1158
|
}
|
|
@@ -1524,97 +1541,24 @@ class ModbusSlave extends EventEmitter {
|
|
|
1524
1541
|
writable: true,
|
|
1525
1542
|
value: new Map()
|
|
1526
1543
|
});
|
|
1544
|
+
Object.defineProperty(this, "_processing", {
|
|
1545
|
+
enumerable: true,
|
|
1546
|
+
configurable: true,
|
|
1547
|
+
writable: true,
|
|
1548
|
+
value: false
|
|
1549
|
+
});
|
|
1550
|
+
Object.defineProperty(this, "_queue", {
|
|
1551
|
+
enumerable: true,
|
|
1552
|
+
configurable: true,
|
|
1553
|
+
writable: true,
|
|
1554
|
+
value: []
|
|
1555
|
+
});
|
|
1527
1556
|
applicationLayer.on('framing', (frame, _response) => {
|
|
1528
1557
|
if (!(frame.unit === 0x00 || this.models.has(frame.unit))) {
|
|
1529
1558
|
return;
|
|
1530
1559
|
}
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
return;
|
|
1534
|
-
}
|
|
1535
|
-
try {
|
|
1536
|
-
yield _response(data);
|
|
1537
|
-
}
|
|
1538
|
-
catch (error) { }
|
|
1539
|
-
});
|
|
1540
|
-
const intercept = (model) => __awaiter(this, void 0, void 0, function* () {
|
|
1541
|
-
if (model.interceptor) {
|
|
1542
|
-
try {
|
|
1543
|
-
const data = yield model.interceptor(frame.fc, frame.data);
|
|
1544
|
-
if (data) {
|
|
1545
|
-
response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data })));
|
|
1546
|
-
return 'break';
|
|
1547
|
-
}
|
|
1548
|
-
}
|
|
1549
|
-
catch (error) {
|
|
1550
|
-
this.responseError(frame, response, error);
|
|
1551
|
-
return 'break';
|
|
1552
|
-
}
|
|
1553
|
-
}
|
|
1554
|
-
});
|
|
1555
|
-
const handleFC = (model) => {
|
|
1556
|
-
switch (frame.fc) {
|
|
1557
|
-
case 0x01: {
|
|
1558
|
-
this.handleFC1(model, frame, response);
|
|
1559
|
-
break;
|
|
1560
|
-
}
|
|
1561
|
-
case 0x02: {
|
|
1562
|
-
this.handleFC2(model, frame, response);
|
|
1563
|
-
break;
|
|
1564
|
-
}
|
|
1565
|
-
case 0x03: {
|
|
1566
|
-
this.handleFC3(model, frame, response);
|
|
1567
|
-
break;
|
|
1568
|
-
}
|
|
1569
|
-
case 0x04: {
|
|
1570
|
-
this.handleFC4(model, frame, response);
|
|
1571
|
-
break;
|
|
1572
|
-
}
|
|
1573
|
-
case 0x05: {
|
|
1574
|
-
this.handleFC5(model, frame, response);
|
|
1575
|
-
break;
|
|
1576
|
-
}
|
|
1577
|
-
case 0x06: {
|
|
1578
|
-
this.handleFC6(model, frame, response);
|
|
1579
|
-
break;
|
|
1580
|
-
}
|
|
1581
|
-
case 0x0f: {
|
|
1582
|
-
this.handleFC15(model, frame, response);
|
|
1583
|
-
break;
|
|
1584
|
-
}
|
|
1585
|
-
case 0x10: {
|
|
1586
|
-
this.handleFC16(model, frame, response);
|
|
1587
|
-
break;
|
|
1588
|
-
}
|
|
1589
|
-
case 0x11: {
|
|
1590
|
-
this.handleFC17(model, frame, response);
|
|
1591
|
-
break;
|
|
1592
|
-
}
|
|
1593
|
-
case 0x16: {
|
|
1594
|
-
this.handleFC22(model, frame, response);
|
|
1595
|
-
break;
|
|
1596
|
-
}
|
|
1597
|
-
case 0x17: {
|
|
1598
|
-
this.handleFC23(model, frame, response);
|
|
1599
|
-
break;
|
|
1600
|
-
}
|
|
1601
|
-
case 0x2b: {
|
|
1602
|
-
this.handleFC43_14(model, frame, response);
|
|
1603
|
-
break;
|
|
1604
|
-
}
|
|
1605
|
-
default: {
|
|
1606
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1607
|
-
break;
|
|
1608
|
-
}
|
|
1609
|
-
}
|
|
1610
|
-
};
|
|
1611
|
-
for (const model of frame.unit === 0x00 ? this.models.values() : [this.models.get(frame.unit)]) {
|
|
1612
|
-
intercept(model).then((res) => {
|
|
1613
|
-
if (res !== 'break') {
|
|
1614
|
-
handleFC(model);
|
|
1615
|
-
}
|
|
1616
|
-
});
|
|
1617
|
-
}
|
|
1560
|
+
this._queue.push({ frame, response: _response });
|
|
1561
|
+
this._drain();
|
|
1618
1562
|
});
|
|
1619
1563
|
physicalLayer.on('error', (error) => {
|
|
1620
1564
|
this.emit('error', error);
|
|
@@ -1624,483 +1568,623 @@ class ModbusSlave extends EventEmitter {
|
|
|
1624
1568
|
});
|
|
1625
1569
|
}
|
|
1626
1570
|
handleFC1(model, frame, response) {
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
if (
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
if (
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1571
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1572
|
+
var _a;
|
|
1573
|
+
if (frame.data.length === 4) {
|
|
1574
|
+
if (model.readCoils) {
|
|
1575
|
+
const bufferRx = Buffer.from(frame.data);
|
|
1576
|
+
const address = bufferRx.readUInt16BE(0);
|
|
1577
|
+
const length = bufferRx.readUInt16BE(2);
|
|
1578
|
+
if (length >= 0x0001 && length <= 0x07d0) {
|
|
1579
|
+
if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).coils)) {
|
|
1580
|
+
try {
|
|
1581
|
+
const coils = yield Promise.resolve(model.readCoils(address, length));
|
|
1582
|
+
const bufferTx = Buffer.alloc(Math.ceil(length / 8));
|
|
1583
|
+
coils.forEach((coil, index) => {
|
|
1584
|
+
if (coil) {
|
|
1585
|
+
bufferTx[~~(index / 8)] |= 1 << index % 8;
|
|
1586
|
+
}
|
|
1587
|
+
});
|
|
1588
|
+
yield response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: [bufferTx.length].concat(Array.from(bufferTx)) })));
|
|
1589
|
+
}
|
|
1590
|
+
catch (error) {
|
|
1591
|
+
yield this.responseError(frame, response, error);
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
else {
|
|
1595
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_ADDRESS));
|
|
1596
|
+
}
|
|
1648
1597
|
}
|
|
1649
1598
|
else {
|
|
1650
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1599
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_VALUE));
|
|
1651
1600
|
}
|
|
1652
1601
|
}
|
|
1653
1602
|
else {
|
|
1654
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1603
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1655
1604
|
}
|
|
1656
1605
|
}
|
|
1657
|
-
|
|
1658
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1659
|
-
}
|
|
1660
|
-
}
|
|
1606
|
+
});
|
|
1661
1607
|
}
|
|
1662
1608
|
handleFC2(model, frame, response) {
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
if (
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
if (
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1609
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1610
|
+
var _a;
|
|
1611
|
+
if (frame.data.length === 4) {
|
|
1612
|
+
if (model.readDiscreteInputs) {
|
|
1613
|
+
const bufferRx = Buffer.from(frame.data);
|
|
1614
|
+
const address = bufferRx.readUInt16BE(0);
|
|
1615
|
+
const length = bufferRx.readUInt16BE(2);
|
|
1616
|
+
if (length >= 0x0001 && length <= 0x07d0) {
|
|
1617
|
+
if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).discreteInputs)) {
|
|
1618
|
+
try {
|
|
1619
|
+
const discreteInputs = yield Promise.resolve(model.readDiscreteInputs(address, length));
|
|
1620
|
+
const bufferTx = Buffer.alloc(Math.ceil(length / 8));
|
|
1621
|
+
discreteInputs.forEach((discreteInput, index) => {
|
|
1622
|
+
if (discreteInput) {
|
|
1623
|
+
bufferTx[~~(index / 8)] |= 1 << index % 8;
|
|
1624
|
+
}
|
|
1625
|
+
});
|
|
1626
|
+
yield response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: [bufferTx.length].concat(Array.from(bufferTx)) })));
|
|
1627
|
+
}
|
|
1628
|
+
catch (error) {
|
|
1629
|
+
yield this.responseError(frame, response, error);
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
else {
|
|
1633
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_ADDRESS));
|
|
1634
|
+
}
|
|
1684
1635
|
}
|
|
1685
1636
|
else {
|
|
1686
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1637
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_VALUE));
|
|
1687
1638
|
}
|
|
1688
1639
|
}
|
|
1689
1640
|
else {
|
|
1690
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1641
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1691
1642
|
}
|
|
1692
1643
|
}
|
|
1693
|
-
|
|
1694
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1695
|
-
}
|
|
1696
|
-
}
|
|
1644
|
+
});
|
|
1697
1645
|
}
|
|
1698
1646
|
handleFC3(model, frame, response) {
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
if (
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
if (
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1647
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1648
|
+
var _a;
|
|
1649
|
+
if (frame.data.length === 4) {
|
|
1650
|
+
if (model.readHoldingRegisters) {
|
|
1651
|
+
const bufferRx = Buffer.from(frame.data);
|
|
1652
|
+
const address = bufferRx.readUInt16BE(0);
|
|
1653
|
+
const length = bufferRx.readUInt16BE(2);
|
|
1654
|
+
if (length >= 0x0001 && length <= 0x007d) {
|
|
1655
|
+
if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).holdingRegisters)) {
|
|
1656
|
+
try {
|
|
1657
|
+
const registers = yield Promise.resolve(model.readHoldingRegisters(address, length));
|
|
1658
|
+
const bufferTx = Buffer.alloc(length * 2);
|
|
1659
|
+
registers.forEach((register, index) => {
|
|
1660
|
+
bufferTx.writeUInt16BE(register, index * 2);
|
|
1661
|
+
});
|
|
1662
|
+
yield response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: [bufferTx.length].concat(Array.from(bufferTx)) })));
|
|
1663
|
+
}
|
|
1664
|
+
catch (error) {
|
|
1665
|
+
yield this.responseError(frame, response, error);
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
else {
|
|
1669
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_ADDRESS));
|
|
1670
|
+
}
|
|
1718
1671
|
}
|
|
1719
1672
|
else {
|
|
1720
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1673
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_VALUE));
|
|
1721
1674
|
}
|
|
1722
1675
|
}
|
|
1723
1676
|
else {
|
|
1724
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1677
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1725
1678
|
}
|
|
1726
1679
|
}
|
|
1727
|
-
|
|
1728
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1729
|
-
}
|
|
1730
|
-
}
|
|
1680
|
+
});
|
|
1731
1681
|
}
|
|
1732
1682
|
handleFC4(model, frame, response) {
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
if (
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
if (
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1683
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1684
|
+
var _a;
|
|
1685
|
+
if (frame.data.length === 4) {
|
|
1686
|
+
if (model.readInputRegisters) {
|
|
1687
|
+
const bufferRx = Buffer.from(frame.data);
|
|
1688
|
+
const address = bufferRx.readUInt16BE(0);
|
|
1689
|
+
const length = bufferRx.readUInt16BE(2);
|
|
1690
|
+
if (length >= 0x0001 && length <= 0x007d) {
|
|
1691
|
+
if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).inputRegisters)) {
|
|
1692
|
+
try {
|
|
1693
|
+
const registers = yield Promise.resolve(model.readInputRegisters(address, length));
|
|
1694
|
+
const bufferTx = Buffer.alloc(length * 2);
|
|
1695
|
+
registers.forEach((register, index) => {
|
|
1696
|
+
bufferTx.writeUInt16BE(register, index * 2);
|
|
1697
|
+
});
|
|
1698
|
+
yield response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: [bufferTx.length].concat(Array.from(bufferTx)) })));
|
|
1699
|
+
}
|
|
1700
|
+
catch (error) {
|
|
1701
|
+
yield this.responseError(frame, response, error);
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
else {
|
|
1705
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_ADDRESS));
|
|
1706
|
+
}
|
|
1752
1707
|
}
|
|
1753
1708
|
else {
|
|
1754
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1709
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_VALUE));
|
|
1755
1710
|
}
|
|
1756
1711
|
}
|
|
1757
1712
|
else {
|
|
1758
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1713
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1759
1714
|
}
|
|
1760
1715
|
}
|
|
1761
|
-
|
|
1762
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1763
|
-
}
|
|
1764
|
-
}
|
|
1716
|
+
});
|
|
1765
1717
|
}
|
|
1766
1718
|
handleFC5(model, frame, response) {
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
if (
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
if (
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1719
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1720
|
+
var _a;
|
|
1721
|
+
if (frame.data.length === 4) {
|
|
1722
|
+
if (model.writeSingleCoil) {
|
|
1723
|
+
const bufferRx = Buffer.from(frame.data);
|
|
1724
|
+
const address = bufferRx.readUInt16BE(0);
|
|
1725
|
+
const value = bufferRx.readUInt16BE(2);
|
|
1726
|
+
if (value === 0x0000 || value === 0xff00) {
|
|
1727
|
+
if (checkRange(address, (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).coils)) {
|
|
1728
|
+
try {
|
|
1729
|
+
yield Promise.resolve(model.writeSingleCoil(address, value === 0xff00));
|
|
1730
|
+
yield response(this.applicationLayer.encode(frame));
|
|
1731
|
+
}
|
|
1732
|
+
catch (error) {
|
|
1733
|
+
yield this.responseError(frame, response, error);
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
else {
|
|
1737
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_ADDRESS));
|
|
1738
|
+
}
|
|
1782
1739
|
}
|
|
1783
1740
|
else {
|
|
1784
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1741
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_VALUE));
|
|
1785
1742
|
}
|
|
1786
1743
|
}
|
|
1787
1744
|
else {
|
|
1788
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1745
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1789
1746
|
}
|
|
1790
1747
|
}
|
|
1791
|
-
|
|
1792
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1793
|
-
}
|
|
1794
|
-
}
|
|
1748
|
+
});
|
|
1795
1749
|
}
|
|
1796
1750
|
handleFC6(model, frame, response) {
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
if (
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
if (
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1751
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1752
|
+
var _a;
|
|
1753
|
+
if (frame.data.length === 4) {
|
|
1754
|
+
if (model.writeSingleRegister) {
|
|
1755
|
+
const bufferRx = Buffer.from(frame.data);
|
|
1756
|
+
const address = bufferRx.readUInt16BE(0);
|
|
1757
|
+
const value = bufferRx.readUInt16BE(2);
|
|
1758
|
+
if (value >= 0x0000 && value <= 0xffff) {
|
|
1759
|
+
if (checkRange(address, (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).holdingRegisters)) {
|
|
1760
|
+
try {
|
|
1761
|
+
yield Promise.resolve(model.writeSingleRegister(address, value));
|
|
1762
|
+
yield response(this.applicationLayer.encode(frame));
|
|
1763
|
+
}
|
|
1764
|
+
catch (error) {
|
|
1765
|
+
yield this.responseError(frame, response, error);
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
else {
|
|
1769
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_ADDRESS));
|
|
1770
|
+
}
|
|
1812
1771
|
}
|
|
1813
1772
|
else {
|
|
1814
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1773
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_VALUE));
|
|
1815
1774
|
}
|
|
1816
1775
|
}
|
|
1817
1776
|
else {
|
|
1818
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1777
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1819
1778
|
}
|
|
1820
1779
|
}
|
|
1821
|
-
|
|
1822
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1823
|
-
}
|
|
1824
|
-
}
|
|
1780
|
+
});
|
|
1825
1781
|
}
|
|
1826
1782
|
handleFC15(model, frame, response) {
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
if (
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
if (
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1783
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1784
|
+
var _a;
|
|
1785
|
+
if (frame.data.length > 5 && frame.data.length === 5 + frame.data[4]) {
|
|
1786
|
+
if (model.writeMultipleCoils || model.writeSingleCoil) {
|
|
1787
|
+
const bufferRx = Buffer.from(frame.data);
|
|
1788
|
+
const address = bufferRx.readUInt16BE(0);
|
|
1789
|
+
const length = bufferRx.readUInt16BE(2);
|
|
1790
|
+
const byteCount = bufferRx[4];
|
|
1791
|
+
if (length >= 0x0001 && length <= 0x07b0 && byteCount === Math.ceil(length / 8)) {
|
|
1792
|
+
if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).coils)) {
|
|
1793
|
+
const value = Array.from({ length }).map((_, index) => (bufferRx[5 + ~~(index / 8)] & (1 << index % 8)) > 0);
|
|
1794
|
+
try {
|
|
1795
|
+
yield Promise.resolve(model.writeMultipleCoils
|
|
1796
|
+
? model.writeMultipleCoils(address, value)
|
|
1797
|
+
: Promise.all(value.map((v, i) => model.writeSingleCoil(address + i, v))));
|
|
1798
|
+
yield response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: Array.from(bufferRx).slice(0, 4) })));
|
|
1799
|
+
}
|
|
1800
|
+
catch (error) {
|
|
1801
|
+
yield this.responseError(frame, response, error);
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
else {
|
|
1805
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_ADDRESS));
|
|
1806
|
+
}
|
|
1846
1807
|
}
|
|
1847
1808
|
else {
|
|
1848
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1809
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_VALUE));
|
|
1849
1810
|
}
|
|
1850
1811
|
}
|
|
1851
1812
|
else {
|
|
1852
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1813
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1853
1814
|
}
|
|
1854
1815
|
}
|
|
1855
|
-
|
|
1856
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1857
|
-
}
|
|
1858
|
-
}
|
|
1816
|
+
});
|
|
1859
1817
|
}
|
|
1860
1818
|
handleFC16(model, frame, response) {
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
if (
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
if (
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1819
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1820
|
+
var _a;
|
|
1821
|
+
if (frame.data.length > 5 && frame.data.length === 5 + frame.data[4]) {
|
|
1822
|
+
if (model.writeMultipleRegisters || model.writeSingleRegister) {
|
|
1823
|
+
const bufferRx = Buffer.from(frame.data);
|
|
1824
|
+
const address = bufferRx.readUInt16BE(0);
|
|
1825
|
+
const length = bufferRx.readUInt16BE(2);
|
|
1826
|
+
const byteCount = bufferRx[4];
|
|
1827
|
+
if (length >= 0x0001 && length <= 0x007b && byteCount === length * 2) {
|
|
1828
|
+
if (checkRange([address, address + length], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).holdingRegisters)) {
|
|
1829
|
+
const value = Array.from({ length }).map((_, index) => bufferRx.readUInt16BE(5 + index * 2));
|
|
1830
|
+
try {
|
|
1831
|
+
yield Promise.resolve(model.writeMultipleRegisters
|
|
1832
|
+
? model.writeMultipleRegisters(address, value)
|
|
1833
|
+
: Promise.all(value.map((v, i) => model.writeSingleRegister(address + i, v))));
|
|
1834
|
+
yield response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: Array.from(bufferRx).slice(0, 4) })));
|
|
1835
|
+
}
|
|
1836
|
+
catch (error) {
|
|
1837
|
+
yield this.responseError(frame, response, error);
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
else {
|
|
1841
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_ADDRESS));
|
|
1842
|
+
}
|
|
1880
1843
|
}
|
|
1881
1844
|
else {
|
|
1882
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1845
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_VALUE));
|
|
1883
1846
|
}
|
|
1884
1847
|
}
|
|
1885
1848
|
else {
|
|
1886
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1849
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1887
1850
|
}
|
|
1888
1851
|
}
|
|
1889
|
-
|
|
1890
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1891
|
-
}
|
|
1892
|
-
}
|
|
1852
|
+
});
|
|
1893
1853
|
}
|
|
1894
1854
|
handleFC17(model, frame, response) {
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1855
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1856
|
+
var _a;
|
|
1857
|
+
if (frame.data.length === 0) {
|
|
1858
|
+
if (model.reportServerId) {
|
|
1859
|
+
try {
|
|
1860
|
+
const { serverId = (_a = model.unit) !== null && _a !== void 0 ? _a : 1, runIndicatorStatus = true, additionalData = [] } = yield Promise.resolve(model.reportServerId());
|
|
1861
|
+
yield response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: [2 + additionalData.length, serverId, runIndicatorStatus ? 0xff : 0x00].concat(additionalData) })));
|
|
1862
|
+
}
|
|
1863
|
+
catch (error) {
|
|
1864
|
+
yield this.responseError(frame, response, error);
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
else {
|
|
1868
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1869
|
+
}
|
|
1909
1870
|
}
|
|
1910
|
-
}
|
|
1871
|
+
});
|
|
1911
1872
|
}
|
|
1912
1873
|
handleFC22(model, frame, response) {
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
if (
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1874
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1875
|
+
var _a;
|
|
1876
|
+
if (frame.data.length === 6) {
|
|
1877
|
+
if (model.maskWriteRegister || (model.readHoldingRegisters && model.writeSingleRegister)) {
|
|
1878
|
+
const bufferRx = Buffer.from(frame.data);
|
|
1879
|
+
const address = bufferRx.readUInt16BE(0);
|
|
1880
|
+
const andMask = bufferRx.readUInt16BE(2);
|
|
1881
|
+
const orMask = bufferRx.readUInt16BE(4);
|
|
1882
|
+
if (checkRange(address, (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).holdingRegisters)) {
|
|
1883
|
+
try {
|
|
1884
|
+
yield Promise.resolve(model.maskWriteRegister
|
|
1885
|
+
? model.maskWriteRegister(address, andMask, orMask)
|
|
1886
|
+
: Promise.resolve(model.readHoldingRegisters(address, 1)).then(([value]) => {
|
|
1887
|
+
return Promise.resolve(model.writeSingleRegister(address, (value & andMask) | (orMask & (~andMask & 0xff))));
|
|
1888
|
+
}));
|
|
1889
|
+
yield response(this.applicationLayer.encode(frame));
|
|
1890
|
+
}
|
|
1891
|
+
catch (error) {
|
|
1892
|
+
yield this.responseError(frame, response, error);
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
else {
|
|
1896
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_ADDRESS));
|
|
1897
|
+
}
|
|
1932
1898
|
}
|
|
1933
1899
|
else {
|
|
1934
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1900
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1935
1901
|
}
|
|
1936
1902
|
}
|
|
1937
|
-
|
|
1938
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1939
|
-
}
|
|
1940
|
-
}
|
|
1903
|
+
});
|
|
1941
1904
|
}
|
|
1942
1905
|
handleFC23(model, frame, response) {
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
if (
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
length.read
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1906
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1907
|
+
var _a;
|
|
1908
|
+
if (frame.data.length > 9 && frame.data.length === 9 + frame.data[8]) {
|
|
1909
|
+
if (model.readHoldingRegisters && (model.writeMultipleRegisters || model.writeSingleRegister)) {
|
|
1910
|
+
const bufferRx = Buffer.from(frame.data);
|
|
1911
|
+
const address = {
|
|
1912
|
+
read: bufferRx.readUInt16BE(0),
|
|
1913
|
+
write: bufferRx.readUInt16BE(4),
|
|
1914
|
+
};
|
|
1915
|
+
const length = {
|
|
1916
|
+
read: bufferRx.readUInt16BE(2),
|
|
1917
|
+
write: bufferRx.readUInt16BE(6),
|
|
1918
|
+
};
|
|
1919
|
+
const byteCount = bufferRx[8];
|
|
1920
|
+
if (length.read >= 0x0001 &&
|
|
1921
|
+
length.read <= 0x007d &&
|
|
1922
|
+
length.write >= 0x0001 &&
|
|
1923
|
+
length.write <= 0x0079 &&
|
|
1924
|
+
byteCount === length.write * 2) {
|
|
1925
|
+
if (checkRange([address.read, address.read + length.read, address.write, address.write + length.write], (_a = model.getAddressRange) === null || _a === void 0 ? void 0 : _a.call(model).holdingRegisters)) {
|
|
1926
|
+
const value = Array.from({ length: length.write }).map((_, index) => bufferRx.readUInt16BE(9 + index * 2));
|
|
1927
|
+
try {
|
|
1928
|
+
yield Promise.resolve(model.writeMultipleRegisters
|
|
1929
|
+
? model.writeMultipleRegisters(address.write, value)
|
|
1930
|
+
: Promise.all(value.map((v, i) => model.writeSingleRegister(address.write + i, v))));
|
|
1931
|
+
const registers = yield Promise.resolve(model.readHoldingRegisters(address.read, length.read));
|
|
1932
|
+
const bufferTx = Buffer.alloc(length.read * 2);
|
|
1933
|
+
registers.forEach((register, index) => {
|
|
1934
|
+
bufferTx.writeUInt16BE(register, index * 2);
|
|
1935
|
+
});
|
|
1936
|
+
yield response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: [bufferTx.length].concat(Array.from(bufferTx)) })));
|
|
1937
|
+
}
|
|
1938
|
+
catch (error) {
|
|
1939
|
+
yield this.responseError(frame, response, error);
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
else {
|
|
1943
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_ADDRESS));
|
|
1944
|
+
}
|
|
1977
1945
|
}
|
|
1978
1946
|
else {
|
|
1979
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1947
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_VALUE));
|
|
1980
1948
|
}
|
|
1981
1949
|
}
|
|
1982
1950
|
else {
|
|
1983
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.
|
|
1951
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1984
1952
|
}
|
|
1985
1953
|
}
|
|
1986
|
-
|
|
1987
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
1988
|
-
}
|
|
1989
|
-
}
|
|
1954
|
+
});
|
|
1990
1955
|
}
|
|
1991
1956
|
handleFC43_14(model, frame, response) {
|
|
1992
|
-
|
|
1993
|
-
if (frame.data
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
objectID
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
case 0x02: {
|
|
2004
|
-
if (objectID >= 0x80 || (objectID > 0x06 && objectID < 0x80)) {
|
|
2005
|
-
objectID = 0x00;
|
|
1957
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1958
|
+
if (frame.data.length === 3) {
|
|
1959
|
+
if (frame.data[0] === 0x0e && model.readDeviceIdentification) {
|
|
1960
|
+
const readDeviceIDCode = frame.data[1];
|
|
1961
|
+
let objectID = frame.data[2];
|
|
1962
|
+
switch (readDeviceIDCode) {
|
|
1963
|
+
case 0x01: {
|
|
1964
|
+
if (objectID > 0x02 || (objectID > 0x06 && objectID < 0x80)) {
|
|
1965
|
+
objectID = 0x00;
|
|
1966
|
+
}
|
|
1967
|
+
break;
|
|
2006
1968
|
}
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
1969
|
+
case 0x02: {
|
|
1970
|
+
if (objectID >= 0x80 || (objectID > 0x06 && objectID < 0x80)) {
|
|
1971
|
+
objectID = 0x00;
|
|
1972
|
+
}
|
|
1973
|
+
break;
|
|
2012
1974
|
}
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
return;
|
|
1975
|
+
case 0x03: {
|
|
1976
|
+
if (objectID > 0x06 && objectID < 0x80) {
|
|
1977
|
+
objectID = 0x00;
|
|
1978
|
+
}
|
|
1979
|
+
break;
|
|
2019
1980
|
}
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
}
|
|
2027
|
-
Promise.resolve(model.readDeviceIdentification())
|
|
2028
|
-
.then((identification) => {
|
|
2029
|
-
const objects = new Map([
|
|
2030
|
-
[0x00, 'null'],
|
|
2031
|
-
[0x01, 'null'],
|
|
2032
|
-
[0x02, 'null'],
|
|
2033
|
-
]);
|
|
2034
|
-
for (const [key, value] of Object.entries(identification)) {
|
|
2035
|
-
const id = parseInt(key);
|
|
2036
|
-
if (!isNaN(id) && id >= 0 && id <= 255) {
|
|
2037
|
-
objects.set(id, value);
|
|
1981
|
+
case 0x04: {
|
|
1982
|
+
if (objectID > 0x06 && objectID < 0x80) {
|
|
1983
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_ADDRESS));
|
|
1984
|
+
return;
|
|
1985
|
+
}
|
|
1986
|
+
break;
|
|
2038
1987
|
}
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
if (readDeviceIDCode === 0x04) {
|
|
2042
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_ADDRESS));
|
|
1988
|
+
default: {
|
|
1989
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_VALUE));
|
|
2043
1990
|
return;
|
|
2044
1991
|
}
|
|
2045
|
-
objectID = 0x00;
|
|
2046
1992
|
}
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
}
|
|
2059
|
-
if (id > 0x80) {
|
|
2060
|
-
conformityLevel = 0x83;
|
|
2061
|
-
}
|
|
2062
|
-
if (objectID > id) {
|
|
2063
|
-
continue;
|
|
2064
|
-
}
|
|
2065
|
-
if (value.length > 245) {
|
|
2066
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.SERVER_DEVICE_FAILURE));
|
|
2067
|
-
return;
|
|
2068
|
-
}
|
|
2069
|
-
if (lastID !== 0) {
|
|
2070
|
-
continue;
|
|
2071
|
-
}
|
|
2072
|
-
if (value.length + 2 > 253 - totalLength) {
|
|
2073
|
-
if (lastID === 0) {
|
|
2074
|
-
lastID = id;
|
|
1993
|
+
try {
|
|
1994
|
+
const identification = yield Promise.resolve(model.readDeviceIdentification());
|
|
1995
|
+
const objects = new Map([
|
|
1996
|
+
[0x00, 'null'],
|
|
1997
|
+
[0x01, 'null'],
|
|
1998
|
+
[0x02, 'null'],
|
|
1999
|
+
]);
|
|
2000
|
+
for (const [key, value] of Object.entries(identification)) {
|
|
2001
|
+
const id = parseInt(key);
|
|
2002
|
+
if (!isNaN(id) && id >= 0 && id <= 255) {
|
|
2003
|
+
objects.set(id, value);
|
|
2075
2004
|
}
|
|
2076
2005
|
}
|
|
2077
|
-
|
|
2078
|
-
totalLength += value.length + 2;
|
|
2079
|
-
ids.push(id);
|
|
2006
|
+
if (!objects.has(objectID)) {
|
|
2080
2007
|
if (readDeviceIDCode === 0x04) {
|
|
2081
|
-
|
|
2008
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_DATA_ADDRESS));
|
|
2009
|
+
return;
|
|
2010
|
+
}
|
|
2011
|
+
objectID = 0x00;
|
|
2012
|
+
}
|
|
2013
|
+
const ids = [];
|
|
2014
|
+
let totalLength = 10;
|
|
2015
|
+
let lastID = 0;
|
|
2016
|
+
let conformityLevel = 0x81;
|
|
2017
|
+
for (const [id, value] of objects.entries()) {
|
|
2018
|
+
if (id < 0x00 || (id >= 0x07 && id <= 0x7f) || id > 0xff) {
|
|
2019
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.SERVER_DEVICE_FAILURE));
|
|
2020
|
+
return;
|
|
2021
|
+
}
|
|
2022
|
+
if (id > 0x02) {
|
|
2023
|
+
conformityLevel = 0x82;
|
|
2024
|
+
}
|
|
2025
|
+
if (id > 0x80) {
|
|
2026
|
+
conformityLevel = 0x83;
|
|
2027
|
+
}
|
|
2028
|
+
if (objectID > id) {
|
|
2029
|
+
continue;
|
|
2030
|
+
}
|
|
2031
|
+
if (value.length > 245) {
|
|
2032
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.SERVER_DEVICE_FAILURE));
|
|
2033
|
+
return;
|
|
2034
|
+
}
|
|
2035
|
+
if (lastID !== 0) {
|
|
2036
|
+
continue;
|
|
2037
|
+
}
|
|
2038
|
+
if (value.length + 2 > 253 - totalLength) {
|
|
2039
|
+
if (lastID === 0) {
|
|
2040
|
+
lastID = id;
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
else {
|
|
2044
|
+
totalLength += value.length + 2;
|
|
2045
|
+
ids.push(id);
|
|
2046
|
+
if (readDeviceIDCode === 0x04) {
|
|
2047
|
+
break;
|
|
2048
|
+
}
|
|
2082
2049
|
}
|
|
2083
2050
|
}
|
|
2051
|
+
ids.sort((a, b) => a - b);
|
|
2052
|
+
yield response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data: [0x0e, readDeviceIDCode, conformityLevel, lastID === 0 ? 0x00 : 0xff, lastID, ids.length].concat(ids
|
|
2053
|
+
.map((id) => {
|
|
2054
|
+
const value = objects.get(id);
|
|
2055
|
+
return [id, value.length].concat(Array.from(Buffer.from(value)));
|
|
2056
|
+
})
|
|
2057
|
+
.flat()) })));
|
|
2084
2058
|
}
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
})
|
|
2093
|
-
.catch((error) => {
|
|
2094
|
-
this.responseError(frame, response, error);
|
|
2095
|
-
});
|
|
2096
|
-
}
|
|
2097
|
-
else {
|
|
2098
|
-
this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
2059
|
+
catch (error) {
|
|
2060
|
+
yield this.responseError(frame, response, error);
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
else {
|
|
2064
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
2065
|
+
}
|
|
2099
2066
|
}
|
|
2100
|
-
}
|
|
2067
|
+
});
|
|
2101
2068
|
}
|
|
2102
2069
|
responseError(frame, response, error) {
|
|
2103
|
-
|
|
2070
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2071
|
+
yield response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { fc: frame.fc | 0x80, data: [getCodeByError(error)] })));
|
|
2072
|
+
});
|
|
2073
|
+
}
|
|
2074
|
+
_drain() {
|
|
2075
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2076
|
+
if (this._processing || this._queue.length === 0) {
|
|
2077
|
+
return;
|
|
2078
|
+
}
|
|
2079
|
+
this._processing = true;
|
|
2080
|
+
const { frame, response: _response } = this._queue.shift();
|
|
2081
|
+
try {
|
|
2082
|
+
yield this._processFrame(frame, _response);
|
|
2083
|
+
}
|
|
2084
|
+
catch (error) {
|
|
2085
|
+
this.emit('error', error);
|
|
2086
|
+
}
|
|
2087
|
+
finally {
|
|
2088
|
+
this._processing = false;
|
|
2089
|
+
if (this._queue.length > 0) {
|
|
2090
|
+
setImmediate(() => this._drain());
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
});
|
|
2094
|
+
}
|
|
2095
|
+
_processFrame(frame, _response) {
|
|
2096
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2097
|
+
const response = (data) => __awaiter(this, void 0, void 0, function* () {
|
|
2098
|
+
if (frame.unit === 0x00) {
|
|
2099
|
+
return;
|
|
2100
|
+
}
|
|
2101
|
+
try {
|
|
2102
|
+
yield _response(data);
|
|
2103
|
+
}
|
|
2104
|
+
catch (error) { }
|
|
2105
|
+
});
|
|
2106
|
+
for (const model of frame.unit === 0x00 ? this.models.values() : [this.models.get(frame.unit)]) {
|
|
2107
|
+
const res = yield this._intercept(model, frame, response);
|
|
2108
|
+
if (res !== 'break') {
|
|
2109
|
+
yield this._handleFC(model, frame, response);
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
});
|
|
2113
|
+
}
|
|
2114
|
+
_intercept(model, frame, response) {
|
|
2115
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2116
|
+
if (model.interceptor) {
|
|
2117
|
+
try {
|
|
2118
|
+
const data = yield model.interceptor(frame.fc, frame.data);
|
|
2119
|
+
if (data) {
|
|
2120
|
+
yield response(this.applicationLayer.encode(Object.assign(Object.assign({}, frame), { data })));
|
|
2121
|
+
return 'break';
|
|
2122
|
+
}
|
|
2123
|
+
}
|
|
2124
|
+
catch (error) {
|
|
2125
|
+
yield this.responseError(frame, response, error);
|
|
2126
|
+
return 'break';
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
});
|
|
2130
|
+
}
|
|
2131
|
+
_handleFC(model, frame, response) {
|
|
2132
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2133
|
+
switch (frame.fc) {
|
|
2134
|
+
case 0x01: {
|
|
2135
|
+
yield this.handleFC1(model, frame, response);
|
|
2136
|
+
break;
|
|
2137
|
+
}
|
|
2138
|
+
case 0x02: {
|
|
2139
|
+
yield this.handleFC2(model, frame, response);
|
|
2140
|
+
break;
|
|
2141
|
+
}
|
|
2142
|
+
case 0x03: {
|
|
2143
|
+
yield this.handleFC3(model, frame, response);
|
|
2144
|
+
break;
|
|
2145
|
+
}
|
|
2146
|
+
case 0x04: {
|
|
2147
|
+
yield this.handleFC4(model, frame, response);
|
|
2148
|
+
break;
|
|
2149
|
+
}
|
|
2150
|
+
case 0x05: {
|
|
2151
|
+
yield this.handleFC5(model, frame, response);
|
|
2152
|
+
break;
|
|
2153
|
+
}
|
|
2154
|
+
case 0x06: {
|
|
2155
|
+
yield this.handleFC6(model, frame, response);
|
|
2156
|
+
break;
|
|
2157
|
+
}
|
|
2158
|
+
case 0x0f: {
|
|
2159
|
+
yield this.handleFC15(model, frame, response);
|
|
2160
|
+
break;
|
|
2161
|
+
}
|
|
2162
|
+
case 0x10: {
|
|
2163
|
+
yield this.handleFC16(model, frame, response);
|
|
2164
|
+
break;
|
|
2165
|
+
}
|
|
2166
|
+
case 0x11: {
|
|
2167
|
+
yield this.handleFC17(model, frame, response);
|
|
2168
|
+
break;
|
|
2169
|
+
}
|
|
2170
|
+
case 0x16: {
|
|
2171
|
+
yield this.handleFC22(model, frame, response);
|
|
2172
|
+
break;
|
|
2173
|
+
}
|
|
2174
|
+
case 0x17: {
|
|
2175
|
+
yield this.handleFC23(model, frame, response);
|
|
2176
|
+
break;
|
|
2177
|
+
}
|
|
2178
|
+
case 0x2b: {
|
|
2179
|
+
yield this.handleFC43_14(model, frame, response);
|
|
2180
|
+
break;
|
|
2181
|
+
}
|
|
2182
|
+
default: {
|
|
2183
|
+
yield this.responseError(frame, response, getErrorByCode(exports.ErrorCode.ILLEGAL_FUNCTION));
|
|
2184
|
+
break;
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
});
|
|
2104
2188
|
}
|
|
2105
2189
|
add(model) {
|
|
2106
2190
|
var _a;
|