UNPKG

zigbee-herdsman

Version:

An open source ZigBee gateway solution with node.js.

102 lines (85 loc) 2.57 kB
/* v8 ignore start */ import {RANDOMIZE_SEQ, RANDOMIZE_START} from "./consts"; import crc16ccitt from "./utils/crc16ccitt"; export enum FrameType { UNKNOWN = 0, ERROR = 1, DATA = 2, ACK = 3, NAK = 4, RST = 5, RSTACK = 6, } /** * Basic class to handle uart-level frames * https://www.silabs.com/documents/public/user-guides/ug101-uart-gateway-protocol-reference.pdf */ export class Frame { /** * Type of the Frame as determined by its control byte. */ public readonly type: FrameType; public readonly buffer: Buffer; public constructor(buffer: Buffer) { this.buffer = buffer; const ctrlByte = this.buffer[0]; if ((ctrlByte & 0x80) === 0) { this.type = FrameType.DATA; } else if ((ctrlByte & 0xe0) === 0x80) { this.type = FrameType.ACK; } else if ((ctrlByte & 0xe0) === 0xa0) { this.type = FrameType.NAK; } else if (ctrlByte === 0xc0) { this.type = FrameType.RST; } else if (ctrlByte === 0xc1) { this.type = FrameType.RSTACK; } else if (ctrlByte === 0xc2) { this.type = FrameType.ERROR; } else { this.type = FrameType.UNKNOWN; } } get control(): number { return this.buffer[0]; } public static fromBuffer(buffer: Buffer): Frame { return new Frame(buffer); } /** * XOR s with a pseudo-random sequence for transmission. * Used only in data frames. */ public static makeRandomizedBuffer(buffer: Buffer): Buffer { let rand = RANDOMIZE_START; const out = Buffer.alloc(buffer.length); let outIdx = 0; for (const c of buffer) { out.writeUInt8(c ^ rand, outIdx++); if (rand % 2) { rand = (rand >> 1) ^ RANDOMIZE_SEQ; } else { rand = rand >> 1; } } return out; } /** * Throws on CRC error. */ public checkCRC(): void { const crc = crc16ccitt(this.buffer.subarray(0, -3), 65535); const crcArr = Buffer.from([crc >> 8, crc % 256]); const subArr = this.buffer.subarray(-3, -1); if (!subArr.equals(crcArr)) { throw new Error(`<-- CRC error: ${this.toString()}|${subArr.toString("hex")}|${crcArr.toString("hex")}`); } } /** * * @returns Buffer to hex string */ public toString(): string { return this.buffer.toString("hex"); } } export default Frame;