zigbee-herdsman 4.3.2 → 4.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/.release-please-manifest.json +1 -1
  2. package/CHANGELOG.md +20 -0
  3. package/dist/adapter/deconz/driver/constants.d.ts +1 -2
  4. package/dist/adapter/deconz/driver/constants.d.ts.map +1 -1
  5. package/dist/adapter/deconz/driver/constants.js +1 -0
  6. package/dist/adapter/deconz/driver/constants.js.map +1 -1
  7. package/dist/adapter/deconz/driver/driver.d.ts +5 -1
  8. package/dist/adapter/deconz/driver/driver.d.ts.map +1 -1
  9. package/dist/adapter/deconz/driver/driver.js +92 -52
  10. package/dist/adapter/deconz/driver/driver.js.map +1 -1
  11. package/dist/adapter/deconz/driver/frameParser.d.ts.map +1 -1
  12. package/dist/adapter/deconz/driver/frameParser.js +115 -30
  13. package/dist/adapter/deconz/driver/frameParser.js.map +1 -1
  14. package/dist/controller/controller.d.ts.map +1 -1
  15. package/dist/controller/controller.js +5 -22
  16. package/dist/controller/controller.js.map +1 -1
  17. package/dist/controller/helpers/installCodes.d.ts +27 -0
  18. package/dist/controller/helpers/installCodes.d.ts.map +1 -0
  19. package/dist/controller/helpers/installCodes.js +90 -0
  20. package/dist/controller/helpers/installCodes.js.map +1 -0
  21. package/dist/zspec/utils.d.ts +0 -13
  22. package/dist/zspec/utils.d.ts.map +1 -1
  23. package/dist/zspec/utils.js +0 -49
  24. package/dist/zspec/utils.js.map +1 -1
  25. package/dist/zspec/zcl/definition/cluster.d.ts.map +1 -1
  26. package/dist/zspec/zcl/definition/cluster.js +6 -0
  27. package/dist/zspec/zcl/definition/cluster.js.map +1 -1
  28. package/package.json +1 -1
  29. package/src/adapter/deconz/driver/constants.ts +2 -2
  30. package/src/adapter/deconz/driver/driver.ts +104 -55
  31. package/src/adapter/deconz/driver/frameParser.ts +139 -32
  32. package/src/controller/controller.ts +5 -26
  33. package/src/controller/helpers/installCodes.ts +107 -0
  34. package/src/zspec/utils.ts +1 -60
  35. package/src/zspec/zcl/definition/cluster.ts +6 -0
  36. package/test/controller.test.ts +82 -5
  37. package/test/utils.test.ts +58 -7
  38. package/test/zspec/utils.test.ts +0 -64
@@ -1,5 +1,5 @@
1
1
  import {createCipheriv} from "node:crypto";
2
- import {AES_MMO_128_BLOCK_SIZE, ALL_802_15_4_CHANNELS, INSTALL_CODE_CRC_SIZE, INSTALL_CODE_SIZES} from "./consts";
2
+ import {AES_MMO_128_BLOCK_SIZE, ALL_802_15_4_CHANNELS} from "./consts";
3
3
  import {BroadcastAddress} from "./enums";
4
4
  import type {Eui64} from "./tstypes";
5
5
 
@@ -245,62 +245,3 @@ export function aes128MmoHash(data: Buffer): Buffer {
245
245
 
246
246
  return result;
247
247
  }
