* Parses a Buffer of data containing at least * one complete packet at the beginning of the buffer. * Will return multiple packets if necessary. * @param {Buffer} buffer of data to parse * @returns {Packet} packet of data
(buffer)
| 99 | * @returns {Packet} packet of data |
| 100 | */ |
| 101 | parsePacket(buffer) { |
| 102 | // Check for length |
| 103 | // At minimum requires: prefix (4), sequence (4), command (4), length (4), |
| 104 | // CRC (4), and suffix (4) for 24 total bytes |
| 105 | // Messages from the device also include return code (4), for 28 total bytes |
| 106 | if (buffer.length < 24) { |
| 107 | throw new TypeError(`Packet too short. Length: ${buffer.length}.`); |
| 108 | } |
| 109 | |
| 110 | // Check for prefix |
| 111 | const prefix = buffer.readUInt32BE(0); |
| 112 | |
| 113 | // Only for 3.4 and 3.5 packets |
| 114 | if (prefix !== 0x000055AA && prefix !== 0x00006699) { |
| 115 | throw new TypeError(`Prefix does not match: ${buffer.toString('hex')}`); |
| 116 | } |
| 117 | |
| 118 | // Check for extra data |
| 119 | let leftover = false; |
| 120 | |
| 121 | let suffixLocation = buffer.indexOf('0000AA55', 0, 'hex'); |
| 122 | if (suffixLocation === -1) {// Couldn't find 0000AA55 during parse |
| 123 | suffixLocation = buffer.indexOf('00009966', 0, 'hex'); |
| 124 | } |
| 125 | |
| 126 | if (suffixLocation !== buffer.length - 4) { |
| 127 | leftover = buffer.slice(suffixLocation + 4); |
| 128 | buffer = buffer.slice(0, suffixLocation + 4); |
| 129 | } |
| 130 | |
| 131 | // Check for suffix |
| 132 | const suffix = buffer.readUInt32BE(buffer.length - 4); |
| 133 | |
| 134 | if (suffix !== 0x0000AA55 && suffix !== 0x00009966) { |
| 135 | throw new TypeError(`Suffix does not match: ${buffer.toString('hex')}`); |
| 136 | } |
| 137 | |
| 138 | let sequenceN; |
| 139 | let commandByte; |
| 140 | let payloadSize; |
| 141 | |
| 142 | if (suffix === 0x0000AA55) { |
| 143 | // Get sequence number |
| 144 | sequenceN = buffer.readUInt32BE(4); |
| 145 | |
| 146 | // Get command byte |
| 147 | commandByte = buffer.readUInt32BE(8); |
| 148 | |
| 149 | // Get payload size |
| 150 | payloadSize = buffer.readUInt32BE(12); |
| 151 | |
| 152 | // Check for payload |
| 153 | if (buffer.length - 8 < payloadSize) { |
| 154 | throw new TypeError(`Packet missing payload: payload has length ${payloadSize}.`); |
| 155 | } |
| 156 | } else if (suffix === 0x00009966) { |
| 157 | // Get sequence number |
| 158 | sequenceN = buffer.readUInt32BE(6); |