Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix!: Fix always use number for reportableChange #1190

Merged
merged 3 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions src/buffalo/buffalo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,30 @@ class Buffalo {
return value;
}

public writeUInt56(value: bigint): void {
this.buffer.writeUIntLE(Number(value & 0xffffffffffffn), this.position, 6);
this.buffer.writeUint8(Number(value >> 48n), this.position + 6);
this.position += 7;
}

public readUInt56(): bigint {
const low = this.buffer.readUIntLE(this.position, 6);
const high = this.buffer.readUInt8(this.position + 6);
this.position += 7;
return (BigInt(high) << 48n) | BigInt(low);
}

public writeUInt64(value: bigint): void {
this.buffer.writeBigUInt64LE(value, this.position);
this.position += 8;
}

public readUInt64(): bigint {
const value = this.buffer.readBigUInt64LE(this.position);
this.position += 8;
return value;
}

public writeInt8(value: number): void {
this.buffer.writeInt8(value, this.position);
this.position++;
Expand Down Expand Up @@ -157,6 +181,38 @@ class Buffalo {
return value;
}

public writeInt56(value: bigint): void {
let unsignedValue = value;
if (value < 0n) {
unsignedValue = (1n << 56n) + value;
}
this.buffer.writeUIntLE(Number(unsignedValue & 0xffffffffffffn), this.position, 6);
this.buffer.writeUint8(Number(unsignedValue >> 48n), this.position + 6);
this.position += 7;
}

public readInt56(): bigint {
const low = BigInt(this.buffer.readUIntLE(this.position, 6));
const high = BigInt(this.buffer.readUInt8(this.position + 6));
let result = (high << 48n) | low;
if (high & 0x80n) {
result -= 1n << 56n;
}
this.position += 7;
return result;
}

public writeInt64(value: bigint): void {
this.buffer.writeBigInt64LE(value, this.position);
this.position += 8;
}

public readInt64(): bigint {
const value = this.buffer.readBigInt64LE(this.position);
this.position += 8;
return value;
}

public writeFloatLE(value: number): void {
this.buffer.writeFloatLE(value, this.position);
this.position += 4;
Expand Down
2 changes: 1 addition & 1 deletion src/controller/model/endpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface ConfigureReportingItem {
attribute: string | number | {ID: number; type: number};
minimumReportInterval: number;
maximumReportInterval: number;
reportableChange: number | [number, number];
reportableChange: number;
}

interface Options {
Expand Down
116 changes: 14 additions & 102 deletions src/zspec/zcl/buffaloZcl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,94 +125,6 @@ interface MiboxerZone {
}

export class BuffaloZcl extends Buffalo {
// TODO: remove read/write int "SB" versions in favor of plain numbers, implemented in buffalo.ts

private writeUInt40SB(value: number[]): void {
this.writeUInt32(value[1]);
this.writeUInt8(value[0]);
}

private readUInt40SB(): [number, number] {
const lsb = this.readUInt32();
const msb = this.readUInt8();
return [msb, lsb];
}

private writeUInt48SB(value: number[]): void {
this.writeUInt32(value[1]);
this.writeUInt16(value[0]);
}

private readUInt48SB(): [number, number] {
const lsb = this.readUInt32();
const msb = this.readUInt16();
return [msb, lsb];
}

private writeUInt56SB(value: number[]): void {
// XXX: [uint32, uint32] param not following read return pattern [uint32, uint16, uint8]
const temp = Buffer.alloc(8);
temp.writeUInt32LE(value[1], 0);
temp.writeUInt32LE(value[0], 4);
this.writeBuffer(temp.subarray(0, 7), 7);
}

private readUInt56SB(): [number, number, number] {
const lsb = this.readUInt32();
const xsb = this.readUInt16();
const msb = this.readUInt8();
return [msb, xsb, lsb];
}

private readUInt64SB(): string {
// XXX: not following pattern, should return as [msb, lsb]
return this.readIeeeAddr();
}

private writeUInt64SB(value: string): void {
// XXX: not following pattern, should pass as number[uint32, uint32]
const msb = parseInt(value.slice(2, 10), 16);
const lsb = parseInt(value.slice(10), 16);
this.writeUInt32(lsb);
this.writeUInt32(msb);
}

private writeInt40SB(value: number[]): void {
this.writeInt32(value[1]);
this.writeInt8(value[0]);
}

private readInt40SB(): [number, number] {
const lsb = this.readInt32();
const msb = this.readInt8();
return [msb, lsb];
}

private writeInt56SB(value: number[]): void {
const temp = Buffer.alloc(8);
temp.writeInt32LE(value[1], 0);
temp.writeInt32LE(value[0], 4);
this.writeBuffer(temp.subarray(0, 7), 7);
}

private readInt56SB(): [number, number, number] {
const lsb = this.readInt32();
const xsb = this.readInt16();
const msb = this.readInt8();
return [msb, xsb, lsb];
}

private writeInt64SB(value: number[]): void {
this.writeInt32(value[1]);
this.writeInt32(value[0]);
}

private readInt64SB(): [number, number] {
const lsb = this.readInt32();
const msb = this.readInt32();
return [msb, lsb];
}

private writeOctetStr(value: number[]): void {
// TODO: this does not allow "non-value" 0xFF
this.writeUInt8(value.length);
Expand Down Expand Up @@ -773,22 +685,22 @@ export class BuffaloZcl extends Buffalo {
case DataType.DATA40:
case DataType.BITMAP40:
case DataType.UINT40: {
return this.writeUInt40SB(value);
return this.writeUInt40(value);
}
case DataType.DATA48:
case DataType.BITMAP48:
case DataType.UINT48: {
return this.writeUInt48SB(value);
return this.writeUInt48(value);
}
case DataType.DATA56:
case DataType.BITMAP56:
case DataType.UINT56: {
return this.writeUInt56SB(value);
return this.writeUInt56(value);
}
case DataType.DATA64:
case DataType.BITMAP64:
case DataType.UINT64: {
return this.writeUInt64SB(value);
return this.writeUInt64(value);
}
case DataType.INT8: {
return this.writeInt8(value);
Expand All @@ -803,16 +715,16 @@ export class BuffaloZcl extends Buffalo {
return this.writeInt32(value);
}
case DataType.INT40: {
return this.writeInt40SB(value);
return this.writeInt40(value);
}
case DataType.INT48: {
return this.writeInt48(value);
}
case DataType.INT56: {
return this.writeInt56SB(value);
return this.writeInt56(value);
}
case DataType.INT64: {
return this.writeInt64SB(value);
return this.writeInt64(value);
}
// case DataType.SEMI_PREC: {
// // https://tc39.es/proposal-float16array/
Expand Down Expand Up @@ -957,22 +869,22 @@ export class BuffaloZcl extends Buffalo {
case DataType.DATA40:
case DataType.BITMAP40:
case DataType.UINT40: {
return this.readUInt40SB();
return this.readUInt40();
}
case DataType.DATA48:
case DataType.BITMAP48:
case DataType.UINT48: {
return this.readUInt48SB();
return this.readUInt48();
}
case DataType.DATA56:
case DataType.BITMAP56:
case DataType.UINT56: {
return this.readUInt56SB();
return this.readUInt56();
}
case DataType.DATA64:
case DataType.BITMAP64:
case DataType.UINT64: {
return this.readUInt64SB();
return this.readUInt64();
}
case DataType.INT8: {
return this.readInt8();
Expand All @@ -987,16 +899,16 @@ export class BuffaloZcl extends Buffalo {
return this.readInt32();
}
case DataType.INT40: {
return this.readInt40SB();
return this.readInt40();
}
case DataType.INT48: {
return this.readInt48();
}
case DataType.INT56: {
return this.readInt56SB();
return this.readInt56();
}
case DataType.INT64: {
return this.readInt64SB();
return this.readInt64();
}
// case DataType.SEMI_PREC: {
// // https://tc39.es/proposal-float16array/
Expand Down
62 changes: 62 additions & 0 deletions test/buffalo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,68 @@ describe('Buffalo', () => {
expect(value).toStrictEqual(6618611909121);
});

it('UINT56 write', () => {
const buffalo = new Buffalo(Buffer.alloc(9), 2);
buffalo.writeUInt56(72057594037927934n);
expect(buffalo.getPosition()).toEqual(9);
expect(buffalo.getBuffer()).toStrictEqual(Buffer.from([0, 0, 254, 255, 255, 255, 255, 255, 255]));
});

it('UINT56 read', () => {
const buffalo = new Buffalo(Buffer.from([254, 255, 255, 255, 255, 255, 255]));
const value = buffalo.readUInt56();
expect(buffalo.getPosition()).toEqual(7);
expect(value).toStrictEqual(72057594037927934n);
});

it.each([
[36028797018963964n, [0, 0, 252, 255, 255, 255, 255, 255, 127]],
[-36028797018963964n, [0, 0, 4, 0, 0, 0, 0, 0, 128]],
])('INT56 write positive', (value: bigint, expectedValues: number[]) => {
const buffalo = new Buffalo(Buffer.alloc(9), 2);
buffalo.writeInt56(value);
expect(buffalo.getPosition()).toEqual(9);
expect(buffalo.getBuffer()).toStrictEqual(Buffer.from(expectedValues));
});

it.each([
[36028797018963964n, [252, 255, 255, 255, 255, 255, 127]],
[-36028797018963964n, [4, 0, 0, 0, 0, 0, 128]],
])('INT56 read', (expectedValue: bigint, values: number[]) => {
const buffalo = new Buffalo(Buffer.from(values));
const value = buffalo.readInt56();
expect(buffalo.getPosition()).toEqual(7);
expect(value).toStrictEqual(expectedValue);
});

it('UINT64 write', () => {
const buffalo = new Buffalo(Buffer.alloc(10), 2);
buffalo.writeUInt64(18446744073709551613n);
expect(buffalo.getPosition()).toEqual(10);
expect(buffalo.getBuffer()).toStrictEqual(Buffer.from([0, 0, 253, 255, 255, 255, 255, 255, 255, 255]));
});

it('UINT64 read', () => {
const buffalo = new Buffalo(Buffer.from([253, 255, 255, 255, 255, 255, 255, 255]));
const value = buffalo.readUInt64();
expect(buffalo.getPosition()).toEqual(8);
expect(value).toStrictEqual(18446744073709551613n);
});

it('INT64 write', () => {
const buffalo = new Buffalo(Buffer.alloc(10), 2);
buffalo.writeInt64(9223372036854775806n);
expect(buffalo.getPosition()).toEqual(10);
expect(buffalo.getBuffer()).toStrictEqual(Buffer.from([0, 0, 254, 255, 255, 255, 255, 255, 255, 127]));
});

it('INT64 read', () => {
const buffalo = new Buffalo(Buffer.from([254, 255, 255, 255, 255, 255, 255, 127]));
const value = buffalo.readInt64();
expect(buffalo.getPosition()).toEqual(8);
expect(value).toStrictEqual(9223372036854775806n);
});

it('IEEEADDR write', () => {
const buffalo = new Buffalo(Buffer.alloc(8));
buffalo.writeIeeeAddr(ieeeaAddr1.string);
Expand Down
6 changes: 3 additions & 3 deletions test/controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4019,7 +4019,7 @@ describe('Controller', () => {
'3': 33,
'4': 5032,
'5': 43,
'6': [0, 327680],
'6': 327680,
'8': 516,
},
modelId: 'lumi.sensor_wleak.aq1',
Expand Down Expand Up @@ -4080,7 +4080,7 @@ describe('Controller', () => {
'3': 33,
'4': 5032,
'5': 43,
'6': [0, 327680],
'6': 327680,
'8': 516,
},
modelId: 'lumi.sensor_wleak.aq1',
Expand All @@ -4094,7 +4094,7 @@ describe('Controller', () => {
'3': 33,
'4': 5032,
'5': 43,
'6': [0, 327680],
'6': 327680,
'8': 516,
'10': 0,
'100': 0,
Expand Down
Loading