248
-
249
- /**
250
- * Check if install code (little-endian) is valid, and if not, and requested, fix it.
251
- *
252
- * WARNING: Due to conflicting sizes between 8-length code with invalid CRC, and 10-length code missing CRC, given 8-length codes are always assumed to be 8-length code with invalid CRC (most probable scenario).
253
- *
254
- * @param code The code to check. Reference is not modified by this procedure but is returned when code was valid, as `outCode`.
255
- * @param adjust If false, throws if the install code is invalid, otherwise try to fix it (CRC)
256
- * @returns
257
- * - The adjusted code, or `code` if not adjusted.
258
- * - If adjust is false, undefined, otherwise, the reason why the code needed adjusting or undefined if not.
259
- * - Throws when adjust=false and invalid, or cannot fix.
260
- */
261
- export function checkInstallCode(code: Buffer, adjust = true): [outCode: Buffer, adjusted: "invalid CRC" | "missing CRC" | undefined] {
262
- const crcLowByteIndex = code.length - INSTALL_CODE_CRC_SIZE;
263
- const crcHighByteIndex = code.length - INSTALL_CODE_CRC_SIZE + 1;
264
-
265
- for (const codeSize of INSTALL_CODE_SIZES) {
266
- if (code.length === codeSize) {
267
- // install code has CRC, check if valid, if not, replace it
268
- const crc = crc16X25(code.subarray(0, -2));
269
- const crcHighByte = (crc >> 8) & 0xff;
270
- const crcLowByte = crc & 0xff;
271
-
272
- if (code[crcLowByteIndex] !== crcLowByte || code[crcHighByteIndex] !== crcHighByte) {
273
- // see WARNING above, 8 is smallest valid length, so always ends up here
274
- if (adjust) {
275
- const outCode = Buffer.from(code);
276
- outCode[crcLowByteIndex] = crcLowByte;
277
- outCode[crcHighByteIndex] = crcHighByte;
278
-
279
- return [outCode, "invalid CRC"];
280
- }
281
-
282
- throw new Error(`Install code ${code.toString("hex")} failed CRC validation`);
283
- }
284
-
285
- return [code, undefined];
286
- }
287
-
288
- if (code.length === codeSize - INSTALL_CODE_CRC_SIZE) {
289
- if (adjust) {
290
- // install code is missing CRC
291
- const crc = crc16X25(code);
292
- const outCode = Buffer.alloc(code.length + INSTALL_CODE_CRC_SIZE);
293
-
294
- code.copy(outCode, 0);
295
- outCode.writeUInt16LE(crc, code.length);
296
-
297
- return [outCode, "missing CRC"];
298
- }
299
-
300
- throw new Error(`Install code ${code.toString("hex")} failed CRC validation`);
301
- }
302
- }
303
-
304
- // never returned from within the above loop
305
- throw new Error(`Install code ${code.toString("hex")} has invalid size`);
306
- }
@@ -1992,6 +1992,9 @@ export const Clusters: Readonly<Record<ClusterName, Readonly<ClusterDefinition>>
1992
1992
  danfossRoomFloorSensorMode: {ID: 0x4120, type: DataType.ENUM8, manufacturerCode: ManufacturerCode.DANFOSS_A_S},
1993
1993
  danfossFloorMinSetpoint: {ID: 0x4121, type: DataType.INT16, manufacturerCode: ManufacturerCode.DANFOSS_A_S},
1994
1994
  danfossFloorMaxSetpoint: {ID: 0x4122, type: DataType.INT16, manufacturerCode: ManufacturerCode.DANFOSS_A_S},
1995
+ danfossScheduleTypeUsed: {ID: 0x4130, type: DataType.ENUM8, manufacturerCode: ManufacturerCode.DANFOSS_A_S},
1996
+ danfossIcon2PreHeat: {ID: 0x4131, type: DataType.ENUM8, manufacturerCode: ManufacturerCode.DANFOSS_A_S},
1997
+ danfossIcon2PreHeatStatus: {ID: 0x414f, type: DataType.ENUM8, manufacturerCode: ManufacturerCode.DANFOSS_A_S},
1995
1998
  elkoLoad: {ID: 0x0401, type: DataType.UINT16},
1996
1999
  elkoDisplayText: {ID: 0x0402, type: DataType.CHAR_STR},
1997
2000
  elkoSensor: {ID: 0x0403, type: DataType.ENUM8},
