UNPKG

5.91 kBJavaScriptView Raw
1"use strict";
2/**
3 * this is the low-level implementation of the E1.31 (sACN) protocol
4 */
5Object.defineProperty(exports, "__esModule", { value: true });
6exports.Packet = void 0;
7const assert = require("assert");
8const util_1 = require("./util");
9const constants_1 = require("./constants");
10/**
11 * This constructs a sACN Packet, either from an
12 * existing `Buffer` or from `Options`.
13 */
14class Packet {
15 constructor(input, sourceAddress) {
16 this.sourceAddress = sourceAddress;
17 /* root layer */
18 this.root_vector = constants_1.RootVector.DATA;
19 this.preambleSize = 0x0010; // =16 (unit16 hence the redundant 00s)
20 this.postambleSize = 0;
21 this.acnPid = constants_1.ACN_PID;
22 /* framing layer */
23 this.frame_vector = constants_1.FrameVector.DATA;
24 /* DMP layer */
25 this.dmp_vector = constants_1.DmpVector.DATA;
26 this.type = 0xa1; // = 61
27 this.firstAddress = 0;
28 this.addressIncrement = 1;
29 this.startCode = 0;
30 if (!input)
31 throw new Error('Buffer packet instantiated with no value');
32 if (input instanceof Buffer) {
33 const buf = input;
34 // If a buffer is supplied, ascertain that the packet implements ACN
35 // correctly, and that is it a data packet. Also asceratain that the
36 // UDP overhead is valid. Then fill up the class values.
37 /* root layer */
38 assert.strictEqual(buf.readUInt32BE(18), this.root_vector);
39 this.root_fl = buf.readUInt16BE(16);
40 assert.deepStrictEqual(buf.slice(4, 16), this.acnPid);
41 assert.strictEqual(buf.readUInt16BE(0), this.preambleSize);
42 assert.strictEqual(buf.readUInt16BE(2), this.postambleSize);
43 this.cid = buf.slice(22, 38);
44 /* frame layer */
45 assert.strictEqual(buf.readUInt32BE(40), this.frame_vector);
46 this.frame_fl = buf.readUInt16BE(38);
47 this.options = buf.readUInt8(112);
48 this.sequence = buf.readUInt8(111);
49 this.sourceName = buf.toString('ascii', 44, 107).replace(/\x00/g, '');
50 this.priority = buf.readUInt8(108);
51 this.syncUniverse = buf.readUInt16BE(109);
52 this.universe = buf.readUInt16BE(113);
53 /* DMP layer */
54 assert.strictEqual(buf.readUInt8(117), this.dmp_vector);
55 this.dmp_fl = buf.readUInt16BE(115);
56 assert.strictEqual(buf.readUInt8(118), this.type);
57 assert.strictEqual(buf.readUInt16BE(119), this.firstAddress);
58 assert.strictEqual(buf.readUInt16BE(121), this.addressIncrement);
59 this.propertyValueCount = buf.readUInt16BE(123);
60 assert.strictEqual(buf.readUInt8(125), this.startCode);
61 this.privatePayload = buf.slice(126);
62 }
63 else {
64 // if input is not a buffer
65 const options = input;
66 // set constants
67 this.preambleSize = 0x0010;
68 this.root_fl = 0x726e;
69 this.frame_fl = 0x7258;
70 this.dmp_fl = 0x720b;
71 this.syncUniverse = 0; // we as a sender don't implement this
72 this.options = 0; // TODO: can we just set to 0?
73 // set properties
74 this.privatePayload = options.payload;
75 this.sourceName = options.sourceName || 'sACN nodejs';
76 this.priority = options.priority || 100;
77 this.sequence = options.sequence;
78 this.universe = options.universe;
79 this.cid = options.cid || constants_1.DEFAULT_CID;
80 // set computed properties
81 this.propertyValueCount = 0x0201; // "Indicates 1+ the number of slots in packet"
82 // We set the highest possible value (1+512) so that channels with zero values are
83 // treated as deliberately 0 (cf. undefined)
84 }
85 }
86 get payload() {
87 return this.privatePayload instanceof Buffer
88 ? util_1.objectify(this.privatePayload)
89 : this.privatePayload;
90 }
91 get payloadAsBuffer() {
92 return this.privatePayload instanceof Buffer ? this.privatePayload : null;
93 }
94 get buffer() {
95 const sourceNameBuf = Buffer.from(this.sourceName.padEnd(64, '\0'));
96 const n = [].concat(
97 /* root layer */
98 util_1.bit(16, this.preambleSize), // 0,1 = preable size
99 util_1.bit(16, this.postambleSize), // 2,3 = postamble size
100 [...this.acnPid], util_1.bit(16, this.root_fl), // 16,17 = root fl
101 util_1.bit(32, this.root_vector), // 18,19,20,21 = Root_vector
102 [...this.cid], // 22-37 = cid
103 /* framing layer */
104 util_1.bit(16, this.frame_fl), // 38,39 = frame fl
105 util_1.bit(32, this.frame_vector), // 40,41,42,43 = frame vector
106 [...sourceNameBuf], // 44 - 107 = sourceName
107 util_1.bit(8, this.priority), // 108 = priority (8bit)
108 util_1.bit(16, this.syncUniverse), // 109,110 = syncUniverse
109 util_1.bit(8, this.sequence), // 111 = sequence
110 util_1.bit(8, this.options), // 112 = options
111 util_1.bit(16, this.universe), // 113,114 = universe
112 /* DMP layer */
113 util_1.bit(16, this.dmp_fl), // 115,116 = dmp_fl
114 util_1.bit(8, this.dmp_vector), // 117 = dmp vector
115 util_1.bit(8, this.type), // 118 = type
116 util_1.bit(16, this.firstAddress), // 119,120 = first adddress
117 util_1.bit(16, this.addressIncrement), // 121,122 = addressIncrement
118 util_1.bit(16, this.propertyValueCount), // 123,124 = propertyValueCount
119 util_1.bit(8, this.startCode), // 125 = startCode
120 util_1.empty(512));
121 for (const ch in this.payload) {
122 if (+ch >= 1 && +ch <= 512) {
123 n[125 + +ch] = util_1.inRange(this.payload[ch] * 2.55);
124 }
125 }
126 return Buffer.from(n);
127 }
128}
129exports.Packet = Packet;