node-opcua-packet-analyzer 2.51.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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014-2021 Etienne Rossignon
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1 @@
1
+ export { analyzePacket, analyseExtensionObject, analyze_object_binary_encoding } from "./packet_analyzer/packet_analyzer";
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.analyze_object_binary_encoding = exports.analyseExtensionObject = exports.analyzePacket = void 0;
4
+ var packet_analyzer_1 = require("./packet_analyzer/packet_analyzer");
5
+ Object.defineProperty(exports, "analyzePacket", { enumerable: true, get: function () { return packet_analyzer_1.analyzePacket; } });
6
+ Object.defineProperty(exports, "analyseExtensionObject", { enumerable: true, get: function () { return packet_analyzer_1.analyseExtensionObject; } });
7
+ Object.defineProperty(exports, "analyze_object_binary_encoding", { enumerable: true, get: function () { return packet_analyzer_1.analyze_object_binary_encoding; } });
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../source/index.ts"],"names":[],"mappings":";;;AAAA,qEAI2C;AAHvC,gHAAA,aAAa,OAAA;AACb,yHAAA,sBAAsB,OAAA;AACtB,iIAAA,8BAA8B,OAAA"}
@@ -0,0 +1,8 @@
1
+ /// <reference types="node" />
2
+ import { BaseUAObject } from "node-opcua-factory";
3
+ interface AnalyzePacketOptions {
4
+ }
5
+ export declare function analyzePacket(buffer: Buffer, objMessage: any, padding: number, offset?: number, customOptions?: AnalyzePacketOptions): void;
6
+ export declare function analyseExtensionObject(buffer: Buffer, padding: number, offset: number, customOptions?: AnalyzePacketOptions): void;
7
+ export declare function analyze_object_binary_encoding(obj: BaseUAObject): void;
8
+ export {};
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ // tslint:disable:no-bitwise
3
+ // tslint:disable:no-console
4
+ // tslint:disable:max-line-length
5
+ // tslint:disable:no-empty-interface
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.analyze_object_binary_encoding = exports.analyseExtensionObject = exports.analyzePacket = void 0;
8
+ const chalk = require("chalk");
9
+ const node_opcua_assert_1 = require("node-opcua-assert");
10
+ const util_1 = require("util");
11
+ const node_opcua_basic_types_1 = require("node-opcua-basic-types");
12
+ const node_opcua_binary_stream_1 = require("node-opcua-binary-stream");
13
+ const node_opcua_debug_1 = require("node-opcua-debug");
14
+ const node_opcua_factory_1 = require("node-opcua-factory");
15
+ const node_opcua_utils_1 = require("node-opcua-utils");
16
+ const spaces = " ";
17
+ function f(n, width) {
18
+ const s = n.toString();
19
+ return (s + " ").substr(0, Math.max(s.length, width));
20
+ }
21
+ function display_encoding_mask(padding, encodingMask, encodingInfo) {
22
+ for (const v in encodingInfo) {
23
+ if (!encodingInfo.hasOwnProperty(v)) {
24
+ continue;
25
+ }
26
+ const enumKey = encodingInfo[v];
27
+ if (typeof enumKey === "number") {
28
+ continue;
29
+ }
30
+ const mask = encodingInfo[enumKey];
31
+ const bit = Math.log(mask) / Math.log(2);
32
+ const bits = [".", ".", ".", ".", ".", ".", ".", ".", "."];
33
+ bits[bit] = (encodingMask & mask) === mask ? "Y" : "n";
34
+ console.log(padding + " ", bits.join(""), " <- has " + enumKey + " 0x" + mask.toString(16));
35
+ }
36
+ // DataValueEncodingByte
37
+ }
38
+ function hex_block(start, end, buffer) {
39
+ const n = end - start;
40
+ const strBuf = (0, node_opcua_utils_1.buffer_ellipsis)(buffer);
41
+ return (chalk.cyan("s:") + f(start, 4) + chalk.cyan(" e:") + f(end, 4) + chalk.cyan(" n:") + f(n, 4) + " " + chalk.yellow(strBuf));
42
+ }
43
+ function make_tracer(buffer, padding, offset) {
44
+ padding = !padding ? 0 : padding;
45
+ offset = offset || 0;
46
+ const pad = () => " ".substr(0, padding);
47
+ function _display(str, hexInfo) {
48
+ hexInfo = hexInfo || "";
49
+ // account for ESC codes for colors
50
+ const nbColorAttributes = [...str.split("")].filter((c) => c === "\u001b").length;
51
+ const extra = nbColorAttributes * 5;
52
+ console.log((pad() + str + spaces).substr(0, 132 + extra) + "|" + hexInfo);
53
+ }
54
+ function display(str, hexInfo) {
55
+ const lines = str.split("\n");
56
+ for (const line of lines) {
57
+ _display(line, hexInfo);
58
+ }
59
+ }
60
+ function display_encodeable(value, buffer1, start, end) {
61
+ const bufferExtract = buffer1.slice(start, end);
62
+ const stream = new node_opcua_binary_stream_1.BinaryStream(bufferExtract);
63
+ const nodeId = (0, node_opcua_basic_types_1.decodeNodeId)(stream);
64
+ const encodingMask = (0, node_opcua_basic_types_1.decodeByte)(stream); // 1 bin 2: xml
65
+ const length = (0, node_opcua_basic_types_1.decodeUInt32)(stream);
66
+ display(chalk.green(" ExpandedNodId =") + " " + nodeId);
67
+ display(chalk.green(" encoding mask =") + " " + encodingMask);
68
+ display(chalk.green(" length =") + " " + length);
69
+ analyzePacket(bufferExtract.slice(stream.length), value.encodingDefaultBinary, padding + 2, start + stream.length);
70
+ }
71
+ return {
72
+ tracer: {
73
+ dump: (title, value) => display(title + " " + chalk.green(value.toString())),
74
+ encoding_byte: (encodingMask, valueEnum, start, end) => {
75
+ (0, node_opcua_assert_1.assert)(valueEnum);
76
+ const b = buffer.slice(start, end);
77
+ display(" 012345678", hex_block(start, end, b));
78
+ display_encoding_mask(pad(), encodingMask, valueEnum);
79
+ },
80
+ trace: (operation, name, value, start, end, fieldType) => {
81
+ const b = buffer.slice(start, end);
82
+ let _hexDump = "";
83
+ switch (operation) {
84
+ case "start":
85
+ padding += 2;
86
+ display(name.toString());
87
+ break;
88
+ case "end":
89
+ padding -= 2;
90
+ break;
91
+ case "start_array":
92
+ display("." + name + " (length = " + value + ") " + "[", hex_block(start, end, b));
93
+ padding += 2;
94
+ break;
95
+ case "end_array":
96
+ padding -= 2;
97
+ display("] // " + name);
98
+ break;
99
+ case "start_element":
100
+ display(" #" + value + " {");
101
+ padding += 2;
102
+ break;
103
+ case "end_element":
104
+ padding -= 2;
105
+ display(" } // # " + value);
106
+ break;
107
+ case "member":
108
+ display("." + name + " : " + fieldType);
109
+ _hexDump = "";
110
+ if (value instanceof Buffer) {
111
+ _hexDump = (0, node_opcua_debug_1.hexDump)(value);
112
+ console.log(_hexDump);
113
+ value = "<BUFFER>";
114
+ }
115
+ if (value && value.encode) {
116
+ if (fieldType === "ExtensionObject") {
117
+ display_encodeable(value, buffer, start, end);
118
+ }
119
+ else {
120
+ const str = value.toString() || "<empty>";
121
+ display(str);
122
+ }
123
+ }
124
+ else {
125
+ display(" " + value, hex_block(start, end, b));
126
+ }
127
+ break;
128
+ }
129
+ }
130
+ }
131
+ };
132
+ }
133
+ function analyzePacket(buffer, objMessage, padding, offset, customOptions) {
134
+ const stream = new node_opcua_binary_stream_1.BinaryStream(buffer);
135
+ _internalAnalyzePacket(buffer, stream, objMessage, padding, customOptions, offset);
136
+ }
137
+ exports.analyzePacket = analyzePacket;
138
+ function analyseExtensionObject(buffer, padding, offset, customOptions) {
139
+ const stream = new node_opcua_binary_stream_1.BinaryStream(buffer);
140
+ let id;
141
+ let objMessage;
142
+ try {
143
+ id = (0, node_opcua_basic_types_1.decodeExpandedNodeId)(stream);
144
+ objMessage = (0, node_opcua_factory_1.constructObject)(id);
145
+ }
146
+ catch (err) {
147
+ console.log(id);
148
+ console.log(err);
149
+ console.log("Cannot read decodeExpandedNodeId on stream " + stream.buffer.toString("hex"));
150
+ }
151
+ _internalAnalyzePacket(buffer, stream, objMessage, padding, customOptions, offset);
152
+ }
153
+ exports.analyseExtensionObject = analyseExtensionObject;
154
+ function _internalAnalyzePacket(buffer, stream, objMessage, padding, customOptions, offset) {
155
+ let options = make_tracer(buffer, padding, offset);
156
+ options.name = "message";
157
+ if (customOptions)
158
+ options = Object.assign(Object.assign({}, options), customOptions);
159
+ try {
160
+ if (objMessage) {
161
+ objMessage.decodeDebug(stream, options);
162
+ }
163
+ else {
164
+ console.log(" Invalid object", objMessage);
165
+ }
166
+ }
167
+ catch (err) {
168
+ console.log(" Error in ", err);
169
+ if (err instanceof Error) {
170
+ console.log(" Error in ", err.stack);
171
+ }
172
+ console.log(" objMessage ", (0, util_1.inspect)(objMessage, { colors: true }));
173
+ }
174
+ }
175
+ function analyze_object_binary_encoding(obj) {
176
+ (0, node_opcua_assert_1.assert)(obj);
177
+ const size = obj.binaryStoreSize();
178
+ console.log("-------------------------------------------------");
179
+ console.log(" size = ", size);
180
+ const stream = new node_opcua_binary_stream_1.BinaryStream(size);
181
+ obj.encode(stream);
182
+ stream.rewind();
183
+ console.log("-------------------------------------------------");
184
+ if (stream.buffer.length < 256) {
185
+ console.log((0, node_opcua_debug_1.hexDump)(stream.buffer));
186
+ console.log("-------------------------------------------------");
187
+ }
188
+ const reloadedObject = new obj.constructor();
189
+ analyzePacket(stream.buffer, reloadedObject, 0);
190
+ }
191
+ exports.analyze_object_binary_encoding = analyze_object_binary_encoding;
192
+ //# sourceMappingURL=packet_analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packet_analyzer.js","sourceRoot":"","sources":["../../../source/packet_analyzer/packet_analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { BaseUAObject } from "node-opcua-factory";
2
+ export declare function compare_obj_by_encoding(obj1: BaseUAObject, obj2: BaseUAObject): boolean;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compare_obj_by_encoding = void 0;
4
+ const node_opcua_binary_stream_1 = require("node-opcua-binary-stream");
5
+ const should = require("should");
6
+ const persist = should;
7
+ function compare_obj_by_encoding(obj1, obj2) {
8
+ function encoded(obj) {
9
+ const stream = new node_opcua_binary_stream_1.BinaryStream(obj.binaryStoreSize());
10
+ obj.encode(stream);
11
+ return stream.buffer.toString("hex");
12
+ }
13
+ encoded(obj1).should.eql(encoded(obj2));
14
+ return true;
15
+ }
16
+ exports.compare_obj_by_encoding = compare_obj_by_encoding;
17
+ //# sourceMappingURL=compare_obj_by_encoding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare_obj_by_encoding.js","sourceRoot":"","sources":["../../test_helpers/compare_obj_by_encoding.ts"],"names":[],"mappings":";;;AAAA,uEAAwD;AAExD,iCAAiC;AACjC,MAAM,OAAO,GAAG,MAAM,CAAC;AAEvB,SAAgB,uBAAuB,CAAC,IAAkB,EAAE,IAAkB;IAE1E,SAAS,OAAO,CAAC,GAAiB;QAC9B,MAAM,MAAM,GAAG,IAAI,uCAAY,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC;QACvD,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACnB,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACxC,OAAO,IAAI,CAAC;AAChB,CAAC;AATD,0DASC"}
@@ -0,0 +1,12 @@
1
+ /// <reference types="node" />
2
+ declare type encode_decode_round_trip_testCallback = (buffer: Buffer, encoding: any, options: any) => void;
3
+ /**
4
+ * @method encode_decode_round_trip_test
5
+ * @param obj : object to test ( the object must provide a binaryStoreSize,encode,decode method
6
+ * @param [options]
7
+ * @param callback_buffer
8
+ * @return {*}
9
+ */
10
+ export declare function encode_decode_round_trip_test(obj: any, options?: any, callback_buffer?: encode_decode_round_trip_testCallback): any;
11
+ export declare function json_encode_decode_round_trip_test(obj: any, options: any, callbackBuffer?: any): any;
12
+ export {};
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.json_encode_decode_round_trip_test = exports.encode_decode_round_trip_test = void 0;
4
+ // @ts-check
5
+ const chalk = require("chalk");
6
+ const node_opcua_binary_stream_1 = require("node-opcua-binary-stream");
7
+ const node_opcua_debug_1 = require("node-opcua-debug");
8
+ const node_opcua_factory_1 = require("node-opcua-factory");
9
+ const node_opcua_test_helpers_1 = require("node-opcua-test-helpers");
10
+ const should = require("should");
11
+ const source_1 = require("../source");
12
+ // tslint:disable:no-console
13
+ function dump_block_in_debug_mode(buffer, id, options) {
14
+ if (process.env.DEBUG) {
15
+ console.log((0, node_opcua_debug_1.hexDump)(buffer));
16
+ (0, source_1.analyzePacket)(buffer, id, 0, 0, options);
17
+ }
18
+ }
19
+ function isTypedArray(v) {
20
+ if (v && v.buffer && v.buffer instanceof ArrayBuffer) {
21
+ return true;
22
+ }
23
+ return false;
24
+ }
25
+ function isArrayOrTypedArray(v) {
26
+ return isTypedArray(v) || v instanceof Array;
27
+ }
28
+ function compare(objReloaded, obj) {
29
+ function displayError(p, expected, actual) {
30
+ console.log(chalk.yellow(" ---------------------------------- error in encode_decode_round_trip_test"));
31
+ console.log(chalk.red(" key "), p);
32
+ console.log(chalk.red(" expected "), JSON.stringify(expected));
33
+ console.log(chalk.cyan(" actual "), JSON.stringify(actual));
34
+ }
35
+ Object.keys(objReloaded).forEach((p) => {
36
+ try {
37
+ if (isArrayOrTypedArray(obj[p])) {
38
+ (0, node_opcua_test_helpers_1.assert_arrays_are_equal)(objReloaded[p], obj[p]);
39
+ }
40
+ else {
41
+ if (objReloaded[p] === undefined || obj[p] === undefined) {
42
+ return;
43
+ }
44
+ JSON.stringify(objReloaded[p]).should.eql(JSON.stringify(obj[p]));
45
+ }
46
+ }
47
+ catch (err) {
48
+ displayError(p, obj[p], objReloaded[p]);
49
+ console.log(obj.toString());
50
+ console.log(objReloaded.toString());
51
+ // re throw exception
52
+ throw err;
53
+ }
54
+ });
55
+ }
56
+ function redirectToNull(functor) {
57
+ const old = console.log;
58
+ if (!process.env.DEBUG) {
59
+ // tslint:disable:no-empty
60
+ console.log = (...args) => { };
61
+ }
62
+ try {
63
+ functor();
64
+ }
65
+ catch (err) {
66
+ throw err;
67
+ }
68
+ finally {
69
+ console.log = old;
70
+ }
71
+ }
72
+ /**
73
+ * @method encode_decode_round_trip_test
74
+ * @param obj : object to test ( the object must provide a binaryStoreSize,encode,decode method
75
+ * @param [options]
76
+ * @param callback_buffer
77
+ * @return {*}
78
+ */
79
+ function encode_decode_round_trip_test(obj, options, callback_buffer) {
80
+ if (!callback_buffer && typeof options === "function") {
81
+ callback_buffer = options;
82
+ options = {};
83
+ }
84
+ callback_buffer = callback_buffer || dump_block_in_debug_mode;
85
+ should.exist(obj);
86
+ const size = obj.binaryStoreSize(options);
87
+ const stream = new node_opcua_binary_stream_1.BinaryStream(Buffer.alloc(size));
88
+ obj.encode(stream, options);
89
+ callback_buffer(stream.buffer, obj.encodingDefaultBinary, options);
90
+ stream.rewind();
91
+ // reconstruct a object ( some object may not have a default Binary and should be recreated
92
+ const expandedNodeId = obj.encodingDefaultBinary;
93
+ const objReloaded = expandedNodeId ? (0, node_opcua_factory_1.constructObject)(expandedNodeId) : new obj.constructor();
94
+ objReloaded.decode(stream, options);
95
+ redirectToNull(() => (0, source_1.analyze_object_binary_encoding)(obj));
96
+ compare(objReloaded, obj);
97
+ return objReloaded;
98
+ }
99
+ exports.encode_decode_round_trip_test = encode_decode_round_trip_test;
100
+ function json_encode_decode_round_trip_test(obj, options, callbackBuffer) {
101
+ if (!callbackBuffer && typeof options === "function") {
102
+ callbackBuffer = options;
103
+ options = {};
104
+ }
105
+ callbackBuffer = callbackBuffer || dump_block_in_debug_mode;
106
+ should.exist(obj);
107
+ const json = JSON.stringify(obj);
108
+ const objReloaded = JSON.parse(json);
109
+ compare(objReloaded, obj);
110
+ return objReloaded;
111
+ }
112
+ exports.json_encode_decode_round_trip_test = json_encode_decode_round_trip_test;
113
+ //# sourceMappingURL=encode_decode_round_trip_test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode_decode_round_trip_test.js","sourceRoot":"","sources":["../../test_helpers/encode_decode_round_trip_test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from "./compare_obj_by_encoding";
2
+ export * from "./encode_decode_round_trip_test";
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ __exportStar(require("./compare_obj_by_encoding"), exports);
14
+ __exportStar(require("./encode_decode_round_trip_test"), exports);
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../test_helpers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,4DAA0C;AAC1C,kEAAgD"}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "node-opcua-packet-analyzer",
3
+ "version": "2.51.0",
4
+ "description": "pure nodejs OPCUA SDK - module -packet-analyzer",
5
+ "main": "./dist/source/index.js",
6
+ "types": "./dist/source/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc -b",
9
+ "clean": "node -e \"require('rimraf').sync('dist');\"",
10
+ "test": "echo no test"
11
+ },
12
+ "author": "Etienne Rossignon",
13
+ "license": "MIT",
14
+ "dependencies": {
15
+ "chalk": "4.1.2",
16
+ "node-opcua-assert": "2.51.0",
17
+ "node-opcua-basic-types": "2.51.0",
18
+ "node-opcua-binary-stream": "2.51.0",
19
+ "node-opcua-debug": "2.51.0",
20
+ "node-opcua-factory": "2.51.0",
21
+ "node-opcua-utils": "2.51.0"
22
+ },
23
+ "devDependencies": {
24
+ "node-opcua-test-helpers": "2.42.0",
25
+ "should": "^13.2.3"
26
+ },
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git://github.com/node-opcua/node-opcua.git"
30
+ },
31
+ "keywords": [
32
+ "OPCUA",
33
+ "opcua",
34
+ "m2m",
35
+ "iot",
36
+ "opc ua",
37
+ "internet of things"
38
+ ],
39
+ "homepage": "http://node-opcua.github.io/",
40
+ "gitHead": "75feb111daf7ec65fa0111e4fa5beb8987fd4945"
41
+ }
@@ -0,0 +1,5 @@
1
+ export {
2
+ analyzePacket,
3
+ analyseExtensionObject,
4
+ analyze_object_binary_encoding
5
+ } from "./packet_analyzer/packet_analyzer";
@@ -0,0 +1,230 @@
1
+ // tslint:disable:no-bitwise
2
+ // tslint:disable:no-console
3
+ // tslint:disable:max-line-length
4
+ // tslint:disable:no-empty-interface
5
+
6
+ import * as chalk from "chalk";
7
+ import { assert } from "node-opcua-assert";
8
+ import { inspect } from "util";
9
+
10
+ import { decodeByte, decodeExpandedNodeId, decodeNodeId, decodeUInt32 } from "node-opcua-basic-types";
11
+ import { BinaryStream } from "node-opcua-binary-stream";
12
+ import { hexDump } from "node-opcua-debug";
13
+ import { BaseUAObject, constructObject } from "node-opcua-factory";
14
+ import { buffer_ellipsis } from "node-opcua-utils";
15
+
16
+ const spaces =
17
+ " ";
18
+
19
+ function f(n: number, width: number): string {
20
+ const s = n.toString();
21
+ return (s + " ").substr(0, Math.max(s.length, width));
22
+ }
23
+
24
+ function display_encoding_mask(padding: string, encodingMask: any, encodingInfo: any) {
25
+ for (const v in encodingInfo) {
26
+ if (!encodingInfo.hasOwnProperty(v)) {
27
+ continue;
28
+ }
29
+ const enumKey = encodingInfo[v];
30
+ if (typeof enumKey === "number") {
31
+ continue;
32
+ }
33
+
34
+ const mask = encodingInfo[enumKey];
35
+ const bit = Math.log(mask) / Math.log(2);
36
+
37
+ const bits = [".", ".", ".", ".", ".", ".", ".", ".", "."];
38
+ bits[bit] = (encodingMask & mask) === mask ? "Y" : "n";
39
+
40
+ console.log(padding + " ", bits.join(""), " <- has " + enumKey + " 0x" + mask.toString(16));
41
+ }
42
+ // DataValueEncodingByte
43
+ }
44
+
45
+ function hex_block(start: number, end: number, buffer: Buffer) {
46
+ const n = end - start;
47
+ const strBuf = buffer_ellipsis(buffer);
48
+ return (
49
+ chalk.cyan("s:") + f(start, 4) + chalk.cyan(" e:") + f(end, 4) + chalk.cyan(" n:") + f(n, 4) + " " + chalk.yellow(strBuf)
50
+ );
51
+ }
52
+
53
+ function make_tracer(buffer: Buffer, padding: number, offset?: number) {
54
+ padding = !padding ? 0 : padding;
55
+ offset = offset || 0;
56
+
57
+ const pad = () => " ".substr(0, padding);
58
+
59
+ function _display(str: string, hexInfo?: string) {
60
+ hexInfo = hexInfo || "";
61
+ // account for ESC codes for colors
62
+ const nbColorAttributes = [...str.split("")].filter((c) => c === "\u001b").length;
63
+ const extra = nbColorAttributes * 5;
64
+ console.log((pad() + str + spaces).substr(0, 132 + extra) + "|" + hexInfo);
65
+ }
66
+ function display(str: string, hexInfo?: string) {
67
+ const lines = str.split("\n");
68
+ for (const line of lines) {
69
+ _display(line, hexInfo);
70
+ }
71
+ }
72
+
73
+ function display_encodeable(value: any, buffer1: Buffer, start: number, end: number) {
74
+ const bufferExtract = buffer1.slice(start, end);
75
+ const stream = new BinaryStream(bufferExtract);
76
+ const nodeId = decodeNodeId(stream);
77
+ const encodingMask = decodeByte(stream); // 1 bin 2: xml
78
+ const length = decodeUInt32(stream);
79
+
80
+ display(chalk.green(" ExpandedNodId =") + " " + nodeId);
81
+ display(chalk.green(" encoding mask =") + " " + encodingMask);
82
+ display(chalk.green(" length =") + " " + length);
83
+ analyzePacket(bufferExtract.slice(stream.length), value.encodingDefaultBinary, padding + 2, start + stream.length);
84
+ }
85
+
86
+ return {
87
+ tracer: {
88
+ dump: (title: string, value: any) => display(title + " " + chalk.green(value.toString())),
89
+
90
+ encoding_byte: (encodingMask: any, valueEnum: any, start: number, end: number) => {
91
+ assert(valueEnum);
92
+ const b = buffer.slice(start, end);
93
+ display(" 012345678", hex_block(start, end, b));
94
+ display_encoding_mask(pad(), encodingMask, valueEnum);
95
+ },
96
+
97
+ trace: (operation: any, name: any, value: any, start: number, end: number, fieldType: string) => {
98
+ const b = buffer.slice(start, end);
99
+ let _hexDump = "";
100
+
101
+ switch (operation) {
102
+ case "start":
103
+ padding += 2;
104
+ display(name.toString());
105
+ break;
106
+
107
+ case "end":
108
+ padding -= 2;
109
+ break;
110
+
111
+ case "start_array":
112
+ display("." + name + " (length = " + value + ") " + "[", hex_block(start, end, b));
113
+ padding += 2;
114
+ break;
115
+
116
+ case "end_array":
117
+ padding -= 2;
118
+ display("] // " + name);
119
+ break;
120
+
121
+ case "start_element":
122
+ display(" #" + value + " {");
123
+ padding += 2;
124
+ break;
125
+
126
+ case "end_element":
127
+ padding -= 2;
128
+ display(" } // # " + value);
129
+ break;
130
+
131
+ case "member":
132
+ display("." + name + " : " + fieldType);
133
+
134
+ _hexDump = "";
135
+ if (value instanceof Buffer) {
136
+ _hexDump = hexDump(value);
137
+ console.log(_hexDump);
138
+ value = "<BUFFER>";
139
+ }
140
+
141
+ if (value && value.encode) {
142
+ if (fieldType === "ExtensionObject") {
143
+ display_encodeable(value, buffer, start, end);
144
+ } else {
145
+ const str = value.toString() || "<empty>";
146
+ display(str);
147
+ }
148
+ } else {
149
+ display(" " + value, hex_block(start, end, b));
150
+ }
151
+ break;
152
+ }
153
+ }
154
+ }
155
+ };
156
+ }
157
+
158
+ interface AnalyzePacketOptions {}
159
+
160
+ export function analyzePacket(
161
+ buffer: Buffer,
162
+ objMessage: any,
163
+ padding: number,
164
+ offset?: number,
165
+ customOptions?: AnalyzePacketOptions
166
+ ) {
167
+ const stream = new BinaryStream(buffer);
168
+ _internalAnalyzePacket(buffer, stream, objMessage, padding, customOptions, offset);
169
+ }
170
+
171
+ export function analyseExtensionObject(buffer: Buffer, padding: number, offset: number, customOptions?: AnalyzePacketOptions) {
172
+ const stream = new BinaryStream(buffer);
173
+ let id;
174
+ let objMessage;
175
+ try {
176
+ id = decodeExpandedNodeId(stream);
177
+ objMessage = constructObject(id);
178
+ } catch (err) {
179
+ console.log(id);
180
+ console.log(err);
181
+ console.log("Cannot read decodeExpandedNodeId on stream " + stream.buffer.toString("hex"));
182
+ }
183
+ _internalAnalyzePacket(buffer, stream, objMessage, padding, customOptions, offset);
184
+ }
185
+
186
+ function _internalAnalyzePacket(
187
+ buffer: Buffer,
188
+ stream: BinaryStream,
189
+ objMessage: any,
190
+ padding: number,
191
+ customOptions?: AnalyzePacketOptions,
192
+ offset?: number
193
+ ) {
194
+ let options: any = make_tracer(buffer, padding, offset);
195
+ options.name = "message";
196
+ if (customOptions) options = { ...options, ...customOptions };
197
+ try {
198
+ if (objMessage) {
199
+ objMessage.decodeDebug(stream, options);
200
+ } else {
201
+ console.log(" Invalid object", objMessage);
202
+ }
203
+ } catch (err) {
204
+ console.log(" Error in ", err);
205
+ if (err instanceof Error) {
206
+ console.log(" Error in ", err.stack);
207
+ }
208
+ console.log(" objMessage ", inspect(objMessage, { colors: true }));
209
+ }
210
+ }
211
+
212
+ export function analyze_object_binary_encoding(obj: BaseUAObject) {
213
+ assert(obj);
214
+
215
+ const size = obj.binaryStoreSize();
216
+ console.log("-------------------------------------------------");
217
+ console.log(" size = ", size);
218
+ const stream = new BinaryStream(size);
219
+ obj.encode(stream);
220
+
221
+ stream.rewind();
222
+ console.log("-------------------------------------------------");
223
+ if (stream.buffer.length < 256) {
224
+ console.log(hexDump(stream.buffer));
225
+ console.log("-------------------------------------------------");
226
+ }
227
+
228
+ const reloadedObject = new (obj.constructor as any)();
229
+ analyzePacket(stream.buffer, reloadedObject, 0);
230
+ }
@@ -0,0 +1,15 @@
1
+ import { BinaryStream } from "node-opcua-binary-stream";
2
+ import { BaseUAObject } from "node-opcua-factory";
3
+ import * as should from "should";
4
+ const persist = should;
5
+
6
+ export function compare_obj_by_encoding(obj1: BaseUAObject, obj2: BaseUAObject): boolean {
7
+
8
+ function encoded(obj: BaseUAObject) {
9
+ const stream = new BinaryStream(obj.binaryStoreSize());
10
+ obj.encode(stream);
11
+ return stream.buffer.toString("hex");
12
+ }
13
+ encoded(obj1).should.eql(encoded(obj2));
14
+ return true;
15
+ }
@@ -0,0 +1,135 @@
1
+ // @ts-check
2
+ import * as chalk from "chalk";
3
+ import { BinaryStream } from "node-opcua-binary-stream";
4
+ import { hexDump } from "node-opcua-debug";
5
+ import { BaseUAObject, constructObject } from "node-opcua-factory";
6
+ import { assert_arrays_are_equal } from "node-opcua-test-helpers";
7
+ import * as should from "should";
8
+
9
+ import { analyze_object_binary_encoding, analyzePacket } from "../source";
10
+ // tslint:disable:no-console
11
+
12
+ function dump_block_in_debug_mode(buffer: Buffer, id: any, options: any) {
13
+ if (process.env.DEBUG) {
14
+ console.log(hexDump(buffer));
15
+ analyzePacket(buffer, id, 0, 0, options);
16
+ }
17
+ }
18
+
19
+ function isTypedArray(v: any): boolean {
20
+ if (v && v.buffer && v.buffer instanceof ArrayBuffer) {
21
+ return true;
22
+ }
23
+ return false;
24
+ }
25
+
26
+ function isArrayOrTypedArray(v: any): boolean {
27
+ return isTypedArray(v) || v instanceof Array;
28
+ }
29
+
30
+ function compare(objReloaded: any, obj: any) {
31
+ function displayError(p: string, expected: any, actual: any) {
32
+ console.log(chalk.yellow(" ---------------------------------- error in encode_decode_round_trip_test"));
33
+ console.log(chalk.red(" key "), p);
34
+ console.log(chalk.red(" expected "), JSON.stringify(expected));
35
+ console.log(chalk.cyan(" actual "), JSON.stringify(actual));
36
+ }
37
+
38
+ Object.keys(objReloaded).forEach((p: any) => {
39
+ try {
40
+ if (isArrayOrTypedArray(obj[p])) {
41
+ assert_arrays_are_equal(objReloaded[p], obj[p]);
42
+ } else {
43
+ if (objReloaded[p] === undefined || obj[p] === undefined) {
44
+ return;
45
+ }
46
+ (JSON.stringify(objReloaded[p]) as any).should.eql(JSON.stringify(obj[p]));
47
+ }
48
+ } catch (err) {
49
+ displayError(p, obj[p], objReloaded[p]);
50
+ console.log(obj.toString());
51
+ console.log(objReloaded.toString());
52
+ // re throw exception
53
+ throw err;
54
+ }
55
+ });
56
+ }
57
+
58
+ function redirectToNull(functor: () => void) {
59
+ const old = console.log;
60
+
61
+ if (!process.env.DEBUG) {
62
+ // tslint:disable:no-empty
63
+ console.log = (...args: any[]) => {};
64
+ }
65
+
66
+ try {
67
+ functor();
68
+ } catch (err) {
69
+ throw err;
70
+ } finally {
71
+ console.log = old;
72
+ }
73
+ }
74
+
75
+ type encode_decode_round_trip_testCallback = (buffer: Buffer, encoding: any, options: any) => void;
76
+
77
+ /**
78
+ * @method encode_decode_round_trip_test
79
+ * @param obj : object to test ( the object must provide a binaryStoreSize,encode,decode method
80
+ * @param [options]
81
+ * @param callback_buffer
82
+ * @return {*}
83
+ */
84
+ export function encode_decode_round_trip_test(
85
+ obj: any,
86
+ options?: any,
87
+ callback_buffer?: encode_decode_round_trip_testCallback
88
+ ): any {
89
+ if (!callback_buffer && typeof options === "function") {
90
+ callback_buffer = options;
91
+ options = {};
92
+ }
93
+
94
+ callback_buffer = callback_buffer || dump_block_in_debug_mode;
95
+
96
+ should.exist(obj);
97
+
98
+ const size = obj.binaryStoreSize(options);
99
+
100
+ const stream = new BinaryStream(Buffer.alloc(size));
101
+
102
+ obj.encode(stream, options);
103
+
104
+ callback_buffer(stream.buffer, obj.encodingDefaultBinary, options);
105
+
106
+ stream.rewind();
107
+
108
+ // reconstruct a object ( some object may not have a default Binary and should be recreated
109
+ const expandedNodeId = obj.encodingDefaultBinary;
110
+ const objReloaded = expandedNodeId ? constructObject(expandedNodeId) : new obj.constructor();
111
+
112
+ objReloaded.decode(stream, options);
113
+
114
+ redirectToNull(() => analyze_object_binary_encoding(obj));
115
+ compare(objReloaded, obj);
116
+ return objReloaded;
117
+ }
118
+
119
+ export function json_encode_decode_round_trip_test(obj: any, options: any, callbackBuffer?: any) {
120
+ if (!callbackBuffer && typeof options === "function") {
121
+ callbackBuffer = options;
122
+ options = {};
123
+ }
124
+ callbackBuffer = callbackBuffer || dump_block_in_debug_mode;
125
+
126
+ should.exist(obj);
127
+
128
+ const json = JSON.stringify(obj);
129
+
130
+ const objReloaded = JSON.parse(json);
131
+
132
+ compare(objReloaded, obj);
133
+
134
+ return objReloaded;
135
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./compare_obj_by_encoding";
2
+ export * from "./encode_decode_round_trip_test";