@@ -4280,8 +4283,11 @@ export const Clusters: Readonly<Record<ClusterName, Readonly<ClusterDefinition>>
4280
4283
  lastMessageLqi: {ID: 284, type: DataType.UINT8},
4281
4284
  lastMessageRssi: {ID: 285, type: DataType.INT8},
4282
4285
  danfossSystemStatusCode: {ID: 0x4000, type: DataType.BITMAP16, manufacturerCode: ManufacturerCode.DANFOSS_A_S},
4286
+ danfossHeatSupplyRequest: {ID: 0x4031, type: DataType.ENUM8, manufacturerCode: ManufacturerCode.DANFOSS_A_S},
4283
4287
  danfossSystemStatusWater: {ID: 0x4200, type: DataType.ENUM8, manufacturerCode: ManufacturerCode.DANFOSS_A_S},
4284
4288
  danfossMultimasterRole: {ID: 0x4201, type: DataType.ENUM8, manufacturerCode: ManufacturerCode.DANFOSS_A_S},
4289
+ danfossIconApplication: {ID: 0x4210, type: DataType.ENUM8, manufacturerCode: ManufacturerCode.DANFOSS_A_S},
4290
+ danfossIconForcedHeatingCooling: {ID: 0x4220, type: DataType.ENUM8, manufacturerCode: ManufacturerCode.DANFOSS_A_S},
4285
4291
  schneiderMeterStatus: {ID: 0xff01, type: DataType.UINT32, manufacturerCode: ManufacturerCode.SCHNEIDER_ELECTRIC},
4286
4292
  schneiderDiagnosticRegister1: {ID: 0xff02, type: DataType.UINT32, manufacturerCode: ManufacturerCode.SCHNEIDER_ELECTRIC},
4287
4293
  schneiderCommunicationQuality: {ID: 0x4000, type: DataType.UINT8, manufacturerCode: ManufacturerCode.SCHNEIDER_ELECTRIC},
