UNPKG

zigbee-herdsman

Version:

An open source ZigBee gateway solution with node.js.

213 lines (188 loc) 7.87 kB
import {Constants, Frame, Parser, Writer} from "../../../src/adapter/z-stack/unpi"; describe("Parser", () => { let parser; let parsed = []; beforeEach(() => { parser = new Parser(); parser.on("parsed", (result) => parsed.push(result)); parsed = []; }); it("Parse simple message", () => { const buffer = Buffer.from([ 0xfe, 0x0e, 0x61, 0x02, 0x02, 0x00, 0x02, 0x06, 0x03, 0xd9, 0x14, 0x34, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x92, ]); parser._transform(buffer, "", () => {}); expect(parsed.length).toBe(1); expect(parsed[0].type).toBe(Constants.Type.SRSP); expect(parsed[0].subsystem).toBe(Constants.Subsystem.SYS); expect(parsed[0].commandID).toBe(2); expect(parsed[0].data).toStrictEqual(Buffer.from([2, 0, 2, 6, 3, 217, 20, 52, 1, 2, 0, 0, 0, 0])); expect(parsed[0].length).toBe(14); expect(parsed[0].fcs).toBe(0x92); }); it("Parse two messages", () => { const buffer = Buffer.from([ 0xfe, 0x0e, 0x61, 0x02, 0x02, 0x00, 0x02, 0x06, 0x03, 0xd9, 0x14, 0x34, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x92, 0xfe, 0x03, 0x61, 0x08, 0x00, 0x01, 0x55, 0x3e, ]); parser._transform(buffer, "", () => {}); expect(parsed.length).toBe(2); expect(parsed[0].type).toBe(Constants.Type.SRSP); expect(parsed[0].subsystem).toBe(Constants.Subsystem.SYS); expect(parsed[0].commandID).toBe(2); expect(parsed[0].data).toStrictEqual(Buffer.from([2, 0, 2, 6, 3, 217, 20, 52, 1, 2, 0, 0, 0, 0])); expect(parsed[0].length).toBe(14); expect(parsed[0].fcs).toBe(0x92); expect(parsed[1].type).toBe(Constants.Type.SRSP); expect(parsed[1].subsystem).toBe(Constants.Subsystem.SYS); expect(parsed[1].commandID).toBe(8); expect(parsed[1].data).toStrictEqual(Buffer.from([0, 1, 85])); expect(parsed[1].length).toBe(3); expect(parsed[1].fcs).toBe(0x3e); }); it("Dont throw error on fcs mismatch", () => { const buffer = Buffer.from([0xfe, 0x03, 0x61, 0x08, 0x00, 0x01, 0x55, 0x3f]); parser._transform(buffer, "", () => {}); expect(parsed.length).toBe(0); }); it("Message in two chunks", () => { let buffer = Buffer.from([0xfe, 0x03, 0x61, 0x08, 0x00, 0x01]); parser._transform(buffer, "", () => {}); expect(parsed.length).toBe(0); buffer = Buffer.from([0x55, 0x3e]); parser._transform(buffer, "", () => {}); expect(parsed.length).toBe(1); expect(parsed[0].type).toBe(Constants.Type.SRSP); expect(parsed[0].subsystem).toBe(Constants.Subsystem.SYS); expect(parsed[0].commandID).toBe(8); expect(parsed[0].data).toStrictEqual(Buffer.from([0, 1, 85])); expect(parsed[0].length).toBe(3); expect(parsed[0].fcs).toBe(0x3e); }); it("Message in two chunks, fcs as separate", () => { let buffer = Buffer.from([0xfe, 0x03, 0x61, 0x08, 0x00, 0x01, 0x55]); parser._transform(buffer, "", () => {}); expect(parsed.length).toBe(0); buffer = Buffer.from([0x3e]); parser._transform(buffer, "", () => {}); expect(parsed.length).toBe(1); expect(parsed[0].type).toBe(Constants.Type.SRSP); expect(parsed[0].subsystem).toBe(Constants.Subsystem.SYS); expect(parsed[0].commandID).toBe(8); expect(parsed[0].data).toStrictEqual(Buffer.from([0, 1, 85])); expect(parsed[0].length).toBe(3); expect(parsed[0].fcs).toBe(0x3e); }); it("Parse message when it doenst start with SOF and buffer is empty (throw away everything until SOF)", () => { const buffer = Buffer.from([ 95, 27, 37, 254, 3, 69, 196, 212, 23, 0, 65, 254, 27, 68, 129, 0, 0, 8, 0, 212, 23, 1, 1, 0, 55, 0, 153, 178, 219, 0, 0, 7, 8, 122, 10, 0, 0, 32, 243, 212, 23, 29, 160, 254, 7, 69, 196, 111, 244, 2, 122, 155, 246, 95, 87, 254, 27, 68, 129, 0, 0, 6, 0, 111, 244, 1, 1, 0, 118, 0, 245, 236, 220, 0, 0, 7, 8, 2, 10, 0, 0, 16, 0, 246, 95, 27, 85, ]); parser._transform(buffer, "", () => {}); expect(parsed.length).toBe(4); expect(parsed[0].type).toBe(Constants.Type.AREQ); expect(parsed[0].subsystem).toBe(Constants.Subsystem.ZDO); expect(parsed[0].commandID).toBe(196); expect(parsed[0].data).toStrictEqual(Buffer.from([0xd4, 0x17, 0x00])); expect(parsed[0].length).toBe(3); expect(parsed[0].fcs).toBe(65); expect(parsed[1].type).toBe(Constants.Type.AREQ); expect(parsed[1].subsystem).toBe(Constants.Subsystem.AF); expect(parsed[1].commandID).toBe(129); expect(parsed[1].data).toStrictEqual( Buffer.from([0, 0, 8, 0, 212, 23, 1, 1, 0, 55, 0, 153, 178, 219, 0, 0, 7, 8, 122, 10, 0, 0, 32, 243, 212, 23, 29]), ); expect(parsed[1].length).toBe(27); expect(parsed[1].fcs).toBe(160); }); it("Continue parsing on fcs mismatch", () => { const buffer1 = Buffer.from([ 0x01, 0x02, 0xfe, 0x03, 0x61, 0x08, 0x00, 0x01, 0x55, 0x3f, // fcs mismatch 0x08, 0x09, 0x12, // Noise ]); const buffer2 = Buffer.from([ 0x08, 0x09, 0x12, // Noise ]); const buffer3 = Buffer.from([ 0x08, 0x09, 0x12, // Noise 0xfe, 0x0e, 0x61, 0x02, // Valid message part 1 ]); const buffer4 = Buffer.from([ 0x02, 0x00, 0x02, 0x06, 0x03, 0xd9, 0x14, 0x34, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x92, // Valid message part 2 ]); parser._transform(buffer1, "", () => {}); parser._transform(buffer2, "", () => {}); parser._transform(buffer3, "", () => {}); parser._transform(buffer4, "", () => {}); expect(parsed.length).toBe(1); expect(parsed[0].type).toBe(Constants.Type.SRSP); expect(parsed[0].subsystem).toBe(Constants.Subsystem.SYS); expect(parsed[0].commandID).toBe(2); expect(parsed[0].data).toStrictEqual(Buffer.from([2, 0, 2, 6, 3, 217, 20, 52, 1, 2, 0, 0, 0, 0])); expect(parsed[0].length).toBe(14); expect(parsed[0].fcs).toBe(0x92); }); }); describe("Frame", () => { it("To buffer", () => { const frame = new Frame(Constants.Type.SRSP, Constants.Subsystem.SYS, 3, Buffer.from([0x06, 0x01])); const buffer = frame.toBuffer(); expect(buffer).toStrictEqual(Buffer.from([0xfe, 0x02, 0x61, 0x03, 0x06, 0x01, 0x67])); }); }); describe("Writer", () => { let writer; beforeEach(() => { writer = new Writer(); }); it("Write frame", () => { const frame = new Frame(Constants.Type.SRSP, Constants.Subsystem.SYS, 3, Buffer.from([0x06, 0x01])); const push = vi.spyOn(writer, "push").mockReturnValue(undefined); writer.writeFrame(frame); expect(push).toHaveBeenCalledTimes(1); expect(push.mock.calls[0][0]).toStrictEqual(frame.toBuffer()); }); it("Write buffer", () => { const buffer = Buffer.from([0x01, 0x02]); const push = vi.spyOn(writer, "push").mockReturnValue(undefined); writer.writeBuffer(buffer); expect(push).toHaveBeenCalledTimes(1); expect(push.mock.calls[0][0]).toStrictEqual(buffer); }); it("Read should do nothing (satisfy coverage)", () => { writer.read(); }); });