UNPKG

zigbee-herdsman

Version:

An open source ZigBee gateway solution with node.js.

57 lines (45 loc) 1.93 kB
import * as stream from "node:stream"; import {logger} from "../../../utils/logger"; import {DataStart, MinMessageLength, PositionDataLength, SOF} from "./constants"; import {Frame} from "./frame"; const NS = "zh:zstack:unpi:parser"; export class Parser extends stream.Transform { private buffer: Buffer; public constructor() { super(); this.buffer = Buffer.from([]); } public override _transform(chunk: Buffer, _: string, cb: () => void): void { logger.debug(`<-- [${[...chunk]}]`, NS); this.buffer = Buffer.concat([this.buffer, chunk]); this.parseNext(); cb(); } private parseNext(): void { logger.debug(`--- parseNext [${[...this.buffer]}]`, NS); if (this.buffer.length !== 0 && this.buffer.readUInt8(0) !== SOF) { // Buffer doesn't start with SOF, skip till SOF. const index = this.buffer.indexOf(SOF); if (index !== -1) { this.buffer = this.buffer.slice(index, this.buffer.length); } } if (this.buffer.length >= MinMessageLength && this.buffer.readUInt8(0) === SOF) { const dataLength = this.buffer[PositionDataLength]; const fcsPosition = DataStart + dataLength; const frameLength = fcsPosition + 1; if (this.buffer.length >= frameLength) { const frameBuffer = this.buffer.slice(0, frameLength); try { const frame = Frame.fromBuffer(dataLength, fcsPosition, frameBuffer); logger.debug(`--> parsed ${frame}`, NS); this.emit("parsed", frame); } catch (error) { logger.debug(`--> error ${error}`, NS); } this.buffer = this.buffer.slice(frameLength, this.buffer.length); this.parseNext(); } } } }