forked from fh1ch/node-bacstack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnpdu.js
More file actions
118 lines (107 loc) · 3.96 KB
/
Copy pathnpdu.js
File metadata and controls
118 lines (107 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
'use strict';
const baEnum = require('./enum');
const BACNET_PROTOCOL_VERSION = 1;
const BacnetAddressTypes = {
NONE: 0,
IP: 1
};
module.exports.decodeFunction = (buffer, offset) => {
if (buffer[offset + 0] !== BACNET_PROTOCOL_VERSION) return;
return buffer[offset + 1];
};
module.exports.decode = (buffer, offset) => {
let adrLen;
const orgOffset = offset;
offset++;
const funct = buffer[offset++];
let destination;
if ((funct & baEnum.NpduControls.DESTINATION_SPECIFIED) === baEnum.NpduControls.DESTINATION_SPECIFIED) {
destination = {type: BacnetAddressTypes.NONE, net: (buffer[offset++] << 8) | (buffer[offset++] << 0)};
adrLen = buffer[offset++];
if (adrLen > 0) {
destination.adr = new Array(adrLen);
for (let i = 0; i < destination.adr.length; i++) {
destination.adr[i] = buffer[offset++];
}
}
}
let source;
if ((funct & baEnum.NpduControls.SOURCE_SPECIFIED) === baEnum.NpduControls.SOURCE_SPECIFIED) {
source = {type: BacnetAddressTypes.NONE, net: (buffer[offset++] << 8) | (buffer[offset++] << 0)};
adrLen = buffer[offset++];
if (adrLen > 0) {
source.adr = new Array(adrLen);
for (let i = 0; i < source.adr.length; i++) {
source.adr[i] = buffer[offset++];
}
}
}
let hopCount = 0;
if ((funct & baEnum.NpduControls.DESTINATION_SPECIFIED) === baEnum.NpduControls.DESTINATION_SPECIFIED) {
hopCount = buffer[offset++];
}
let networkMsgType = baEnum.NetworkMessageTypes.NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK;
let vendorId = 0;
if ((funct & baEnum.NpduControls.NETWORK_LAYER_MESSAGE) === baEnum.NpduControls.NETWORK_LAYER_MESSAGE) {
networkMsgType = buffer[offset++];
if (networkMsgType >= 0x80) {
vendorId = (buffer[offset++] << 8) | (buffer[offset++] << 0);
} else if (networkMsgType === baEnum.NetworkMessageTypes.NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK) {
offset += 2;
}
}
if (buffer[orgOffset + 0] !== BACNET_PROTOCOL_VERSION) return;
return {
len: offset - orgOffset,
funct: funct,
destination: destination,
source: source,
hopCount: hopCount,
networkMsgType: networkMsgType,
vendorId: vendorId
};
};
module.exports.encode = (buffer, funct, destination, source, hopCount, networkMsgType, vendorId) => {
const hasDestination = destination && destination.net > 0;
const hasSource = source && source.net > 0 && source.net !== 0xFFFF;
buffer.buffer[buffer.offset++] = BACNET_PROTOCOL_VERSION;
buffer.buffer[buffer.offset++] = funct | (hasDestination ? baEnum.NpduControls.DESTINATION_SPECIFIED : 0) | (hasSource ? baEnum.NpduControls.SOURCE_SPECIFIED : 0);
if (hasDestination) {
buffer.buffer[buffer.offset++] = (destination.net & 0xFF00) >> 8;
buffer.buffer[buffer.offset++] = (destination.net & 0x00FF) >> 0;
if (destination.net === 0xFFFF) {
buffer.buffer[buffer.offset++] = 0;
} else {
buffer.buffer[buffer.offset++] = destination.adr.length;
if (destination.adr.length > 0) {
for (let i = 0; i < destination.adr.length; i++) {
buffer.buffer[buffer.offset++] = destination.adr[i];
}
}
}
}
if (hasSource) {
buffer.buffer[buffer.offset++] = (source.net & 0xFF00) >> 8;
buffer.buffer[buffer.offset++] = (source.net & 0x00FF) >> 0;
if (destination.net === 0xFFFF) {
buffer.buffer[buffer.offset++] = 0;
} else {
buffer.buffer[buffer.offset++] = destination.adr.length;
if (destination.adr.length > 0) {
for (let i = 0; i < destination.adr.length; i++) {
buffer.buffer[buffer.offset++] = destination.adr[i];
}
}
}
}
if (hasDestination) {
buffer.buffer[buffer.offset++] = hopCount;
}
if ((funct & baEnum.NpduControls.NETWORK_LAYER_MESSAGE) > 0) {
buffer.buffer[buffer.offset++] = networkMsgType;
if (networkMsgType >= 0x80) {
buffer.buffer[buffer.offset++] = (vendorId & 0xFF00) >> 8;
buffer.buffer[buffer.offset++] = (vendorId & 0x00FF) >> 0;
}
}
};