@@ -1839,7 +1839,7 @@ describe("Controller", () => {
1839
1839
  await controller.addInstallCode(code);
1840
1840
  expect(mockAddInstallCode).toHaveBeenCalledTimes(1);
1841
1841
  expect(mockAddInstallCode).toHaveBeenCalledWith(
1842
- "0x9035EAFFFE424783",
1842
+ "0x9035eafffe424783",
1843
1843
  Buffer.from([0xae, 0x3b, 0x28, 0x72, 0x81, 0xcf, 0x16, 0xf5, 0x50, 0x73, 0x3a, 0x0c, 0xec, 0x38, 0xaa, 0x31, 0xe8, 0x02]),
1844
1844
  false,
1845
1845
  );
@@ -1851,37 +1851,102 @@ describe("Controller", () => {
1851
1851
  await controller.addInstallCode(code);
1852
1852
  expect(mockAddInstallCode).toHaveBeenCalledTimes(2);
1853
1853
  expect(mockAddInstallCode).toHaveBeenCalledWith(
1854
- "0x000D6F00179F2BC9",
1854
+ "0x000d6f00179f2bc9",
1855
1855
  Buffer.from([0xd0, 0xf4, 0x71, 0xc9, 0xbb, 0xa2, 0xc0, 0x20, 0x86, 0x08, 0xe9, 0x1e, 0xed, 0x17, 0xe2, 0xb1, 0x9a, 0xec]),
1856
1856
  false,
1857
1857
  );
1858
1858
  expect(mockAddInstallCode).toHaveBeenCalledWith(
1859
- "0x000D6F00179F2BC9",
1859
+ "0x000d6f00179f2bc9",
1860
1860
  Buffer.from([0xd0, 0xf4, 0x71, 0xc9, 0xbb, 0xa2, 0xc0, 0x20, 0x86, 0x08, 0xe9, 0x1e, 0xed, 0x17, 0xe2, 0xb1]),
1861
1861
  true,
1862
1862
  );
1863
1863
  expect(mockLogger.info).toHaveBeenCalledWith(`Install code was adjusted for reason 'missing CRC'.`, "zh:controller");
1864
1864
  });
1865
1865
 
1866
+ it("Add install code widely adopted format", async () => {
1867
+ await controller.start();
1868
+ // inovelli
1869
+ const code = "Z:6C5CB1FFFE44FDFD$I:5492072F8DE72829FEE139CF8ACA4F43EF21";
1870
+ await controller.addInstallCode(code);
1871
+ expect(mockAddInstallCode).toHaveBeenNthCalledWith(
1872
+ 1,
1873
+ "0x6c5cb1fffe44fdfd",
1874
+ Buffer.from([
1875
+ 0x54, 0x92, 0x07, 0x2f, 0x8d, 0xe7, 0x28, 0x29, 0xfe, 0xe1, 0x39, 0xcf, 0x8a, 0xca, 0x4f, 0x43, /*0xef, 0x21 bad CRC?*/ 0x85, 0x44,
1876
+ ]),
1877
+ false,
1878
+ );
1879
+ // danfoss
1880
+ const code2 = "G$M:IC2%Z:540F57FFFE599FAA$I:D79CB21C6D197CE7A3339A683A90DFF2442A%M:1246";
1881
+ await controller.addInstallCode(code2);
1882
+ expect(mockAddInstallCode).toHaveBeenNthCalledWith(
1883
+ 2,
1884
+ "0x540f57fffe599faa",
1885
+ Buffer.from([0xd7, 0x9c, 0xb2, 0x1c, 0x6d, 0x19, 0x7c, 0xe7, 0xa3, 0x33, 0x9a, 0x68, 0x3a, 0x90, 0xdf, 0xf2, 0x44, 0x2a]),
1886
+ false,
1887
+ );
1888
+ // ??
1889
+ const code3 = "Z:4CC206FFFE306C43$I:150A1A57D11A1A01362622DBA97ACF0F9185$D:202%B:4CC206306C43$P:983639%M:1220$F:002D";
1890
+ await controller.addInstallCode(code3);
1891
+ expect(mockAddInstallCode).toHaveBeenNthCalledWith(
1892
+ 3,
1893
+ "0x4cc206fffe306c43",
1894
+ Buffer.from([
1895
+ 0x15, 0x0a, 0x1a, 0x57, 0xd1, 0x1a, 0x1a, 0x01, 0x36, 0x26, 0x22, 0xdb, 0xa9, 0x7a, 0xcf, 0x0f, /*0x91, 0x85 bad CRC?*/ 0x0c, 0xca,
1896
+ ]),
1897
+ false,
1898
+ );
1899
+ // ubisys
1900
+ const code4 = "Z:0102030405060708$I:0102030405060708090A0B0C0D0E0F1090FD%G$M:S1-R%M:10F2";
1901
+ await controller.addInstallCode(code4);
1902
+ expect(mockAddInstallCode).toHaveBeenNthCalledWith(
1903
+ 4,
1904
+ "0x0102030405060708",
1905
+ Buffer.from([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x90, 0xfd]),
1906
+ false,
1907
+ );
1908
+ // ledvance
1909
+ const code5 = "Z:F0D1B8000017389A$I:6AB6973274EE6F720200530162754044C930%M:1189$D:008B452720";
1910
+ await controller.addInstallCode(code5);
1911
+ expect(mockAddInstallCode).toHaveBeenNthCalledWith(
1912
+ 5,
1913
+ "0xf0d1b8000017389a",
1914
+ Buffer.from([0x6a, 0xb6, 0x97, 0x32, 0x74, 0xee, 0x6f, 0x72, 0x02, 0x00, 0x53, 0x01, 0x62, 0x75, 0x40, 0x44, 0xc9, 0x30]),
1915
+ false,
1916
+ );
1917
+ });
1918
+
1866
1919
  it("Add install code Aqara", async () => {
1867
1920
  await controller.start();
1868
1921
  const code = "G$M:69775$S:680S00003915$D:0000000017B2335C%Z$A:54EF44100006E7DF$I:3313A005E177A647FC7925620AB207C4BEF5";
1869
1922
  await controller.addInstallCode(code);
1870
1923
  expect(mockAddInstallCode).toHaveBeenCalledTimes(1);
1871
1924
  expect(mockAddInstallCode).toHaveBeenCalledWith(
1872
- "0x54EF44100006E7DF",
1925
+ "0x54ef44100006e7df",
1873
1926
  Buffer.from([0x33, 0x13, 0xa0, 0x05, 0xe1, 0x77, 0xa6, 0x47, 0xfc, 0x79, 0x25, 0x62, 0x0a, 0xb2, 0x07, 0xc4, 0xbe, 0xf5]),
1874
1927
  false,
1875
1928
  );
1876
1929
  });
1877
1930
 
1931
+ it("Add install code Hue", async () => {
1932
+ await controller.start();
1933
+ const code = "HUE:Z:0123456789ABCDEF0123456789ABCDEF0123 M:0123456789ABCDEF D:L3B A:1184";
1934
+ await controller.addInstallCode(code);
1935
+ expect(mockAddInstallCode).toHaveBeenCalledTimes(1);
1936
+ expect(mockAddInstallCode).toHaveBeenCalledWith(
1937
+ "0x0123456789abcdef",
1938
+ Buffer.from([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xe7, 0xb8]),
1939
+ false,
1940
+ );
1941
+ });
1942
+
1878
1943
  it("Add install code pipe", async () => {
1879
1944
  await controller.start();
1880
1945
  const code = "54EF44100006E7DF|3313A005E177A647FC7925620AB207C4BEF5";
1881
1946
  await controller.addInstallCode(code);
1882
1947
  expect(mockAddInstallCode).toHaveBeenCalledTimes(1);
1883
1948
  expect(mockAddInstallCode).toHaveBeenCalledWith(
1884
- "0x54EF44100006E7DF",
1949
+ "0x54ef44100006e7df",
1885
1950
  Buffer.from([0x33, 0x13, 0xa0, 0x05, 0xe1, 0x77, 0xa6, 0x47, 0xfc, 0x79, 0x25, 0x62, 0x0a, 0xb2, 0x07, 0xc4, 0xbe, 0xf5]),
1886
1951
  false,
1887
1952
  );
@@ -1897,6 +1962,18 @@ describe("Controller", () => {
1897
1962
  expect(mockAddInstallCode).toHaveBeenCalledTimes(0);
1898
1963
  });
1899
1964
 
1965
+ it("Add install code unknown format", async () => {
1966
+ await controller.start();
1967
+
1968
+ const code = "54EF44100006E7DF`3313A005E177A647FC7925620AB207";
1969
+
1970
+ await expect(controller.addInstallCode(code)).rejects.toThrow(
1971
+ "Unsupported install code, got 47 chars, expected 95 or 91 chars, or known format",
1972
+ );
1973
+
1974
+ expect(mockAddInstallCode).toHaveBeenCalledTimes(0);
1975
+ });
1976
+
1900
1977
  it("Controller permit joining all, disabled automatically", async () => {
1901
1978
  await controller.start();
1902
1979
 
@@ -1,3 +1,4 @@
1
+ import {checkInstallCode} from "../src/controller/helpers/installCodes";
1
2
  import {Queue, Utils, Waitress, wait} from "../src/utils";
2
3
  import {logger, setLogger} from "../src/utils/logger";
3
4
 
@@ -133,14 +134,14 @@ describe("Utils", () => {
133
134
 
134
135
  it("Test queue", async () => {
135
136
  const queue = new Queue(4);
136
- const finished = [];
137
+ const finished: number[] = [];
137
138
 
138
- let job1Promise;
139
- let job2Promise;
140
- const job1 = new Promise((resolve) => {
139
+ let job1Promise: (() => void) | undefined;
140
+ let job2Promise: (() => void) | undefined;
141
+ const job1 = new Promise<void>((resolve) => {
141
142
  job1Promise = resolve;
142
143
  });
143
- const job2 = new Promise((resolve) => {
144
+ const job2 = new Promise<void>((resolve) => {
144
145
  job2Promise = resolve;
145
146
  });
146
147
  const job5 = new Promise((_resolve) => {});
@@ -189,11 +190,11 @@ describe("Utils", () => {
189
190
  });
190
191
 
191
192
  expect(finished).toEqual([4]);
192
- job1Promise();
193
+ job1Promise?.();
193
194
  expect(await job1Result).toBe("finished");
194
195
  await job1Result;
195
196
  expect(finished).toEqual([4, 1]);
196
- job2Promise();
197
+ job2Promise?.();
197
198
  await job2Result;
198
199
  expect(finished).toEqual([4, 1, 2, 3]);
199
200
  expect(queue.count()).toBe(5);
@@ -224,4 +225,54 @@ describe("Utils", () => {
224
225
  logger.error("error", "zh");
225
226
  expect(mockLogger.error).toHaveBeenCalledWith("error", "zh");
226
227
  });
228
+
229
+ it("Checks install codes of all lengths", () => {
230
+ expect(() => checkInstallCode(Buffer.from("001122", "hex"))).toThrow("Install code 001122 has invalid size");
231
+
232
+ const code8Valid = Buffer.from("83FED3407A932B70", "hex");
233
+ const code8Invalid = Buffer.from("FFFED3407A939723", "hex");
234
+ const code8InvalidFixed = Buffer.from("FFFED3407A93DE84", "hex");
235
+ const code8MissingCRC = Buffer.from("83FED3407A93", "hex");
236
+
237
+ expect(checkInstallCode(code8Valid)).toStrictEqual([code8Valid, undefined]);
238
+ expect(checkInstallCode(code8Invalid)).toStrictEqual([code8InvalidFixed, "invalid CRC"]);
239
+ expect(() => checkInstallCode(code8Invalid, false)).toThrow(`Install code ${code8Invalid.toString("hex")} failed CRC validation`);
240
+ expect(checkInstallCode(code8MissingCRC)).toStrictEqual([code8Valid, "missing CRC"]);
241
+ expect(() => checkInstallCode(code8MissingCRC, false)).toThrow(`Install code ${code8MissingCRC.toString("hex")} failed CRC validation`);
242
+
243
+ const code10Valid = Buffer.from("83FED3407A93972397FC", "hex");
244
+ const code10Invalid = Buffer.from("FFFED3407A939723A5C6", "hex");
245
+ const code10InvalidFixed = Buffer.from("FFFED3407A9397238C4F", "hex");
246
+ // consired as 8-length with invalid CRC
247
+ const code10MissingCRC = Buffer.from("83FED3407A939723", "hex");
248
+ const code10MissingCRCFixed = Buffer.from("83FED3407A932B70", "hex");
249
+
250
+ expect(checkInstallCode(code10Valid)).toStrictEqual([code10Valid, undefined]);
251
+ expect(checkInstallCode(code10Invalid)).toStrictEqual([code10InvalidFixed, "invalid CRC"]);
252
+ expect(() => checkInstallCode(code10Invalid, false)).toThrow(`Install code ${code10Invalid.toString("hex")} failed CRC validation`);
253
+ expect(checkInstallCode(code10MissingCRC)).toStrictEqual([code10MissingCRCFixed, "invalid CRC"]);
254
+ expect(() => checkInstallCode(code10MissingCRC, false)).toThrow(`Install code ${code10MissingCRC.toString("hex")} failed CRC validation`);
255
+
256
+ const code14Valid = Buffer.from("83FED3407A939723A5C639FF4C12", "hex");
257
+ const code14Invalid = Buffer.from("FFFED3407A939723A5C639FF4C12", "hex");
258
+ const code14InvalidFixed = Buffer.from("FFFED3407A939723A5C639FFDE74", "hex");
259
+ const code14MissingCRC = Buffer.from("83FED3407A939723A5C639FF", "hex");
260
+
261
+ expect(checkInstallCode(code14Valid)).toStrictEqual([code14Valid, undefined]);
262
+ expect(checkInstallCode(code14Invalid)).toStrictEqual([code14InvalidFixed, "invalid CRC"]);
263
+ expect(() => checkInstallCode(code14Invalid, false)).toThrow(`Install code ${code14Invalid.toString("hex")} failed CRC validation`);
264
+ expect(checkInstallCode(code14MissingCRC)).toStrictEqual([code14Valid, "missing CRC"]);
265
+ expect(() => checkInstallCode(code14MissingCRC, false)).toThrow(`Install code ${code14MissingCRC.toString("hex")} failed CRC validation`);
266
+
267
+ const code18Valid = Buffer.from("83FED3407A939723A5C639B26916D505C3B5", "hex");
268
+ const code18Invalid = Buffer.from("FFFED3407A939723A5C639B26916D505C3B5", "hex");
269
+ const code18InvalidFixed = Buffer.from("FFFED3407A939723A5C639B26916D505EEB1", "hex");
270
+ const code18MissingCRC = Buffer.from("83FED3407A939723A5C639B26916D505", "hex");
271
+
272
+ expect(checkInstallCode(code18Valid)).toStrictEqual([code18Valid, undefined]);
273
+ expect(checkInstallCode(code18Invalid)).toStrictEqual([code18InvalidFixed, "invalid CRC"]);
274
+ expect(() => checkInstallCode(code18Invalid, false)).toThrow(`Install code ${code18Invalid.toString("hex")} failed CRC validation`);
275
+ expect(checkInstallCode(code18MissingCRC)).toStrictEqual([code18Valid, "missing CRC"]);
276
+ expect(() => checkInstallCode(code18MissingCRC, false)).toThrow(`Install code ${code18MissingCRC.toString("hex")} failed CRC validation`);
277
+ });
227
278
  });
@@ -64,68 +64,4 @@ describe("ZSpec Utils", () => {
64
64
  expect(ZSpec.Utils.aes128MmoHash(val3)).toStrictEqual(Buffer.from("3C3D537529A7A9A03F669DCD886CB52C", "hex"));
65
65
  expect(ZSpec.Utils.aes128MmoHash(val4)).toStrictEqual(Buffer.from("4512807BF94CB3400F0E2C25FB76E999", "hex"));
66
66
  });
67
-
68
- it("Checks install codes of all lengths", () => {
69
- expect(() => ZSpec.Utils.checkInstallCode(Buffer.from("001122", "hex"))).toThrow("Install code 001122 has invalid size");
70
-
71
- const code8Valid = Buffer.from("83FED3407A932B70", "hex");
72
- const code8Invalid = Buffer.from("FFFED3407A939723", "hex");
73
- const code8InvalidFixed = Buffer.from("FFFED3407A93DE84", "hex");
74
- const code8MissingCRC = Buffer.from("83FED3407A93", "hex");
75
-
76
- expect(ZSpec.Utils.checkInstallCode(code8Valid)).toStrictEqual([code8Valid, undefined]);
77
- expect(ZSpec.Utils.checkInstallCode(code8Invalid)).toStrictEqual([code8InvalidFixed, "invalid CRC"]);
78
- expect(() => ZSpec.Utils.checkInstallCode(code8Invalid, false)).toThrow(`Install code ${code8Invalid.toString("hex")} failed CRC validation`);
79
- expect(ZSpec.Utils.checkInstallCode(code8MissingCRC)).toStrictEqual([code8Valid, "missing CRC"]);
80
- expect(() => ZSpec.Utils.checkInstallCode(code8MissingCRC, false)).toThrow(
81
- `Install code ${code8MissingCRC.toString("hex")} failed CRC validation`,
82
- );
83
-
84
- const code10Valid = Buffer.from("83FED3407A93972397FC", "hex");
85
- const code10Invalid = Buffer.from("FFFED3407A939723A5C6", "hex");
86
- const code10InvalidFixed = Buffer.from("FFFED3407A9397238C4F", "hex");
87
- // consired as 8-length with invalid CRC
88
- const code10MissingCRC = Buffer.from("83FED3407A939723", "hex");
89
- const code10MissingCRCFixed = Buffer.from("83FED3407A932B70", "hex");
90
-
91
- expect(ZSpec.Utils.checkInstallCode(code10Valid)).toStrictEqual([code10Valid, undefined]);
92
- expect(ZSpec.Utils.checkInstallCode(code10Invalid)).toStrictEqual([code10InvalidFixed, "invalid CRC"]);
93
- expect(() => ZSpec.Utils.checkInstallCode(code10Invalid, false)).toThrow(
94
- `Install code ${code10Invalid.toString("hex")} failed CRC validation`,
95
- );
96
- expect(ZSpec.Utils.checkInstallCode(code10MissingCRC)).toStrictEqual([code10MissingCRCFixed, "invalid CRC"]);
97
- expect(() => ZSpec.Utils.checkInstallCode(code10MissingCRC, false)).toThrow(
98
- `Install code ${code10MissingCRC.toString("hex")} failed CRC validation`,
99
- );
100
-
101
- const code14Valid = Buffer.from("83FED3407A939723A5C639FF4C12", "hex");
102
- const code14Invalid = Buffer.from("FFFED3407A939723A5C639FF4C12", "hex");
103
- const code14InvalidFixed = Buffer.from("FFFED3407A939723A5C639FFDE74", "hex");
104
- const code14MissingCRC = Buffer.from("83FED3407A939723A5C639FF", "hex");
105
-
106
- expect(ZSpec.Utils.checkInstallCode(code14Valid)).toStrictEqual([code14Valid, undefined]);
107
- expect(ZSpec.Utils.checkInstallCode(code14Invalid)).toStrictEqual([code14InvalidFixed, "invalid CRC"]);
108
- expect(() => ZSpec.Utils.checkInstallCode(code14Invalid, false)).toThrow(
109
- `Install code ${code14Invalid.toString("hex")} failed CRC validation`,
110
- );
111
- expect(ZSpec.Utils.checkInstallCode(code14MissingCRC)).toStrictEqual([code14Valid, "missing CRC"]);
112
- expect(() => ZSpec.Utils.checkInstallCode(code14MissingCRC, false)).toThrow(
113
- `Install code ${code14MissingCRC.toString("hex")} failed CRC validation`,
114
- );
115
-
116
- const code18Valid = Buffer.from("83FED3407A939723A5C639B26916D505C3B5", "hex");
117
- const code18Invalid = Buffer.from("FFFED3407A939723A5C639B26916D505C3B5", "hex");
118
- const code18InvalidFixed = Buffer.from("FFFED3407A939723A5C639B26916D505EEB1", "hex");
119
- const code18MissingCRC = Buffer.from("83FED3407A939723A5C639B26916D505", "hex");
120
-
121
- expect(ZSpec.Utils.checkInstallCode(code18Valid)).toStrictEqual([code18Valid, undefined]);
122
- expect(ZSpec.Utils.checkInstallCode(code18Invalid)).toStrictEqual([code18InvalidFixed, "invalid CRC"]);
123
- expect(() => ZSpec.Utils.checkInstallCode(code18Invalid, false)).toThrow(
124
- `Install code ${code18Invalid.toString("hex")} failed CRC validation`,
125
- );
126
- expect(ZSpec.Utils.checkInstallCode(code18MissingCRC)).toStrictEqual([code18Valid, "missing CRC"]);
127
- expect(() => ZSpec.Utils.checkInstallCode(code18MissingCRC, false)).toThrow(
128
- `Install code ${code18MissingCRC.toString("hex")} failed CRC validation`,
129
- );
130
- });
131
67
  });