UNPKG

zigbee-herdsman

Version:

An open source ZigBee gateway solution with node.js.

65 lines (53 loc) 2.01 kB
/* v8 ignore start */ import * as stream from "node:stream"; import {logger} from "../../../utils/logger"; import * as consts from "./consts"; import {crc16ccitt} from "./utils"; const NS = "zh:ezsp:uart"; export class Writer extends stream.Readable { public writeBuffer(buffer: Buffer): void { logger.debug(`--> [${buffer.toString("hex")}]`, NS); this.push(buffer); } public override _read(): void {} public sendACK(ackNum: number): void { /* Construct a acknowledgement frame */ const ackFrame = this.makeFrame(0b10000000 | ackNum); this.writeBuffer(ackFrame); } public sendNAK(ackNum: number): void { /* Construct a negative acknowledgement frame */ const nakFrame = this.makeFrame(0b10100000 | ackNum); this.writeBuffer(nakFrame); } public sendReset(): void { /* Construct a reset frame */ const rstFrame = Buffer.concat([Buffer.from([consts.CANCEL]), this.makeFrame(0xc0)]); this.writeBuffer(rstFrame); } public sendData(data: Buffer, seq: number, rxmit: number, ackSeq: number): void { /* Construct a data frame */ const control = (seq << 4) | (rxmit << 3) | ackSeq; const dataFrame = this.makeFrame(control, data); this.writeBuffer(dataFrame); } private *stuff(buffer: number[]): Generator<number> { /* Byte stuff (escape) a string for transmission */ for (const byte of buffer) { if (consts.RESERVED.includes(byte)) { yield consts.ESCAPE; yield byte ^ consts.STUFF; } else { yield byte; } } } private makeFrame(control: number, data?: Buffer): Buffer { /* Construct a frame */ const frm = [control, ...(data || [])]; const crc = crc16ccitt(frm, 65535); frm.push(crc >> 8); frm.push(crc % 256); return Buffer.from([...this.stuff(frm), consts.FLAG]); } }