node-red-contrib-my-tools 1.0.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.txt +69 -0
- package/node-red-contrib-mysql-extended-test/mysql-extended.html +443 -0
- package/node-red-contrib-mysql-extended-test/mysql-extended.js +355 -0
- package/node-red-contrib-rfid-helper/rfid-lazy.html +153 -0
- package/node-red-contrib-rfid-helper/rfid-lazy.js +361 -0
- package/node-red-contrib-s7-plus/LICENSE +235 -0
- package/node-red-contrib-s7-plus/README.md +141 -0
- package/node-red-contrib-s7-plus/examples/read-multiple-values-flow.json +346 -0
- package/node-red-contrib-s7-plus/examples/read-write-test-flow.json +172 -0
- package/node-red-contrib-s7-plus/examples/write-single-values-flow.json +5583 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/README.md +72 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/areas.js +36 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/datatypes.js +91 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/flat-browser.js +433 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/index.js +22 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/lazy.js +397 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/node-id.js +22 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/resolve-symbolic.js +181 -0
- package/node-red-contrib-s7-plus/lib/s7plus/browse/vte-helpers.js +49 -0
- package/node-red-contrib-s7-plus/lib/s7plus/buffer-stream.js +96 -0
- package/node-red-contrib-s7-plus/lib/s7plus/client.js +1238 -0
- package/node-red-contrib-s7-plus/lib/s7plus/constants.js +155 -0
- package/node-red-contrib-s7-plus/lib/s7plus/crc/index.js +3 -0
- package/node-red-contrib-s7-plus/lib/s7plus/crc/s7-crc32.js +70 -0
- package/node-red-contrib-s7-plus/lib/s7plus/crc/symbol-crc.js +271 -0
- package/node-red-contrib-s7-plus/lib/s7plus/debug.js +88 -0
- package/node-red-contrib-s7-plus/lib/s7plus/explore-result.js +41 -0
- package/node-red-contrib-s7-plus/lib/s7plus/item-address.js +55 -0
- package/node-red-contrib-s7-plus/lib/s7plus/pdu-explore.js +77 -0
- package/node-red-contrib-s7-plus/lib/s7plus/pdu-messages.js +359 -0
- package/node-red-contrib-s7-plus/lib/s7plus/pobject.js +197 -0
- package/node-red-contrib-s7-plus/lib/s7plus/pvalue-codec.js +435 -0
- package/node-red-contrib-s7-plus/lib/s7plus/pvalue.js +653 -0
- package/node-red-contrib-s7-plus/lib/s7plus/pvar-lists.js +336 -0
- package/node-red-contrib-s7-plus/lib/s7plus/read-result.js +91 -0
- package/node-red-contrib-s7-plus/lib/s7plus/s7p.js +266 -0
- package/node-red-contrib-s7-plus/lib/s7plus/tag-routing.js +30 -0
- package/node-red-contrib-s7-plus/lib/s7plus/transport/cotp-stream.js +335 -0
- package/node-red-contrib-s7-plus/lib/s7plus/transport/s7-transport.js +335 -0
- package/node-red-contrib-s7-plus/nodes/icons/s7complus.png +0 -0
- package/node-red-contrib-s7-plus/nodes/icons/s7complus.svg +17 -0
- package/node-red-contrib-s7-plus/nodes/s7complus-endpoint.js +825 -0
- package/node-red-contrib-s7-plus/nodes/s7complus-explore.js +91 -0
- package/node-red-contrib-s7-plus/nodes/s7complus-in.js +255 -0
- package/node-red-contrib-s7-plus/nodes/s7complus-out.js +182 -0
- package/node-red-contrib-s7-plus/nodes/s7complus.html +1541 -0
- package/node-red-contrib-s7-plus/nodes/s7complus.js +10 -0
- package/node-red-contrib-s7-plus/package.json +50 -0
- package/node-red-contrib-s7-plus/plc/s7-1500/DB_Arrays.db +17 -0
- package/node-red-contrib-s7-plus/plc/s7-1500/DB_Binary.db +16 -0
- package/node-red-contrib-s7-plus/plc/s7-1500/DB_BitStrings.db +36 -0
- package/node-red-contrib-s7-plus/plc/s7-1500/DB_CharacterStrings.db +42 -0
- package/node-red-contrib-s7-plus/plc/s7-1500/DB_DateAndTime.db +70 -0
- package/node-red-contrib-s7-plus/plc/s7-1500/DB_FloatingPoint.db +42 -0
- package/node-red-contrib-s7-plus/plc/s7-1500/DB_Integers.db +72 -0
- package/node-red-contrib-s7-plus/plc/s7-1500/DB_Timers.db +40 -0
- package/node-red-contrib-s7-plus/scripts/example-flow-shared.js +39 -0
- package/node-red-contrib-s7-plus/scripts/generate-read-multiple-flow.js +331 -0
- package/node-red-contrib-s7-plus/scripts/generate-rw-test-flow.js +690 -0
- package/node-red-contrib-s7-plus/scripts/generate-write-flow.js +476 -0
- package/node-red-contrib-s7-plus/scripts/layout-write-flow.js +156 -0
- package/node-red-contrib-s7-plus/scripts/run-tests.js +16 -0
- package/node-red-flowgobal-change/variable-change.html +425 -0
- package/node-red-flowgobal-change/variable-change.js +92 -0
- package/node-red-ui_media_viewer/ui_media_viewer.html +87 -0
- package/node-red-ui_media_viewer/ui_media_viewer.js +136 -0
- package/package.json +12 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const BufferStream = require('./buffer-stream');
|
|
4
|
+
const S7p = require('./s7p');
|
|
5
|
+
const PObject = require('./pobject');
|
|
6
|
+
const { Opcode, Functioncode } = require('./constants');
|
|
7
|
+
|
|
8
|
+
function writeRequestHeader(buf, req) {
|
|
9
|
+
S7p.encodeByte(buf, Opcode.Request);
|
|
10
|
+
S7p.encodeUInt16(buf, 0);
|
|
11
|
+
S7p.encodeUInt16(buf, req.functionCode);
|
|
12
|
+
S7p.encodeUInt16(buf, 0);
|
|
13
|
+
S7p.encodeUInt16(buf, req.sequenceNumber);
|
|
14
|
+
S7p.encodeUInt32(buf, req.sessionId >>> 0);
|
|
15
|
+
S7p.encodeByte(buf, req.transportFlags);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
class ExploreRequest {
|
|
19
|
+
constructor(protocolVersion) {
|
|
20
|
+
this.protocolVersion = protocolVersion;
|
|
21
|
+
this.functionCode = Functioncode.Explore;
|
|
22
|
+
this.transportFlags = 0x34;
|
|
23
|
+
this.exploreId = 0;
|
|
24
|
+
this.exploreRequestId = 0;
|
|
25
|
+
this.exploreChildsRecursive = 1;
|
|
26
|
+
this.exploreParents = 0;
|
|
27
|
+
this.filterData = null;
|
|
28
|
+
this.addressList = [];
|
|
29
|
+
this.sessionId = 0;
|
|
30
|
+
this.sequenceNumber = 0;
|
|
31
|
+
this.integrityId = 0;
|
|
32
|
+
this.withIntegrityId = true;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
serialize() {
|
|
36
|
+
const buf = new BufferStream();
|
|
37
|
+
writeRequestHeader(buf, this);
|
|
38
|
+
S7p.encodeUInt32(buf, this.exploreId >>> 0);
|
|
39
|
+
S7p.encodeUInt32Vlq(buf, this.exploreRequestId >>> 0);
|
|
40
|
+
S7p.encodeByte(buf, this.exploreChildsRecursive);
|
|
41
|
+
S7p.encodeByte(buf, 1);
|
|
42
|
+
S7p.encodeByte(buf, this.exploreParents);
|
|
43
|
+
if (this.filterData) {
|
|
44
|
+
S7p.encodeByte(buf, 1);
|
|
45
|
+
this.filterData.serialize(buf);
|
|
46
|
+
}
|
|
47
|
+
S7p.encodeByte(buf, 0);
|
|
48
|
+
S7p.encodeUInt32Vlq(buf, this.addressList.length);
|
|
49
|
+
for (const id of this.addressList) S7p.encodeUInt32Vlq(buf, id >>> 0);
|
|
50
|
+
if (this.withIntegrityId) S7p.encodeUInt32Vlq(buf, this.integrityId >>> 0);
|
|
51
|
+
S7p.encodeUInt32(buf, 0);
|
|
52
|
+
S7p.encodeByte(buf, 0);
|
|
53
|
+
return buf.toBuffer();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
class ExploreResponse {
|
|
58
|
+
static deserializeFromPdu(pdu, withIntegrityId) {
|
|
59
|
+
const ver = pdu.readByte();
|
|
60
|
+
const op = pdu.readByte();
|
|
61
|
+
if (op !== Opcode.Response) return null;
|
|
62
|
+
S7p.decodeUInt16(pdu);
|
|
63
|
+
const fn = S7p.decodeUInt16(pdu).v;
|
|
64
|
+
S7p.decodeUInt16(pdu);
|
|
65
|
+
if (fn !== Functioncode.Explore) return null;
|
|
66
|
+
|
|
67
|
+
const seq = S7p.decodeUInt16(pdu).v;
|
|
68
|
+
pdu.readByte();
|
|
69
|
+
S7p.decodeUInt64Vlq(pdu);
|
|
70
|
+
S7p.decodeUInt32(pdu);
|
|
71
|
+
if (withIntegrityId) S7p.decodeUInt32Vlq(pdu);
|
|
72
|
+
const objects = PObject.decodeObjectList(pdu);
|
|
73
|
+
return { protocolVersion: ver, sequenceNumber: seq, objects };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
module.exports = { ExploreRequest, ExploreResponse };
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const BufferStream = require('./buffer-stream');
|
|
4
|
+
const S7p = require('./s7p');
|
|
5
|
+
const PObject = require('./pobject');
|
|
6
|
+
const { encodeObjectQualifier } = require('./pvalue');
|
|
7
|
+
const {
|
|
8
|
+
Opcode,
|
|
9
|
+
Functioncode,
|
|
10
|
+
ProtocolVersion,
|
|
11
|
+
Ids,
|
|
12
|
+
Datatype
|
|
13
|
+
} = require('./constants');
|
|
14
|
+
const ItemAddress = require('./item-address');
|
|
15
|
+
|
|
16
|
+
function writeRequestHeader(buf, req) {
|
|
17
|
+
let n = 0;
|
|
18
|
+
n += S7p.encodeByte(buf, Opcode.Request);
|
|
19
|
+
n += S7p.encodeUInt16(buf, 0);
|
|
20
|
+
n += S7p.encodeUInt16(buf, req.functionCode);
|
|
21
|
+
n += S7p.encodeUInt16(buf, 0);
|
|
22
|
+
n += S7p.encodeUInt16(buf, req.sequenceNumber);
|
|
23
|
+
n += S7p.encodeUInt32(buf, req.sessionId >>> 0);
|
|
24
|
+
n += S7p.encodeByte(buf, req.transportFlags);
|
|
25
|
+
return n;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function parseResponseHeader(pdu) {
|
|
29
|
+
const ver = pdu.readByte();
|
|
30
|
+
const op = pdu.readByte();
|
|
31
|
+
if (op !== Opcode.Response) return null;
|
|
32
|
+
S7p.decodeUInt16(pdu);
|
|
33
|
+
const fn = S7p.decodeUInt16(pdu).v;
|
|
34
|
+
S7p.decodeUInt16(pdu);
|
|
35
|
+
return { protocolVersion: ver, functionCode: fn };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
class InitSslRequest {
|
|
39
|
+
constructor(protocolVersion, seqNum, sessionId) {
|
|
40
|
+
this.protocolVersion = protocolVersion;
|
|
41
|
+
this.sequenceNumber = seqNum;
|
|
42
|
+
this.sessionId = sessionId;
|
|
43
|
+
this.functionCode = Functioncode.InitSsl;
|
|
44
|
+
this.transportFlags = 0x30;
|
|
45
|
+
this.withIntegrityId = false;
|
|
46
|
+
this.integrityId = 0;
|
|
47
|
+
}
|
|
48
|
+
serialize() {
|
|
49
|
+
const buf = new BufferStream();
|
|
50
|
+
writeRequestHeader(buf, this);
|
|
51
|
+
S7p.encodeUInt32(buf, 0);
|
|
52
|
+
return buf.toBuffer();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
class InitSslResponse {
|
|
57
|
+
static deserializeFromPdu(pdu) {
|
|
58
|
+
const h = parseResponseHeader(pdu);
|
|
59
|
+
if (!h || h.functionCode !== Functioncode.InitSsl) return null;
|
|
60
|
+
const seq = S7p.decodeUInt16(pdu).v;
|
|
61
|
+
S7p.decodeByte(pdu);
|
|
62
|
+
const rv = S7p.decodeUInt64Vlq(pdu).v;
|
|
63
|
+
return { sequenceNumber: seq, returnValue: rv };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
class CreateObjectRequest {
|
|
68
|
+
constructor(protocolVersion, seqNum, withIntegrityId) {
|
|
69
|
+
this.protocolVersion = protocolVersion;
|
|
70
|
+
this.sequenceNumber = seqNum;
|
|
71
|
+
this.withIntegrityId = withIntegrityId;
|
|
72
|
+
this.functionCode = Functioncode.CreateObject;
|
|
73
|
+
this.transportFlags = 0x36;
|
|
74
|
+
this.sessionId = 0;
|
|
75
|
+
this.integrityId = 0;
|
|
76
|
+
this.requestId = 0;
|
|
77
|
+
this.requestValue = null;
|
|
78
|
+
this.requestObject = null;
|
|
79
|
+
}
|
|
80
|
+
setNullServerSessionData() {
|
|
81
|
+
const { ValueUDInt, ValueRID } = require('./pvalue');
|
|
82
|
+
this.transportFlags = 0x36;
|
|
83
|
+
this.requestId = Ids.ObjectServerSessionContainer;
|
|
84
|
+
this.requestValue = new ValueUDInt(0);
|
|
85
|
+
const sess = new PObject(Ids.GetNewRIDOnServer, Ids.ClassServerSession, Ids.None);
|
|
86
|
+
sess.addAttribute(Ids.ServerSessionClientRID, new ValueRID(0x80c3c901));
|
|
87
|
+
sess.addObject(new PObject(Ids.GetNewRIDOnServer, Ids.ClassSubscriptions, Ids.None));
|
|
88
|
+
this.requestObject = sess;
|
|
89
|
+
}
|
|
90
|
+
serialize() {
|
|
91
|
+
const buf = new BufferStream();
|
|
92
|
+
writeRequestHeader(buf, this);
|
|
93
|
+
S7p.encodeUInt32(buf, this.requestId >>> 0);
|
|
94
|
+
this.requestValue.serialize(buf);
|
|
95
|
+
S7p.encodeUInt32(buf, 0);
|
|
96
|
+
if (this.withIntegrityId) S7p.encodeUInt32Vlq(buf, this.integrityId >>> 0);
|
|
97
|
+
this.requestObject.serialize(buf);
|
|
98
|
+
S7p.encodeUInt32(buf, 0);
|
|
99
|
+
return buf.toBuffer();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
class CreateObjectResponse {
|
|
104
|
+
static deserializeFromPdu(pdu) {
|
|
105
|
+
const h = parseResponseHeader(pdu);
|
|
106
|
+
if (!h || h.functionCode !== Functioncode.CreateObject) return null;
|
|
107
|
+
const seq = S7p.decodeUInt16(pdu).v;
|
|
108
|
+
S7p.decodeByte(pdu);
|
|
109
|
+
const returnValue = S7p.decodeUInt64Vlq(pdu).v;
|
|
110
|
+
const idCount = pdu.readByte();
|
|
111
|
+
const objectIds = [];
|
|
112
|
+
for (let i = 0; i < idCount; i++) {
|
|
113
|
+
objectIds.push(S7p.decodeUInt32Vlq(pdu).v);
|
|
114
|
+
}
|
|
115
|
+
const responseObject = PObject.decode(pdu);
|
|
116
|
+
return { sequenceNumber: seq, returnValue, objectIds, responseObject };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
class SetMultiVariablesRequest {
|
|
121
|
+
constructor(protocolVersion) {
|
|
122
|
+
this.protocolVersion = protocolVersion;
|
|
123
|
+
this.functionCode = Functioncode.SetMultiVariables;
|
|
124
|
+
this.transportFlags = 0x34;
|
|
125
|
+
this.withIntegrityId = true;
|
|
126
|
+
this.inObjectId = 0;
|
|
127
|
+
this.addressList = [];
|
|
128
|
+
this.addressListVar = [];
|
|
129
|
+
this.valueList = [];
|
|
130
|
+
this.sessionId = 0;
|
|
131
|
+
this.sequenceNumber = 0;
|
|
132
|
+
this.integrityId = 0;
|
|
133
|
+
}
|
|
134
|
+
setSessionSetupData(sessionId, sessionVersion) {
|
|
135
|
+
this.sessionId = sessionId;
|
|
136
|
+
this.inObjectId = sessionId;
|
|
137
|
+
this.addressList = [Ids.ServerSessionVersion];
|
|
138
|
+
this.valueList = [sessionVersion];
|
|
139
|
+
this.withIntegrityId = false;
|
|
140
|
+
}
|
|
141
|
+
serialize() {
|
|
142
|
+
const buf = new BufferStream();
|
|
143
|
+
writeRequestHeader(buf, this);
|
|
144
|
+
S7p.encodeUInt32(buf, this.inObjectId >>> 0);
|
|
145
|
+
S7p.encodeUInt32Vlq(buf, this.valueList.length);
|
|
146
|
+
if (this.inObjectId > 0) {
|
|
147
|
+
S7p.encodeUInt32Vlq(buf, this.addressList.length);
|
|
148
|
+
for (const id of this.addressList) S7p.encodeUInt32Vlq(buf, id >>> 0);
|
|
149
|
+
} else {
|
|
150
|
+
let fieldCount = 0;
|
|
151
|
+
for (const adr of this.addressListVar) fieldCount += adr.getNumberOfFields();
|
|
152
|
+
S7p.encodeUInt32Vlq(buf, fieldCount);
|
|
153
|
+
for (const adr of this.addressListVar) adr.serialize(buf);
|
|
154
|
+
}
|
|
155
|
+
let i = 1;
|
|
156
|
+
for (const val of this.valueList) {
|
|
157
|
+
S7p.encodeUInt32Vlq(buf, i++);
|
|
158
|
+
val.serialize(buf);
|
|
159
|
+
}
|
|
160
|
+
S7p.encodeByte(buf, 0);
|
|
161
|
+
encodeObjectQualifier(buf);
|
|
162
|
+
if (this.withIntegrityId) S7p.encodeUInt32Vlq(buf, this.integrityId >>> 0);
|
|
163
|
+
S7p.encodeUInt32(buf, 0);
|
|
164
|
+
return buf.toBuffer();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
class SetMultiVariablesResponse {
|
|
169
|
+
static deserializeFromPdu(pdu) {
|
|
170
|
+
const h = parseResponseHeader(pdu);
|
|
171
|
+
if (!h || h.functionCode !== Functioncode.SetMultiVariables) return null;
|
|
172
|
+
const seq = S7p.decodeUInt16(pdu).v;
|
|
173
|
+
S7p.decodeByte(pdu);
|
|
174
|
+
const returnValue = S7p.decodeUInt64Vlq(pdu).v;
|
|
175
|
+
let itemnr = S7p.decodeUInt32Vlq(pdu).v;
|
|
176
|
+
const errorValues = new Map();
|
|
177
|
+
while (itemnr > 0) {
|
|
178
|
+
const rv = S7p.decodeUInt64Vlq(pdu).v;
|
|
179
|
+
errorValues.set(itemnr, rv);
|
|
180
|
+
itemnr = S7p.decodeUInt32Vlq(pdu).v;
|
|
181
|
+
}
|
|
182
|
+
const integrityId = S7p.decodeUInt32Vlq(pdu).v;
|
|
183
|
+
return { sequenceNumber: seq, returnValue, errorValues, integrityId };
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
class GetMultiVariablesRequest {
|
|
188
|
+
constructor(protocolVersion) {
|
|
189
|
+
this.protocolVersion = protocolVersion;
|
|
190
|
+
this.functionCode = Functioncode.GetMultiVariables;
|
|
191
|
+
this.transportFlags = 0x34;
|
|
192
|
+
this.linkId = 0;
|
|
193
|
+
this.addressList = [];
|
|
194
|
+
this.withIntegrityId = true;
|
|
195
|
+
this.sessionId = 0;
|
|
196
|
+
this.sequenceNumber = 0;
|
|
197
|
+
this.integrityId = 0;
|
|
198
|
+
}
|
|
199
|
+
serialize() {
|
|
200
|
+
const buf = new BufferStream();
|
|
201
|
+
writeRequestHeader(buf, this);
|
|
202
|
+
S7p.encodeUInt32(buf, this.linkId >>> 0);
|
|
203
|
+
S7p.encodeUInt32Vlq(buf, this.addressList.length);
|
|
204
|
+
let fieldCount = 0;
|
|
205
|
+
for (const adr of this.addressList) fieldCount += adr.getNumberOfFields();
|
|
206
|
+
S7p.encodeUInt32Vlq(buf, fieldCount);
|
|
207
|
+
for (const adr of this.addressList) adr.serialize(buf);
|
|
208
|
+
encodeObjectQualifier(buf);
|
|
209
|
+
if (this.withIntegrityId) S7p.encodeUInt32Vlq(buf, this.integrityId >>> 0);
|
|
210
|
+
S7p.encodeUInt32(buf, 0);
|
|
211
|
+
return buf.toBuffer();
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
class GetMultiVariablesResponse {
|
|
216
|
+
static deserializeFromPdu(pdu) {
|
|
217
|
+
const h = parseResponseHeader(pdu);
|
|
218
|
+
if (!h || h.functionCode !== Functioncode.GetMultiVariables) return null;
|
|
219
|
+
const pvalue = require('./pvalue');
|
|
220
|
+
const seq = S7p.decodeUInt16(pdu).v;
|
|
221
|
+
S7p.decodeByte(pdu);
|
|
222
|
+
const returnValue = S7p.decodeUInt64Vlq(pdu).v;
|
|
223
|
+
const values = new Map();
|
|
224
|
+
let itemnr = S7p.decodeUInt32Vlq(pdu).v;
|
|
225
|
+
while (itemnr > 0) {
|
|
226
|
+
values.set(itemnr, pvalue.deserialize(pdu));
|
|
227
|
+
itemnr = S7p.decodeUInt32Vlq(pdu).v;
|
|
228
|
+
}
|
|
229
|
+
const errorValues = new Map();
|
|
230
|
+
itemnr = S7p.decodeUInt32Vlq(pdu).v;
|
|
231
|
+
while (itemnr > 0) {
|
|
232
|
+
const rv = S7p.decodeUInt64Vlq(pdu).v;
|
|
233
|
+
errorValues.set(itemnr, rv);
|
|
234
|
+
itemnr = S7p.decodeUInt32Vlq(pdu).v;
|
|
235
|
+
}
|
|
236
|
+
const integrityId = S7p.decodeUInt32Vlq(pdu).v;
|
|
237
|
+
return { sequenceNumber: seq, returnValue, values, errorValues, integrityId };
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
class DeleteObjectRequest {
|
|
242
|
+
constructor(protocolVersion) {
|
|
243
|
+
this.protocolVersion = protocolVersion;
|
|
244
|
+
this.functionCode = Functioncode.DeleteObject;
|
|
245
|
+
this.transportFlags = 0x34;
|
|
246
|
+
this.deleteObjectId = 0;
|
|
247
|
+
this.withIntegrityId = true;
|
|
248
|
+
this.sessionId = 0;
|
|
249
|
+
this.sequenceNumber = 0;
|
|
250
|
+
this.integrityId = 0;
|
|
251
|
+
}
|
|
252
|
+
serialize() {
|
|
253
|
+
const buf = new BufferStream();
|
|
254
|
+
writeRequestHeader(buf, this);
|
|
255
|
+
S7p.encodeUInt32(buf, this.deleteObjectId >>> 0);
|
|
256
|
+
if (this.withIntegrityId) S7p.encodeUInt32Vlq(buf, this.integrityId >>> 0);
|
|
257
|
+
S7p.encodeUInt32(buf, 0);
|
|
258
|
+
return buf.toBuffer();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
class GetVarSubstreamedRequest {
|
|
263
|
+
constructor(protocolVersion) {
|
|
264
|
+
this.protocolVersion = protocolVersion;
|
|
265
|
+
this.functionCode = Functioncode.GetVarSubStreamed;
|
|
266
|
+
this.transportFlags = 0x34;
|
|
267
|
+
this.inObjectId = 0;
|
|
268
|
+
this.address = 0;
|
|
269
|
+
this.withIntegrityId = true;
|
|
270
|
+
this.sessionId = 0;
|
|
271
|
+
this.sequenceNumber = 0;
|
|
272
|
+
this.integrityId = 0;
|
|
273
|
+
}
|
|
274
|
+
serialize() {
|
|
275
|
+
const buf = new BufferStream();
|
|
276
|
+
writeRequestHeader(buf, this);
|
|
277
|
+
S7p.encodeUInt32(buf, this.inObjectId >>> 0);
|
|
278
|
+
S7p.encodeByte(buf, 0x20);
|
|
279
|
+
S7p.encodeByte(buf, Datatype.UDInt);
|
|
280
|
+
S7p.encodeByte(buf, 1);
|
|
281
|
+
S7p.encodeUInt32Vlq(buf, this.address >>> 0);
|
|
282
|
+
encodeObjectQualifier(buf);
|
|
283
|
+
S7p.encodeUInt16(buf, 0x0001);
|
|
284
|
+
if (this.withIntegrityId) S7p.encodeUInt32Vlq(buf, this.integrityId >>> 0);
|
|
285
|
+
S7p.encodeUInt32(buf, 0);
|
|
286
|
+
return buf.toBuffer();
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
class GetVarSubstreamedResponse {
|
|
291
|
+
static deserializeFromPdu(pdu) {
|
|
292
|
+
const h = parseResponseHeader(pdu);
|
|
293
|
+
if (!h || h.functionCode !== Functioncode.GetVarSubStreamed) return null;
|
|
294
|
+
const pvalue = require('./pvalue');
|
|
295
|
+
const seq = S7p.decodeUInt16(pdu).v;
|
|
296
|
+
S7p.decodeByte(pdu);
|
|
297
|
+
const returnValue = S7p.decodeUInt64Vlq(pdu).v;
|
|
298
|
+
const value = pvalue.deserialize(pdu);
|
|
299
|
+
const integrityId = S7p.decodeUInt32Vlq(pdu).v;
|
|
300
|
+
return { sequenceNumber: seq, returnValue, value, integrityId };
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
class SetVariableRequest {
|
|
305
|
+
constructor(protocolVersion) {
|
|
306
|
+
this.protocolVersion = protocolVersion;
|
|
307
|
+
this.functionCode = Functioncode.SetVariable;
|
|
308
|
+
this.transportFlags = 0x34;
|
|
309
|
+
this.inObjectId = 0;
|
|
310
|
+
this.address = 0;
|
|
311
|
+
this.value = null;
|
|
312
|
+
this.withIntegrityId = true;
|
|
313
|
+
this.sessionId = 0;
|
|
314
|
+
this.sequenceNumber = 0;
|
|
315
|
+
this.integrityId = 0;
|
|
316
|
+
}
|
|
317
|
+
serialize() {
|
|
318
|
+
const buf = new BufferStream();
|
|
319
|
+
writeRequestHeader(buf, this);
|
|
320
|
+
S7p.encodeUInt32(buf, this.inObjectId >>> 0);
|
|
321
|
+
S7p.encodeByte(buf, 0x20);
|
|
322
|
+
S7p.encodeByte(buf, Datatype.UDInt);
|
|
323
|
+
S7p.encodeByte(buf, 1);
|
|
324
|
+
S7p.encodeUInt32Vlq(buf, this.address >>> 0);
|
|
325
|
+
this.value.serialize(buf);
|
|
326
|
+
encodeObjectQualifier(buf);
|
|
327
|
+
S7p.encodeUInt16(buf, 0x0001);
|
|
328
|
+
if (this.withIntegrityId) S7p.encodeUInt32Vlq(buf, this.integrityId >>> 0);
|
|
329
|
+
S7p.encodeUInt32(buf, 0);
|
|
330
|
+
return buf.toBuffer();
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
class SetVariableResponse {
|
|
335
|
+
static deserializeFromPdu(pdu) {
|
|
336
|
+
const h = parseResponseHeader(pdu);
|
|
337
|
+
if (!h || h.functionCode !== Functioncode.SetVariable) return null;
|
|
338
|
+
const seq = S7p.decodeUInt16(pdu).v;
|
|
339
|
+
S7p.decodeByte(pdu);
|
|
340
|
+
const returnValue = S7p.decodeUInt64Vlq(pdu).v;
|
|
341
|
+
return { sequenceNumber: seq, returnValue };
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
module.exports = {
|
|
346
|
+
InitSslRequest,
|
|
347
|
+
InitSslResponse,
|
|
348
|
+
CreateObjectRequest,
|
|
349
|
+
CreateObjectResponse,
|
|
350
|
+
SetMultiVariablesRequest,
|
|
351
|
+
SetMultiVariablesResponse,
|
|
352
|
+
GetMultiVariablesRequest,
|
|
353
|
+
GetMultiVariablesResponse,
|
|
354
|
+
DeleteObjectRequest,
|
|
355
|
+
GetVarSubstreamedRequest,
|
|
356
|
+
GetVarSubstreamedResponse,
|
|
357
|
+
SetVariableRequest,
|
|
358
|
+
SetVariableResponse
|
|
359
|
+
};
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const S7p = require('./s7p');
|
|
4
|
+
const { ElementID } = require('./constants');
|
|
5
|
+
const { PVartypeList, PVarnameList } = require('./pvar-lists');
|
|
6
|
+
|
|
7
|
+
class PObject {
|
|
8
|
+
constructor(rid = 0, clsid = 0, aid = 0) {
|
|
9
|
+
this.relationId = rid;
|
|
10
|
+
this.classId = clsid;
|
|
11
|
+
this.classFlags = 0;
|
|
12
|
+
this.attributeId = aid;
|
|
13
|
+
this.attributes = new Map();
|
|
14
|
+
this.objects = [];
|
|
15
|
+
this.relations = new Map();
|
|
16
|
+
this.vartypeList = null;
|
|
17
|
+
this.varnameList = null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
addAttribute(id, value) {
|
|
21
|
+
this.attributes.set(id, value);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getAttribute(id) {
|
|
25
|
+
return this.attributes.get(id);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
addObject(obj) {
|
|
29
|
+
this.objects.push(obj);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getObjects() {
|
|
33
|
+
return this.objects;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getObjectByRelationId(relId) {
|
|
37
|
+
return this.objects.find(o => o.relationId === relId) || null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
serialize(buf) {
|
|
41
|
+
let ret = 0;
|
|
42
|
+
ret += S7p.encodeByte(buf, ElementID.StartOfObject);
|
|
43
|
+
ret += S7p.encodeUInt32(buf, this.relationId >>> 0);
|
|
44
|
+
ret += S7p.encodeUInt32Vlq(buf, this.classId >>> 0);
|
|
45
|
+
ret += S7p.encodeUInt32Vlq(buf, this.classFlags >>> 0);
|
|
46
|
+
ret += S7p.encodeUInt32Vlq(buf, this.attributeId >>> 0);
|
|
47
|
+
for (const [k, v] of this.attributes) {
|
|
48
|
+
ret += S7p.encodeByte(buf, ElementID.Attribute);
|
|
49
|
+
ret += S7p.encodeUInt32Vlq(buf, k >>> 0);
|
|
50
|
+
ret += v.serialize(buf);
|
|
51
|
+
}
|
|
52
|
+
for (const o of this.objects) ret += o.serialize(buf);
|
|
53
|
+
for (const [k, v] of this.relations) {
|
|
54
|
+
ret += S7p.encodeByte(buf, ElementID.Relation);
|
|
55
|
+
ret += S7p.encodeUInt32Vlq(buf, k >>> 0);
|
|
56
|
+
ret += S7p.encodeUInt32(buf, v >>> 0);
|
|
57
|
+
}
|
|
58
|
+
ret += S7p.encodeByte(buf, ElementID.TerminatingObject);
|
|
59
|
+
return ret;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static decodeObjectList(buf) {
|
|
63
|
+
const list = [];
|
|
64
|
+
let tagId = buf.readByte();
|
|
65
|
+
if (tagId === null) return list;
|
|
66
|
+
buf.position -= 1;
|
|
67
|
+
while (tagId === ElementID.StartOfObject) {
|
|
68
|
+
list.push(PObject.decodeObject(buf, true));
|
|
69
|
+
tagId = buf.readByte();
|
|
70
|
+
if (tagId === null) break;
|
|
71
|
+
buf.position -= 1;
|
|
72
|
+
}
|
|
73
|
+
return list;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static decodeObject(buf, asList = false) {
|
|
77
|
+
let obj = null;
|
|
78
|
+
let terminate = false;
|
|
79
|
+
while (!terminate) {
|
|
80
|
+
const tag = buf.readByte();
|
|
81
|
+
if (tag === null) break;
|
|
82
|
+
switch (tag) {
|
|
83
|
+
case ElementID.StartOfObject: {
|
|
84
|
+
if (obj === null) {
|
|
85
|
+
obj = new PObject();
|
|
86
|
+
obj.relationId = S7p.decodeUInt32(buf).v;
|
|
87
|
+
obj.classId = S7p.decodeUInt32Vlq(buf).v;
|
|
88
|
+
obj.classFlags = S7p.decodeUInt32Vlq(buf).v;
|
|
89
|
+
obj.attributeId = S7p.decodeUInt32Vlq(buf).v;
|
|
90
|
+
if (!asList) {
|
|
91
|
+
PObject._decodeInner(buf, obj);
|
|
92
|
+
terminate = true;
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
const child = new PObject();
|
|
96
|
+
child.relationId = S7p.decodeUInt32(buf).v;
|
|
97
|
+
child.classId = S7p.decodeUInt32Vlq(buf).v;
|
|
98
|
+
child.classFlags = S7p.decodeUInt32Vlq(buf).v;
|
|
99
|
+
child.attributeId = S7p.decodeUInt32Vlq(buf).v;
|
|
100
|
+
PObject._decodeInner(buf, child);
|
|
101
|
+
obj.addObject(child);
|
|
102
|
+
}
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
case ElementID.TerminatingObject:
|
|
106
|
+
terminate = true;
|
|
107
|
+
break;
|
|
108
|
+
case ElementID.Attribute: {
|
|
109
|
+
const id = S7p.decodeUInt32Vlq(buf).v;
|
|
110
|
+
const val = require('./pvalue').deserialize(buf);
|
|
111
|
+
obj.addAttribute(id, val);
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
case 0xaa: // StartOfTagDescription — skip (legacy 1200)
|
|
115
|
+
break;
|
|
116
|
+
case ElementID.VartypeList: {
|
|
117
|
+
const typelist = new PVartypeList();
|
|
118
|
+
typelist.deserialize(buf);
|
|
119
|
+
obj.vartypeList = typelist;
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
case ElementID.VarnameList: {
|
|
123
|
+
const namelist = new PVarnameList();
|
|
124
|
+
namelist.deserialize(buf);
|
|
125
|
+
obj.varnameList = namelist;
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
case ElementID.Relation: {
|
|
129
|
+
const relId = S7p.decodeUInt32Vlq(buf).v;
|
|
130
|
+
const val = S7p.decodeUInt32(buf).v;
|
|
131
|
+
obj.relations.set(relId, val);
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
default:
|
|
135
|
+
terminate = true;
|
|
136
|
+
buf.position -= 1;
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return obj || new PObject();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
static _decodeInner(buf, obj) {
|
|
144
|
+
let terminate = false;
|
|
145
|
+
while (!terminate) {
|
|
146
|
+
const tag = buf.readByte();
|
|
147
|
+
if (tag === null) break;
|
|
148
|
+
switch (tag) {
|
|
149
|
+
case ElementID.StartOfObject: {
|
|
150
|
+
buf.position -= 1;
|
|
151
|
+
obj.addObject(PObject.decodeObject(buf, true));
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
case ElementID.TerminatingObject:
|
|
155
|
+
terminate = true;
|
|
156
|
+
break;
|
|
157
|
+
case ElementID.Attribute: {
|
|
158
|
+
const id = S7p.decodeUInt32Vlq(buf).v;
|
|
159
|
+
const val = require('./pvalue').deserialize(buf);
|
|
160
|
+
obj.addAttribute(id, val);
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
case 0xaa:
|
|
164
|
+
break;
|
|
165
|
+
case ElementID.VartypeList: {
|
|
166
|
+
const typelist = new PVartypeList();
|
|
167
|
+
typelist.deserialize(buf);
|
|
168
|
+
obj.vartypeList = typelist;
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
case ElementID.VarnameList: {
|
|
172
|
+
const namelist = new PVarnameList();
|
|
173
|
+
namelist.deserialize(buf);
|
|
174
|
+
obj.varnameList = namelist;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
case ElementID.Relation: {
|
|
178
|
+
const relId = S7p.decodeUInt32Vlq(buf).v;
|
|
179
|
+
const val = S7p.decodeUInt32(buf).v;
|
|
180
|
+
obj.relations.set(relId, val);
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
default:
|
|
184
|
+
terminate = true;
|
|
185
|
+
buf.position -= 1;
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/** @deprecated use decodeObject */
|
|
192
|
+
static decode(buf, asList = false) {
|
|
193
|
+
return PObject.decodeObject(buf, asList);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
module.exports = PObject;
|