@willieee802/zigbee-herdsman 0.48.2 → 0.49.0

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 (1025) hide show
  1. package/.github/ISSUE_TEMPLATE/config.yml +5 -0
  2. package/.github/copilot-instructions.md +689 -0
  3. package/.github/dependabot.yml +22 -0
  4. package/.github/prompts/copilot-instructions-blueprint-generator.prompt.md +294 -0
  5. package/.github/prompts/create-agentsmd.prompt.md +249 -0
  6. package/.github/prompts/create-specification.prompt.md +127 -0
  7. package/.github/prompts/review-and-refactor.prompt.md +15 -0
  8. package/.github/prompts/update-specification.prompt.md +127 -0
  9. package/.github/workflows/ci.yml +70 -0
  10. package/.github/workflows/release-please.yml +18 -0
  11. package/.github/workflows/stale.yml +20 -0
  12. package/.github/workflows/typedoc.yaml +47 -0
  13. package/.release-please-manifest.json +2 -2
  14. package/.vscode/extensions.json +3 -0
  15. package/.vscode/settings.json +11 -0
  16. package/AGENTS.md +441 -0
  17. package/CHANGELOG.md +1245 -0
  18. package/README.md +2 -2
  19. package/biome.json +103 -0
  20. package/examples/join-and-log.js +18 -18
  21. package/package.json +83 -70
  22. package/release-please-config.json +8 -8
  23. package/scripts/check-clusters-changes.ts +328 -0
  24. package/scripts/clusters-changes.log +584 -0
  25. package/scripts/clusters-typegen.ts +608 -0
  26. package/scripts/utils.ts +88 -0
  27. package/scripts/zap-update-clusters-report.json +303 -0
  28. package/scripts/zap-update-clusters.ts +1520 -0
  29. package/scripts/zap-update-types.ts +707 -0
  30. package/scripts/zap-xml-clusters-overrides-data.ts +52 -0
  31. package/scripts/zap-xml-clusters-overrides.ts +400 -0
  32. package/scripts/zap-xml-types.ts +146 -0
  33. package/src/adapter/adapter.ts +210 -0
  34. package/src/adapter/adapterDiscovery.ts +736 -0
  35. package/src/adapter/const.ts +12 -0
  36. package/src/adapter/deconz/adapter/deconzAdapter.ts +888 -0
  37. package/src/adapter/deconz/driver/constants.ts +246 -0
  38. package/src/adapter/deconz/driver/driver.ts +1528 -0
  39. package/src/adapter/deconz/driver/frame.ts +11 -0
  40. package/src/adapter/deconz/driver/frameParser.ts +766 -0
  41. package/src/adapter/deconz/driver/parser.ts +45 -0
  42. package/src/adapter/deconz/driver/writer.ts +22 -0
  43. package/src/adapter/deconz/types.d.ts +13 -0
  44. package/src/adapter/ember/adapter/emberAdapter.ts +2262 -0
  45. package/src/adapter/ember/adapter/endpoints.ts +86 -0
  46. package/src/adapter/ember/adapter/oneWaitress.ts +324 -0
  47. package/src/adapter/ember/adapter/tokensManager.ts +780 -0
  48. package/src/adapter/ember/consts.ts +178 -0
  49. package/src/adapter/ember/enums.ts +1746 -0
  50. package/src/adapter/ember/ezsp/buffalo.ts +1392 -0
  51. package/src/adapter/ember/ezsp/consts.ts +148 -0
  52. package/src/adapter/ember/ezsp/enums.ts +1114 -0
  53. package/src/adapter/ember/ezsp/ezsp.ts +9073 -0
  54. package/src/adapter/ember/ezspError.ts +10 -0
  55. package/src/adapter/ember/types.ts +866 -0
  56. package/src/adapter/ember/uart/ash.ts +1933 -0
  57. package/src/adapter/ember/uart/consts.ts +109 -0
  58. package/src/adapter/ember/uart/enums.ts +192 -0
  59. package/src/adapter/ember/uart/parser.ts +42 -0
  60. package/src/adapter/ember/uart/queues.ts +247 -0
  61. package/src/adapter/ember/uart/writer.ts +50 -0
  62. package/src/adapter/ember/utils/initters.ts +58 -0
  63. package/src/adapter/ember/utils/math.ts +71 -0
  64. package/src/adapter/events.ts +21 -0
  65. package/src/adapter/ezsp/adapter/backup.ts +100 -0
  66. package/src/adapter/ezsp/adapter/ezspAdapter.ts +632 -0
  67. package/src/adapter/ezsp/driver/commands.ts +2497 -0
  68. package/src/adapter/ezsp/driver/consts.ts +11 -0
  69. package/src/adapter/ezsp/driver/driver.ts +1002 -0
  70. package/src/adapter/ezsp/driver/ezsp.ts +802 -0
  71. package/src/adapter/ezsp/driver/frame.ts +101 -0
  72. package/src/adapter/ezsp/driver/index.ts +4 -0
  73. package/src/adapter/ezsp/driver/multicast.ts +78 -0
  74. package/src/adapter/ezsp/driver/parser.ts +81 -0
  75. package/src/adapter/ezsp/driver/types/basic.ts +201 -0
  76. package/src/adapter/ezsp/driver/types/index.ts +239 -0
  77. package/src/adapter/ezsp/driver/types/named.ts +2330 -0
  78. package/src/adapter/ezsp/driver/types/struct.ts +844 -0
  79. package/src/adapter/ezsp/driver/uart.ts +460 -0
  80. package/src/adapter/ezsp/driver/utils/crc16ccitt.ts +44 -0
  81. package/src/adapter/ezsp/driver/utils/index.ts +32 -0
  82. package/src/adapter/ezsp/driver/writer.ts +64 -0
  83. package/src/adapter/index.ts +3 -0
  84. package/src/adapter/serialPort.ts +58 -0
  85. package/src/adapter/tstype.ts +57 -0
  86. package/src/adapter/utils.ts +41 -0
  87. package/src/adapter/z-stack/adapter/adapter-backup.ts +509 -0
  88. package/src/adapter/z-stack/adapter/adapter-nv-memory.ts +457 -0
  89. package/src/adapter/z-stack/adapter/endpoints.ts +60 -0
  90. package/src/adapter/z-stack/adapter/manager.ts +543 -0
  91. package/src/adapter/z-stack/adapter/tstype.ts +6 -0
  92. package/src/adapter/z-stack/adapter/zStackAdapter.ts +1350 -0
  93. package/src/adapter/z-stack/constants/af.ts +27 -0
  94. package/src/adapter/z-stack/constants/common.ts +285 -0
  95. package/src/adapter/z-stack/constants/dbg.ts +23 -0
  96. package/src/adapter/z-stack/constants/index.ts +11 -0
  97. package/src/adapter/z-stack/constants/mac.ts +128 -0
  98. package/src/adapter/z-stack/constants/sapi.ts +25 -0
  99. package/src/adapter/z-stack/constants/sys.ts +72 -0
  100. package/src/adapter/z-stack/constants/util.ts +82 -0
  101. package/src/adapter/z-stack/constants/utils.ts +14 -0
  102. package/src/adapter/z-stack/constants/zdo.ts +103 -0
  103. package/src/adapter/z-stack/models/startup-options.ts +13 -0
  104. package/src/adapter/z-stack/structs/entries/address-manager-entry.ts +44 -0
  105. package/src/adapter/z-stack/structs/entries/address-manager-table.ts +19 -0
  106. package/src/adapter/z-stack/structs/entries/aps-link-key-data-entry.ts +12 -0
  107. package/src/adapter/z-stack/structs/entries/aps-link-key-data-table.ts +21 -0
  108. package/src/adapter/z-stack/structs/entries/aps-tc-link-key-entry.ts +19 -0
  109. package/src/adapter/z-stack/structs/entries/aps-tc-link-key-table.ts +21 -0
  110. package/src/adapter/z-stack/structs/entries/channel-list.ts +8 -0
  111. package/src/adapter/z-stack/structs/entries/has-configured.ts +16 -0
  112. package/src/adapter/z-stack/structs/entries/index.ts +16 -0
  113. package/src/adapter/z-stack/structs/entries/nib.ts +66 -0
  114. package/src/adapter/z-stack/structs/entries/nwk-key-descriptor.ts +15 -0
  115. package/src/adapter/z-stack/structs/entries/nwk-key.ts +13 -0
  116. package/src/adapter/z-stack/structs/entries/nwk-pan-id.ts +8 -0
  117. package/src/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-entry.ts +20 -0
  118. package/src/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-table.ts +19 -0
  119. package/src/adapter/z-stack/structs/entries/security-manager-entry.ts +33 -0
  120. package/src/adapter/z-stack/structs/entries/security-manager-table.ts +22 -0
  121. package/src/adapter/z-stack/structs/index.ts +4 -0
  122. package/src/adapter/z-stack/structs/serializable-memory-object.ts +14 -0
  123. package/src/adapter/z-stack/structs/struct.ts +367 -0
  124. package/src/adapter/z-stack/structs/table.ts +198 -0
  125. package/src/adapter/z-stack/unpi/constants.ts +33 -0
  126. package/src/adapter/z-stack/unpi/frame.ts +62 -0
  127. package/src/adapter/z-stack/unpi/index.ts +4 -0
  128. package/src/adapter/z-stack/unpi/parser.ts +67 -0
  129. package/src/adapter/z-stack/unpi/writer.ts +37 -0
  130. package/src/adapter/z-stack/utils/channel-list.ts +40 -0
  131. package/src/adapter/z-stack/utils/index.ts +2 -0
  132. package/src/adapter/z-stack/utils/network-options.ts +26 -0
  133. package/src/adapter/z-stack/znp/buffaloZnp.ts +175 -0
  134. package/src/adapter/z-stack/znp/definition.ts +2713 -0
  135. package/src/adapter/z-stack/znp/index.ts +2 -0
  136. package/src/adapter/z-stack/znp/parameterType.ts +22 -0
  137. package/src/adapter/z-stack/znp/tstype.ts +44 -0
  138. package/src/adapter/z-stack/znp/utils.ts +10 -0
  139. package/src/adapter/z-stack/znp/znp.ts +345 -0
  140. package/src/adapter/z-stack/znp/zpiObject.ts +148 -0
  141. package/src/adapter/zboss/adapter/zbossAdapter.ts +535 -0
  142. package/src/adapter/zboss/commands.ts +1184 -0
  143. package/src/adapter/zboss/consts.ts +9 -0
  144. package/src/adapter/zboss/driver.ts +422 -0
  145. package/src/adapter/zboss/enums.ts +360 -0
  146. package/src/adapter/zboss/frame.ts +227 -0
  147. package/src/adapter/zboss/reader.ts +65 -0
  148. package/src/adapter/zboss/types.ts +0 -0
  149. package/src/adapter/zboss/uart.ts +428 -0
  150. package/src/adapter/zboss/utils.ts +58 -0
  151. package/src/adapter/zboss/writer.ts +49 -0
  152. package/src/adapter/zigate/adapter/patchZdoBuffaloBE.ts +25 -0
  153. package/src/adapter/zigate/adapter/zigateAdapter.ts +633 -0
  154. package/src/adapter/zigate/driver/LICENSE +17 -0
  155. package/src/adapter/zigate/driver/buffaloZiGate.ts +210 -0
  156. package/src/adapter/zigate/driver/commandType.ts +418 -0
  157. package/src/adapter/zigate/driver/constants.ts +150 -0
  158. package/src/adapter/zigate/driver/frame.ts +197 -0
  159. package/src/adapter/zigate/driver/messageType.ts +287 -0
  160. package/src/adapter/zigate/driver/parameterType.ts +32 -0
  161. package/src/adapter/zigate/driver/ziGateObject.ts +146 -0
  162. package/src/adapter/zigate/driver/zigate.ts +422 -0
  163. package/src/adapter/zoh/adapter/utils.ts +27 -0
  164. package/src/adapter/zoh/adapter/zohAdapter.ts +931 -0
  165. package/src/buffalo/buffalo.ts +336 -0
  166. package/src/buffalo/index.ts +1 -0
  167. package/src/controller/controller.ts +1159 -0
  168. package/src/controller/database.ts +148 -0
  169. package/src/controller/events.ts +52 -0
  170. package/src/controller/greenPower.ts +613 -0
  171. package/src/controller/helpers/index.ts +1 -0
  172. package/src/controller/helpers/installCodes.ts +107 -0
  173. package/src/controller/helpers/ota.ts +575 -0
  174. package/src/controller/helpers/request.ts +96 -0
  175. package/src/controller/helpers/requestQueue.ts +126 -0
  176. package/src/controller/helpers/zclFrameConverter.ts +64 -0
  177. package/src/controller/helpers/zclTransactionSequenceNumber.ts +15 -0
  178. package/src/controller/index.ts +6 -0
  179. package/src/controller/model/device.ts +1791 -0
  180. package/src/controller/model/endpoint.ts +1235 -0
  181. package/src/controller/model/entity.ts +43 -0
  182. package/src/controller/model/group.ts +446 -0
  183. package/src/controller/model/index.ts +5 -0
  184. package/src/controller/model/konnextConfig.ts +6 -0
  185. package/src/controller/model/zigbeeEntity.ts +30 -0
  186. package/src/controller/touchlink.ts +195 -0
  187. package/src/controller/tstype.ts +374 -0
  188. package/src/index.ts +14 -0
  189. package/src/models/backup-storage-legacy.ts +48 -0
  190. package/src/models/backup-storage-unified.ts +47 -0
  191. package/src/models/backup.ts +37 -0
  192. package/src/models/index.ts +5 -0
  193. package/src/models/network-options.ts +11 -0
  194. package/src/utils/aes.ts +218 -0
  195. package/src/utils/async-mutex.ts +31 -0
  196. package/src/utils/backup.ts +152 -0
  197. package/src/utils/index.ts +5 -0
  198. package/src/utils/logger.ts +20 -0
  199. package/src/utils/patchBigIntSerialization.ts +8 -0
  200. package/src/utils/queue.ts +79 -0
  201. package/src/utils/timeService.ts +139 -0
  202. package/src/utils/utils.ts +19 -0
  203. package/src/utils/wait.ts +5 -0
  204. package/src/utils/waitress.ts +96 -0
  205. package/src/zspec/consts.ts +89 -0
  206. package/src/zspec/enums.ts +22 -0
  207. package/src/zspec/index.ts +3 -0
  208. package/src/zspec/tstypes.ts +18 -0
  209. package/src/zspec/utils.ts +247 -0
  210. package/src/zspec/zcl/buffaloZcl.ts +1073 -0
  211. package/src/zspec/zcl/definition/cluster.ts +7845 -0
  212. package/src/zspec/zcl/definition/clusters-types.ts +8577 -0
  213. package/src/zspec/zcl/definition/consts.ts +24 -0
  214. package/src/zspec/zcl/definition/datatypes.ts +2454 -0
  215. package/src/zspec/zcl/definition/enums.ts +224 -0
  216. package/src/zspec/zcl/definition/foundation.ts +342 -0
  217. package/src/zspec/zcl/definition/manufacturerCode.ts +730 -0
  218. package/src/zspec/zcl/definition/status.ts +69 -0
  219. package/src/zspec/zcl/definition/tstype.ts +446 -0
  220. package/src/zspec/zcl/index.ts +11 -0
  221. package/src/zspec/zcl/utils.ts +521 -0
  222. package/src/zspec/zcl/zclFrame.ts +383 -0
  223. package/src/zspec/zcl/zclHeader.ts +102 -0
  224. package/src/zspec/zcl/zclStatusError.ts +10 -0
  225. package/src/zspec/zdo/buffaloZdo.ts +2336 -0
  226. package/src/zspec/zdo/definition/clusters.ts +722 -0
  227. package/src/zspec/zdo/definition/consts.ts +16 -0
  228. package/src/zspec/zdo/definition/enums.ts +99 -0
  229. package/src/zspec/zdo/definition/status.ts +105 -0
  230. package/src/zspec/zdo/definition/tstypes.ts +1062 -0
  231. package/src/zspec/zdo/index.ts +7 -0
  232. package/src/zspec/zdo/utils.ts +76 -0
  233. package/src/zspec/zdo/zdoStatusError.ts +10 -0
  234. package/test/adapter/adapter.test.ts +1276 -0
  235. package/test/adapter/ember/ash.test.ts +337 -0
  236. package/test/adapter/ember/consts.ts +131 -0
  237. package/test/adapter/ember/emberAdapter.test.ts +3447 -0
  238. package/test/adapter/ember/ezsp.test.ts +389 -0
  239. package/test/adapter/ember/ezspBuffalo.test.ts +93 -0
  240. package/test/adapter/ember/ezspError.test.ts +12 -0
  241. package/test/adapter/ember/math.test.ts +190 -0
  242. package/test/adapter/ezsp/frame.test.ts +30 -0
  243. package/test/adapter/ezsp/uart.test.ts +181 -0
  244. package/test/adapter/z-stack/adapter.test.ts +4260 -0
  245. package/test/adapter/z-stack/constants.test.ts +33 -0
  246. package/test/adapter/z-stack/structs.test.ts +115 -0
  247. package/test/adapter/z-stack/unpi.test.ts +213 -0
  248. package/test/adapter/z-stack/znp.test.ts +1288 -0
  249. package/test/adapter/zboss/fixZdoResponse.test.ts +179 -0
  250. package/test/adapter/zigate/patchZdoBuffaloBE.test.ts +81 -0
  251. package/test/adapter/zigate/zdo.test.ts +187 -0
  252. package/test/adapter/zoh/utils.test.ts +36 -0
  253. package/test/adapter/zoh/zohAdapter.test.ts +1451 -0
  254. package/test/benchOptions.ts +14 -0
  255. package/test/buffalo.test.ts +431 -0
  256. package/test/controller.bench.ts +215 -0
  257. package/test/controller.test.ts +10030 -0
  258. package/test/data/integrity-code-1166-012B-24031511-upgradeMe-RB 249 T.zigbee +0 -0
  259. package/test/data/manuf-tags-tradfri-cv-cct-unified_release_prod_v587757105_33e34452-9267-4665-bc5a-844c8f61f063.ota +0 -0
  260. package/test/data/padded-tretakt_smart_plug_soc-0x1100-2.4.25-prod.ota.ota.signed +0 -0
  261. package/test/data/telink-aes-A60_RGBW_T-0x00B6-0x03483712-MF_DIS.OTA +0 -0
  262. package/test/data/zbminir2_v1.0.8.ota +0 -0
  263. package/test/device-ota.test.ts +3332 -0
  264. package/test/greenpower.test.ts +1409 -0
  265. package/test/mockAdapters.ts +95 -0
  266. package/test/mockDevices.ts +623 -0
  267. package/test/requests.bench.ts +321 -0
  268. package/test/testUtils.ts +20 -0
  269. package/test/timeService.test.ts +214 -0
  270. package/test/tsconfig.json +9 -0
  271. package/test/utils/math.ts +19 -0
  272. package/test/utils.test.ts +352 -0
  273. package/test/vitest.config.mts +28 -0
  274. package/test/vitest.ts +9 -0
  275. package/test/zcl.test.ts +2858 -0
  276. package/test/zspec/utils.test.ts +68 -0
  277. package/test/zspec/zcl/buffalo.test.ts +1316 -0
  278. package/test/zspec/zcl/frame.test.ts +1056 -0
  279. package/test/zspec/zcl/utils.test.ts +650 -0
  280. package/test/zspec/zdo/buffalo.test.ts +1850 -0
  281. package/test/zspec/zdo/utils.test.ts +241 -0
  282. package/tsconfig.json +8 -10
  283. package/.babelrc.js +0 -6
  284. package/.eslintignore +0 -3
  285. package/dist/adapter/adapter.d.ts +0 -64
  286. package/dist/adapter/adapter.d.ts.map +0 -1
  287. package/dist/adapter/adapter.js +0 -157
  288. package/dist/adapter/adapter.js.map +0 -1
  289. package/dist/adapter/deconz/adapter/deconzAdapter.d.ts +0 -71
  290. package/dist/adapter/deconz/adapter/deconzAdapter.d.ts.map +0 -1
  291. package/dist/adapter/deconz/adapter/deconzAdapter.js +0 -1072
  292. package/dist/adapter/deconz/adapter/deconzAdapter.js.map +0 -1
  293. package/dist/adapter/deconz/adapter/index.d.ts +0 -3
  294. package/dist/adapter/deconz/adapter/index.d.ts.map +0 -1
  295. package/dist/adapter/deconz/adapter/index.js +0 -11
  296. package/dist/adapter/deconz/adapter/index.js.map +0 -1
  297. package/dist/adapter/deconz/driver/constants.d.ts +0 -105
  298. package/dist/adapter/deconz/driver/constants.d.ts.map +0 -1
  299. package/dist/adapter/deconz/driver/constants.js +0 -56
  300. package/dist/adapter/deconz/driver/constants.js.map +0 -1
  301. package/dist/adapter/deconz/driver/driver.d.ts +0 -82
  302. package/dist/adapter/deconz/driver/driver.d.ts.map +0 -1
  303. package/dist/adapter/deconz/driver/driver.js +0 -751
  304. package/dist/adapter/deconz/driver/driver.js.map +0 -1
  305. package/dist/adapter/deconz/driver/frame.d.ts +0 -7
  306. package/dist/adapter/deconz/driver/frame.d.ts.map +0 -1
  307. package/dist/adapter/deconz/driver/frame.js +0 -14
  308. package/dist/adapter/deconz/driver/frame.js.map +0 -1
  309. package/dist/adapter/deconz/driver/frameParser.d.ts +0 -3
  310. package/dist/adapter/deconz/driver/frameParser.d.ts.map +0 -1
  311. package/dist/adapter/deconz/driver/frameParser.js +0 -444
  312. package/dist/adapter/deconz/driver/frameParser.js.map +0 -1
  313. package/dist/adapter/deconz/driver/parser.d.ts +0 -13
  314. package/dist/adapter/deconz/driver/parser.d.ts.map +0 -1
  315. package/dist/adapter/deconz/driver/parser.js +0 -64
  316. package/dist/adapter/deconz/driver/parser.js.map +0 -1
  317. package/dist/adapter/deconz/driver/writer.d.ts +0 -9
  318. package/dist/adapter/deconz/driver/writer.d.ts.map +0 -1
  319. package/dist/adapter/deconz/driver/writer.js +0 -45
  320. package/dist/adapter/deconz/driver/writer.js.map +0 -1
  321. package/dist/adapter/ember/adapter/emberAdapter.d.ts +0 -806
  322. package/dist/adapter/ember/adapter/emberAdapter.d.ts.map +0 -1
  323. package/dist/adapter/ember/adapter/emberAdapter.js +0 -2942
  324. package/dist/adapter/ember/adapter/emberAdapter.js.map +0 -1
  325. package/dist/adapter/ember/adapter/endpoints.d.ts +0 -27
  326. package/dist/adapter/ember/adapter/endpoints.d.ts.map +0 -1
  327. package/dist/adapter/ember/adapter/endpoints.js +0 -68
  328. package/dist/adapter/ember/adapter/endpoints.js.map +0 -1
  329. package/dist/adapter/ember/adapter/index.d.ts +0 -3
  330. package/dist/adapter/ember/adapter/index.d.ts.map +0 -1
  331. package/dist/adapter/ember/adapter/index.js +0 -6
  332. package/dist/adapter/ember/adapter/index.js.map +0 -1
  333. package/dist/adapter/ember/adapter/oneWaitress.d.ts +0 -108
  334. package/dist/adapter/ember/adapter/oneWaitress.d.ts.map +0 -1
  335. package/dist/adapter/ember/adapter/oneWaitress.js +0 -241
  336. package/dist/adapter/ember/adapter/oneWaitress.js.map +0 -1
  337. package/dist/adapter/ember/adapter/requestQueue.d.ts +0 -57
  338. package/dist/adapter/ember/adapter/requestQueue.d.ts.map +0 -1
  339. package/dist/adapter/ember/adapter/requestQueue.js +0 -139
  340. package/dist/adapter/ember/adapter/requestQueue.js.map +0 -1
  341. package/dist/adapter/ember/adapter/tokensManager.d.ts +0 -69
  342. package/dist/adapter/ember/adapter/tokensManager.d.ts.map +0 -1
  343. package/dist/adapter/ember/adapter/tokensManager.js +0 -688
  344. package/dist/adapter/ember/adapter/tokensManager.js.map +0 -1
  345. package/dist/adapter/ember/consts.d.ts +0 -191
  346. package/dist/adapter/ember/consts.d.ts.map +0 -1
  347. package/dist/adapter/ember/consts.js +0 -246
  348. package/dist/adapter/ember/consts.js.map +0 -1
  349. package/dist/adapter/ember/enums.d.ts +0 -2172
  350. package/dist/adapter/ember/enums.d.ts.map +0 -1
  351. package/dist/adapter/ember/enums.js +0 -2375
  352. package/dist/adapter/ember/enums.js.map +0 -1
  353. package/dist/adapter/ember/ezsp/buffalo.d.ts +0 -156
  354. package/dist/adapter/ember/ezsp/buffalo.d.ts.map +0 -1
  355. package/dist/adapter/ember/ezsp/buffalo.js +0 -1033
  356. package/dist/adapter/ember/ezsp/buffalo.js.map +0 -1
  357. package/dist/adapter/ember/ezsp/consts.d.ts +0 -116
  358. package/dist/adapter/ember/ezsp/consts.d.ts.map +0 -1
  359. package/dist/adapter/ember/ezsp/consts.js +0 -128
  360. package/dist/adapter/ember/ezsp/consts.js.map +0 -1
  361. package/dist/adapter/ember/ezsp/enums.d.ts +0 -879
  362. package/dist/adapter/ember/ezsp/enums.d.ts.map +0 -1
  363. package/dist/adapter/ember/ezsp/enums.js +0 -948
  364. package/dist/adapter/ember/ezsp/enums.js.map +0 -1
  365. package/dist/adapter/ember/ezsp/ezsp.d.ts +0 -2662
  366. package/dist/adapter/ember/ezsp/ezsp.d.ts.map +0 -1
  367. package/dist/adapter/ember/ezsp/ezsp.js +0 -6454
  368. package/dist/adapter/ember/ezsp/ezsp.js.map +0 -1
  369. package/dist/adapter/ember/types.d.ts +0 -733
  370. package/dist/adapter/ember/types.d.ts.map +0 -1
  371. package/dist/adapter/ember/types.js +0 -3
  372. package/dist/adapter/ember/types.js.map +0 -1
  373. package/dist/adapter/ember/uart/ash.d.ts +0 -464
  374. package/dist/adapter/ember/uart/ash.d.ts.map +0 -1
  375. package/dist/adapter/ember/uart/ash.js +0 -1633
  376. package/dist/adapter/ember/uart/ash.js.map +0 -1
  377. package/dist/adapter/ember/uart/consts.d.ts +0 -91
  378. package/dist/adapter/ember/uart/consts.d.ts.map +0 -1
  379. package/dist/adapter/ember/uart/consts.js +0 -100
  380. package/dist/adapter/ember/uart/consts.js.map +0 -1
  381. package/dist/adapter/ember/uart/enums.d.ts +0 -191
  382. package/dist/adapter/ember/uart/enums.d.ts.map +0 -1
  383. package/dist/adapter/ember/uart/enums.js +0 -197
  384. package/dist/adapter/ember/uart/enums.js.map +0 -1
  385. package/dist/adapter/ember/uart/parser.d.ts +0 -10
  386. package/dist/adapter/ember/uart/parser.d.ts.map +0 -1
  387. package/dist/adapter/ember/uart/parser.js +0 -37
  388. package/dist/adapter/ember/uart/parser.js.map +0 -1
  389. package/dist/adapter/ember/uart/queues.d.ts +0 -85
  390. package/dist/adapter/ember/uart/queues.d.ts.map +0 -1
  391. package/dist/adapter/ember/uart/queues.js +0 -214
  392. package/dist/adapter/ember/uart/queues.js.map +0 -1
  393. package/dist/adapter/ember/uart/writer.d.ts +0 -15
  394. package/dist/adapter/ember/uart/writer.d.ts.map +0 -1
  395. package/dist/adapter/ember/uart/writer.js +0 -46
  396. package/dist/adapter/ember/uart/writer.js.map +0 -1
  397. package/dist/adapter/ember/utils/initters.d.ts +0 -20
  398. package/dist/adapter/ember/utils/initters.d.ts.map +0 -1
  399. package/dist/adapter/ember/utils/initters.js +0 -58
  400. package/dist/adapter/ember/utils/initters.js.map +0 -1
  401. package/dist/adapter/ember/utils/math.d.ts +0 -51
  402. package/dist/adapter/ember/utils/math.d.ts.map +0 -1
  403. package/dist/adapter/ember/utils/math.js +0 -102
  404. package/dist/adapter/ember/utils/math.js.map +0 -1
  405. package/dist/adapter/ember/zdo.d.ts +0 -925
  406. package/dist/adapter/ember/zdo.d.ts.map +0 -1
  407. package/dist/adapter/ember/zdo.js +0 -723
  408. package/dist/adapter/ember/zdo.js.map +0 -1
  409. package/dist/adapter/events.d.ts +0 -42
  410. package/dist/adapter/events.d.ts.map +0 -1
  411. package/dist/adapter/events.js +0 -13
  412. package/dist/adapter/events.js.map +0 -1
  413. package/dist/adapter/ezsp/adapter/backup.d.ts +0 -13
  414. package/dist/adapter/ezsp/adapter/backup.d.ts.map +0 -1
  415. package/dist/adapter/ezsp/adapter/backup.js +0 -101
  416. package/dist/adapter/ezsp/adapter/backup.js.map +0 -1
  417. package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts +0 -65
  418. package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts.map +0 -1
  419. package/dist/adapter/ezsp/adapter/ezspAdapter.js +0 -634
  420. package/dist/adapter/ezsp/adapter/ezspAdapter.js.map +0 -1
  421. package/dist/adapter/ezsp/adapter/index.d.ts +0 -3
  422. package/dist/adapter/ezsp/adapter/index.d.ts.map +0 -1
  423. package/dist/adapter/ezsp/adapter/index.js +0 -11
  424. package/dist/adapter/ezsp/adapter/index.js.map +0 -1
  425. package/dist/adapter/ezsp/driver/commands.d.ts +0 -37
  426. package/dist/adapter/ezsp/driver/commands.d.ts.map +0 -1
  427. package/dist/adapter/ezsp/driver/commands.js +0 -2387
  428. package/dist/adapter/ezsp/driver/commands.js.map +0 -1
  429. package/dist/adapter/ezsp/driver/consts.d.ts +0 -11
  430. package/dist/adapter/ezsp/driver/consts.d.ts.map +0 -1
  431. package/dist/adapter/ezsp/driver/consts.js +0 -14
  432. package/dist/adapter/ezsp/driver/consts.js.map +0 -1
  433. package/dist/adapter/ezsp/driver/driver.d.ts +0 -109
  434. package/dist/adapter/ezsp/driver/driver.d.ts.map +0 -1
  435. package/dist/adapter/ezsp/driver/driver.js +0 -796
  436. package/dist/adapter/ezsp/driver/driver.js.map +0 -1
  437. package/dist/adapter/ezsp/driver/ezsp.d.ts +0 -106
  438. package/dist/adapter/ezsp/driver/ezsp.d.ts.map +0 -1
  439. package/dist/adapter/ezsp/driver/ezsp.js +0 -664
  440. package/dist/adapter/ezsp/driver/ezsp.js.map +0 -1
  441. package/dist/adapter/ezsp/driver/frame.d.ts +0 -40
  442. package/dist/adapter/ezsp/driver/frame.d.ts.map +0 -1
  443. package/dist/adapter/ezsp/driver/frame.js +0 -101
  444. package/dist/adapter/ezsp/driver/frame.js.map +0 -1
  445. package/dist/adapter/ezsp/driver/index.d.ts +0 -4
  446. package/dist/adapter/ezsp/driver/index.d.ts.map +0 -1
  447. package/dist/adapter/ezsp/driver/index.js +0 -9
  448. package/dist/adapter/ezsp/driver/index.js.map +0 -1
  449. package/dist/adapter/ezsp/driver/multicast.d.ts +0 -13
  450. package/dist/adapter/ezsp/driver/multicast.d.ts.map +0 -1
  451. package/dist/adapter/ezsp/driver/multicast.js +0 -74
  452. package/dist/adapter/ezsp/driver/multicast.js.map +0 -1
  453. package/dist/adapter/ezsp/driver/parser.d.ts +0 -12
  454. package/dist/adapter/ezsp/driver/parser.d.ts.map +0 -1
  455. package/dist/adapter/ezsp/driver/parser.js +0 -105
  456. package/dist/adapter/ezsp/driver/parser.js.map +0 -1
  457. package/dist/adapter/ezsp/driver/types/basic.d.ts +0 -63
  458. package/dist/adapter/ezsp/driver/types/basic.d.ts.map +0 -1
  459. package/dist/adapter/ezsp/driver/types/basic.js +0 -209
  460. package/dist/adapter/ezsp/driver/types/basic.js.map +0 -1
  461. package/dist/adapter/ezsp/driver/types/index.d.ts +0 -10
  462. package/dist/adapter/ezsp/driver/types/index.d.ts.map +0 -1
  463. package/dist/adapter/ezsp/driver/types/index.js +0 -139
  464. package/dist/adapter/ezsp/driver/types/index.js.map +0 -1
  465. package/dist/adapter/ezsp/driver/types/named.d.ts +0 -1288
  466. package/dist/adapter/ezsp/driver/types/named.d.ts.map +0 -1
  467. package/dist/adapter/ezsp/driver/types/named.js +0 -2330
  468. package/dist/adapter/ezsp/driver/types/named.js.map +0 -1
  469. package/dist/adapter/ezsp/driver/types/struct.d.ts +0 -271
  470. package/dist/adapter/ezsp/driver/types/struct.d.ts.map +0 -1
  471. package/dist/adapter/ezsp/driver/types/struct.js +0 -804
  472. package/dist/adapter/ezsp/driver/types/struct.js.map +0 -1
  473. package/dist/adapter/ezsp/driver/uart.d.ts +0 -49
  474. package/dist/adapter/ezsp/driver/uart.d.ts.map +0 -1
  475. package/dist/adapter/ezsp/driver/uart.js +0 -383
  476. package/dist/adapter/ezsp/driver/uart.js.map +0 -1
  477. package/dist/adapter/ezsp/driver/utils/crc16ccitt.d.ts +0 -3
  478. package/dist/adapter/ezsp/driver/utils/crc16ccitt.d.ts.map +0 -1
  479. package/dist/adapter/ezsp/driver/utils/crc16ccitt.js +0 -56
  480. package/dist/adapter/ezsp/driver/utils/crc16ccitt.js.map +0 -1
  481. package/dist/adapter/ezsp/driver/utils/index.d.ts +0 -20
  482. package/dist/adapter/ezsp/driver/utils/index.d.ts.map +0 -1
  483. package/dist/adapter/ezsp/driver/utils/index.js +0 -73
  484. package/dist/adapter/ezsp/driver/utils/index.js.map +0 -1
  485. package/dist/adapter/ezsp/driver/writer.d.ts +0 -14
  486. package/dist/adapter/ezsp/driver/writer.d.ts.map +0 -1
  487. package/dist/adapter/ezsp/driver/writer.js +0 -83
  488. package/dist/adapter/ezsp/driver/writer.js.map +0 -1
  489. package/dist/adapter/index.d.ts +0 -5
  490. package/dist/adapter/index.d.ts.map +0 -1
  491. package/dist/adapter/index.js +0 -36
  492. package/dist/adapter/index.js.map +0 -1
  493. package/dist/adapter/serialPort.d.ts +0 -14
  494. package/dist/adapter/serialPort.d.ts.map +0 -1
  495. package/dist/adapter/serialPort.js +0 -47
  496. package/dist/adapter/serialPort.js.map +0 -1
  497. package/dist/adapter/serialPortUtils.d.ts +0 -13
  498. package/dist/adapter/serialPortUtils.d.ts.map +0 -1
  499. package/dist/adapter/serialPortUtils.js +0 -19
  500. package/dist/adapter/serialPortUtils.js.map +0 -1
  501. package/dist/adapter/socketPortUtils.d.ts +0 -11
  502. package/dist/adapter/socketPortUtils.d.ts.map +0 -1
  503. package/dist/adapter/socketPortUtils.js +0 -17
  504. package/dist/adapter/socketPortUtils.js.map +0 -1
  505. package/dist/adapter/tstype.d.ts +0 -86
  506. package/dist/adapter/tstype.d.ts.map +0 -1
  507. package/dist/adapter/tstype.js +0 -3
  508. package/dist/adapter/tstype.js.map +0 -1
  509. package/dist/adapter/z-stack/adapter/adapter-backup.d.ts +0 -62
  510. package/dist/adapter/z-stack/adapter/adapter-backup.d.ts.map +0 -1
  511. package/dist/adapter/z-stack/adapter/adapter-backup.js +0 -459
  512. package/dist/adapter/z-stack/adapter/adapter-backup.js.map +0 -1
  513. package/dist/adapter/z-stack/adapter/adapter-nv-memory.d.ts +0 -151
  514. package/dist/adapter/z-stack/adapter/adapter-nv-memory.d.ts.map +0 -1
  515. package/dist/adapter/z-stack/adapter/adapter-nv-memory.js +0 -259
  516. package/dist/adapter/z-stack/adapter/adapter-nv-memory.js.map +0 -1
  517. package/dist/adapter/z-stack/adapter/endpoints.d.ts +0 -12
  518. package/dist/adapter/z-stack/adapter/endpoints.d.ts.map +0 -1
  519. package/dist/adapter/z-stack/adapter/endpoints.js +0 -74
  520. package/dist/adapter/z-stack/adapter/endpoints.js.map +0 -1
  521. package/dist/adapter/z-stack/adapter/index.d.ts +0 -3
  522. package/dist/adapter/z-stack/adapter/index.d.ts.map +0 -1
  523. package/dist/adapter/z-stack/adapter/index.js +0 -9
  524. package/dist/adapter/z-stack/adapter/index.js.map +0 -1
  525. package/dist/adapter/z-stack/adapter/manager.d.ts +0 -84
  526. package/dist/adapter/z-stack/adapter/manager.d.ts.map +0 -1
  527. package/dist/adapter/z-stack/adapter/manager.js +0 -474
  528. package/dist/adapter/z-stack/adapter/manager.js.map +0 -1
  529. package/dist/adapter/z-stack/adapter/tstype.d.ts +0 -7
  530. package/dist/adapter/z-stack/adapter/tstype.d.ts.map +0 -1
  531. package/dist/adapter/z-stack/adapter/tstype.js +0 -10
  532. package/dist/adapter/z-stack/adapter/tstype.js.map +0 -1
  533. package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts +0 -86
  534. package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts.map +0 -1
  535. package/dist/adapter/z-stack/adapter/zStackAdapter.js +0 -912
  536. package/dist/adapter/z-stack/adapter/zStackAdapter.js.map +0 -1
  537. package/dist/adapter/z-stack/constants/af.d.ts +0 -24
  538. package/dist/adapter/z-stack/constants/af.d.ts.map +0 -1
  539. package/dist/adapter/z-stack/constants/af.js +0 -28
  540. package/dist/adapter/z-stack/constants/af.js.map +0 -1
  541. package/dist/adapter/z-stack/constants/common.d.ts +0 -279
  542. package/dist/adapter/z-stack/constants/common.d.ts.map +0 -1
  543. package/dist/adapter/z-stack/constants/common.js +0 -293
  544. package/dist/adapter/z-stack/constants/common.js.map +0 -1
  545. package/dist/adapter/z-stack/constants/dbg.d.ts +0 -23
  546. package/dist/adapter/z-stack/constants/dbg.d.ts.map +0 -1
  547. package/dist/adapter/z-stack/constants/dbg.js +0 -25
  548. package/dist/adapter/z-stack/constants/dbg.js.map +0 -1
  549. package/dist/adapter/z-stack/constants/index.d.ts +0 -11
  550. package/dist/adapter/z-stack/constants/index.d.ts.map +0 -1
  551. package/dist/adapter/z-stack/constants/index.js +0 -48
  552. package/dist/adapter/z-stack/constants/index.js.map +0 -1
  553. package/dist/adapter/z-stack/constants/mac.d.ts +0 -128
  554. package/dist/adapter/z-stack/constants/mac.d.ts.map +0 -1
  555. package/dist/adapter/z-stack/constants/mac.js +0 -130
  556. package/dist/adapter/z-stack/constants/mac.js.map +0 -1
  557. package/dist/adapter/z-stack/constants/sapi.d.ts +0 -25
  558. package/dist/adapter/z-stack/constants/sapi.d.ts.map +0 -1
  559. package/dist/adapter/z-stack/constants/sapi.js +0 -27
  560. package/dist/adapter/z-stack/constants/sapi.js.map +0 -1
  561. package/dist/adapter/z-stack/constants/sys.d.ts +0 -72
  562. package/dist/adapter/z-stack/constants/sys.d.ts.map +0 -1
  563. package/dist/adapter/z-stack/constants/sys.js +0 -74
  564. package/dist/adapter/z-stack/constants/sys.js.map +0 -1
  565. package/dist/adapter/z-stack/constants/util.d.ts +0 -82
  566. package/dist/adapter/z-stack/constants/util.d.ts.map +0 -1
  567. package/dist/adapter/z-stack/constants/util.js +0 -84
  568. package/dist/adapter/z-stack/constants/util.js.map +0 -1
  569. package/dist/adapter/z-stack/constants/utils.d.ts +0 -5
  570. package/dist/adapter/z-stack/constants/utils.d.ts.map +0 -1
  571. package/dist/adapter/z-stack/constants/utils.js +0 -15
  572. package/dist/adapter/z-stack/constants/utils.js.map +0 -1
  573. package/dist/adapter/z-stack/constants/zdo.d.ts +0 -103
  574. package/dist/adapter/z-stack/constants/zdo.d.ts.map +0 -1
  575. package/dist/adapter/z-stack/constants/zdo.js +0 -105
  576. package/dist/adapter/z-stack/constants/zdo.js.map +0 -1
  577. package/dist/adapter/z-stack/models/index.d.ts +0 -2
  578. package/dist/adapter/z-stack/models/index.d.ts.map +0 -1
  579. package/dist/adapter/z-stack/models/index.js +0 -18
  580. package/dist/adapter/z-stack/models/index.js.map +0 -1
  581. package/dist/adapter/z-stack/models/startup-options.d.ts +0 -13
  582. package/dist/adapter/z-stack/models/startup-options.d.ts.map +0 -1
  583. package/dist/adapter/z-stack/models/startup-options.js +0 -3
  584. package/dist/adapter/z-stack/models/startup-options.js.map +0 -1
  585. package/dist/adapter/z-stack/structs/entries/address-manager-entry.d.ts +0 -24
  586. package/dist/adapter/z-stack/structs/entries/address-manager-entry.d.ts.map +0 -1
  587. package/dist/adapter/z-stack/structs/entries/address-manager-entry.js +0 -46
  588. package/dist/adapter/z-stack/structs/entries/address-manager-entry.js.map +0 -1
  589. package/dist/adapter/z-stack/structs/entries/address-manager-table.d.ts +0 -11
  590. package/dist/adapter/z-stack/structs/entries/address-manager-table.d.ts.map +0 -1
  591. package/dist/adapter/z-stack/structs/entries/address-manager-table.js +0 -23
  592. package/dist/adapter/z-stack/structs/entries/address-manager-table.js.map +0 -1
  593. package/dist/adapter/z-stack/structs/entries/aps-link-key-data-entry.d.ts +0 -11
  594. package/dist/adapter/z-stack/structs/entries/aps-link-key-data-entry.d.ts.map +0 -1
  595. package/dist/adapter/z-stack/structs/entries/aps-link-key-data-entry.js +0 -22
  596. package/dist/adapter/z-stack/structs/entries/aps-link-key-data-entry.js.map +0 -1
  597. package/dist/adapter/z-stack/structs/entries/aps-link-key-data-table.d.ts +0 -11
  598. package/dist/adapter/z-stack/structs/entries/aps-link-key-data-table.d.ts.map +0 -1
  599. package/dist/adapter/z-stack/structs/entries/aps-link-key-data-table.js +0 -24
  600. package/dist/adapter/z-stack/structs/entries/aps-link-key-data-table.js.map +0 -1
  601. package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-entry.d.ts +0 -11
  602. package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-entry.d.ts.map +0 -1
  603. package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-entry.js +0 -25
  604. package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-entry.js.map +0 -1
  605. package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-table.d.ts +0 -11
  606. package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-table.d.ts.map +0 -1
  607. package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-table.js +0 -24
  608. package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-table.js.map +0 -1
  609. package/dist/adapter/z-stack/structs/entries/channel-list.d.ts +0 -9
  610. package/dist/adapter/z-stack/structs/entries/channel-list.d.ts.map +0 -1
  611. package/dist/adapter/z-stack/structs/entries/channel-list.js +0 -16
  612. package/dist/adapter/z-stack/structs/entries/channel-list.js.map +0 -1
  613. package/dist/adapter/z-stack/structs/entries/has-configured.d.ts +0 -9
  614. package/dist/adapter/z-stack/structs/entries/has-configured.d.ts.map +0 -1
  615. package/dist/adapter/z-stack/structs/entries/has-configured.js +0 -17
  616. package/dist/adapter/z-stack/structs/entries/has-configured.js.map +0 -1
  617. package/dist/adapter/z-stack/structs/entries/index.d.ts +0 -17
  618. package/dist/adapter/z-stack/structs/entries/index.d.ts.map +0 -1
  619. package/dist/adapter/z-stack/structs/entries/index.js +0 -33
  620. package/dist/adapter/z-stack/structs/entries/index.js.map +0 -1
  621. package/dist/adapter/z-stack/structs/entries/nib.d.ts +0 -11
  622. package/dist/adapter/z-stack/structs/entries/nib.d.ts.map +0 -1
  623. package/dist/adapter/z-stack/structs/entries/nib.js +0 -69
  624. package/dist/adapter/z-stack/structs/entries/nib.js.map +0 -1
  625. package/dist/adapter/z-stack/structs/entries/nwk-key-descriptor.d.ts +0 -11
  626. package/dist/adapter/z-stack/structs/entries/nwk-key-descriptor.d.ts.map +0 -1
  627. package/dist/adapter/z-stack/structs/entries/nwk-key-descriptor.js +0 -19
  628. package/dist/adapter/z-stack/structs/entries/nwk-key-descriptor.js.map +0 -1
  629. package/dist/adapter/z-stack/structs/entries/nwk-key.d.ts +0 -9
  630. package/dist/adapter/z-stack/structs/entries/nwk-key.d.ts.map +0 -1
  631. package/dist/adapter/z-stack/structs/entries/nwk-key.js +0 -16
  632. package/dist/adapter/z-stack/structs/entries/nwk-key.js.map +0 -1
  633. package/dist/adapter/z-stack/structs/entries/nwk-pan-id.d.ts +0 -9
  634. package/dist/adapter/z-stack/structs/entries/nwk-pan-id.d.ts.map +0 -1
  635. package/dist/adapter/z-stack/structs/entries/nwk-pan-id.js +0 -16
  636. package/dist/adapter/z-stack/structs/entries/nwk-pan-id.js.map +0 -1
  637. package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-entry.d.ts +0 -14
  638. package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-entry.d.ts.map +0 -1
  639. package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-entry.js +0 -24
  640. package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-entry.js.map +0 -1
  641. package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-table.d.ts +0 -11
  642. package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-table.d.ts.map +0 -1
  643. package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-table.js +0 -23
  644. package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-table.js.map +0 -1
  645. package/dist/adapter/z-stack/structs/entries/security-manager-entry.d.ts +0 -21
  646. package/dist/adapter/z-stack/structs/entries/security-manager-entry.d.ts.map +0 -1
  647. package/dist/adapter/z-stack/structs/entries/security-manager-entry.js +0 -37
  648. package/dist/adapter/z-stack/structs/entries/security-manager-entry.js.map +0 -1
  649. package/dist/adapter/z-stack/structs/entries/security-manager-table.d.ts +0 -11
  650. package/dist/adapter/z-stack/structs/entries/security-manager-table.d.ts.map +0 -1
  651. package/dist/adapter/z-stack/structs/entries/security-manager-table.js +0 -25
  652. package/dist/adapter/z-stack/structs/entries/security-manager-table.js.map +0 -1
  653. package/dist/adapter/z-stack/structs/index.d.ts +0 -5
  654. package/dist/adapter/z-stack/structs/index.d.ts.map +0 -1
  655. package/dist/adapter/z-stack/structs/index.js +0 -21
  656. package/dist/adapter/z-stack/structs/index.js.map +0 -1
  657. package/dist/adapter/z-stack/structs/serializable-memory-object.d.ts +0 -14
  658. package/dist/adapter/z-stack/structs/serializable-memory-object.d.ts.map +0 -1
  659. package/dist/adapter/z-stack/structs/serializable-memory-object.js +0 -3
  660. package/dist/adapter/z-stack/structs/serializable-memory-object.js.map +0 -1
  661. package/dist/adapter/z-stack/structs/struct.d.ts +0 -100
  662. package/dist/adapter/z-stack/structs/struct.d.ts.map +0 -1
  663. package/dist/adapter/z-stack/structs/struct.js +0 -297
  664. package/dist/adapter/z-stack/structs/struct.js.map +0 -1
  665. package/dist/adapter/z-stack/structs/table.d.ts +0 -95
  666. package/dist/adapter/z-stack/structs/table.d.ts.map +0 -1
  667. package/dist/adapter/z-stack/structs/table.js +0 -164
  668. package/dist/adapter/z-stack/structs/table.js.map +0 -1
  669. package/dist/adapter/z-stack/unpi/constants.d.ts +0 -29
  670. package/dist/adapter/z-stack/unpi/constants.d.ts.map +0 -1
  671. package/dist/adapter/z-stack/unpi/constants.js +0 -40
  672. package/dist/adapter/z-stack/unpi/constants.js.map +0 -1
  673. package/dist/adapter/z-stack/unpi/frame.d.ts +0 -17
  674. package/dist/adapter/z-stack/unpi/frame.d.ts.map +0 -1
  675. package/dist/adapter/z-stack/unpi/frame.js +0 -55
  676. package/dist/adapter/z-stack/unpi/frame.js.map +0 -1
  677. package/dist/adapter/z-stack/unpi/index.d.ts +0 -6
  678. package/dist/adapter/z-stack/unpi/index.d.ts.map +0 -1
  679. package/dist/adapter/z-stack/unpi/index.js +0 -38
  680. package/dist/adapter/z-stack/unpi/index.js.map +0 -1
  681. package/dist/adapter/z-stack/unpi/parser.d.ts +0 -13
  682. package/dist/adapter/z-stack/unpi/parser.d.ts.map +0 -1
  683. package/dist/adapter/z-stack/unpi/parser.js +0 -86
  684. package/dist/adapter/z-stack/unpi/parser.js.map +0 -1
  685. package/dist/adapter/z-stack/unpi/writer.d.ts +0 -12
  686. package/dist/adapter/z-stack/unpi/writer.d.ts.map +0 -1
  687. package/dist/adapter/z-stack/unpi/writer.js +0 -55
  688. package/dist/adapter/z-stack/unpi/writer.js.map +0 -1
  689. package/dist/adapter/z-stack/utils/channel-list.d.ts +0 -21
  690. package/dist/adapter/z-stack/utils/channel-list.d.ts.map +0 -1
  691. package/dist/adapter/z-stack/utils/channel-list.js +0 -41
  692. package/dist/adapter/z-stack/utils/channel-list.js.map +0 -1
  693. package/dist/adapter/z-stack/utils/index.d.ts +0 -3
  694. package/dist/adapter/z-stack/utils/index.d.ts.map +0 -1
  695. package/dist/adapter/z-stack/utils/index.js +0 -19
  696. package/dist/adapter/z-stack/utils/index.js.map +0 -1
  697. package/dist/adapter/z-stack/utils/network-options.d.ts +0 -9
  698. package/dist/adapter/z-stack/utils/network-options.d.ts.map +0 -1
  699. package/dist/adapter/z-stack/utils/network-options.js +0 -23
  700. package/dist/adapter/z-stack/utils/network-options.js.map +0 -1
  701. package/dist/adapter/z-stack/znp/buffaloZnp.d.ts +0 -14
  702. package/dist/adapter/z-stack/znp/buffaloZnp.d.ts.map +0 -1
  703. package/dist/adapter/z-stack/znp/buffaloZnp.js +0 -243
  704. package/dist/adapter/z-stack/znp/buffaloZnp.js.map +0 -1
  705. package/dist/adapter/z-stack/znp/definition.d.ts +0 -6
  706. package/dist/adapter/z-stack/znp/definition.d.ts.map +0 -1
  707. package/dist/adapter/z-stack/znp/definition.js +0 -3052
  708. package/dist/adapter/z-stack/znp/definition.js.map +0 -1
  709. package/dist/adapter/z-stack/znp/index.d.ts +0 -4
  710. package/dist/adapter/z-stack/znp/index.d.ts.map +0 -1
  711. package/dist/adapter/z-stack/znp/index.js +0 -11
  712. package/dist/adapter/z-stack/znp/index.js.map +0 -1
  713. package/dist/adapter/z-stack/znp/parameterType.d.ts +0 -23
  714. package/dist/adapter/z-stack/znp/parameterType.d.ts.map +0 -1
  715. package/dist/adapter/z-stack/znp/parameterType.js +0 -26
  716. package/dist/adapter/z-stack/znp/parameterType.js.map +0 -1
  717. package/dist/adapter/z-stack/znp/tstype.d.ts +0 -23
  718. package/dist/adapter/z-stack/znp/tstype.d.ts.map +0 -1
  719. package/dist/adapter/z-stack/znp/tstype.js +0 -3
  720. package/dist/adapter/z-stack/znp/tstype.js.map +0 -1
  721. package/dist/adapter/z-stack/znp/znp.d.ts +0 -47
  722. package/dist/adapter/z-stack/znp/znp.d.ts.map +0 -1
  723. package/dist/adapter/z-stack/znp/znp.js +0 -322
  724. package/dist/adapter/z-stack/znp/znp.js.map +0 -1
  725. package/dist/adapter/z-stack/znp/zpiObject.d.ts +0 -20
  726. package/dist/adapter/z-stack/znp/zpiObject.d.ts.map +0 -1
  727. package/dist/adapter/z-stack/znp/zpiObject.js +0 -103
  728. package/dist/adapter/z-stack/znp/zpiObject.js.map +0 -1
  729. package/dist/adapter/zigate/adapter/index.d.ts +0 -3
  730. package/dist/adapter/zigate/adapter/index.d.ts.map +0 -1
  731. package/dist/adapter/zigate/adapter/index.js +0 -11
  732. package/dist/adapter/zigate/adapter/index.js.map +0 -1
  733. package/dist/adapter/zigate/adapter/zigateAdapter.d.ts +0 -72
  734. package/dist/adapter/zigate/adapter/zigateAdapter.d.ts.map +0 -1
  735. package/dist/adapter/zigate/adapter/zigateAdapter.js +0 -681
  736. package/dist/adapter/zigate/adapter/zigateAdapter.js.map +0 -1
  737. package/dist/adapter/zigate/driver/buffaloZiGate.d.ts +0 -18
  738. package/dist/adapter/zigate/driver/buffaloZiGate.d.ts.map +0 -1
  739. package/dist/adapter/zigate/driver/buffaloZiGate.js +0 -190
  740. package/dist/adapter/zigate/driver/buffaloZiGate.js.map +0 -1
  741. package/dist/adapter/zigate/driver/commandType.d.ts +0 -43
  742. package/dist/adapter/zigate/driver/commandType.d.ts.map +0 -1
  743. package/dist/adapter/zigate/driver/commandType.js +0 -390
  744. package/dist/adapter/zigate/driver/commandType.js.map +0 -1
  745. package/dist/adapter/zigate/driver/constants.d.ts +0 -277
  746. package/dist/adapter/zigate/driver/constants.d.ts.map +0 -1
  747. package/dist/adapter/zigate/driver/constants.js +0 -372
  748. package/dist/adapter/zigate/driver/constants.js.map +0 -1
  749. package/dist/adapter/zigate/driver/frame.d.ts +0 -27
  750. package/dist/adapter/zigate/driver/frame.d.ts.map +0 -1
  751. package/dist/adapter/zigate/driver/frame.js +0 -173
  752. package/dist/adapter/zigate/driver/frame.js.map +0 -1
  753. package/dist/adapter/zigate/driver/messageType.d.ts +0 -13
  754. package/dist/adapter/zigate/driver/messageType.d.ts.map +0 -1
  755. package/dist/adapter/zigate/driver/messageType.js +0 -284
  756. package/dist/adapter/zigate/driver/messageType.js.map +0 -1
  757. package/dist/adapter/zigate/driver/parameterType.d.ts +0 -28
  758. package/dist/adapter/zigate/driver/parameterType.d.ts.map +0 -1
  759. package/dist/adapter/zigate/driver/parameterType.js +0 -33
  760. package/dist/adapter/zigate/driver/parameterType.js.map +0 -1
  761. package/dist/adapter/zigate/driver/ziGateObject.d.ts +0 -24
  762. package/dist/adapter/zigate/driver/ziGateObject.d.ts.map +0 -1
  763. package/dist/adapter/zigate/driver/ziGateObject.js +0 -111
  764. package/dist/adapter/zigate/driver/ziGateObject.js.map +0 -1
  765. package/dist/adapter/zigate/driver/zigate.d.ts +0 -50
  766. package/dist/adapter/zigate/driver/zigate.d.ts.map +0 -1
  767. package/dist/adapter/zigate/driver/zigate.js +0 -289
  768. package/dist/adapter/zigate/driver/zigate.js.map +0 -1
  769. package/dist/buffalo/buffalo.d.ts +0 -55
  770. package/dist/buffalo/buffalo.d.ts.map +0 -1
  771. package/dist/buffalo/buffalo.js +0 -230
  772. package/dist/buffalo/buffalo.js.map +0 -1
  773. package/dist/buffalo/index.d.ts +0 -3
  774. package/dist/buffalo/index.d.ts.map +0 -1
  775. package/dist/buffalo/index.js +0 -9
  776. package/dist/buffalo/index.js.map +0 -1
  777. package/dist/controller/controller.d.ts +0 -119
  778. package/dist/controller/controller.d.ts.map +0 -1
  779. package/dist/controller/controller.js +0 -700
  780. package/dist/controller/controller.js.map +0 -1
  781. package/dist/controller/database.d.ts +0 -20
  782. package/dist/controller/database.d.ts.map +0 -1
  783. package/dist/controller/database.js +0 -94
  784. package/dist/controller/database.js.map +0 -1
  785. package/dist/controller/events.d.ts +0 -59
  786. package/dist/controller/events.d.ts.map +0 -1
  787. package/dist/controller/events.js +0 -113
  788. package/dist/controller/events.js.map +0 -1
  789. package/dist/controller/greenPower.d.ts +0 -14
  790. package/dist/controller/greenPower.d.ts.map +0 -1
  791. package/dist/controller/greenPower.js +0 -216
  792. package/dist/controller/greenPower.js.map +0 -1
  793. package/dist/controller/helpers/index.d.ts +0 -3
  794. package/dist/controller/helpers/index.d.ts.map +0 -1
  795. package/dist/controller/helpers/index.js +0 -29
  796. package/dist/controller/helpers/index.js.map +0 -1
  797. package/dist/controller/helpers/request.d.ts +0 -22
  798. package/dist/controller/helpers/request.d.ts.map +0 -1
  799. package/dist/controller/helpers/request.js +0 -78
  800. package/dist/controller/helpers/request.js.map +0 -1
  801. package/dist/controller/helpers/requestQueue.d.ts +0 -13
  802. package/dist/controller/helpers/requestQueue.d.ts.map +0 -1
  803. package/dist/controller/helpers/requestQueue.js +0 -106
  804. package/dist/controller/helpers/requestQueue.js.map +0 -1
  805. package/dist/controller/helpers/zclFrameConverter.d.ts +0 -9
  806. package/dist/controller/helpers/zclFrameConverter.d.ts.map +0 -1
  807. package/dist/controller/helpers/zclFrameConverter.js +0 -70
  808. package/dist/controller/helpers/zclFrameConverter.js.map +0 -1
  809. package/dist/controller/helpers/zclTransactionSequenceNumber.d.ts +0 -6
  810. package/dist/controller/helpers/zclTransactionSequenceNumber.d.ts.map +0 -1
  811. package/dist/controller/helpers/zclTransactionSequenceNumber.js +0 -14
  812. package/dist/controller/helpers/zclTransactionSequenceNumber.js.map +0 -1
  813. package/dist/controller/index.d.ts +0 -6
  814. package/dist/controller/index.d.ts.map +0 -1
  815. package/dist/controller/index.js +0 -9
  816. package/dist/controller/index.js.map +0 -1
  817. package/dist/controller/model/device.d.ts +0 -140
  818. package/dist/controller/model/device.d.ts.map +0 -1
  819. package/dist/controller/model/device.js +0 -746
  820. package/dist/controller/model/device.js.map +0 -1
  821. package/dist/controller/model/endpoint.d.ts +0 -134
  822. package/dist/controller/model/endpoint.d.ts.map +0 -1
  823. package/dist/controller/model/endpoint.js +0 -667
  824. package/dist/controller/model/endpoint.js.map +0 -1
  825. package/dist/controller/model/entity.d.ts +0 -15
  826. package/dist/controller/model/entity.d.ts.map +0 -1
  827. package/dist/controller/model/entity.js +0 -27
  828. package/dist/controller/model/entity.js.map +0 -1
  829. package/dist/controller/model/group.d.ts +0 -39
  830. package/dist/controller/model/group.d.ts.map +0 -1
  831. package/dist/controller/model/group.js +0 -226
  832. package/dist/controller/model/group.js.map +0 -1
  833. package/dist/controller/model/index.d.ts +0 -6
  834. package/dist/controller/model/index.d.ts.map +0 -1
  835. package/dist/controller/model/index.js +0 -15
  836. package/dist/controller/model/index.js.map +0 -1
  837. package/dist/controller/model/konnextConfig.d.ts +0 -7
  838. package/dist/controller/model/konnextConfig.d.ts.map +0 -1
  839. package/dist/controller/model/konnextConfig.js +0 -3
  840. package/dist/controller/model/konnextConfig.js.map +0 -1
  841. package/dist/controller/touchlink.d.ts +0 -20
  842. package/dist/controller/touchlink.d.ts.map +0 -1
  843. package/dist/controller/touchlink.js +0 -157
  844. package/dist/controller/touchlink.js.map +0 -1
  845. package/dist/controller/tstype.d.ts +0 -21
  846. package/dist/controller/tstype.d.ts.map +0 -1
  847. package/dist/controller/tstype.js +0 -9
  848. package/dist/controller/tstype.js.map +0 -1
  849. package/dist/index.d.ts +0 -6
  850. package/dist/index.d.ts.map +0 -1
  851. package/dist/index.js +0 -37
  852. package/dist/index.js.map +0 -1
  853. package/dist/models/backup-storage-legacy.d.ts +0 -27
  854. package/dist/models/backup-storage-legacy.d.ts.map +0 -1
  855. package/dist/models/backup-storage-legacy.js +0 -3
  856. package/dist/models/backup-storage-legacy.js.map +0 -1
  857. package/dist/models/backup-storage-unified.d.ts +0 -50
  858. package/dist/models/backup-storage-unified.d.ts.map +0 -1
  859. package/dist/models/backup-storage-unified.js +0 -3
  860. package/dist/models/backup-storage-unified.js.map +0 -1
  861. package/dist/models/backup.d.ts +0 -38
  862. package/dist/models/backup.d.ts.map +0 -1
  863. package/dist/models/backup.js +0 -3
  864. package/dist/models/backup.js.map +0 -1
  865. package/dist/models/index.d.ts +0 -5
  866. package/dist/models/index.d.ts.map +0 -1
  867. package/dist/models/index.js +0 -21
  868. package/dist/models/index.js.map +0 -1
  869. package/dist/models/network-options.d.ts +0 -13
  870. package/dist/models/network-options.d.ts.map +0 -1
  871. package/dist/models/network-options.js +0 -3
  872. package/dist/models/network-options.js.map +0 -1
  873. package/dist/utils/aes.d.ts +0 -40
  874. package/dist/utils/aes.d.ts.map +0 -1
  875. package/dist/utils/aes.js +0 -198
  876. package/dist/utils/aes.js.map +0 -1
  877. package/dist/utils/assertString.d.ts +0 -3
  878. package/dist/utils/assertString.d.ts.map +0 -1
  879. package/dist/utils/assertString.js +0 -9
  880. package/dist/utils/assertString.js.map +0 -1
  881. package/dist/utils/backup.d.ts +0 -21
  882. package/dist/utils/backup.d.ts.map +0 -1
  883. package/dist/utils/backup.js +0 -190
  884. package/dist/utils/backup.js.map +0 -1
  885. package/dist/utils/equalsPartial.d.ts +0 -3
  886. package/dist/utils/equalsPartial.d.ts.map +0 -1
  887. package/dist/utils/equalsPartial.js +0 -12
  888. package/dist/utils/equalsPartial.js.map +0 -1
  889. package/dist/utils/index.d.ts +0 -10
  890. package/dist/utils/index.d.ts.map +0 -1
  891. package/dist/utils/index.js +0 -46
  892. package/dist/utils/index.js.map +0 -1
  893. package/dist/utils/isNumberArray.d.ts +0 -3
  894. package/dist/utils/isNumberArray.d.ts.map +0 -1
  895. package/dist/utils/isNumberArray.js +0 -7
  896. package/dist/utils/isNumberArray.js.map +0 -1
  897. package/dist/utils/logger.d.ts +0 -9
  898. package/dist/utils/logger.d.ts.map +0 -1
  899. package/dist/utils/logger.js +0 -14
  900. package/dist/utils/logger.js.map +0 -1
  901. package/dist/utils/queue.d.ts +0 -12
  902. package/dist/utils/queue.d.ts.map +0 -1
  903. package/dist/utils/queue.js +0 -62
  904. package/dist/utils/queue.js.map +0 -1
  905. package/dist/utils/realpathSync.d.ts +0 -3
  906. package/dist/utils/realpathSync.d.ts.map +0 -1
  907. package/dist/utils/realpathSync.js +0 -13
  908. package/dist/utils/realpathSync.js.map +0 -1
  909. package/dist/utils/wait.d.ts +0 -3
  910. package/dist/utils/wait.d.ts.map +0 -1
  911. package/dist/utils/wait.js +0 -9
  912. package/dist/utils/wait.js.map +0 -1
  913. package/dist/utils/waitress.d.ts +0 -22
  914. package/dist/utils/waitress.d.ts.map +0 -1
  915. package/dist/utils/waitress.js +0 -69
  916. package/dist/utils/waitress.js.map +0 -1
  917. package/dist/zspec/consts.d.ts +0 -60
  918. package/dist/zspec/consts.d.ts.map +0 -1
  919. package/dist/zspec/consts.js +0 -64
  920. package/dist/zspec/consts.js.map +0 -1
  921. package/dist/zspec/enums.d.ts +0 -19
  922. package/dist/zspec/enums.d.ts.map +0 -1
  923. package/dist/zspec/enums.js +0 -28
  924. package/dist/zspec/enums.js.map +0 -1
  925. package/dist/zspec/index.d.ts +0 -4
  926. package/dist/zspec/index.d.ts.map +0 -1
  927. package/dist/zspec/index.js +0 -43
  928. package/dist/zspec/index.js.map +0 -1
  929. package/dist/zspec/tstypes.d.ts +0 -19
  930. package/dist/zspec/tstypes.d.ts.map +0 -1
  931. package/dist/zspec/tstypes.js +0 -3
  932. package/dist/zspec/tstypes.js.map +0 -1
  933. package/dist/zspec/utils.d.ts +0 -14
  934. package/dist/zspec/utils.d.ts.map +0 -1
  935. package/dist/zspec/utils.js +0 -29
  936. package/dist/zspec/utils.js.map +0 -1
  937. package/dist/zspec/zcl/buffaloZcl.d.ts +0 -55
  938. package/dist/zspec/zcl/buffaloZcl.d.ts.map +0 -1
  939. package/dist/zspec/zcl/buffaloZcl.js +0 -929
  940. package/dist/zspec/zcl/buffaloZcl.js.map +0 -1
  941. package/dist/zspec/zcl/definition/cluster.d.ts +0 -3
  942. package/dist/zspec/zcl/definition/cluster.d.ts.map +0 -1
  943. package/dist/zspec/zcl/definition/cluster.js +0 -5500
  944. package/dist/zspec/zcl/definition/cluster.js.map +0 -1
  945. package/dist/zspec/zcl/definition/consts.d.ts +0 -9
  946. package/dist/zspec/zcl/definition/consts.d.ts.map +0 -1
  947. package/dist/zspec/zcl/definition/consts.js +0 -27
  948. package/dist/zspec/zcl/definition/consts.js.map +0 -1
  949. package/dist/zspec/zcl/definition/enums.d.ts +0 -177
  950. package/dist/zspec/zcl/definition/enums.d.ts.map +0 -1
  951. package/dist/zspec/zcl/definition/enums.js +0 -187
  952. package/dist/zspec/zcl/definition/enums.js.map +0 -1
  953. package/dist/zspec/zcl/definition/foundation.d.ts +0 -11
  954. package/dist/zspec/zcl/definition/foundation.d.ts.map +0 -1
  955. package/dist/zspec/zcl/definition/foundation.js +0 -241
  956. package/dist/zspec/zcl/definition/foundation.js.map +0 -1
  957. package/dist/zspec/zcl/definition/manufacturerCode.d.ts +0 -727
  958. package/dist/zspec/zcl/definition/manufacturerCode.d.ts.map +0 -1
  959. package/dist/zspec/zcl/definition/manufacturerCode.js +0 -733
  960. package/dist/zspec/zcl/definition/manufacturerCode.js.map +0 -1
  961. package/dist/zspec/zcl/definition/status.d.ts +0 -69
  962. package/dist/zspec/zcl/definition/status.d.ts.map +0 -1
  963. package/dist/zspec/zcl/definition/status.js +0 -74
  964. package/dist/zspec/zcl/definition/status.js.map +0 -1
  965. package/dist/zspec/zcl/definition/tstype.d.ts +0 -114
  966. package/dist/zspec/zcl/definition/tstype.d.ts.map +0 -1
  967. package/dist/zspec/zcl/definition/tstype.js +0 -4
  968. package/dist/zspec/zcl/definition/tstype.js.map +0 -1
  969. package/dist/zspec/zcl/index.d.ts +0 -11
  970. package/dist/zspec/zcl/index.d.ts.map +0 -1
  971. package/dist/zspec/zcl/index.js +0 -47
  972. package/dist/zspec/zcl/index.js.map +0 -1
  973. package/dist/zspec/zcl/utils.d.ts +0 -7
  974. package/dist/zspec/zcl/utils.d.ts.map +0 -1
  975. package/dist/zspec/zcl/utils.js +0 -234
  976. package/dist/zspec/zcl/utils.js.map +0 -1
  977. package/dist/zspec/zcl/zclFrame.d.ts +0 -36
  978. package/dist/zspec/zcl/zclFrame.d.ts.map +0 -1
  979. package/dist/zspec/zcl/zclFrame.js +0 -304
  980. package/dist/zspec/zcl/zclFrame.js.map +0 -1
  981. package/dist/zspec/zcl/zclHeader.d.ts +0 -17
  982. package/dist/zspec/zcl/zclHeader.d.ts.map +0 -1
  983. package/dist/zspec/zcl/zclHeader.js +0 -88
  984. package/dist/zspec/zcl/zclHeader.js.map +0 -1
  985. package/dist/zspec/zcl/zclStatusError.d.ts +0 -6
  986. package/dist/zspec/zcl/zclStatusError.d.ts.map +0 -1
  987. package/dist/zspec/zcl/zclStatusError.js +0 -13
  988. package/dist/zspec/zcl/zclStatusError.js.map +0 -1
  989. package/dist/zspec/zdo/buffaloZdo.d.ts +0 -438
  990. package/dist/zspec/zdo/buffaloZdo.d.ts.map +0 -1
  991. package/dist/zspec/zdo/buffaloZdo.js +0 -1892
  992. package/dist/zspec/zdo/buffaloZdo.js.map +0 -1
  993. package/dist/zspec/zdo/definition/clusters.d.ts +0 -624
  994. package/dist/zspec/zdo/definition/clusters.d.ts.map +0 -1
  995. package/dist/zspec/zdo/definition/clusters.js +0 -687
  996. package/dist/zspec/zdo/definition/clusters.js.map +0 -1
  997. package/dist/zspec/zdo/definition/consts.d.ts +0 -13
  998. package/dist/zspec/zdo/definition/consts.d.ts.map +0 -1
  999. package/dist/zspec/zdo/definition/consts.js +0 -16
  1000. package/dist/zspec/zdo/definition/consts.js.map +0 -1
  1001. package/dist/zspec/zdo/definition/enums.d.ts +0 -75
  1002. package/dist/zspec/zdo/definition/enums.d.ts.map +0 -1
  1003. package/dist/zspec/zdo/definition/enums.js +0 -97
  1004. package/dist/zspec/zdo/definition/enums.js.map +0 -1
  1005. package/dist/zspec/zdo/definition/status.d.ts +0 -99
  1006. package/dist/zspec/zdo/definition/status.d.ts.map +0 -1
  1007. package/dist/zspec/zdo/definition/status.js +0 -109
  1008. package/dist/zspec/zdo/definition/status.js.map +0 -1
  1009. package/dist/zspec/zdo/definition/tstypes.d.ts +0 -787
  1010. package/dist/zspec/zdo/definition/tstypes.d.ts.map +0 -1
  1011. package/dist/zspec/zdo/definition/tstypes.js +0 -3
  1012. package/dist/zspec/zdo/definition/tstypes.js.map +0 -1
  1013. package/dist/zspec/zdo/index.d.ts +0 -7
  1014. package/dist/zspec/zdo/index.d.ts.map +0 -1
  1015. package/dist/zspec/zdo/index.js +0 -39
  1016. package/dist/zspec/zdo/index.js.map +0 -1
  1017. package/dist/zspec/zdo/utils.d.ts +0 -25
  1018. package/dist/zspec/zdo/utils.d.ts.map +0 -1
  1019. package/dist/zspec/zdo/utils.js +0 -75
  1020. package/dist/zspec/zdo/utils.js.map +0 -1
  1021. package/dist/zspec/zdo/zdoStatusError.d.ts +0 -6
  1022. package/dist/zspec/zdo/zdoStatusError.d.ts.map +0 -1
  1023. package/dist/zspec/zdo/zdoStatusError.js +0 -13
  1024. package/dist/zspec/zdo/zdoStatusError.js.map +0 -1
  1025. package/typedoc-tsconfig.json +0 -44
@@ -0,0 +1,4260 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import equals from "fast-deep-equal/es6";
4
+ import {afterAll, beforeAll, beforeEach, describe, expect, it, vi} from "vitest";
5
+ import type {ZclPayload} from "../../../src/adapter/events";
6
+ import {ZnpVersion} from "../../../src/adapter/z-stack/adapter/tstype";
7
+ import {ZStackAdapter} from "../../../src/adapter/z-stack/adapter/zStackAdapter";
8
+ import * as Constants from "../../../src/adapter/z-stack/constants";
9
+ import {AddressMode, DevStates, NvItemsIds, NvSystemIds, type ZnpCommandStatus} from "../../../src/adapter/z-stack/constants/common";
10
+ import * as Structs from "../../../src/adapter/z-stack/structs";
11
+ import {Subsystem, Type} from "../../../src/adapter/z-stack/unpi/constants";
12
+ import {Znp, type ZpiObject} from "../../../src/adapter/z-stack/znp";
13
+ import Definition from "../../../src/adapter/z-stack/znp/definition";
14
+ import type {ZpiObjectPayload} from "../../../src/adapter/z-stack/znp/tstype";
15
+ import type {UnifiedBackupStorage} from "../../../src/models";
16
+ import {setLogger} from "../../../src/utils/logger";
17
+ import * as ZSpec from "../../../src/zspec";
18
+ import {BroadcastAddress} from "../../../src/zspec/enums";
19
+ import * as Zcl from "../../../src/zspec/zcl";
20
+ import * as Zdo from "../../../src/zspec/zdo";
21
+ import type {
22
+ ActiveEndpointsResponse,
23
+ EndDeviceAnnounce,
24
+ LQITableResponse,
25
+ NetworkAddressResponse,
26
+ NodeDescriptorResponse,
27
+ RoutingTableResponse,
28
+ SimpleDescriptorResponse,
29
+ } from "../../../src/zspec/zdo/definition/tstypes";
30
+
31
+ const DUMMY_NODE_DESC_RSP_CAPABILITIES = {
32
+ allocateAddress: 0,
33
+ alternatePANCoordinator: 0,
34
+ deviceType: 2,
35
+ powerSource: 0,
36
+ reserved1: 0,
37
+ reserved2: 0,
38
+ rxOnWhenIdle: 0,
39
+ securityCapability: 0,
40
+ };
41
+
42
+ const STR_500_BYTES =
43
+ "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 " +
44
+ "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 " +
45
+ "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 " +
46
+ "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 " +
47
+ "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ";
48
+
49
+ const mockLogger = {
50
+ debug: vi.fn(),
51
+ info: vi.fn(),
52
+ warning: vi.fn(),
53
+ error: vi.fn(),
54
+ };
55
+ const deepClone = (obj) => JSON.parse(JSON.stringify(obj));
56
+ const mockSetTimeout = () => {
57
+ return vi.spyOn(globalThis, "setTimeout").mockImplementation(
58
+ // @ts-expect-error mock
59
+ (cb) => cb(),
60
+ );
61
+ };
62
+
63
+ vi.mock("../../../src/utils/wait", () => ({
64
+ wait: vi.fn(() => {
65
+ return new Promise<void>((resolve) => resolve());
66
+ }),
67
+ }));
68
+
69
+ const waitForResult = (payloadOrPromise: Promise<unknown> | ZpiObjectPayload, id?: number) => {
70
+ id = id || 1;
71
+ if (payloadOrPromise instanceof Promise) {
72
+ return {
73
+ start: () => {
74
+ return {promise: payloadOrPromise, ID: id};
75
+ },
76
+ ID: id,
77
+ };
78
+ }
79
+
80
+ return {
81
+ start: () => {
82
+ return {promise: new Promise((r) => r(payloadOrPromise)), ID: id};
83
+ },
84
+ ID: id,
85
+ };
86
+ };
87
+
88
+ const networkOptions = {
89
+ panID: 123,
90
+ extendedPanID: [0x00, 0x12, 0x4b, 0x00, 0x09, 0xd6, 0x9f, 0x77],
91
+ channelList: [21],
92
+ networkKey: [1, 3, 5, 7, 9, 11, 13, 15, 0, 2, 4, 6, 8, 10, 12, 13],
93
+ networkKeyDistribute: false,
94
+ };
95
+
96
+ const networkOptionsDefaultExtendedPanId = {
97
+ panID: 123,
98
+ extendedPanID: [0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd],
99
+ channelList: [21],
100
+ networkKey: [1, 3, 5, 7, 9, 11, 13, 15, 0, 2, 4, 6, 8, 10, 12, 13],
101
+ networkKeyDistribute: false,
102
+ };
103
+
104
+ const networkOptionsMismatched = {
105
+ panID: 124,
106
+ extendedPanID: [0x00, 0x12, 0x4b, 0x00, 0x09, 0xd6, 0x9f, 0x77],
107
+ channelList: [21],
108
+ networkKey: [1, 3, 5, 7, 9, 11, 13, 15, 0, 2, 4, 6, 8, 10, 12, 13],
109
+ networkKeyDistribute: false,
110
+ };
111
+
112
+ const networkOptionsInvalidPanId = {
113
+ panID: 65535,
114
+ extendedPanID: [0x00, 0x12, 0x4b, 0x00, 0x09, 0xd6, 0x9f, 0x77],
115
+ channelList: [21],
116
+ networkKey: [1, 3, 5, 7, 9, 11, 13, 15, 0, 2, 4, 6, 8, 10, 12, 13],
117
+ networkKeyDistribute: false,
118
+ };
119
+
120
+ const serialPortOptions = {
121
+ baudRate: 800,
122
+ rtscts: false,
123
+ path: "dummy",
124
+ };
125
+
126
+ const backupMatchingConfig = {
127
+ metadata: {
128
+ format: "zigpy/open-coordinator-backup",
129
+ version: 1,
130
+ source: "zigbee-herdsman@0.13.65",
131
+ internal: {
132
+ date: "2021-03-03T19:15:40.524Z",
133
+ znpVersion: 2,
134
+ },
135
+ },
136
+ stack_specific: {
137
+ zstack: {
138
+ tclk_seed: "928a2c479e72a9a53e3b5133fc55021f",
139
+ },
140
+ },
141
+ coordinator_ieee: "00124b0009d80ba7",
142
+ pan_id: "007b",
143
+ extended_pan_id: "00124b0009d69f77",
144
+ nwk_update_id: 0,
145
+ security_level: 5,
146
+ channel: 21,
147
+ channel_mask: [21],
148
+ network_key: {
149
+ key: "01030507090b0d0f00020406080a0c0d",
150
+ sequence_number: 0,
151
+ frame_counter: 16754,
152
+ },
153
+ devices: [
154
+ {
155
+ nwk_address: "ddf6",
156
+ ieee_address: "00124b002226ef87",
157
+ },
158
+ {
159
+ nwk_address: "c2dc",
160
+ ieee_address: "04cf8cdf3c79455f",
161
+ link_key: {
162
+ key: "0e768569dd935d8e7302e74e7629f13f",
163
+ rx_counter: 0,
164
+ tx_counter: 275,
165
+ },
166
+ },
167
+ {
168
+ nwk_address: "740a",
169
+ ieee_address: "680ae2fffeae5647",
170
+ link_key: {
171
+ key: "7c079d02aae015facd7ae9608d4baf56",
172
+ rx_counter: 0,
173
+ tx_counter: 275,
174
+ },
175
+ },
176
+ {
177
+ nwk_address: "19fa",
178
+ ieee_address: "00158d00024fa79b",
179
+ link_key: {
180
+ key: "cea550908aa1529ee90eea3c3bdc26fc",
181
+ rx_counter: 0,
182
+ tx_counter: 44,
183
+ },
184
+ },
185
+ {
186
+ nwk_address: "6182",
187
+ ieee_address: "00158d00024f4518",
188
+ link_key: {
189
+ key: "267e1e31fcd8171f8acf63459effbca5",
190
+ rx_counter: 0,
191
+ tx_counter: 44,
192
+ },
193
+ },
194
+ {
195
+ nwk_address: "4285",
196
+ ieee_address: "00158d00024f810d",
197
+ is_child: false,
198
+ link_key: {
199
+ key: "55ba1e31fcd8171f9f0b63459effbca5",
200
+ rx_counter: 0,
201
+ tx_counter: 44,
202
+ },
203
+ },
204
+ {
205
+ // "nwk_address": "4286", commented because `nwk_address` is optional in the backup
206
+ ieee_address: "00158d00024f810e",
207
+ is_child: true,
208
+ link_key: {
209
+ key: "55ba1e31fcd8171fee0b63459effeea5",
210
+ rx_counter: 24,
211
+ tx_counter: 91,
212
+ },
213
+ },
214
+ ],
215
+ };
216
+
217
+ const backupMatchingConfig12 = {
218
+ metadata: {
219
+ format: "zigpy/open-coordinator-backup",
220
+ version: 1,
221
+ source: "zigbee-herdsman@0.13.65",
222
+ internal: {
223
+ date: "2021-03-03T19:15:40.524Z",
224
+ znpVersion: 0,
225
+ },
226
+ },
227
+ stack_specific: {
228
+ zstack: {},
229
+ },
230
+ coordinator_ieee: "00124b0009d80ba7",
231
+ pan_id: "007b",
232
+ extended_pan_id: "00124b0009d69f77",
233
+ nwk_update_id: 0,
234
+ security_level: 5,
235
+ channel: 21,
236
+ channel_mask: [21],
237
+ network_key: {
238
+ key: "01030507090b0d0f00020406080a0c0d",
239
+ sequence_number: 0,
240
+ frame_counter: 0,
241
+ },
242
+ devices: [
243
+ {
244
+ nwk_address: "ddf6",
245
+ ieee_address: "00124b002226ef87",
246
+ },
247
+ ],
248
+ };
249
+
250
+ const backupNotMatchingConfig = {
251
+ metadata: {
252
+ format: "zigpy/open-coordinator-backup",
253
+ version: 1,
254
+ source: "zigbee-herdsman@0.13.65",
255
+ internal: {
256
+ date: "2021-03-03T19:15:40.524Z",
257
+ znpVersion: 2,
258
+ },
259
+ },
260
+ stack_specific: {
261
+ zstack: {
262
+ tclk_seed: "928a2c479e72a9a53e3b5133fc55021f",
263
+ },
264
+ },
265
+ coordinator_ieee: "00124b0009d80ba7",
266
+ pan_id: "007c",
267
+ extended_pan_id: "00124b0009d69f77",
268
+ nwk_update_id: 0,
269
+ security_level: 5,
270
+ channel: 21,
271
+ channel_mask: [21],
272
+ network_key: {
273
+ key: "01030507090b0d0f00020406080a0c0d",
274
+ sequence_number: 0,
275
+ frame_counter: 16754,
276
+ },
277
+ devices: [
278
+ {
279
+ nwk_address: "ddf6",
280
+ ieee_address: "00124b002226ef87",
281
+ },
282
+ {
283
+ nwk_address: "c2dc",
284
+ ieee_address: "04cf8cdf3c79455f",
285
+ link_key: {
286
+ key: "0e768569dd935d8e7302e74e7629f13f",
287
+ rx_counter: 0,
288
+ tx_counter: 275,
289
+ },
290
+ },
291
+ {
292
+ nwk_address: "740a",
293
+ ieee_address: "680ae2fffeae5647",
294
+ link_key: {
295
+ key: "7c079d02aae015facd7ae9608d4baf56",
296
+ rx_counter: 0,
297
+ tx_counter: 275,
298
+ },
299
+ },
300
+ {
301
+ nwk_address: "19fa",
302
+ ieee_address: "00158d00024fa79b",
303
+ link_key: {
304
+ key: "cea550908aa1529ee90eea3c3bdc26fc",
305
+ rx_counter: 0,
306
+ tx_counter: 44,
307
+ },
308
+ },
309
+ {
310
+ nwk_address: "6182",
311
+ ieee_address: "00158d00024f4518",
312
+ link_key: {
313
+ key: "267e1e31fcd8171f8acf63459effbca5",
314
+ rx_counter: 0,
315
+ tx_counter: 44,
316
+ },
317
+ },
318
+ {
319
+ nwk_address: "4285",
320
+ ieee_address: "00158d00024f810d",
321
+ link_key: {
322
+ key: "55ba1e31fcd8171f9f0b63459effbca5",
323
+ rx_counter: 0,
324
+ tx_counter: 44,
325
+ },
326
+ },
327
+ ],
328
+ };
329
+
330
+ const legacyBackup = {
331
+ adapterType: "zStack",
332
+ time: "Thu, 04 Mar 2021 10:55:12 GMT",
333
+ meta: {
334
+ product: 2,
335
+ },
336
+ data: {
337
+ ZCD_NV_EXTADDR: {
338
+ id: 1,
339
+ offset: 0,
340
+ osal: true,
341
+ product: -1,
342
+ value: [167, 11, 216, 9, 0, 75, 18, 0],
343
+ len: 8,
344
+ },
345
+ ZCD_NV_NIB: {
346
+ id: 33,
347
+ offset: 0,
348
+ osal: true,
349
+ product: -1,
350
+ value: [
351
+ 145, 5, 2, 16, 20, 16, 0, 20, 0, 0, 0, 1, 5, 1, 143, 7, 0, 2, 5, 30, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 0, 8, 0, 0, 32, 0,
352
+ 15, 15, 4, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 119, 159, 214, 9, 0, 75, 18, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
353
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 3, 0, 1, 120, 10, 1, 0, 0, 146, 235, 0,
354
+ ],
355
+ len: 110,
356
+ },
357
+ ZCD_NV_PANID: {
358
+ id: 131,
359
+ offset: 0,
360
+ osal: true,
361
+ product: -1,
362
+ value: [123, 0],
363
+ len: 2,
364
+ },
365
+ ZCD_NV_EXTENDED_PAN_ID: {
366
+ id: 45,
367
+ offset: 0,
368
+ osal: true,
369
+ product: -1,
370
+ value: [221, 221, 221, 221, 221, 221, 221, 221],
371
+ len: 8,
372
+ },
373
+ ZCD_NV_NWK_ACTIVE_KEY_INFO: {
374
+ id: 58,
375
+ offset: 0,
376
+ osal: true,
377
+ product: -1,
378
+ value: [0, 1, 3, 5, 7, 9, 11, 13, 15, 0, 2, 4, 6, 8, 10, 12, 13],
379
+ len: 17,
380
+ },
381
+ ZCD_NV_NWK_ALTERN_KEY_INFO: {
382
+ id: 59,
383
+ offset: 0,
384
+ osal: true,
385
+ product: -1,
386
+ value: [0, 1, 3, 5, 7, 9, 11, 13, 15, 0, 2, 4, 6, 8, 10, 12, 13],
387
+ len: 17,
388
+ },
389
+ ZCD_NV_APS_USE_EXT_PANID: {
390
+ id: 71,
391
+ offset: 0,
392
+ osal: true,
393
+ product: -1,
394
+ value: [0, 0, 0, 0, 0, 0, 0, 0],
395
+ len: 8,
396
+ },
397
+ ZCD_NV_PRECFGKEY: {
398
+ id: 98,
399
+ offset: 0,
400
+ osal: true,
401
+ product: -1,
402
+ value: [1, 3, 5, 7, 9, 11, 13, 15, 0, 2, 4, 6, 8, 10, 12, 13],
403
+ len: 16,
404
+ },
405
+ ZCD_NV_PRECFGKEY_ENABLE: {
406
+ id: 99,
407
+ offset: 0,
408
+ osal: true,
409
+ product: -1,
410
+ value: [0],
411
+ len: 1,
412
+ },
413
+ ZCD_NV_CHANLIST: {
414
+ id: 132,
415
+ offset: 0,
416
+ osal: true,
417
+ product: -1,
418
+ value: [0, 20, 0, 0],
419
+ len: 4,
420
+ },
421
+ ZCD_NV_LEGACY_TCLK_TABLE_START: {
422
+ id: 273,
423
+ product: 2,
424
+ offset: 0,
425
+ osal: true,
426
+ value: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0],
427
+ len: 19,
428
+ },
429
+ ZCD_NV_LEGACY_NWK_SEC_MATERIAL_TABLE_START: {
430
+ id: 117,
431
+ product: 2,
432
+ offset: 0,
433
+ osal: true,
434
+ value: [83, 144, 14, 0, 134, 114, 56, 25, 0, 75, 18, 0],
435
+ len: 12,
436
+ },
437
+ },
438
+ };
439
+
440
+ class ZnpRequestMockBuilder {
441
+ // biome-ignore lint/suspicious/noExplicitAny: API
442
+ public responders: {subsystem: Subsystem; command: string; exec: (payload: any, handler?: ZnpRequestMockBuilder) => any}[] = [];
443
+ public nvItems: {id: NvItemsIds; value?: Buffer}[] = [];
444
+ public nvExtendedItems: {sysId: NvSystemIds; id: NvItemsIds; subId: number; value?: Buffer}[] = [];
445
+
446
+ constructor() {
447
+ const handleOsalNvRead = (payload, handler) => {
448
+ if (payload.offset !== undefined && payload.offset !== 0) {
449
+ throw new Error("osalNvLength offset not supported");
450
+ }
451
+ const item = handler.nvItems.find((e) => e.id === payload.id);
452
+ return {payload: {status: item?.value ? 0 : 1, value: item?.value ? item.value : undefined}};
453
+ };
454
+ this.handle(Subsystem.SYS, "osalNvRead", handleOsalNvRead);
455
+ this.handle(Subsystem.SYS, "osalNvReadExt", handleOsalNvRead);
456
+
457
+ const handleOsalNvWrite = (payload, handler) => {
458
+ if (payload.offset !== undefined && payload.offset !== 0) {
459
+ throw new Error("osalNvLength offset not supported");
460
+ }
461
+ const item = handler.nvItems.find((e) => e.id === payload.id);
462
+ if (item) {
463
+ item.value = payload.value;
464
+ return {payload: {status: 0}};
465
+ }
466
+
467
+ return {payload: {status: 1}};
468
+ };
469
+ this.handle(Subsystem.SYS, "osalNvWrite", handleOsalNvWrite);
470
+ this.handle(Subsystem.SYS, "osalNvWriteExt", handleOsalNvWrite);
471
+
472
+ this.handle(Subsystem.SYS, "osalNvItemInit", (payload, handler) => {
473
+ let item = handler.nvItems.find((e) => e.id === payload.id);
474
+ if (item) {
475
+ if (item.value && item.value.length !== payload.len) {
476
+ return {payload: {status: 0x0a}};
477
+ }
478
+ return {payload: {status: 0x00}};
479
+ }
480
+
481
+ item = {
482
+ id: payload.id,
483
+ value: payload.initvalue || null,
484
+ };
485
+ handler.nvItems.push(item);
486
+ return {payload: {status: 0x09}};
487
+ });
488
+ this.handle(Subsystem.SYS, "osalNvLength", (payload, handler) => {
489
+ if (payload.offset !== undefined && payload.offset !== 0) {
490
+ throw new Error("osalNvLength offset not supported");
491
+ }
492
+ const item = handler.nvItems.find((e) => e.id === payload.id);
493
+ return {payload: {length: item?.value ? item.value.length : 0}};
494
+ });
495
+ this.handle(Subsystem.SYS, "osalNvDelete", (payload, handler) => {
496
+ const item = handler.nvItems.find((e) => e.id === payload.id);
497
+ if (item) {
498
+ if (item.value && item.value.length !== payload.len) {
499
+ return {payload: {status: 0x0a}};
500
+ }
501
+ const itemIndex = handler.nvItems.indexOf(item);
502
+ handler.nvItems.splice(itemIndex, 1);
503
+ return {payload: {status: 0x00}};
504
+ }
505
+
506
+ return {payload: {status: 0x09}};
507
+ });
508
+
509
+ this.handle(Subsystem.SYS, "nvRead", (payload, handler: ZnpRequestMockBuilder) => {
510
+ if (payload.offset !== undefined && payload.offset !== 0) {
511
+ throw new Error("nvRead offset not supported");
512
+ }
513
+ const item = handler.nvExtendedItems.find((e) => e.sysId === payload.sysid && e.id === payload.itemid && e.subId === payload.subid);
514
+ return {
515
+ payload: {
516
+ status: item?.value ? 0 : 1,
517
+ value: item?.value ? item.value : undefined,
518
+ len: item?.value?.length || undefined,
519
+ },
520
+ };
521
+ });
522
+
523
+ this.handle(Subsystem.SYS, "nvWrite", (payload, handler: ZnpRequestMockBuilder) => {
524
+ if (payload.offset !== undefined && payload.offset !== 0) {
525
+ throw new Error("nwWrite offset not supported");
526
+ }
527
+ const item = handler.nvExtendedItems.find((e) => e.sysId === payload.sysid && e.id === payload.itemid && e.subId === payload.subid);
528
+ if (item) {
529
+ item.value = payload.value;
530
+ return {payload: {status: 0}};
531
+ }
532
+
533
+ return {payload: {status: 1}};
534
+ });
535
+
536
+ this.handle(Subsystem.SYS, "nvCreate", (payload, handler: ZnpRequestMockBuilder) => {
537
+ let item = handler.nvExtendedItems.find((e) => e.sysId === payload.sysid && e.id === payload.itemid && e.subId === payload.subid);
538
+ if (item) {
539
+ if (item.value && item.value.length !== payload.len) {
540
+ return {payload: {status: 0x0a}};
541
+ }
542
+ return {payload: {status: 0x00}};
543
+ }
544
+
545
+ item = {
546
+ sysId: payload.sysid,
547
+ id: payload.itemid,
548
+ subId: payload.subid,
549
+ value: null,
550
+ };
551
+ handler.nvExtendedItems.push(item);
552
+ return {payload: {status: 0x09}};
553
+ });
554
+ this.handle(Subsystem.SYS, "nvLength", (payload, handler) => {
555
+ if (payload.offset !== undefined && payload.offset !== 0) {
556
+ throw new Error("nvLength offset not supported");
557
+ }
558
+ const item = handler.nvExtendedItems.find((e) => e.sysId === payload.sysid && e.id === payload.itemid && e.subId === payload.subid);
559
+ return {payload: {len: item?.value ? item.value.length : 0}};
560
+ });
561
+ this.handle(Subsystem.SYS, "nvDelete", (payload, handler) => {
562
+ const item = handler.nvExtendedItems.find((e) => e.sysId === payload.sysid && e.id === payload.itemid && e.subId === payload.subid);
563
+ if (item) {
564
+ if (item.value && item.value.length !== payload.len) {
565
+ return {payload: {status: 0x0a}};
566
+ }
567
+ const itemIndex = handler.nvItems.indexOf(item);
568
+ handler.nvItems.splice(itemIndex, 1);
569
+ return {payload: {status: 0x00}};
570
+ }
571
+
572
+ return {payload: {status: 0x09}};
573
+ });
574
+ }
575
+
576
+ // biome-ignore lint/suspicious/noExplicitAny: API
577
+ public handle(subsystem: Subsystem, command: string, exec?: (payload: any, handler?: ZnpRequestMockBuilder) => any) {
578
+ const index = this.responders.findIndex((r) => r.subsystem === subsystem && r.command === command);
579
+ if (index > -1) {
580
+ this.responders.splice(index, 1);
581
+ }
582
+ this.responders.push({subsystem, command, exec: exec || (() => ({}))});
583
+ return this;
584
+ }
585
+
586
+ public nv(id: NvItemsIds, value?: Buffer) {
587
+ const index = this.nvItems.findIndex((e) => e.id === id);
588
+ if (index > -1) {
589
+ this.nvItems.splice(index, 1);
590
+ }
591
+ if (value) {
592
+ this.nvItems.push({id, value: value || null});
593
+ }
594
+ return this;
595
+ }
596
+
597
+ public nvExtended(sysId: NvSystemIds, id: NvItemsIds, subId: number, value?: Buffer) {
598
+ const index = this.nvExtendedItems.findIndex((e) => e.sysId === sysId && e.id === id && e.subId === subId);
599
+ if (index > -1) {
600
+ this.nvExtendedItems.splice(index, 1);
601
+ }
602
+ if (value) {
603
+ this.nvExtendedItems.push({sysId, id, subId, value: value || null});
604
+ }
605
+ return this;
606
+ }
607
+
608
+ // biome-ignore lint/suspicious/noExplicitAny: API
609
+ public execute(message: {subsystem: Subsystem; command: string; payload: any}) {
610
+ const responder = this.responders.find((r) => r.subsystem === message.subsystem && r.command === message.command);
611
+ if (!responder) {
612
+ const msg = `Not implemented - ${Subsystem[message.subsystem]} - ${message.command} - ${JSON.stringify(message.payload)}`;
613
+ console.log(msg);
614
+ throw new Error(msg);
615
+ }
616
+ const response = responder.exec(message.payload, this);
617
+ return response;
618
+ }
619
+
620
+ public clone(): ZnpRequestMockBuilder {
621
+ const newBuilder = new ZnpRequestMockBuilder();
622
+ newBuilder.responders = this.responders.map((responder) => ({...responder}));
623
+ newBuilder.nvItems = this.nvItems.map((item) => ({...item, value: Buffer.from(item.value)}));
624
+ newBuilder.nvExtendedItems = this.nvExtendedItems.map((item) => ({...item, value: Buffer.from(item.value)}));
625
+ return newBuilder;
626
+ }
627
+ }
628
+
629
+ const baseZnpRequestMock = new ZnpRequestMockBuilder()
630
+ .handle(Subsystem.SYS, "version", (payload) => (equals(payload, {}) ? {payload: {product: ZnpVersion.ZStack30x, revision: 20201026}} : undefined))
631
+ .handle(Subsystem.SYS, "ping", () => ({}))
632
+ .handle(Subsystem.SYS, "resetReq", () => ({}))
633
+ .handle(Subsystem.SYS, "getExtAddr", () => ({payload: {extaddress: "0x00124b0009d69f77"}}))
634
+ .handle(Subsystem.SYS, "stackTune", () => ({}))
635
+ .handle(Subsystem.ZDO, "extFindGroup", () => ({payload: {status: 0}}))
636
+ .handle(Subsystem.ZDO, "extAddGroup", () => ({payload: {status: 0}}))
637
+ .handle(Subsystem.UTIL, "getDeviceInfo", () => ({payload: {devicestate: 0x00, ieeeaddr: "0x00124b0009d80ba7"}}))
638
+ .handle(Subsystem.ZDO, "activeEpReq", () => ({}))
639
+ .handle(Subsystem.ZDO, "simpleDescReq", () => ({}))
640
+ .handle(Subsystem.ZDO, "mgmtPermitJoinReq", () => ({}))
641
+ .handle(Subsystem.ZDO, "nodeDescReq", () => ({}))
642
+ .handle(Subsystem.ZDO, "bindReq", () => ({}))
643
+ .handle(Subsystem.ZDO, "unbindReq", () => ({}))
644
+ .handle(Subsystem.ZDO, "mgmtLeaveReq", () => ({}))
645
+ .handle(Subsystem.ZDO, "mgmtLqiReq", () => ({}))
646
+ .handle(Subsystem.ZDO, "mgmtRtgReq", () => ({}))
647
+ .handle(Subsystem.ZDO, "mgmtNwkUpdateReq", () => ({}))
648
+ .handle(Subsystem.AF, "interPanCtl", () => ({}))
649
+ .handle(Subsystem.ZDO, "extRouteDisc", () => ({}))
650
+ .handle(Subsystem.ZDO, "nwkAddrReq", () => ({}))
651
+ .handle(Subsystem.UTIL, "assocRemove", () => ({payload: {}}))
652
+ .handle(Subsystem.UTIL, "assocGetWithAddress", () => ({payload: {noderelation: assocGetWithAddressNodeRelation}}))
653
+ .handle(Subsystem.UTIL, "assocAdd", () => ({payload: {}}))
654
+ .handle(Subsystem.UTIL, "ledControl", () => ({}))
655
+ .handle(Subsystem.APP_CNF, "bdbAddInstallCode", () => ({}))
656
+ .handle(Subsystem.AF, "register", () => ({}))
657
+ .handle(Subsystem.AF, "dataRequest", () => {
658
+ if (dataRequestCode !== 0) {
659
+ throw new Error(`Data request failed with code '${dataRequestCode}'`);
660
+ }
661
+ return {};
662
+ })
663
+ .handle(Subsystem.AF, "dataRequestExt", () => {
664
+ if (dataRequestExtCode !== 0) {
665
+ throw new Error(`Data request failed with code '${dataRequestExtCode}'`);
666
+ }
667
+ return {};
668
+ })
669
+ .handle(Subsystem.SYS, "resetReq", () => ({}))
670
+ .handle(Subsystem.APP_CNF, "bdbSetChannel", () => ({}))
671
+ .handle(Subsystem.APP_CNF, "bdbStartCommissioning", (_, handler) => {
672
+ const nibIndex = handler.nvItems.findIndex((e) => e.id === NvItemsIds.NIB);
673
+ if (nibIndex > -1) {
674
+ handler.nvItems.splice(nibIndex, 1);
675
+ }
676
+ handler.nvItems.push({
677
+ id: NvItemsIds.NIB,
678
+ value: Buffer.from(
679
+ "fb050279147900640000000105018f000700020d1e0000001500000000000000000000007b000800000020000f0f0400010000000100000000779fd609004b1200010000000000000000000000000000000000000000000000000000000000000000000000003c0c0001780a0100000006020000",
680
+ "hex",
681
+ ),
682
+ });
683
+ return {};
684
+ })
685
+ .handle(Subsystem.ZDO, "extNwkInfo", (_, handler) => {
686
+ const nib = Structs.nib(handler.nvItems.find((item) => item.id === NvItemsIds.NIB).value);
687
+ return {payload: {panid: nib.nwkPanId, extendedpanid: `0x${nib.extendedPANID.toString("hex")}`, channel: nib.nwkLogicalChannel}};
688
+ })
689
+ .handle(Subsystem.ZDO, "startupFromApp", () => ({}))
690
+ .nv(NvItemsIds.CHANLIST, Buffer.from([0, 8, 0, 0]))
691
+ .nv(NvItemsIds.PRECFGKEY, Buffer.alloc(16, 0))
692
+ .nv(NvItemsIds.PRECFGKEYS_ENABLE, Buffer.from([0]))
693
+ .nv(NvItemsIds.NWKKEY, Buffer.alloc(24, 0))
694
+ .nv(NvItemsIds.NWK_ACTIVE_KEY_INFO, Buffer.from("000000000000000000000000000000000000", "hex"))
695
+ .nv(NvItemsIds.NWK_ALTERN_KEY_INFO, Buffer.from("000000000000000000000000000000000000", "hex"))
696
+ .nv(NvItemsIds.ZNP_HAS_CONFIGURED_ZSTACK3, Buffer.from([0x00]))
697
+ .nv(
698
+ NvItemsIds.NIB,
699
+ Buffer.from(
700
+ "fb050279147900640000000105018f000700020d1e0000001500000000000000000000000bcd0800000020000f0f0400010000000100000000779fd609004b1200010000000000000000000000000000000000000000000000000000000000000000000000003c0c0001780a0100000006020000",
701
+ "hex",
702
+ ),
703
+ );
704
+
705
+ let mockHugePayloadTimestamp: number | undefined;
706
+ let mockHugePayloadIndex = 0;
707
+ let mockHugePayload: Buffer = Buffer.alloc(0);
708
+ let mockHugePayloadError = 0;
709
+
710
+ /**
711
+ * @param mockError 0: none
712
+ * 1: dataRetrieve error return
713
+ * 2: dataRetrieve wrong data size return
714
+ */
715
+ const mockIncomingMsgExtSetHugeData = (timestamp: number, data: Buffer, mockError = 0) => {
716
+ mockHugePayloadTimestamp = timestamp;
717
+ mockHugePayload = data;
718
+ mockHugePayloadIndex = 0;
719
+ mockHugePayloadError = mockError;
720
+ };
721
+
722
+ const incomingMsgExtHugeDataReqMock = baseZnpRequestMock.clone().handle(Subsystem.AF, "dataRetrieve", (payload) => {
723
+ if (payload.timestamp !== mockHugePayloadTimestamp) {
724
+ throw new Error("Payload timestamp doesnt match mock data timestamp. Did you call mockIncomingMsgExtSetHugeData?");
725
+ }
726
+ if (payload.length > mockHugePayload.length - mockHugePayloadIndex) {
727
+ // Unclear if ZNP returns error or just returns fewer bytes
728
+ // in this case, but handler should request the correct amount.
729
+ throw new Error("Requested data chunk exceeds available bytes");
730
+ }
731
+ const chunk = {
732
+ payload: {
733
+ status: mockHugePayloadError === 1 ? 0x01 : 0x00,
734
+ length: mockHugePayloadError === 2 ? payload.length + 1 : payload.length,
735
+ data: mockHugePayload.subarray(mockHugePayloadIndex, mockHugePayloadIndex + payload.length),
736
+ },
737
+ };
738
+ if (payload.length === 0) {
739
+ // dataRetrieve with length 0 closes the ZNP buffer
740
+ mockHugePayloadTimestamp = 0;
741
+ mockHugePayloadIndex = 0;
742
+ } else {
743
+ mockHugePayloadIndex += payload.length;
744
+ }
745
+ return chunk;
746
+ });
747
+
748
+ const empty3UnalignedRequestMock = baseZnpRequestMock
749
+ .clone()
750
+ .handle(Subsystem.APP_CNF, "bdbStartCommissioning", (_, handler) => {
751
+ const nibIndex = handler.nvItems.findIndex((e) => e.id === NvItemsIds.NIB);
752
+ if (nibIndex > -1) {
753
+ handler.nvItems.splice(nibIndex, 1);
754
+ }
755
+ handler.nvItems.push({
756
+ id: NvItemsIds.NIB,
757
+ value: Buffer.from(
758
+ "fb050279147900640000000105018f0700020d1e000015000000000000000000007b0008000020000f0f0400010000000100000000779fd609004b1200010000000000000000000000000000000000000000000000000000000000000000000000003c0c0001780a010000060200",
759
+ "hex",
760
+ ),
761
+ });
762
+ return {};
763
+ })
764
+ .nv(NvItemsIds.NWKKEY, Buffer.alloc(21, 0))
765
+ .nv(NvItemsIds.ZNP_HAS_CONFIGURED_ZSTACK3, Buffer.from([0x00]))
766
+ .nv(
767
+ NvItemsIds.NIB,
768
+ Buffer.from(
769
+ "fb050279147900640000000105018f0700020d1e00001500000000000000000000ffff08000020000f0f0400010000000100000000779fd609004b1200010000000000000000000000000000000000000000000000000000000000000000000000003c0c0001780a010000060200",
770
+ "hex",
771
+ ),
772
+ )
773
+ .nv(
774
+ NvItemsIds.ADDRMGR,
775
+ Buffer.from(
776
+ "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
777
+ "hex",
778
+ ),
779
+ )
780
+ .nv(
781
+ NvItemsIds.APS_LINK_KEY_TABLE,
782
+ Buffer.from(
783
+ "0000feff000000feff000000feff000000feff000000feff000000feff000000feff000000feff000000feff000000feff000000feff000000feff000000feff000000feff000000feff000000feff000000",
784
+ "hex",
785
+ ),
786
+ );
787
+ for (let i = 0; i < 4; i++) {
788
+ empty3UnalignedRequestMock.nv(NvItemsIds.LEGACY_NWK_SEC_MATERIAL_TABLE_START + i, Buffer.from("000000000000000000000000", "hex"));
789
+ }
790
+ for (let i = 0; i < 16; i++) {
791
+ empty3UnalignedRequestMock.nv(NvItemsIds.LEGACY_TCLK_TABLE_START + i, Buffer.from("00000000000000000000000000000000000000", "hex"));
792
+ }
793
+ for (let i = 0; i < 16; i++) {
794
+ empty3UnalignedRequestMock.nv(NvItemsIds.APS_LINK_KEY_DATA_START + i, Buffer.from("000000000000000000000000000000000000000000000000", "hex"));
795
+ }
796
+
797
+ const empty3AlignedRequestMock = baseZnpRequestMock
798
+ .clone()
799
+ .nv(NvItemsIds.ZNP_HAS_CONFIGURED_ZSTACK3, Buffer.from([0x00]))
800
+ .nv(
801
+ NvItemsIds.NIB,
802
+ Buffer.from(
803
+ "fb050279147900640000000105018f000700020d1e000000150000000000000000000000ffff0800000020000f0f0400010000000100000000779fd609004b1200010000000000000000000000000000000000000000000000000000000000000000000000003c0c0001780a0100000006020000",
804
+ "hex",
805
+ ),
806
+ )
807
+ .nv(
808
+ NvItemsIds.ADDRMGR,
809
+ Buffer.from(
810
+ "00ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff00000000000000000000",
811
+ "hex",
812
+ ),
813
+ )
814
+ .nv(
815
+ NvItemsIds.APS_LINK_KEY_TABLE,
816
+ Buffer.from(
817
+ "0000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000",
818
+ "hex",
819
+ ),
820
+ );
821
+ for (let i = 0; i < 4; i++) {
822
+ empty3AlignedRequestMock.nv(NvItemsIds.LEGACY_NWK_SEC_MATERIAL_TABLE_START + i, Buffer.from("000000000000000000000000", "hex"));
823
+ }
824
+ for (let i = 0; i < 16; i++) {
825
+ empty3AlignedRequestMock.nv(NvItemsIds.LEGACY_TCLK_TABLE_START + i, Buffer.from("0000000000000000000000000000000000000000", "hex"));
826
+ }
827
+ for (let i = 0; i < 16; i++) {
828
+ empty3AlignedRequestMock.nv(NvItemsIds.APS_LINK_KEY_DATA_START + i, Buffer.from("000000000000000000000000000000000000000000000000", "hex"));
829
+ }
830
+
831
+ const commissioned3AlignedRequestMock = empty3AlignedRequestMock
832
+ .clone()
833
+ .nv(NvItemsIds.ZNP_HAS_CONFIGURED_ZSTACK3, Buffer.from([0x55]))
834
+ .nv(NvItemsIds.PRECFGKEY, Buffer.from("01030507090b0d0f00020406080a0c0d", "hex"))
835
+ .nv(NvItemsIds.NWK_ACTIVE_KEY_INFO, Buffer.from("0001030507090b0d0f00020406080a0c0d00", "hex"))
836
+ .nv(NvItemsIds.NWK_ALTERN_KEY_INFO, Buffer.from("0001030507090b0d0f00020406080a0c0d00", "hex"))
837
+ .nv(
838
+ NvItemsIds.NIB,
839
+ Buffer.from(
840
+ "fb050279147900640000000105018f000700020d1e0000001500000000000000000000007b000800000020000f0f0400010000000100000000779fd609004b1200010000000000000000000000000000000000000000000000000000000000000000000000003c0c0001780a0100000006020000",
841
+ "hex",
842
+ ),
843
+ )
844
+ .nv(
845
+ NvItemsIds.ADDRMGR,
846
+ Buffer.from(
847
+ "01ff4f3a080000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff0000000000000000000000ff00000000000000000000",
848
+ "hex",
849
+ ),
850
+ );
851
+
852
+ const commissioned3AlignedConfigMistmachRequestMock = commissioned3AlignedRequestMock
853
+ .clone()
854
+ .nv(NvItemsIds.NWK_ACTIVE_KEY_INFO, Buffer.from("0001030507090b0d0f00020406080a0c0d00", "hex"))
855
+ .nv(NvItemsIds.NWK_ALTERN_KEY_INFO, Buffer.from("0001030507090b0d0f00020406080a0c0d00", "hex"))
856
+ .nv(
857
+ NvItemsIds.NIB,
858
+ Buffer.from(
859
+ "fb050279147900640000000105018f000700020d1e0000001500000000000000000000007e000800000020000f0f0400010000000100000000779fd609004b1200010000000000000000000000000000000000000000000000000000000000000000000000003c0c0001780a0100000006020000",
860
+ "hex",
861
+ ),
862
+ );
863
+
864
+ const empty3x0AlignedRequestMock = baseZnpRequestMock
865
+ .clone()
866
+ .handle(Subsystem.SYS, "version", (payload) => (equals(payload, {}) ? {payload: {product: ZnpVersion.ZStack3x0, revision: 20210430}} : undefined))
867
+ .nv(NvItemsIds.ZNP_HAS_CONFIGURED_ZSTACK3, Buffer.from([0x00]))
868
+ .nv(
869
+ NvItemsIds.NIB,
870
+ Buffer.from(
871
+ "fb050279147900640000000105018f000700020d1e000000150000000000000000000000ffff0800000020000f0f0400010000000100000000779fd609004b1200010000000000000000000000000000000000000000000000000000000000000000000000003c0c0001780a0100000006020000",
872
+ "hex",
873
+ ),
874
+ )
875
+ .nv(
876
+ NvItemsIds.APS_LINK_KEY_TABLE,
877
+ Buffer.from(
878
+ "0000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000feff00000000",
879
+ "hex",
880
+ ),
881
+ );
882
+ for (let i = 0; i < 16; i++) {
883
+ empty3x0AlignedRequestMock.nvExtended(NvSystemIds.ZSTACK, NvItemsIds.ZCD_NV_EX_ADDRMGR, i, Buffer.from("00ff00000000000000000000", "hex"));
884
+ }
885
+ for (let i = 0; i < 4; i++) {
886
+ empty3x0AlignedRequestMock.nvExtended(
887
+ NvSystemIds.ZSTACK,
888
+ NvItemsIds.EX_NWK_SEC_MATERIAL_TABLE,
889
+ i,
890
+ Buffer.from("000000000000000000000000", "hex"),
891
+ );
892
+ }
893
+ for (let i = 0; i < 16; i++) {
894
+ empty3x0AlignedRequestMock.nvExtended(
895
+ NvSystemIds.ZSTACK,
896
+ NvItemsIds.EX_TCLK_TABLE,
897
+ i,
898
+ Buffer.from("0000000000000000000000000000000000000000", "hex"),
899
+ );
900
+ }
901
+ for (let i = 0; i < 16; i++) {
902
+ empty3x0AlignedRequestMock.nvExtended(
903
+ NvSystemIds.ZSTACK,
904
+ NvItemsIds.ZCD_NV_EX_APS_KEY_DATA_TABLE,
905
+ i,
906
+ Buffer.from("000000000000000000000000000000000000000000000000", "hex"),
907
+ );
908
+ }
909
+
910
+ const commissioned3x0AlignedRequestMock = empty3x0AlignedRequestMock
911
+ .clone()
912
+ .nv(NvItemsIds.ZNP_HAS_CONFIGURED_ZSTACK3, Buffer.from([0x55]))
913
+ .nv(NvItemsIds.PRECFGKEY, Buffer.from("01030507090b0d0f00020406080a0c0d", "hex"))
914
+ .nv(NvItemsIds.NWK_ACTIVE_KEY_INFO, Buffer.from("0001030507090b0d0f00020406080a0c0d00", "hex"))
915
+ .nv(NvItemsIds.NWK_ALTERN_KEY_INFO, Buffer.from("0001030507090b0d0f00020406080a0c0d00", "hex"))
916
+ .nv(
917
+ NvItemsIds.NIB,
918
+ Buffer.from(
919
+ "fb050279147900640000000105018f000700020d1e0000001500000000000000000000007b000800000020000f0f0400010000000100000000779fd609004b1200010000000000000000000000000000000000000000000000000000000000000000000000003c0c0001780a0100000006020000",
920
+ "hex",
921
+ ),
922
+ )
923
+ .nvExtended(NvSystemIds.ZSTACK, NvItemsIds.ZCD_NV_EX_ADDRMGR, 0, Buffer.from("01ff4f3a0800000000000000", "hex"));
924
+
925
+ const empty12UnalignedRequestMock = baseZnpRequestMock
926
+ .clone()
927
+ .handle(Subsystem.SYS, "version", (payload) => (equals(payload, {}) ? {payload: {product: ZnpVersion.ZStack12}} : undefined))
928
+ .handle(Subsystem.SAPI, "readConfiguration", (payload, handler) => {
929
+ if (payload.configid !== NvItemsIds.PRECFGKEY) {
930
+ throw new Error("Only pre-configured key should be read/written using SAPI layer");
931
+ }
932
+ const item = handler.nvItems.find((item) => item.id === payload.configid);
933
+ if (item) {
934
+ return {payload: {status: 0, configid: item.id, len: item.value?.length || 0, value: item.value}};
935
+ }
936
+ return {payload: {status: 1}};
937
+ })
938
+ .handle(Subsystem.SAPI, "writeConfiguration", (payload, handler) => {
939
+ if (payload.configid !== NvItemsIds.PRECFGKEY) {
940
+ throw new Error("Only pre-configured key should be read/written using SAPI layer");
941
+ }
942
+ const item = handler.nvItems.find((item) => item.id === payload.configid);
943
+ if (item) {
944
+ item.value = payload.value;
945
+ } else {
946
+ handler.nvItems.push({id: payload.configid, value: payload.value});
947
+ }
948
+ handler.nv(
949
+ NvItemsIds.NIB,
950
+ Buffer.from(
951
+ "fb050279147900640000000105018f0700020d1e000015000000000000000000007b0008000020000f0f0400010000000100000000779fd609004b1200010000000000000000000000000000000000000000000000000000000000000000000000003c0c0001780a010000060200",
952
+ "hex",
953
+ ),
954
+ );
955
+ return {payload: {status: 0}};
956
+ })
957
+ .nv(NvItemsIds.ZNP_HAS_CONFIGURED_ZSTACK1, Buffer.from([0x00]));
958
+
959
+ const commissioned12UnalignedRequestMock = empty12UnalignedRequestMock
960
+ .clone()
961
+ .nv(NvItemsIds.ZNP_HAS_CONFIGURED_ZSTACK1, Buffer.from([0x55]))
962
+ .nv(NvItemsIds.PRECFGKEY, Buffer.from("01030507090b0d0f00020406080a0c0d", "hex"))
963
+ .nv(
964
+ NvItemsIds.NIB,
965
+ Buffer.from(
966
+ "fb050279147900640000000105018f0700020d1e000015000000000000000000007b0008000020000f0f0400010000000100000000779fd609004b1200010000000000000000000000000000000000000000000000000000000000000000000000003c0c0001780a010000060200",
967
+ "hex",
968
+ ),
969
+ );
970
+
971
+ const commissioned12UnalignedMismatchRequestMock = commissioned12UnalignedRequestMock
972
+ .clone()
973
+ .nv(NvItemsIds.PRECFGKEY, Buffer.from("aabb0507090b0d0f00020406080a0c0d", "hex"));
974
+
975
+ const mockZnpRequest = vi
976
+ .fn()
977
+ .mockReturnValue(new Promise((resolve) => resolve({payload: {}})))
978
+ .mockImplementation(
979
+ // biome-ignore lint/suspicious/noExplicitAny: API
980
+ (subsystem: Subsystem, command: string, payload: any, _expectedStatus: ZnpCommandStatus) =>
981
+ new Promise((resolve) => resolve(baseZnpRequestMock.execute({subsystem, command, payload}))),
982
+ );
983
+ const mockZnpRequestZdo = vi.fn();
984
+ const mockZnpWaitFor = vi.fn();
985
+ const mockZnpOpen = vi.fn();
986
+ const mockZnpClose = vi.fn();
987
+ const mockQueueExecute = vi.fn().mockImplementation(async (func) => await func());
988
+ const mocks = [mockZnpOpen, mockZnpRequest, mockZnpClose];
989
+
990
+ const mockZnpRequestWith = (builder: ZnpRequestMockBuilder) => {
991
+ builder = builder.clone();
992
+ mockZnpRequest.mockImplementation(
993
+ // biome-ignore lint/suspicious/noExplicitAny: API
994
+ (subsystem: Subsystem, command: string, payload: any, _expectedStatus: ZnpCommandStatus) =>
995
+ new Promise((resolve) => resolve(builder.execute({subsystem, command, payload}))),
996
+ );
997
+ };
998
+
999
+ const mockZnpWaitForDefault = () => {
1000
+ mockZnpWaitFor.mockImplementation((type, subsystem, command, target, transid, state, timeout) => {
1001
+ const missing = () => {
1002
+ const msg = `Not implemented - ${Type[type]} - ${Subsystem[subsystem]} - ${command} - ${target} - ${transid} - ${state} - ${timeout}`;
1003
+ console.log(msg);
1004
+ throw new Error(msg);
1005
+ };
1006
+
1007
+ if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "activeEpRsp") {
1008
+ return waitForResult(
1009
+ mockZdoZpiObject<ActiveEndpointsResponse>("activeEpRsp", target, [
1010
+ Zdo.Status.SUCCESS,
1011
+ {
1012
+ nwkAddress: 0,
1013
+ endpointList: [],
1014
+ },
1015
+ ]),
1016
+ );
1017
+ }
1018
+
1019
+ if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "mgmtPermitJoinRsp") {
1020
+ return waitForResult(mockZdoZpiObject("mgmtPermitJoinRsp", target, [Zdo.Status.SUCCESS, undefined]));
1021
+ }
1022
+
1023
+ if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "stateChangeInd") {
1024
+ return waitForResult({payload: {state: 9}});
1025
+ }
1026
+
1027
+ missing();
1028
+ });
1029
+ };
1030
+
1031
+ const mockZnpWaitForStateChangeIndTimeout = () => {
1032
+ mockZnpWaitFor.mockImplementation((type, subsystem, command, target, transid, state, timeout) => {
1033
+ const missing = () => {
1034
+ const msg = `Not implemented - ${Type[type]} - ${Subsystem[subsystem]} - ${command} - ${target} - ${transid} - ${state} - ${timeout}`;
1035
+ console.log(msg);
1036
+ throw new Error(msg);
1037
+ };
1038
+
1039
+ if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "activeEpRsp") {
1040
+ return waitForResult(
1041
+ mockZdoZpiObject<ActiveEndpointsResponse>("activeEpRsp", target, [
1042
+ Zdo.Status.SUCCESS,
1043
+ {
1044
+ nwkAddress: 0,
1045
+ endpointList: [],
1046
+ },
1047
+ ]),
1048
+ );
1049
+ }
1050
+
1051
+ if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "stateChangeInd") {
1052
+ return;
1053
+ }
1054
+
1055
+ missing();
1056
+ });
1057
+ };
1058
+
1059
+ let bindStatusResponse = 0;
1060
+
1061
+ const mockZdoZpiObject = <T>(commandName: string, srcaddr: number | undefined, payload: [Zdo.Status, T | undefined]): ZpiObject => {
1062
+ const subsystem = Subsystem.ZDO;
1063
+ const command = Definition[subsystem].find((c) => c.name === commandName)!;
1064
+ return {
1065
+ type: Type.AREQ,
1066
+ subsystem,
1067
+ command,
1068
+ payload: {srcaddr, zdo: payload},
1069
+ };
1070
+ };
1071
+
1072
+ const mockZpiObject = (type: Type, subsystem: Subsystem, commandName: string, payload: {[s: string]: unknown}) => {
1073
+ const command = Definition[subsystem].find((c) => c.name === commandName);
1074
+ return {type, subsystem, payload, command};
1075
+ };
1076
+
1077
+ const basicMocks = () => {
1078
+ mockZnpRequestWith(commissioned3x0AlignedRequestMock);
1079
+ mockZnpWaitFor.mockImplementation((type, subsystem, command, target, transid, state, timeout) => {
1080
+ const missing = () => {
1081
+ const msg = `Not implemented - ${Type[type]} - ${Subsystem[subsystem]} - ${command} - ${target} - ${transid} - ${state} - ${timeout}`;
1082
+ console.log(msg);
1083
+ throw new Error(msg);
1084
+ };
1085
+
1086
+ if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "activeEpRsp") {
1087
+ return waitForResult(
1088
+ mockZdoZpiObject<ActiveEndpointsResponse>("activeEpRsp", target, [
1089
+ Zdo.Status.SUCCESS,
1090
+ {
1091
+ nwkAddress: 0,
1092
+ endpointList: [1, 2, 3, 4, 5, 6, 8, 10, 11, 110, 12, 13, 47, 242],
1093
+ },
1094
+ ]),
1095
+ );
1096
+ }
1097
+
1098
+ if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "stateChangeInd") {
1099
+ return waitForResult({payload: {}});
1100
+ }
1101
+
1102
+ if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "mgmtPermitJoinRsp") {
1103
+ return waitForResult(mockZdoZpiObject("mgmtPermitJoinRsp", target, [Zdo.Status.SUCCESS, undefined]));
1104
+ }
1105
+
1106
+ if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "simpleDescRsp") {
1107
+ let responsePayload: SimpleDescriptorResponse;
1108
+ if (simpleDescriptorEndpoint === 1) {
1109
+ responsePayload = {
1110
+ length: 1, // bogus
1111
+ endpoint: 1,
1112
+ profileId: 123,
1113
+ deviceId: 5,
1114
+ inClusterList: [1],
1115
+ outClusterList: [2],
1116
+ nwkAddress: target,
1117
+ deviceVersion: 0,
1118
+ };
1119
+ } else if (simpleDescriptorEndpoint === 99) {
1120
+ responsePayload = {
1121
+ length: 1, // bogus
1122
+ endpoint: 99,
1123
+ profileId: 123,
1124
+ deviceId: 5,
1125
+ inClusterList: [1],
1126
+ outClusterList: [2],
1127
+ nwkAddress: target,
1128
+ deviceVersion: 0,
1129
+ };
1130
+ } else {
1131
+ responsePayload = {
1132
+ length: 1, // bogus
1133
+ endpoint: simpleDescriptorEndpoint,
1134
+ profileId: 124,
1135
+ deviceId: 7,
1136
+ inClusterList: [8],
1137
+ outClusterList: [9],
1138
+ nwkAddress: target,
1139
+ deviceVersion: 0,
1140
+ };
1141
+ }
1142
+
1143
+ return waitForResult(mockZdoZpiObject<SimpleDescriptorResponse>("simpleDescRsp", target, [Zdo.Status.SUCCESS, responsePayload]));
1144
+ }
1145
+
1146
+ if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "nodeDescRsp") {
1147
+ if (nodeDescRspErrorOnce) {
1148
+ nodeDescRspErrorOnce = false;
1149
+ return {
1150
+ start: () => {
1151
+ return {
1152
+ promise: new Promise((_resolve, reject) => {
1153
+ reject("timeout after xx");
1154
+ }),
1155
+ };
1156
+ },
1157
+ ID: 89,
1158
+ };
1159
+ }
1160
+
1161
+ return waitForResult(
1162
+ mockZdoZpiObject<NodeDescriptorResponse>("nodeDescRsp", target, [
1163
+ Zdo.Status.SUCCESS,
1164
+ {
1165
+ manufacturerCode: target * 2,
1166
+ apsFlags: 0,
1167
+ capabilities: DUMMY_NODE_DESC_RSP_CAPABILITIES,
1168
+ deprecated1: 0,
1169
+ fragmentationSupported: true,
1170
+ frequencyBand: 0,
1171
+ logicalType: target - 1,
1172
+ maxBufSize: 0,
1173
+ maxIncTxSize: 0,
1174
+ maxOutTxSize: 0,
1175
+ nwkAddress: target,
1176
+ serverMask: {
1177
+ backupTrustCenter: 0,
1178
+ deprecated1: 0,
1179
+ deprecated2: 0,
1180
+ deprecated3: 0,
1181
+ deprecated4: 0,
1182
+ networkManager: 0,
1183
+ primaryTrustCenter: 0,
1184
+ reserved1: 0,
1185
+ reserved2: 0,
1186
+ stackComplianceRevision: 0,
1187
+ },
1188
+ tlvs: [],
1189
+ },
1190
+ ]),
1191
+ );
1192
+ }
1193
+
1194
+ if (type === Type.AREQ && subsystem === Subsystem.AF && command === "dataConfirm") {
1195
+ const status = dataConfirmCode;
1196
+ if (dataConfirmCodeReset) {
1197
+ dataConfirmCode = 0;
1198
+ }
1199
+
1200
+ if (status === 9999) {
1201
+ return {
1202
+ start: () => {
1203
+ return {
1204
+ promise: new Promise((_resolve, reject) => {
1205
+ reject("timeout after xx");
1206
+ }),
1207
+ };
1208
+ },
1209
+ ID: 99,
1210
+ };
1211
+ }
1212
+
1213
+ return waitForResult({payload: {status}}, 99);
1214
+ }
1215
+
1216
+ if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "mgmtLqiRsp" && target === 203) {
1217
+ const defaults = {deviceType: 0, extendedPanId: [0], permitJoining: 0, reserved1: 0, reserved2: 0, rxOnWhenIdle: 0};
1218
+
1219
+ if (lastStartIndex === 0) {
1220
+ lastStartIndex += 2;
1221
+ return waitForResult(
1222
+ mockZdoZpiObject<LQITableResponse>("mgmtLqiRsp", target, [
1223
+ Zdo.Status.SUCCESS,
1224
+ {
1225
+ neighborTableEntries: 5,
1226
+ startIndex: 0,
1227
+ entryList: [
1228
+ {lqi: 10, nwkAddress: 2, eui64: "0x3", relationship: 3, depth: 1, ...defaults},
1229
+ {lqi: 15, nwkAddress: 3, eui64: "0x4", relationship: 2, depth: 5, ...defaults},
1230
+ ],
1231
+ },
1232
+ ]),
1233
+ );
1234
+ }
1235
+
1236
+ if (lastStartIndex === 2) {
1237
+ lastStartIndex += 2;
1238
+ return waitForResult(
1239
+ mockZdoZpiObject<LQITableResponse>("mgmtLqiRsp", target, [
1240
+ Zdo.Status.SUCCESS,
1241
+ {
1242
+ neighborTableEntries: 5,
1243
+ startIndex: 0,
1244
+ entryList: [
1245
+ {lqi: 10, nwkAddress: 5, eui64: "0x6", relationship: 3, depth: 1, ...defaults},
1246
+ {lqi: 15, nwkAddress: 7, eui64: "0x8", relationship: 2, depth: 5, ...defaults},
1247
+ ],
1248
+ },
1249
+ ]),
1250
+ );
1251
+ }
1252
+
1253
+ if (lastStartIndex === 4) {
1254
+ return waitForResult(
1255
+ mockZdoZpiObject<LQITableResponse>("mgmtLqiRsp", target, [
1256
+ Zdo.Status.SUCCESS,
1257
+ {
1258
+ neighborTableEntries: 5,
1259
+ startIndex: 0,
1260
+ entryList: [{lqi: 10, nwkAddress: 9, eui64: "0x10", relationship: 3, depth: 1, ...defaults}],
1261
+ },
1262
+ ]),
1263
+ );
1264
+ }
1265
+ } else if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "mgmtLqiRsp" && target === 204) {
1266
+ return waitForResult(mockZdoZpiObject<LQITableResponse>("mgmtLqiRsp", target, [Zdo.Status.NOT_AUTHORIZED, undefined]));
1267
+ } else if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "mgmtRtgRsp" && target === 205) {
1268
+ const defaultEntryList = {
1269
+ manyToOne: 0,
1270
+ memoryConstrained: 0,
1271
+ reserved1: 0,
1272
+ routeRecordRequired: 0,
1273
+ status: Zdo.RoutingTableStatus[0] as keyof typeof Zdo.RoutingTableStatus,
1274
+ };
1275
+ if (lastStartIndex === 0) {
1276
+ lastStartIndex += 2;
1277
+ return waitForResult(
1278
+ mockZdoZpiObject<RoutingTableResponse>("mgmtRtgRsp", target, [
1279
+ Zdo.Status.SUCCESS,
1280
+ {
1281
+ startIndex: 0,
1282
+ routingTableEntries: 5,
1283
+ entryList: [
1284
+ {destinationAddress: 10, nextHopAddress: 3, ...defaultEntryList},
1285
+ {destinationAddress: 11, nextHopAddress: 3, ...defaultEntryList},
1286
+ ],
1287
+ },
1288
+ ]),
1289
+ );
1290
+ }
1291
+
1292
+ if (lastStartIndex === 2) {
1293
+ lastStartIndex += 2;
1294
+ return waitForResult(
1295
+ mockZdoZpiObject<RoutingTableResponse>("mgmtRtgRsp", target, [
1296
+ Zdo.Status.SUCCESS,
1297
+ {
1298
+ startIndex: 0,
1299
+ routingTableEntries: 5,
1300
+ entryList: [
1301
+ {destinationAddress: 12, nextHopAddress: 3, ...defaultEntryList},
1302
+ {destinationAddress: 13, nextHopAddress: 3, ...defaultEntryList},
1303
+ ],
1304
+ },
1305
+ ]),
1306
+ );
1307
+ }
1308
+
1309
+ if (lastStartIndex === 4) {
1310
+ return waitForResult(
1311
+ mockZdoZpiObject<RoutingTableResponse>("mgmtRtgRsp", target, [
1312
+ Zdo.Status.SUCCESS,
1313
+ {
1314
+ startIndex: 0,
1315
+ routingTableEntries: 5,
1316
+ entryList: [{destinationAddress: 14, nextHopAddress: 3, ...defaultEntryList}],
1317
+ },
1318
+ ]),
1319
+ );
1320
+ }
1321
+ } else if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "mgmtRtgRsp" && target === 206) {
1322
+ return waitForResult(mockZdoZpiObject<RoutingTableResponse>("mgmtRtgRsp", target, [Zdo.Status.INSUFFICIENT_SPACE, undefined]));
1323
+ } else if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "bindRsp" && target === 301) {
1324
+ return waitForResult(mockZdoZpiObject("bindRsp", target, [bindStatusResponse, undefined]));
1325
+ } else if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "unbindRsp" && target === 301) {
1326
+ return waitForResult(mockZdoZpiObject("unbindRsp", target, [bindStatusResponse, undefined]));
1327
+ } else if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "mgmtLeaveRsp" && target === 401) {
1328
+ return waitForResult(mockZdoZpiObject("mgmtLeaveRsp", target, [Zdo.Status.SUCCESS, undefined]));
1329
+ } else if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "nwkAddrRsp" && target === "0x03") {
1330
+ return waitForResult(
1331
+ mockZdoZpiObject<NetworkAddressResponse>("nwkAddrRsp", target, [
1332
+ Zdo.Status.SUCCESS,
1333
+ {
1334
+ nwkAddress: 3,
1335
+ eui64: "0x03",
1336
+ assocDevList: [],
1337
+ startIndex: 0,
1338
+ },
1339
+ ]),
1340
+ );
1341
+ } else if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "nwkAddrRsp" && target === "0x02") {
1342
+ return waitForResult(
1343
+ mockZdoZpiObject<NetworkAddressResponse>("nwkAddrRsp", target, [
1344
+ Zdo.Status.SUCCESS,
1345
+ {
1346
+ nwkAddress: 2,
1347
+ eui64: "0x02",
1348
+ assocDevList: [],
1349
+ startIndex: 0,
1350
+ },
1351
+ ]),
1352
+ );
1353
+ } else {
1354
+ missing();
1355
+ }
1356
+ });
1357
+ };
1358
+
1359
+ const touchlinkScanRequest = Zcl.Frame.create(
1360
+ Zcl.FrameType.SPECIFIC,
1361
+ Zcl.Direction.CLIENT_TO_SERVER,
1362
+ false,
1363
+ undefined,
1364
+ 12,
1365
+ "scanRequest",
1366
+ Zcl.Utils.getCluster("touchlink", undefined, {}).ID,
1367
+ {transactionID: 1, zigbeeInformation: 4, touchlinkInformation: 18},
1368
+ {},
1369
+ );
1370
+
1371
+ const touchlinkScanResponse = Zcl.Frame.create(
1372
+ Zcl.FrameType.SPECIFIC,
1373
+ Zcl.Direction.SERVER_TO_CLIENT,
1374
+ false,
1375
+ undefined,
1376
+ 12,
1377
+ "scanResponse",
1378
+ Zcl.Utils.getCluster("touchlink", undefined, {}).ID,
1379
+ {
1380
+ transactionID: 1,
1381
+ rssiCorrection: 10,
1382
+ zigbeeInformation: 5,
1383
+ touchlinkInformation: 6,
1384
+ keyBitmask: 12,
1385
+ responseID: 11,
1386
+ extendedPanID: "0x0017210104d9cd33",
1387
+ networkUpdateID: 1,
1388
+ logicalChannel: 12,
1389
+ panID: 13,
1390
+ networkAddress: 5,
1391
+ numberOfSubDevices: 10,
1392
+ totalGroupIdentifiers: 5,
1393
+ },
1394
+ {},
1395
+ );
1396
+
1397
+ const touchlinkIdentifyRequest = Zcl.Frame.create(
1398
+ Zcl.FrameType.SPECIFIC,
1399
+ Zcl.Direction.CLIENT_TO_SERVER,
1400
+ false,
1401
+ undefined,
1402
+ 12,
1403
+ "identifyRequest",
1404
+ Zcl.Utils.getCluster("touchlink", undefined, {}).ID,
1405
+ {transactionID: 1, duration: 65535},
1406
+ {},
1407
+ );
1408
+
1409
+ const getRandomArbitrary = (min, max) => {
1410
+ return Math.random() * (max - min) + min;
1411
+ };
1412
+
1413
+ const getTempFile = () => {
1414
+ const tempPath = path.resolve("temp");
1415
+ if (!fs.existsSync(tempPath)) {
1416
+ fs.mkdirSync(tempPath);
1417
+ }
1418
+ return path.join(tempPath, `temp_${getRandomArbitrary(1, 99999999)}`);
1419
+ };
1420
+
1421
+ let znpReceived;
1422
+ let znpClose;
1423
+ let dataConfirmCode = 0;
1424
+ let dataConfirmCodeReset = false;
1425
+ let nodeDescRspErrorOnce = false;
1426
+ let dataRequestCode = 0;
1427
+ let dataRequestExtCode = 0;
1428
+ let lastStartIndex = 0;
1429
+ let simpleDescriptorEndpoint = 0;
1430
+ let assocGetWithAddressNodeRelation;
1431
+
1432
+ vi.mock("../../../src/adapter/z-stack/znp/znp", () => ({
1433
+ Znp: vi.fn(() => ({
1434
+ on: (event, handler) => {
1435
+ if (event === "received") {
1436
+ znpReceived = handler;
1437
+ } else if (event === "close") {
1438
+ znpClose = handler;
1439
+ }
1440
+ },
1441
+ open: mockZnpOpen,
1442
+ request: mockZnpRequest,
1443
+ requestZdo: mockZnpRequestZdo,
1444
+ requestWithReply: mockZnpRequest,
1445
+ waitFor: mockZnpWaitFor,
1446
+ close: mockZnpClose,
1447
+ })),
1448
+ }));
1449
+
1450
+ vi.mock("../../../src/utils/queue", () => ({
1451
+ Queue: vi.fn(() => ({
1452
+ execute: mockQueueExecute,
1453
+ count: () => 1,
1454
+ })),
1455
+ }));
1456
+
1457
+ const mocksClear = [mockLogger.debug, mockLogger.info, mockLogger.warning, mockLogger.error];
1458
+
1459
+ describe("zstack-adapter", () => {
1460
+ let adapter: ZStackAdapter;
1461
+
1462
+ beforeAll(() => {
1463
+ setLogger(mockLogger);
1464
+ });
1465
+
1466
+ afterAll(() => {
1467
+ vi.useRealTimers();
1468
+ });
1469
+
1470
+ beforeEach(() => {
1471
+ vi.useRealTimers();
1472
+ vi.useFakeTimers();
1473
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, "backup.json", {concurrent: 3});
1474
+ mockZnpWaitForDefault();
1475
+ for (const m of mocks) m.mockRestore();
1476
+ for (const m of mocksClear) m.mockClear();
1477
+ mockQueueExecute.mockClear();
1478
+ mockZnpWaitFor.mockClear();
1479
+ dataConfirmCode = 0;
1480
+ dataRequestCode = 0;
1481
+ dataRequestExtCode = 0;
1482
+ bindStatusResponse = 0;
1483
+ assocGetWithAddressNodeRelation = 1;
1484
+ networkOptions.networkKeyDistribute = false;
1485
+ dataConfirmCodeReset = false;
1486
+ nodeDescRspErrorOnce = false;
1487
+ lastStartIndex = 0;
1488
+ simpleDescriptorEndpoint = 0;
1489
+ });
1490
+
1491
+ it("should commission network with 3.0.x adapter", async () => {
1492
+ mockZnpRequestWith(empty3AlignedRequestMock);
1493
+ const result = await adapter.start();
1494
+ expect(result).toBe("reset");
1495
+ });
1496
+
1497
+ it("should commission network with 3.0.x adapter - auto concurrency", async () => {
1498
+ mockZnpRequestWith(empty3AlignedRequestMock);
1499
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, "backup.json", {});
1500
+ const result = await adapter.start();
1501
+ expect(result).toBe("reset");
1502
+ });
1503
+
1504
+ it("should commission network with 3.x.0 adapter - auto concurrency", async () => {
1505
+ mockZnpRequestWith(empty3x0AlignedRequestMock);
1506
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, "backup.json", {});
1507
+ const result = await adapter.start();
1508
+ expect(result).toBe("reset");
1509
+ });
1510
+
1511
+ it("should commission network with 3.0.x adapter - unaligned 8-bit", async () => {
1512
+ mockZnpRequestWith(empty3UnalignedRequestMock);
1513
+ const result = await adapter.start();
1514
+ expect(result).toBe("reset");
1515
+ });
1516
+
1517
+ it("should commission network with 3.0.x adapter - default extended pan id", async () => {
1518
+ mockZnpRequestWith(empty3AlignedRequestMock);
1519
+ adapter = new ZStackAdapter(networkOptionsDefaultExtendedPanId, serialPortOptions, "backup.json", {concurrent: 3});
1520
+ const result = await adapter.start();
1521
+ expect(result).toBe("reset");
1522
+ });
1523
+
1524
+ it("should commission with 3.0.x adapter - empty, mismatched config/backup", async () => {
1525
+ const backupFile = getTempFile();
1526
+ fs.writeFileSync(backupFile, JSON.stringify(backupNotMatchingConfig), "utf8");
1527
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1528
+ mockZnpRequestWith(empty3AlignedRequestMock);
1529
+ const result = await adapter.start();
1530
+ expect(result).toBe("reset");
1531
+ });
1532
+
1533
+ it("should commission with 3.0.x adapter - commissioned, mismatched adapter-config-backup", async () => {
1534
+ const backupFile = getTempFile();
1535
+ fs.writeFileSync(backupFile, JSON.stringify(backupNotMatchingConfig), "utf8");
1536
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1537
+ mockZnpRequestWith(commissioned3AlignedConfigMistmachRequestMock);
1538
+ const result = await adapter.start();
1539
+ expect(result).toBe("reset");
1540
+ });
1541
+
1542
+ it("should fail to commission network with 3.0.x adapter with invalid pan id 65535", async () => {
1543
+ mockZnpRequestWith(empty3AlignedRequestMock);
1544
+ adapter = new ZStackAdapter(networkOptionsInvalidPanId, serialPortOptions, "backup.json", {concurrent: 3});
1545
+ await expect(adapter.start()).rejects.toThrowError("network commissioning failed - cannot use pan id 65535");
1546
+ });
1547
+
1548
+ it("should fail to commission network with 3.0.x adapter when bdb commissioning times out", async () => {
1549
+ mockZnpWaitForStateChangeIndTimeout();
1550
+ mockZnpRequestWith(empty3AlignedRequestMock);
1551
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, "backup.json", {concurrent: 3});
1552
+ await expect(adapter.start()).rejects.toThrowError(
1553
+ "network commissioning timed out - most likely network with the same panId or extendedPanId already exists nearby",
1554
+ );
1555
+ });
1556
+
1557
+ it("should fail to commission network with 3.0.x adapter when nib fails to settle", async () => {
1558
+ mockZnpRequestWith(empty3AlignedRequestMock.clone().handle(Subsystem.APP_CNF, "bdbStartCommissioning", () => ({})));
1559
+ vi.setConfig({testTimeout: 35000});
1560
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, "backup.json", {concurrent: 3});
1561
+ const promise = adapter.start();
1562
+ await expect(promise).rejects.toThrowError("network commissioning failed - timed out waiting for nib to settle");
1563
+ });
1564
+
1565
+ it("should fail to commission network with 3.0.x adapter when nib reports different pan id", async () => {
1566
+ mockZnpRequestWith(
1567
+ empty3AlignedRequestMock.clone().handle(Subsystem.APP_CNF, "bdbStartCommissioning", (_, handler) => {
1568
+ const nibIndex = handler.nvItems.findIndex((e) => e.id === NvItemsIds.NIB);
1569
+ if (nibIndex > -1) {
1570
+ handler.nvItems.splice(nibIndex, 1);
1571
+ }
1572
+ handler.nvItems.push({
1573
+ id: NvItemsIds.NIB,
1574
+ value: Buffer.from(
1575
+ "fb050279147900640000000105018f000700020d1e0000001500000000000000000000007c000800000020000f0f0400010000000100000000779fd609004b1200010000000000000000000000000000000000000000000000000000000000000000000000003c0c0001780a0100000006020000",
1576
+ "hex",
1577
+ ),
1578
+ });
1579
+ return {};
1580
+ }),
1581
+ );
1582
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, "backup.json", {concurrent: 3});
1583
+ const promise = adapter.start();
1584
+ await expect(promise).rejects.toThrowError("network commissioning failed - panId collision detected (expected=123, actual=124)");
1585
+ });
1586
+
1587
+ it("should start network with 3.0.x adapter", async () => {
1588
+ mockZnpRequestWith(commissioned3AlignedRequestMock);
1589
+ const result = await adapter.start();
1590
+ expect(result).toBe("resumed");
1591
+ });
1592
+
1593
+ it("should restore unified backup with 3.0.x adapter and create backup - empty", async () => {
1594
+ const backupFile = getTempFile();
1595
+ fs.writeFileSync(backupFile, JSON.stringify(backupMatchingConfig), "utf8");
1596
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1597
+ mockZnpRequestWith(empty3AlignedRequestMock);
1598
+ const result = await adapter.start();
1599
+ expect(result).toBe("restored");
1600
+
1601
+ await adapter.backup([]);
1602
+ });
1603
+
1604
+ it("should restore unified backup with 3.0.x adapter and create backup - no tclk seed", async () => {
1605
+ const backupFile = getTempFile();
1606
+ const backup = JSON.parse(JSON.stringify(backupMatchingConfig));
1607
+ delete backup.stack_specific.zstack;
1608
+ fs.writeFileSync(backupFile, JSON.stringify(backup), "utf8");
1609
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1610
+ mockZnpRequestWith(empty3AlignedRequestMock);
1611
+ const result = await adapter.start();
1612
+ expect(result).toBe("restored");
1613
+
1614
+ await adapter.backup([]);
1615
+ });
1616
+
1617
+ it("should restore unified backup with 3.x.0 adapter and create backup - empty", async () => {
1618
+ const backupFile = getTempFile();
1619
+ fs.writeFileSync(backupFile, JSON.stringify(backupMatchingConfig), "utf8");
1620
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1621
+ mockZnpRequestWith(empty3x0AlignedRequestMock);
1622
+ const result = await adapter.start();
1623
+ expect(result).toBe("restored");
1624
+
1625
+ await adapter.backup([]);
1626
+ });
1627
+
1628
+ it("should (recommission) restore unified backup with 1.2 adapter and create backup - empty", async () => {
1629
+ const backupFile = getTempFile();
1630
+ fs.writeFileSync(backupFile, JSON.stringify(backupMatchingConfig12), "utf8");
1631
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 1});
1632
+ mockZnpRequestWith(empty12UnalignedRequestMock);
1633
+ const result = await adapter.start();
1634
+ expect(result).toBe("restored");
1635
+
1636
+ const backup = await adapter.backup([]);
1637
+ expect(backup.networkKeyInfo.frameCounter).toBe(0);
1638
+ });
1639
+
1640
+ it("should create backup with 3.0.x adapter - default security material table entry", async () => {
1641
+ const builder = commissioned3AlignedRequestMock.clone();
1642
+ mockZnpRequestWith(builder);
1643
+ const result = await adapter.start();
1644
+ expect(result).toBe("resumed");
1645
+ for (let i = 0; i < 4; i++) {
1646
+ builder.nv(NvItemsIds.LEGACY_NWK_SEC_MATERIAL_TABLE_START + i, Buffer.from("000000000000000000000000", "hex"));
1647
+ }
1648
+
1649
+ const secMaterialTableEntry = Structs.nwkSecMaterialDescriptorEntry();
1650
+ secMaterialTableEntry.extendedPanID = Buffer.alloc(8, 0xff);
1651
+ secMaterialTableEntry.FrameCounter = 2800;
1652
+ builder.nv(NvItemsIds.LEGACY_NWK_SEC_MATERIAL_TABLE_START + 0, secMaterialTableEntry.serialize("aligned"));
1653
+ mockZnpRequestWith(builder);
1654
+
1655
+ const backup = await adapter.backup([]);
1656
+ expect(backup.networkKeyInfo.frameCounter).toBe(2800);
1657
+ });
1658
+
1659
+ it("should create backup with 3.0.x adapter - emnpty security material table", async () => {
1660
+ const builder = commissioned3AlignedRequestMock.clone();
1661
+ mockZnpRequestWith(builder);
1662
+ const result = await adapter.start();
1663
+ expect(result).toBe("resumed");
1664
+ for (let i = 0; i < 4; i++) {
1665
+ builder.nv(NvItemsIds.LEGACY_NWK_SEC_MATERIAL_TABLE_START + i, Buffer.from("000000000000000000000000", "hex"));
1666
+ }
1667
+ mockZnpRequestWith(builder);
1668
+
1669
+ const backup = await adapter.backup([]);
1670
+ expect(backup.networkKeyInfo.frameCounter).toBe(1250);
1671
+ });
1672
+
1673
+ it("should create backup with 3.0.x adapter - security material table with generic record", async () => {
1674
+ const builder = commissioned3AlignedRequestMock.clone();
1675
+ mockZnpRequestWith(builder);
1676
+ const result = await adapter.start();
1677
+ expect(result).toBe("resumed");
1678
+ for (let i = 0; i < 4; i++) {
1679
+ builder.nv(NvItemsIds.LEGACY_NWK_SEC_MATERIAL_TABLE_START + i, Buffer.from("000000000000000000000000", "hex"));
1680
+ }
1681
+ const genericEntry = Structs.nwkSecMaterialDescriptorEntry();
1682
+ genericEntry.extendedPanID = Buffer.from("ffffffffffffffff", "hex");
1683
+ genericEntry.FrameCounter = 8737;
1684
+ builder.nv(NvItemsIds.LEGACY_NWK_SEC_MATERIAL_TABLE_START + 3, genericEntry.serialize("aligned"));
1685
+ mockZnpRequestWith(builder);
1686
+
1687
+ const backup = await adapter.backup([]);
1688
+ expect(backup.networkKeyInfo.frameCounter).toBe(8737);
1689
+ });
1690
+
1691
+ it("should create backup with 1.2 adapter", async () => {
1692
+ mockZnpRequestWith(commissioned12UnalignedRequestMock);
1693
+ const result = await adapter.start();
1694
+ expect(result).toBe("resumed");
1695
+
1696
+ const backup = await adapter.backup([]);
1697
+ expect(backup.networkKeyInfo.frameCounter).toBe(0);
1698
+ });
1699
+
1700
+ it("should keep missing devices in backup", async () => {
1701
+ const backupFile = getTempFile();
1702
+ const backupWithMissingDevice = JSON.parse(JSON.stringify(backupMatchingConfig));
1703
+ backupWithMissingDevice.devices.push({
1704
+ nwk_address: "20fa",
1705
+ ieee_address: "00128d11124fa80b",
1706
+ link_key: {
1707
+ key: "bff550908aa1529ee90eea3c3bdc26fc",
1708
+ rx_counter: 0,
1709
+ tx_counter: 2,
1710
+ },
1711
+ });
1712
+ fs.writeFileSync(backupFile, JSON.stringify(backupMatchingConfig), "utf8");
1713
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1714
+ mockZnpRequestWith(empty3AlignedRequestMock);
1715
+ await adapter.start();
1716
+ fs.writeFileSync(backupFile, JSON.stringify(backupWithMissingDevice), "utf8");
1717
+ const devicesInDatabase = backupWithMissingDevice.devices.map((d) => ZSpec.Utils.eui64BEBufferToHex(d.ieee_address));
1718
+ const backup = await adapter.backup(devicesInDatabase);
1719
+ const missingDevice = backup.devices.find((d) => d.ieeeAddress.toString("hex") === "00128d11124fa80b");
1720
+ expect(missingDevice).not.toBeNull();
1721
+ expect(backupWithMissingDevice.devices.length).toBe(backup.devices.length);
1722
+ expect(missingDevice?.linkKey?.key.toString("hex")).toBe("bff550908aa1529ee90eea3c3bdc26fc");
1723
+ });
1724
+
1725
+ it("should fail when backup file is corrupted - Coordinator backup is corrupted", async () => {
1726
+ const backupFile = getTempFile();
1727
+ fs.writeFileSync(backupFile, "{", "utf8");
1728
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1729
+ mockZnpRequestWith(empty3AlignedRequestMock);
1730
+ await expect(adapter.start()).rejects.toThrowError("Coordinator backup is corrupted");
1731
+ });
1732
+
1733
+ it("should fail to restore unified backup with 3.0.x adapter - invalid open coordinator backup version", async () => {
1734
+ const backupFile = getTempFile();
1735
+ let backupData: UnifiedBackupStorage = JSON.parse(JSON.stringify(backupMatchingConfig));
1736
+ backupData = {
1737
+ ...backupData,
1738
+ metadata: {
1739
+ ...backupData.metadata,
1740
+ // biome-ignore lint/suspicious/noExplicitAny: mock
1741
+ version: 99 as any,
1742
+ },
1743
+ };
1744
+
1745
+ fs.writeFileSync(backupFile, JSON.stringify(backupData), "utf8");
1746
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1747
+ mockZnpRequestWith(empty3AlignedRequestMock);
1748
+ await expect(adapter.start()).rejects.toThrowError("Unsupported open coordinator backup version (version=99)");
1749
+ });
1750
+
1751
+ it("should fail to restore (unified) backup with 3.0.x adapter - unsupported backup format", async () => {
1752
+ const backupFile = getTempFile();
1753
+ let backupData: UnifiedBackupStorage = JSON.parse(JSON.stringify(backupMatchingConfig));
1754
+ backupData = {
1755
+ ...backupData,
1756
+ metadata: {
1757
+ ...backupData.metadata,
1758
+ version: undefined,
1759
+ },
1760
+ };
1761
+
1762
+ fs.writeFileSync(backupFile, JSON.stringify(backupData), "utf8");
1763
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1764
+ mockZnpRequestWith(empty3AlignedRequestMock);
1765
+ await expect(adapter.start()).rejects.toThrowError("Unknown backup format");
1766
+ });
1767
+
1768
+ it("should fail to restore unified backup with 3.0.x adapter - insufficient tclk table size", async () => {
1769
+ const backupFile = getTempFile();
1770
+ const backupData: UnifiedBackupStorage = JSON.parse(JSON.stringify(backupMatchingConfig));
1771
+ fs.writeFileSync(backupFile, JSON.stringify(backupData), "utf8");
1772
+
1773
+ const builder = empty3AlignedRequestMock.clone();
1774
+ for (let i = 0; i < 16; i++) {
1775
+ builder.nv(NvItemsIds.LEGACY_TCLK_TABLE_START + i, null);
1776
+ }
1777
+ builder.nv(NvItemsIds.LEGACY_TCLK_TABLE_START + 0, Buffer.from("0000000000000000000000000000000000000000", "hex"));
1778
+ mockZnpRequestWith(builder);
1779
+
1780
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1781
+ await expect(adapter.start()).rejects.toThrowError("target adapter tclk table size insufficient (size=1)");
1782
+ });
1783
+
1784
+ it("should fail to restore unified backup with 3.0.x adapter - insufficient aps link key data table size", async () => {
1785
+ const backupFile = getTempFile();
1786
+ const backupData: UnifiedBackupStorage = JSON.parse(JSON.stringify(backupMatchingConfig));
1787
+ fs.writeFileSync(backupFile, JSON.stringify(backupData), "utf8");
1788
+
1789
+ const builder = empty3AlignedRequestMock.clone();
1790
+ for (let i = 0; i < 16; i++) {
1791
+ builder.nv(NvItemsIds.APS_LINK_KEY_DATA_START + i, null);
1792
+ }
1793
+ builder.nv(NvItemsIds.APS_LINK_KEY_DATA_START + 0, Buffer.from("000000000000000000000000000000000000000000000000", "hex"));
1794
+ mockZnpRequestWith(builder);
1795
+
1796
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1797
+ await expect(adapter.start()).rejects.toThrowError("target adapter aps link key data table size insufficient (size=1)");
1798
+ });
1799
+
1800
+ it("should fail to restore unified backup with 3.0.x adapter - insufficient security manager table size", async () => {
1801
+ const backupFile = getTempFile();
1802
+ const backupData: UnifiedBackupStorage = JSON.parse(JSON.stringify(backupMatchingConfig));
1803
+ fs.writeFileSync(backupFile, JSON.stringify(backupData), "utf8");
1804
+
1805
+ const builder = empty3AlignedRequestMock.clone();
1806
+ builder.nv(NvItemsIds.APS_LINK_KEY_TABLE, Buffer.from("0000feff00000000", "hex"));
1807
+ mockZnpRequestWith(builder);
1808
+
1809
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1810
+ await expect(adapter.start()).rejects.toThrowError("target adapter security manager table size insufficient (size=1)");
1811
+ });
1812
+
1813
+ it("should fail to restore unified backup with 1.2 adapter - backup from newer adapter", async () => {
1814
+ const backupFile = getTempFile();
1815
+ const backupData: UnifiedBackupStorage = JSON.parse(JSON.stringify(backupMatchingConfig));
1816
+ fs.writeFileSync(backupFile, JSON.stringify(backupData), "utf8");
1817
+
1818
+ mockZnpRequestWith(empty12UnalignedRequestMock);
1819
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1820
+ await expect(adapter.start()).rejects.toThrowError(
1821
+ "your backup is from newer platform version (Z-Stack 3.0.x+) and cannot be restored onto Z-Stack 1.2 adapter - please remove backup before proceeding",
1822
+ );
1823
+ });
1824
+
1825
+ it("should fail to create backup with 3.0.x adapter - unable to read ieee address", async () => {
1826
+ mockZnpRequestWith(commissioned3AlignedRequestMock.clone().handle(Subsystem.SYS, "getExtAddr", () => ({payload: {}})));
1827
+ const result = await adapter.start();
1828
+ expect(result).toBe("resumed");
1829
+ await expect(adapter.backup([])).rejects.toThrowError("Failed to read adapter IEEE address");
1830
+ });
1831
+
1832
+ it("should fail to create backup with 3.0.x adapter - adapter not commissioned - missing nib", async () => {
1833
+ const builder = empty3AlignedRequestMock.clone();
1834
+ mockZnpRequestWith(builder);
1835
+ const result = await adapter.start();
1836
+ expect(result).toBe("reset");
1837
+ builder.nv(NvItemsIds.NIB, null);
1838
+ mockZnpRequestWith(builder);
1839
+ await expect(adapter.backup([])).rejects.toThrowError("Cannot backup - adapter not commissioned");
1840
+ });
1841
+
1842
+ it("should fail to create backup with 3.0.x adapter - missing active key info", async () => {
1843
+ const builder = empty3AlignedRequestMock.clone();
1844
+ mockZnpRequestWith(builder);
1845
+ const result = await adapter.start();
1846
+ expect(result).toBe("reset");
1847
+ builder.nv(NvItemsIds.NWK_ACTIVE_KEY_INFO, null);
1848
+ mockZnpRequestWith(builder);
1849
+ await expect(adapter.backup([])).rejects.toThrowError("Cannot backup - missing active key info");
1850
+ });
1851
+
1852
+ it("should restore legacy backup with 3.0.x adapter - empty", async () => {
1853
+ const backupFile = getTempFile();
1854
+ fs.writeFileSync(backupFile, JSON.stringify(legacyBackup), "utf8");
1855
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1856
+ mockZnpRequestWith(empty3AlignedRequestMock);
1857
+ const result = await adapter.start();
1858
+ expect(result).toBe("restored");
1859
+ });
1860
+
1861
+ it("should fail to restore legacy backup with 3.0.x adapter - missing NIB", async () => {
1862
+ const backupFile = getTempFile();
1863
+ const backup = JSON.parse(JSON.stringify(legacyBackup));
1864
+ delete backup.data.ZCD_NV_NIB;
1865
+ fs.writeFileSync(backupFile, JSON.stringify(backup), "utf8");
1866
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1867
+ mockZnpRequestWith(empty3AlignedRequestMock);
1868
+ await expect(adapter.start()).rejects.toThrowError("Backup corrupted - missing NIB");
1869
+ });
1870
+
1871
+ it("should fail to restore legacy backup with 3.0.x adapter - missing active key info", async () => {
1872
+ const backupFile = getTempFile();
1873
+ const backup = JSON.parse(JSON.stringify(legacyBackup));
1874
+ delete backup.data.ZCD_NV_NWK_ACTIVE_KEY_INFO;
1875
+ fs.writeFileSync(backupFile, JSON.stringify(backup), "utf8");
1876
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1877
+ mockZnpRequestWith(empty3AlignedRequestMock);
1878
+ await expect(adapter.start()).rejects.toThrowError("Backup corrupted - missing active key info");
1879
+ });
1880
+
1881
+ it("should fail to restore legacy backup with 3.0.x adapter - missing pre-configured key enabled", async () => {
1882
+ const backupFile = getTempFile();
1883
+ const backup = JSON.parse(JSON.stringify(legacyBackup));
1884
+ delete backup.data.ZCD_NV_PRECFGKEY_ENABLE;
1885
+ fs.writeFileSync(backupFile, JSON.stringify(backup), "utf8");
1886
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1887
+ mockZnpRequestWith(empty3AlignedRequestMock);
1888
+ await expect(adapter.start()).rejects.toThrowError("Backup corrupted - missing pre-configured key enable attribute");
1889
+ });
1890
+
1891
+ it("should fail to restore legacy backup with 3.0.x adapter - pre-configured key enabled", async () => {
1892
+ const backupFile = getTempFile();
1893
+ const backup = JSON.parse(JSON.stringify(legacyBackup));
1894
+ delete backup.data.ZCD_NV_EX_NWK_SEC_MATERIAL_TABLE;
1895
+ delete backup.data.ZCD_NV_LEGACY_NWK_SEC_MATERIAL_TABLE_START;
1896
+ fs.writeFileSync(backupFile, JSON.stringify(backup), "utf8");
1897
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1898
+ mockZnpRequestWith(empty3AlignedRequestMock);
1899
+ await expect(adapter.start()).rejects.toThrowError("Backup corrupted - missing network security material table");
1900
+ });
1901
+
1902
+ it("should fail to restore legacy backup with 3.0.x adapter - missing adapter ieee address", async () => {
1903
+ const backupFile = getTempFile();
1904
+ const backup = JSON.parse(JSON.stringify(legacyBackup));
1905
+ delete backup.data.ZCD_NV_EXTADDR;
1906
+ fs.writeFileSync(backupFile, JSON.stringify(backup), "utf8");
1907
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1908
+ mockZnpRequestWith(empty3AlignedRequestMock);
1909
+ await expect(adapter.start()).rejects.toThrow("Backup corrupted - missing adapter IEEE address NV entry");
1910
+ });
1911
+
1912
+ it("should fail to start with 3.0.x adapter - commissioned, config-adapter mismatch", async () => {
1913
+ const backupFile = getTempFile();
1914
+ fs.writeFileSync(backupFile, JSON.stringify(backupMatchingConfig), "utf8");
1915
+
1916
+ adapter = new ZStackAdapter(networkOptionsMismatched, serialPortOptions, backupFile, {concurrent: 3});
1917
+ mockZnpRequestWith(commissioned3AlignedRequestMock);
1918
+ await expect(adapter.start()).rejects.toThrow("startup failed - configuration-adapter mismatch - see logs above for more information");
1919
+ expect(mockLogger.error.mock.calls[0][0]).toBe("Configuration is not consistent with adapter state/backup!");
1920
+ expect(mockLogger.error.mock.calls[1][0]).toBe("- PAN ID: configured=124, adapter=123");
1921
+ expect(mockLogger.error.mock.calls[2][0]).toBe("- Extended PAN ID: configured=00124b0009d69f77, adapter=00124b0009d69f77");
1922
+ expect(mockLogger.error.mock.calls[3][0]).toBe(
1923
+ "- Network Key: configured=01030507090b0d0f00020406080a0c0d, adapter:active=01030507090b0d0f00020406080a0c0d adapter:preconfigured=01030507090b0d0f00020406080a0c0d, adapter:alternate=01030507090b0d0f00020406080a0c0d",
1924
+ );
1925
+ expect(mockLogger.error.mock.calls[4][0]).toBe("- Channel List: configured=21, adapter=21");
1926
+ expect(mockLogger.error.mock.calls[5][0]).toBe("Please update configuration to prevent further issues.");
1927
+ expect(mockLogger.error.mock.calls[6][0]).toMatch(
1928
+ `If you wish to re-commission your network, please remove coordinator backup at ${backupFile}`,
1929
+ );
1930
+ expect(mockLogger.error.mock.calls[7][0]).toBe("Re-commissioning your network will require re-pairing of all devices!");
1931
+ });
1932
+
1933
+ it("should start with runInconsistent option with 3.0.x adapter - commissioned, config-adapter mismatch", async () => {
1934
+ const backupFile = getTempFile();
1935
+ fs.writeFileSync(backupFile, JSON.stringify(backupMatchingConfig), "utf8");
1936
+
1937
+ adapter = new ZStackAdapter(networkOptionsMismatched, serialPortOptions, backupFile, {
1938
+ concurrent: 3,
1939
+ forceStartWithInconsistentAdapterConfiguration: true,
1940
+ });
1941
+ mockZnpRequestWith(commissioned3AlignedRequestMock);
1942
+ const result = await adapter.start();
1943
+ expect(result).toBe("resumed");
1944
+ expect(mockLogger.error.mock.calls[0][0]).toBe("Configuration is not consistent with adapter state/backup!");
1945
+ expect(mockLogger.error.mock.calls[1][0]).toBe("- PAN ID: configured=124, adapter=123");
1946
+ expect(mockLogger.error.mock.calls[2][0]).toBe("- Extended PAN ID: configured=00124b0009d69f77, adapter=00124b0009d69f77");
1947
+ expect(mockLogger.error.mock.calls[3][0]).toBe(
1948
+ "- Network Key: configured=01030507090b0d0f00020406080a0c0d, adapter:active=01030507090b0d0f00020406080a0c0d adapter:preconfigured=01030507090b0d0f00020406080a0c0d, adapter:alternate=01030507090b0d0f00020406080a0c0d",
1949
+ );
1950
+ expect(mockLogger.error.mock.calls[4][0]).toBe("- Channel List: configured=21, adapter=21");
1951
+ expect(mockLogger.error.mock.calls[5][0]).toBe("Please update configuration to prevent further issues.");
1952
+ expect(mockLogger.error.mock.calls[6][0]).toMatch(
1953
+ `If you wish to re-commission your network, please remove coordinator backup at ${backupFile}`,
1954
+ );
1955
+ expect(mockLogger.error.mock.calls[7][0]).toBe("Re-commissioning your network will require re-pairing of all devices!");
1956
+ expect(mockLogger.error.mock.calls[8][0]).toBe(
1957
+ "Running despite adapter configuration mismatch as configured. Please update the adapter to compatible firmware and recreate your network as soon as possible.",
1958
+ );
1959
+ });
1960
+
1961
+ it("should start with 3.0.x adapter - backward-compat - reversed extended pan id", async () => {
1962
+ const backupFile = getTempFile();
1963
+ fs.writeFileSync(backupFile, JSON.stringify(backupMatchingConfig), "utf8");
1964
+
1965
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1966
+ const nib = Structs.nib(Buffer.from(commissioned3AlignedRequestMock.nvItems.find((item) => item.id === NvItemsIds.NIB).value));
1967
+ nib.extendedPANID = nib.extendedPANID.reverse();
1968
+ mockZnpRequestWith(commissioned3AlignedRequestMock.clone().nv(NvItemsIds.NIB, nib.serialize()));
1969
+ const result = await adapter.start();
1970
+ expect(result).toBe("resumed");
1971
+ expect(mockLogger.warning.mock.calls[0][0]).toBe("Extended PAN ID is reversed (expected=00124b0009d69f77, actual=779fd609004b1200)");
1972
+ });
1973
+
1974
+ it("should restore unified backup with 3.0.x adapter - commissioned, mismatched adapter-config, matching config-backup", async () => {
1975
+ const backupFile = getTempFile();
1976
+ fs.writeFileSync(backupFile, JSON.stringify(backupMatchingConfig), "utf8");
1977
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, backupFile, {concurrent: 3});
1978
+ mockZnpRequestWith(commissioned3AlignedConfigMistmachRequestMock);
1979
+ const result = await adapter.start();
1980
+ expect(result).toBe("restored");
1981
+ });
1982
+
1983
+ it("should start network with 3.0.x adapter - resume in coordinator mode", async () => {
1984
+ mockZnpRequestWith(
1985
+ commissioned3AlignedRequestMock.clone().handle(Subsystem.UTIL, "getDeviceInfo", () => ({payload: {devicestate: DevStates.ZB_COORD}})),
1986
+ );
1987
+ mockZnpWaitFor.mockImplementation((type, subsystem, command, target, transid, state, timeout) => {
1988
+ const missing = () => {
1989
+ const msg = `Not implemented - ${Type[type]} - ${Subsystem[subsystem]} - ${command} - ${target} - ${transid} - ${state} - ${timeout}`;
1990
+ console.log(msg);
1991
+ throw new Error(msg);
1992
+ };
1993
+
1994
+ if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "activeEpRsp") {
1995
+ return waitForResult(
1996
+ mockZdoZpiObject<ActiveEndpointsResponse>("activeEpRsp", target, [
1997
+ Zdo.Status.SUCCESS,
1998
+ {
1999
+ nwkAddress: 0,
2000
+ endpointList: [1, 2, 3],
2001
+ },
2002
+ ]),
2003
+ );
2004
+ }
2005
+
2006
+ if (type === Type.AREQ && subsystem === Subsystem.ZDO && command === "stateChangeInd") {
2007
+ return waitForResult({payload: {state: 9}});
2008
+ }
2009
+
2010
+ missing();
2011
+ });
2012
+ const result = await adapter.start();
2013
+ expect(result).toBe("resumed");
2014
+ });
2015
+
2016
+ it("should start network with 3.0.x adapter - resume in coordinator mode, extGroupFind failed", async () => {
2017
+ mockZnpRequestWith(
2018
+ commissioned3AlignedRequestMock
2019
+ .clone()
2020
+ .handle(Subsystem.UTIL, "getDeviceInfo", () => ({payload: {devicestate: DevStates.ZB_COORD}}))
2021
+ .handle(Subsystem.ZDO, "extFindGroup", () => ({payload: {status: 1}})),
2022
+ );
2023
+ const result = await adapter.start();
2024
+ expect(result).toBe("resumed");
2025
+ });
2026
+
2027
+ it("should commission network with 1.2 adapter", async () => {
2028
+ mockZnpRequestWith(empty12UnalignedRequestMock);
2029
+ const result = await adapter.start();
2030
+ expect(result).toBe("restored");
2031
+ });
2032
+
2033
+ it("should commission network with 1.2 adapter - default extended pan id", async () => {
2034
+ mockZnpRequestWith(empty12UnalignedRequestMock);
2035
+ adapter = new ZStackAdapter(networkOptionsDefaultExtendedPanId, serialPortOptions, "backup.json", {concurrent: 3});
2036
+ const result = await adapter.start();
2037
+ expect(result).toBe("restored");
2038
+ });
2039
+
2040
+ it("should commission network with 1.2 adapter - old adapter without version reporting", async () => {
2041
+ mockZnpRequestWith(empty12UnalignedRequestMock.clone().handle(Subsystem.SYS, "version", () => undefined));
2042
+ const result = await adapter.start();
2043
+ expect(result).toBe("restored");
2044
+ });
2045
+
2046
+ it("should reset network with 1.2 adapter - config mismtach", async () => {
2047
+ mockZnpRequestWith(commissioned12UnalignedMismatchRequestMock);
2048
+ const result = await adapter.start();
2049
+ expect(result).toBe("reset");
2050
+ });
2051
+
2052
+ it("Add install code: Install Code + CRC", async () => {
2053
+ basicMocks();
2054
+ await adapter.start();
2055
+ await adapter.addInstallCode(
2056
+ "0x9035EAFFFE424783",
2057
+ Buffer.from([0xae, 0x3b, 0x28, 0x72, 0x81, 0xcf, 0x16, 0xf5, 0x50, 0x73, 0x3a, 0x0c, 0xec, 0x38, 0xaa, 0x31, 0xe8, 0x02]),
2058
+ false,
2059
+ );
2060
+ const payload = {
2061
+ installCodeFormat: 0x1,
2062
+ ieeeaddr: "0x9035EAFFFE424783",
2063
+ installCode: Buffer.from([0xae, 0x3b, 0x28, 0x72, 0x81, 0xcf, 0x16, 0xf5, 0x50, 0x73, 0x3a, 0x0c, 0xec, 0x38, 0xaa, 0x31, 0xe8, 0x02]),
2064
+ };
2065
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.APP_CNF, "bdbAddInstallCode", payload);
2066
+ });
2067
+
2068
+ it("Add install code: Key derived from Install Code", async () => {
2069
+ basicMocks();
2070
+ await adapter.start();
2071
+ await adapter.addInstallCode(
2072
+ "0x9035EAFFFE424783",
2073
+ Buffer.from([0xae, 0x3b, 0x28, 0x72, 0x81, 0xcf, 0x16, 0xf5, 0x50, 0x73, 0x3a, 0x0c, 0xec, 0x38, 0xaa, 0x31]),
2074
+ true,
2075
+ );
2076
+ const payload = {
2077
+ installCodeFormat: 0x2,
2078
+ ieeeaddr: "0x9035EAFFFE424783",
2079
+ installCode: Buffer.from([0xae, 0x3b, 0x28, 0x72, 0x81, 0xcf, 0x16, 0xf5, 0x50, 0x73, 0x3a, 0x0c, 0xec, 0x38, 0xaa, 0x31]),
2080
+ };
2081
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.APP_CNF, "bdbAddInstallCode", payload);
2082
+ });
2083
+
2084
+ it("LED behaviour: disable LED true, firmware not handling leds", async () => {
2085
+ basicMocks();
2086
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, "backup.json", {disableLED: true});
2087
+ await adapter.start();
2088
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.UTIL, "ledControl", {ledid: 3, mode: 0}, undefined, 500);
2089
+ mockZnpRequest.mockClear();
2090
+ mockQueueExecute.mockClear();
2091
+ await adapter.permitJoin(255, 0);
2092
+ expect(mockZnpRequest).not.toHaveBeenCalledWith(Subsystem.UTIL, "ledControl", expect.any(Object), undefined, 500);
2093
+ mockZnpRequest.mockClear();
2094
+ mockQueueExecute.mockClear();
2095
+ await adapter.permitJoin(0, 0);
2096
+ expect(mockZnpRequest).not.toHaveBeenCalledWith(Subsystem.UTIL, "ledControl", expect.any(Object), undefined, 500);
2097
+ });
2098
+
2099
+ it("LED behaviour: disable LED false, firmware not handling leds", async () => {
2100
+ basicMocks();
2101
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, "backup.json", {disableLED: false});
2102
+ await adapter.start();
2103
+ expect(mockZnpRequest).not.toHaveBeenCalledWith(Subsystem.UTIL, "ledControl", expect.any(Object), undefined, 500);
2104
+ mockZnpRequest.mockClear();
2105
+ mockQueueExecute.mockClear();
2106
+ await adapter.permitJoin(255, 0);
2107
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.UTIL, "ledControl", {ledid: 3, mode: 1}, undefined, 500);
2108
+ mockZnpRequest.mockClear();
2109
+ mockQueueExecute.mockClear();
2110
+ await adapter.permitJoin(0, 0);
2111
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.UTIL, "ledControl", {ledid: 3, mode: 0}, undefined, 500);
2112
+ });
2113
+
2114
+ it("LED behaviour: disable LED true, firmware handling leds", async () => {
2115
+ mockZnpRequestWith(
2116
+ baseZnpRequestMock.clone().handle(Subsystem.SYS, "version", (_payload) => {
2117
+ return {payload: {product: ZnpVersion.ZStack30x, revision: 20211030}};
2118
+ }),
2119
+ );
2120
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, "backup.json", {disableLED: true});
2121
+ await adapter.start();
2122
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.UTIL, "ledControl", {ledid: 0xff, mode: 5}, undefined, 500);
2123
+ mockZnpRequest.mockClear();
2124
+ mockQueueExecute.mockClear();
2125
+ await adapter.permitJoin(255, 0);
2126
+ expect(mockZnpRequest).not.toHaveBeenCalledWith(Subsystem.UTIL, "ledControl", expect.any(Object), undefined, 500);
2127
+ mockZnpRequest.mockClear();
2128
+ mockQueueExecute.mockClear();
2129
+ await adapter.permitJoin(0, 0);
2130
+ expect(mockZnpRequest).not.toHaveBeenCalledWith(Subsystem.UTIL, "ledControl", expect.any(Object), undefined, 500);
2131
+ });
2132
+
2133
+ it("LED behaviour: disable LED false, firmware handling leds", async () => {
2134
+ mockZnpRequestWith(
2135
+ baseZnpRequestMock.clone().handle(Subsystem.SYS, "version", (_payload) => {
2136
+ return {payload: {product: ZnpVersion.ZStack30x, revision: 20211030}};
2137
+ }),
2138
+ );
2139
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, "backup.json", {disableLED: false});
2140
+ await adapter.start();
2141
+ expect(mockZnpRequest).not.toHaveBeenCalledWith(Subsystem.UTIL, "ledControl", expect.any(Object), null, 500);
2142
+ mockZnpRequest.mockClear();
2143
+ mockQueueExecute.mockClear();
2144
+ await adapter.permitJoin(255, 0);
2145
+ expect(mockZnpRequest).not.toHaveBeenCalledWith(Subsystem.UTIL, "ledControl", expect.any(Object), null, 500);
2146
+ mockZnpRequest.mockClear();
2147
+ mockQueueExecute.mockClear();
2148
+ await adapter.permitJoin(0, 0);
2149
+ expect(mockZnpRequest).not.toHaveBeenCalledWith(Subsystem.UTIL, "ledControl", expect.any(Object), null, 500);
2150
+ });
2151
+
2152
+ /* Original Tests */
2153
+
2154
+ it("Call znp constructor", () => {
2155
+ expect(Znp).toHaveBeenCalledWith("dummy", 800, false);
2156
+ });
2157
+
2158
+ it("Close adapter", async () => {
2159
+ basicMocks();
2160
+ await adapter.start();
2161
+ await adapter.stop();
2162
+ expect(mockZnpClose).toHaveBeenCalledTimes(1);
2163
+ });
2164
+
2165
+ it("Get coordinator IEEE", async () => {
2166
+ basicMocks();
2167
+ await adapter.start();
2168
+ const ieee = await adapter.getCoordinatorIEEE();
2169
+ expect(ieee).toStrictEqual("0x00124b0009d80ba7");
2170
+ });
2171
+
2172
+ it("Permit join all", async () => {
2173
+ basicMocks();
2174
+ await adapter.start();
2175
+ mockZnpRequest.mockClear();
2176
+ mockZnpRequestZdo.mockClear();
2177
+ mockQueueExecute.mockClear();
2178
+ await adapter.permitJoin(100);
2179
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
2180
+ expect(mockZnpRequestZdo).toHaveBeenCalledTimes(1);
2181
+ const zdoPayload = Zdo.Buffalo.buildRequest(false, Zdo.ClusterId.PERMIT_JOINING_REQUEST, 100, 1, []);
2182
+ expect(mockZnpRequestZdo).toHaveBeenCalledWith(
2183
+ Zdo.ClusterId.PERMIT_JOINING_REQUEST,
2184
+ Buffer.from([
2185
+ AddressMode.ADDR_BROADCAST,
2186
+ ZSpec.BroadcastAddress.DEFAULT & 0xff,
2187
+ (ZSpec.BroadcastAddress.DEFAULT >> 8) & 0xff,
2188
+ ...zdoPayload,
2189
+ ]),
2190
+ undefined,
2191
+ // Subsystem.ZDO, 'mgmtPermitJoinReq', {
2192
+ // addrmode: 0x0f,
2193
+ // dstaddr: 0xfffc,
2194
+ // duration: 100,
2195
+ // tcsignificance: 0,
2196
+ // }
2197
+ );
2198
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.UTIL, "ledControl", {ledid: 3, mode: 1}, undefined, 500);
2199
+ });
2200
+
2201
+ it("Permit join specific networkAddress", async () => {
2202
+ basicMocks();
2203
+ await adapter.start();
2204
+ mockZnpRequest.mockClear();
2205
+ mockZnpRequestZdo.mockClear();
2206
+ mockQueueExecute.mockClear();
2207
+ await adapter.permitJoin(102, 42102);
2208
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
2209
+ expect(mockZnpRequestZdo).toHaveBeenCalledTimes(1);
2210
+ const zdoPayload = Zdo.Buffalo.buildRequest(false, Zdo.ClusterId.PERMIT_JOINING_REQUEST, 102, 1, []);
2211
+ expect(mockZnpRequestZdo).toHaveBeenCalledWith(
2212
+ Zdo.ClusterId.PERMIT_JOINING_REQUEST,
2213
+ Buffer.from([AddressMode.ADDR_16BIT, 42102 & 0xff, (42102 >> 8) & 0xff, ...zdoPayload]),
2214
+ expect.any(Number),
2215
+ // Subsystem.ZDO, 'mgmtPermitJoinReq', {
2216
+ // addrmode: 2,
2217
+ // dstaddr: 42102,
2218
+ // duration: 102,
2219
+ // tcsignificance: 0,
2220
+ // }
2221
+ );
2222
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.UTIL, "ledControl", {ledid: 3, mode: 1}, undefined, 500);
2223
+ });
2224
+
2225
+ it("Get coordinator version", async () => {
2226
+ basicMocks();
2227
+ await adapter.start();
2228
+ mockZnpRequest.mockClear();
2229
+ mockQueueExecute.mockClear();
2230
+ expect(await adapter.getCoordinatorVersion()).toStrictEqual({type: "ZStack3x0", meta: {revision: 20210430, product: 1}});
2231
+ });
2232
+
2233
+ it("Soft reset", async () => {
2234
+ basicMocks();
2235
+ await adapter.start();
2236
+ mockZnpRequest.mockClear();
2237
+ mockQueueExecute.mockClear();
2238
+ await adapter.reset("soft");
2239
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
2240
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.SYS, "resetReq", {type: 1});
2241
+ });
2242
+
2243
+ it("Hard reset", async () => {
2244
+ basicMocks();
2245
+ await adapter.start();
2246
+ mockZnpRequest.mockClear();
2247
+ mockQueueExecute.mockClear();
2248
+ await adapter.reset("hard");
2249
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
2250
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.SYS, "resetReq", {type: 0});
2251
+ });
2252
+
2253
+ it("Start with transmit power set", async () => {
2254
+ basicMocks();
2255
+ adapter = new ZStackAdapter(networkOptions, serialPortOptions, "backup.json", {transmitPower: 2, disableLED: false});
2256
+ await adapter.start();
2257
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.SYS, "stackTune", {operation: 0, value: 2});
2258
+ });
2259
+
2260
+ it("Support LED should go to false when LED request fails", async () => {
2261
+ basicMocks();
2262
+ await adapter.start();
2263
+ mockZnpRequest.mockClear();
2264
+ mockQueueExecute.mockClear();
2265
+ mockZnpRequest.mockImplementation(
2266
+ (_, cmd) =>
2267
+ new Promise((resolve, reject) => {
2268
+ if (cmd === "ledControl") reject("FAILED");
2269
+ else resolve(undefined);
2270
+ }),
2271
+ );
2272
+ await adapter.permitJoin(0, 0);
2273
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.UTIL, "ledControl", {ledid: 3, mode: 0}, undefined, 500);
2274
+ mockZnpRequest.mockClear();
2275
+ mockQueueExecute.mockClear();
2276
+ await adapter.permitJoin(0, 0);
2277
+ expect(mockZnpRequest).not.toHaveBeenCalledWith(Subsystem.UTIL, "ledControl", {ledid: 3, mode: 0}, undefined, 500);
2278
+ });
2279
+
2280
+ it("Send zcl frame network address", async () => {
2281
+ basicMocks();
2282
+ await adapter.start();
2283
+
2284
+ mockZnpRequest.mockClear();
2285
+ mockQueueExecute.mockClear();
2286
+ const frame = Zcl.Frame.create(
2287
+ Zcl.FrameType.GLOBAL,
2288
+ Zcl.Direction.CLIENT_TO_SERVER,
2289
+ true,
2290
+ undefined,
2291
+ 100,
2292
+ "writeNoRsp",
2293
+ 0,
2294
+ [{attrId: 0, dataType: 0, attrData: null}],
2295
+ {},
2296
+ );
2297
+ await adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false);
2298
+ expect(mockQueueExecute.mock.calls[0][1]).toBe(2);
2299
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
2300
+ expect(mockZnpRequest).toHaveBeenCalledWith(
2301
+ 4,
2302
+ "dataRequest",
2303
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 1},
2304
+ 99,
2305
+ );
2306
+ });
2307
+
2308
+ it("Send zcl frame network address retry on MAC channel access failure", async () => {
2309
+ basicMocks();
2310
+ dataConfirmCode = 225;
2311
+ dataConfirmCodeReset = true;
2312
+ await adapter.start();
2313
+ mockZnpRequest.mockClear();
2314
+ mockQueueExecute.mockClear();
2315
+ const frame = Zcl.Frame.create(
2316
+ Zcl.FrameType.GLOBAL,
2317
+ Zcl.Direction.CLIENT_TO_SERVER,
2318
+ true,
2319
+ undefined,
2320
+ 100,
2321
+ "writeNoRsp",
2322
+ 0,
2323
+ [{attrId: 0, dataType: 0, attrData: null}],
2324
+ {},
2325
+ );
2326
+ await adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false);
2327
+ expect(mockQueueExecute.mock.calls[0][1]).toBe(2);
2328
+ expect(mockZnpRequest).toHaveBeenCalledTimes(2);
2329
+ expect(mockZnpRequest).toHaveBeenCalledWith(
2330
+ 4,
2331
+ "dataRequest",
2332
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 1},
2333
+ 99,
2334
+ );
2335
+ });
2336
+
2337
+ it("Send zcl frame network address dataConfirm fails", async () => {
2338
+ basicMocks();
2339
+ await adapter.start();
2340
+ dataConfirmCode = 201;
2341
+ mockZnpRequest.mockClear();
2342
+ mockQueueExecute.mockClear();
2343
+ const frame = Zcl.Frame.create(
2344
+ Zcl.FrameType.GLOBAL,
2345
+ Zcl.Direction.CLIENT_TO_SERVER,
2346
+ true,
2347
+ undefined,
2348
+ 100,
2349
+ "writeNoRsp",
2350
+ 0,
2351
+ [{attrId: 0, dataType: 0, attrData: null}],
2352
+ {},
2353
+ );
2354
+ let error;
2355
+ try {
2356
+ await adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false);
2357
+ } catch (e) {
2358
+ error = e;
2359
+ }
2360
+ expect(error.message).toStrictEqual("Data request failed with error: 'NWK_UNSUPPORTED_ATTRIBUTE' (0xc9)");
2361
+ });
2362
+
2363
+ it("Send zcl frame network address with default response", async () => {
2364
+ basicMocks();
2365
+ await adapter.start();
2366
+ const defaultReponse = Zcl.Frame.create(
2367
+ Zcl.FrameType.GLOBAL,
2368
+ Zcl.Direction.SERVER_TO_CLIENT,
2369
+ true,
2370
+ undefined,
2371
+ 100,
2372
+ "defaultRsp",
2373
+ 0,
2374
+ {cmdId: 0, status: 0},
2375
+ {},
2376
+ );
2377
+ const object = mockZpiObject(Type.AREQ, Subsystem.AF, "incomingMsg", {
2378
+ clusterid: 0,
2379
+ srcendpoint: 20,
2380
+ srcaddr: 2,
2381
+ linkquality: 101,
2382
+ groupid: 12,
2383
+ data: defaultReponse.toBuffer(),
2384
+ });
2385
+ mockZnpRequest.mockClear();
2386
+ mockQueueExecute.mockClear();
2387
+ const frame = Zcl.Frame.create(
2388
+ Zcl.FrameType.GLOBAL,
2389
+ Zcl.Direction.CLIENT_TO_SERVER,
2390
+ false,
2391
+ undefined,
2392
+ 100,
2393
+ "writeNoRsp",
2394
+ 0,
2395
+ [{attrId: 0, dataType: 0, attrData: null}],
2396
+ {},
2397
+ );
2398
+ const request = adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false);
2399
+ znpReceived(object);
2400
+ await request;
2401
+ expect(mockQueueExecute.mock.calls[0][1]).toBe(2);
2402
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
2403
+ expect(mockZnpRequest).toHaveBeenCalledWith(
2404
+ 4,
2405
+ "dataRequest",
2406
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 1},
2407
+ 99,
2408
+ );
2409
+ });
2410
+
2411
+ it("Send zcl frame network address fails because mac transaction expire, should retry", async () => {
2412
+ basicMocks();
2413
+ await adapter.start();
2414
+ dataConfirmCode = 240;
2415
+ mockZnpRequest.mockClear();
2416
+ mockZnpRequestZdo.mockClear();
2417
+ mockQueueExecute.mockClear();
2418
+ const frame = Zcl.Frame.create(
2419
+ Zcl.FrameType.GLOBAL,
2420
+ Zcl.Direction.CLIENT_TO_SERVER,
2421
+ true,
2422
+ undefined,
2423
+ 100,
2424
+ "writeNoRsp",
2425
+ 0,
2426
+ [{attrId: 0, dataType: 0, attrData: null}],
2427
+ {},
2428
+ );
2429
+ const response = adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false);
2430
+ let error;
2431
+ try {
2432
+ await response;
2433
+ } catch (e) {
2434
+ error = e;
2435
+ }
2436
+
2437
+ expect(error.message).toStrictEqual("Data request failed with error: 'MAC_TRANSACTION_EXPIRED' (0xf0)");
2438
+ expect(mockZnpRequest).toHaveBeenCalledTimes(9);
2439
+ expect(mockZnpRequestZdo).toHaveBeenCalledTimes(1);
2440
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2441
+ 1,
2442
+ 4,
2443
+ "dataRequest",
2444
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 1},
2445
+ 99,
2446
+ );
2447
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2448
+ 2,
2449
+ 4,
2450
+ "dataRequest",
2451
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 2},
2452
+ 99,
2453
+ );
2454
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(3, 7, "assocGetWithAddress", {extaddr: "0x02", nwkaddr: 2});
2455
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(4, 7, "assocRemove", {ieeeadr: "0x02"});
2456
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2457
+ 5,
2458
+ 4,
2459
+ "dataRequest",
2460
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 3},
2461
+ 99,
2462
+ );
2463
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(6, 7, "assocAdd", {ieeeadr: "0x02", noderelation: 1, nwkaddr: 2});
2464
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(7, 5, "extRouteDisc", {dstAddr: 2, options: 0, radius: 30});
2465
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2466
+ 8,
2467
+ 4,
2468
+ "dataRequest",
2469
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 4},
2470
+ 99,
2471
+ );
2472
+ expect(mockZnpRequestZdo).toHaveBeenCalledWith(
2473
+ Zdo.ClusterId.NETWORK_ADDRESS_REQUEST,
2474
+ Zdo.Buffalo.buildRequest(false, Zdo.ClusterId.NETWORK_ADDRESS_REQUEST, "0x02", false, 0),
2475
+ expect.any(Number),
2476
+ //9, 5, 'nwkAddrReq', {ieeeaddr: '0x02', reqtype: 0, startindex: 0}
2477
+ );
2478
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2479
+ 9,
2480
+ 4,
2481
+ "dataRequest",
2482
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 5},
2483
+ 99,
2484
+ );
2485
+ });
2486
+
2487
+ it("Send zcl frame network address fails because mac transaction expire when not being a parent, should retry", async () => {
2488
+ basicMocks();
2489
+ await adapter.start();
2490
+ dataConfirmCode = 240;
2491
+ assocGetWithAddressNodeRelation = 255;
2492
+ mockZnpRequest.mockClear();
2493
+ mockZnpRequestZdo.mockClear();
2494
+ mockQueueExecute.mockClear();
2495
+ const frame = Zcl.Frame.create(
2496
+ Zcl.FrameType.GLOBAL,
2497
+ Zcl.Direction.CLIENT_TO_SERVER,
2498
+ true,
2499
+ undefined,
2500
+ 100,
2501
+ "writeNoRsp",
2502
+ 0,
2503
+ [{attrId: 0, dataType: 0, attrData: null}],
2504
+ {},
2505
+ );
2506
+ const response = adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false);
2507
+ let error;
2508
+ try {
2509
+ await response;
2510
+ } catch (e) {
2511
+ error = e;
2512
+ }
2513
+
2514
+ expect(error.message).toStrictEqual("Data request failed with error: 'MAC_TRANSACTION_EXPIRED' (0xf0)");
2515
+ expect(mockZnpRequest).toHaveBeenCalledTimes(7);
2516
+ expect(mockZnpRequestZdo).toHaveBeenCalledTimes(1);
2517
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2518
+ 1,
2519
+ 4,
2520
+ "dataRequest",
2521
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 1},
2522
+ 99,
2523
+ );
2524
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2525
+ 2,
2526
+ 4,
2527
+ "dataRequest",
2528
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 2},
2529
+ 99,
2530
+ );
2531
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(3, 7, "assocGetWithAddress", {extaddr: "0x02", nwkaddr: 2});
2532
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(4, 5, "extRouteDisc", {dstAddr: 2, options: 0, radius: 30});
2533
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2534
+ 5,
2535
+ 4,
2536
+ "dataRequest",
2537
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 3},
2538
+ 99,
2539
+ );
2540
+ expect(mockZnpRequestZdo).toHaveBeenCalledWith(
2541
+ Zdo.ClusterId.NETWORK_ADDRESS_REQUEST,
2542
+ Zdo.Buffalo.buildRequest(false, Zdo.ClusterId.NETWORK_ADDRESS_REQUEST, "0x02", false, 0),
2543
+ expect.any(Number),
2544
+ //6, 5, 'nwkAddrReq', {ieeeaddr: '0x02', reqtype: 0, startindex: 0}
2545
+ );
2546
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2547
+ 6,
2548
+ 4,
2549
+ "dataRequest",
2550
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 4},
2551
+ 99,
2552
+ );
2553
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2554
+ 7,
2555
+ 4,
2556
+ "dataRequest",
2557
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 5},
2558
+ 99,
2559
+ );
2560
+ });
2561
+
2562
+ it("Send zcl frame network address fails because mac no ack, should retry", async () => {
2563
+ basicMocks();
2564
+ await adapter.start();
2565
+ dataConfirmCode = 233;
2566
+ mockZnpRequest.mockClear();
2567
+ mockZnpRequestZdo.mockClear();
2568
+ mockQueueExecute.mockClear();
2569
+ const frame = Zcl.Frame.create(
2570
+ Zcl.FrameType.GLOBAL,
2571
+ Zcl.Direction.CLIENT_TO_SERVER,
2572
+ true,
2573
+ undefined,
2574
+ 100,
2575
+ "writeNoRsp",
2576
+ 0,
2577
+ [{attrId: 0, dataType: 0, attrData: null}],
2578
+ {},
2579
+ );
2580
+ const response = adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false);
2581
+ let error;
2582
+ try {
2583
+ await response;
2584
+ } catch (e) {
2585
+ error = e;
2586
+ }
2587
+
2588
+ expect(error.message).toStrictEqual("Data request failed with error: 'MAC_NO_ACK' (0xe9)");
2589
+ expect(mockZnpRequest).toHaveBeenCalledTimes(6);
2590
+ expect(mockZnpRequestZdo).toHaveBeenCalledTimes(1);
2591
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2592
+ 1,
2593
+ 4,
2594
+ "dataRequest",
2595
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 1},
2596
+ 99,
2597
+ );
2598
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2599
+ 2,
2600
+ 4,
2601
+ "dataRequest",
2602
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 2},
2603
+ 99,
2604
+ );
2605
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(3, 5, "extRouteDisc", {dstAddr: 2, options: 0, radius: 30});
2606
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2607
+ 4,
2608
+ 4,
2609
+ "dataRequest",
2610
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 3},
2611
+ 99,
2612
+ );
2613
+ expect(mockZnpRequestZdo).toHaveBeenCalledWith(
2614
+ Zdo.ClusterId.NETWORK_ADDRESS_REQUEST,
2615
+ Zdo.Buffalo.buildRequest(false, Zdo.ClusterId.NETWORK_ADDRESS_REQUEST, "0x02", false, 0),
2616
+ expect.any(Number),
2617
+ //5, 5, 'nwkAddrReq', {ieeeaddr: '0x02', reqtype: 0, startindex: 0}
2618
+ );
2619
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2620
+ 5,
2621
+ 4,
2622
+ "dataRequest",
2623
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 4},
2624
+ 99,
2625
+ );
2626
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2627
+ 6,
2628
+ 4,
2629
+ "dataRequest",
2630
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 5},
2631
+ 99,
2632
+ );
2633
+ });
2634
+
2635
+ it("Send zcl frame network address fails because mac no ack with network address change, should retry", async () => {
2636
+ basicMocks();
2637
+ await adapter.start();
2638
+ dataConfirmCode = 233;
2639
+ mockZnpRequest.mockClear();
2640
+ mockZnpRequestZdo.mockClear();
2641
+ mockQueueExecute.mockClear();
2642
+ const frame = Zcl.Frame.create(
2643
+ Zcl.FrameType.GLOBAL,
2644
+ Zcl.Direction.CLIENT_TO_SERVER,
2645
+ true,
2646
+ undefined,
2647
+ 100,
2648
+ "writeNoRsp",
2649
+ 0,
2650
+ [{attrId: 0, dataType: 0, attrData: null}],
2651
+ {},
2652
+ );
2653
+ const response = adapter.sendZclFrameToEndpoint("0x03", 2, 20, frame, 10000, false, false);
2654
+ let error;
2655
+ try {
2656
+ await response;
2657
+ } catch (e) {
2658
+ error = e;
2659
+ }
2660
+
2661
+ expect(error.message).toStrictEqual("Data request failed with error: 'MAC_NO_ACK' (0xe9)");
2662
+ // expect(mockZnpRequest).toHaveBeenCalledTimes(7);
2663
+ // expect(mockZnpRequestZdo).toHaveBeenCalledTimes(1);
2664
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2665
+ 1,
2666
+ 4,
2667
+ "dataRequest",
2668
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 1},
2669
+ 99,
2670
+ );
2671
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2672
+ 2,
2673
+ 4,
2674
+ "dataRequest",
2675
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 2},
2676
+ 99,
2677
+ );
2678
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(3, 5, "extRouteDisc", {dstAddr: 2, options: 0, radius: 30});
2679
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2680
+ 4,
2681
+ 4,
2682
+ "dataRequest",
2683
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 3},
2684
+ 99,
2685
+ );
2686
+ expect(mockZnpRequestZdo).toHaveBeenCalledWith(
2687
+ Zdo.ClusterId.NETWORK_ADDRESS_REQUEST,
2688
+ Zdo.Buffalo.buildRequest(false, Zdo.ClusterId.NETWORK_ADDRESS_REQUEST, "0x03", false, 0),
2689
+ expect.any(Number),
2690
+ //5, 5, 'nwkAddrReq', {ieeeaddr: '0x03', reqtype: 0, startindex: 0}
2691
+ );
2692
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(5, 5, "extRouteDisc", {dstAddr: 3, options: 0, radius: 30});
2693
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2694
+ 6,
2695
+ 4,
2696
+ "dataRequest",
2697
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 3, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 4},
2698
+ 99,
2699
+ );
2700
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2701
+ 7,
2702
+ 4,
2703
+ "dataRequest",
2704
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 3, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 5},
2705
+ 99,
2706
+ );
2707
+ });
2708
+
2709
+ it("Send zcl frame network address fails because mac no ack with network address change, without recovery", async () => {
2710
+ basicMocks();
2711
+ await adapter.start();
2712
+ dataConfirmCode = 233;
2713
+ mockZnpRequest.mockClear();
2714
+ mockQueueExecute.mockClear();
2715
+ const frame = Zcl.Frame.create(
2716
+ Zcl.FrameType.GLOBAL,
2717
+ Zcl.Direction.CLIENT_TO_SERVER,
2718
+ true,
2719
+ undefined,
2720
+ 100,
2721
+ "writeNoRsp",
2722
+ 0,
2723
+ [{attrId: 0, dataType: 0, attrData: null}],
2724
+ {},
2725
+ );
2726
+ const response = adapter.sendZclFrameToEndpoint("0x03", 2, 20, frame, 10000, false, true, undefined);
2727
+ let error;
2728
+ try {
2729
+ await response;
2730
+ } catch (e) {
2731
+ error = e;
2732
+ }
2733
+
2734
+ expect(error.message).toStrictEqual("Data request failed with error: 'MAC_NO_ACK' (0xe9)");
2735
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
2736
+ });
2737
+
2738
+ it("Send zcl frame network address fails because requested profileId is not configured", async () => {
2739
+ basicMocks();
2740
+ await adapter.start();
2741
+
2742
+ mockZnpRequest.mockClear();
2743
+ mockQueueExecute.mockClear();
2744
+ const frame = Zcl.Frame.create(
2745
+ Zcl.FrameType.GLOBAL,
2746
+ Zcl.Direction.CLIENT_TO_SERVER,
2747
+ true,
2748
+ undefined,
2749
+ 100,
2750
+ "writeNoRsp",
2751
+ 0,
2752
+ [{attrId: 0, dataType: 0, attrData: null}],
2753
+ {},
2754
+ );
2755
+ const response = adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false, undefined, 9999);
2756
+ let error;
2757
+ try {
2758
+ await response;
2759
+ } catch (e) {
2760
+ error = e;
2761
+ }
2762
+
2763
+ expect(error.message).toStrictEqual("Profile ID 9999 is not supported by this adapter.");
2764
+ });
2765
+
2766
+ it("Source Endpoint is selected based on profileId", async () => {
2767
+ basicMocks();
2768
+ await adapter.start();
2769
+
2770
+ mockZnpRequest.mockClear();
2771
+ mockQueueExecute.mockClear();
2772
+ const frame = Zcl.Frame.create(
2773
+ Zcl.FrameType.GLOBAL,
2774
+ Zcl.Direction.CLIENT_TO_SERVER,
2775
+ true,
2776
+ undefined,
2777
+ 100,
2778
+ "writeNoRsp",
2779
+ 0,
2780
+ [{attrId: 0, dataType: 0, attrData: null}],
2781
+ {},
2782
+ );
2783
+ await adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false, undefined, 0x0109);
2784
+ expect(mockZnpRequest).toHaveBeenCalledWith(
2785
+ 4,
2786
+ "dataRequest",
2787
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 6, transid: 1},
2788
+ 99,
2789
+ );
2790
+ });
2791
+
2792
+ it("Send zcl frame network address should retry on dataconfirm timeout", async () => {
2793
+ basicMocks();
2794
+ await adapter.start();
2795
+ dataConfirmCode = 9999;
2796
+ dataConfirmCodeReset = true;
2797
+ mockZnpRequest.mockClear();
2798
+ mockQueueExecute.mockClear();
2799
+ const frame = Zcl.Frame.create(
2800
+ Zcl.FrameType.GLOBAL,
2801
+ Zcl.Direction.CLIENT_TO_SERVER,
2802
+ true,
2803
+ undefined,
2804
+ 100,
2805
+ "writeNoRsp",
2806
+ 0,
2807
+ [{attrId: 0, dataType: 0, attrData: null}],
2808
+ {},
2809
+ );
2810
+ const response = adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false);
2811
+ let error;
2812
+ try {
2813
+ await response;
2814
+ } catch (e) {
2815
+ error = e;
2816
+ }
2817
+ expect(error.message).toStrictEqual("Data request failed with error: 'TIMEOUT'");
2818
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
2819
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
2820
+ 1,
2821
+ 4,
2822
+ "dataRequest",
2823
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 6, options: 0, radius: 30, srcendpoint: 1, transid: 1},
2824
+ 99,
2825
+ );
2826
+ });
2827
+
2828
+ it("Send zcl frame group", async () => {
2829
+ basicMocks();
2830
+ await adapter.start();
2831
+
2832
+ mockZnpRequest.mockClear();
2833
+ mockQueueExecute.mockClear();
2834
+ const frame = Zcl.Frame.create(Zcl.FrameType.GLOBAL, Zcl.Direction.CLIENT_TO_SERVER, true, undefined, 100, "read", 0, [{attrId: 0}], {});
2835
+ await adapter.sendZclFrameToGroup(25, frame, 1);
2836
+ expect(mockQueueExecute.mock.calls[0][1]).toBe(undefined);
2837
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
2838
+ expect(mockZnpRequest).toHaveBeenCalledWith(
2839
+ 4,
2840
+ "dataRequestExt",
2841
+ {
2842
+ clusterid: 0,
2843
+ data: frame.toBuffer(),
2844
+ destendpoint: 255,
2845
+ dstaddr: "0x0000000000000019",
2846
+ len: 5,
2847
+ options: 0,
2848
+ radius: 30,
2849
+ srcendpoint: 1,
2850
+ transid: 1,
2851
+ dstaddrmode: 1,
2852
+ dstpanid: 0,
2853
+ },
2854
+ 99,
2855
+ );
2856
+ });
2857
+
2858
+ it("Send zcl frame group retry on MAC channel access failure", async () => {
2859
+ basicMocks();
2860
+ dataConfirmCode = 225;
2861
+ dataConfirmCodeReset = true;
2862
+ await adapter.start();
2863
+ mockZnpRequest.mockClear();
2864
+ mockQueueExecute.mockClear();
2865
+ const frame = Zcl.Frame.create(
2866
+ Zcl.FrameType.GLOBAL,
2867
+ Zcl.Direction.CLIENT_TO_SERVER,
2868
+ false,
2869
+ undefined,
2870
+ 100,
2871
+ "writeNoRsp",
2872
+ 0,
2873
+ [{attrId: 0, dataType: 0, attrData: null}],
2874
+ {},
2875
+ );
2876
+ await adapter.sendZclFrameToGroup(25, frame, 1);
2877
+ expect(mockQueueExecute.mock.calls[0][1]).toBe(undefined);
2878
+ expect(mockZnpRequest).toHaveBeenCalledTimes(2);
2879
+ expect(mockZnpRequest).toHaveBeenCalledWith(
2880
+ 4,
2881
+ "dataRequestExt",
2882
+ {
2883
+ clusterid: 0,
2884
+ data: frame.toBuffer(),
2885
+ destendpoint: 255,
2886
+ dstaddr: "0x0000000000000019",
2887
+ len: 6,
2888
+ options: 0,
2889
+ radius: 30,
2890
+ srcendpoint: 1,
2891
+ transid: 1,
2892
+ dstaddrmode: 1,
2893
+ dstpanid: 0,
2894
+ },
2895
+ 99,
2896
+ );
2897
+ });
2898
+
2899
+ it("Send zcl frame to all - DEFAULT", async () => {
2900
+ basicMocks();
2901
+ await adapter.start();
2902
+
2903
+ mockZnpRequest.mockClear();
2904
+ mockQueueExecute.mockClear();
2905
+ const frame = Zcl.Frame.create(Zcl.FrameType.GLOBAL, Zcl.Direction.CLIENT_TO_SERVER, true, undefined, 100, "read", 0, [{attrId: 0}], {});
2906
+ await adapter.sendZclFrameToAll(242, frame, 250, BroadcastAddress.DEFAULT);
2907
+ expect(mockQueueExecute.mock.calls[0][1]).toBe(undefined);
2908
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
2909
+ expect(mockZnpRequest).toHaveBeenCalledWith(
2910
+ 4,
2911
+ "dataRequestExt",
2912
+ {
2913
+ clusterid: 0,
2914
+ data: frame.toBuffer(),
2915
+ destendpoint: 242,
2916
+ dstaddr: "0x000000000000fffc",
2917
+ len: 5,
2918
+ options: 0,
2919
+ radius: 30,
2920
+ srcendpoint: 250,
2921
+ transid: 1,
2922
+ dstaddrmode: 2,
2923
+ dstpanid: 0,
2924
+ },
2925
+ undefined,
2926
+ );
2927
+ });
2928
+
2929
+ it("Send zcl frame to all - RX_ON_WHEN_IDLE", async () => {
2930
+ basicMocks();
2931
+ await adapter.start();
2932
+
2933
+ mockZnpRequest.mockClear();
2934
+ mockQueueExecute.mockClear();
2935
+ const frame = Zcl.Frame.create(Zcl.FrameType.GLOBAL, Zcl.Direction.CLIENT_TO_SERVER, true, undefined, 100, "read", 0, [{attrId: 0}], {});
2936
+ await adapter.sendZclFrameToAll(255, frame, 1, BroadcastAddress.RX_ON_WHEN_IDLE);
2937
+ expect(mockQueueExecute.mock.calls[0][1]).toBe(undefined);
2938
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
2939
+ expect(mockZnpRequest).toHaveBeenCalledWith(
2940
+ 4,
2941
+ "dataRequestExt",
2942
+ {
2943
+ clusterid: 0,
2944
+ data: frame.toBuffer(),
2945
+ destendpoint: 255,
2946
+ dstaddr: "0x000000000000fffd",
2947
+ len: 5,
2948
+ options: 0,
2949
+ radius: 30,
2950
+ srcendpoint: 1,
2951
+ transid: 1,
2952
+ dstaddrmode: 2,
2953
+ dstpanid: 0,
2954
+ },
2955
+ undefined,
2956
+ );
2957
+ });
2958
+
2959
+ it("Send zcl frame to all - SLEEPY", async () => {
2960
+ basicMocks();
2961
+ await adapter.start();
2962
+
2963
+ mockZnpRequest.mockClear();
2964
+ mockQueueExecute.mockClear();
2965
+ const frame = Zcl.Frame.create(Zcl.FrameType.GLOBAL, Zcl.Direction.CLIENT_TO_SERVER, true, undefined, 100, "read", 0, [{attrId: 0}], {});
2966
+ await adapter.sendZclFrameToAll(255, frame, 1, BroadcastAddress.SLEEPY);
2967
+ expect(mockQueueExecute.mock.calls[0][1]).toBe(undefined);
2968
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
2969
+ expect(mockZnpRequest).toHaveBeenCalledWith(
2970
+ 4,
2971
+ "dataRequestExt",
2972
+ {
2973
+ clusterid: 0,
2974
+ data: frame.toBuffer(),
2975
+ destendpoint: 255,
2976
+ dstaddr: "0x000000000000ffff",
2977
+ len: 5,
2978
+ options: 0,
2979
+ radius: 30,
2980
+ srcendpoint: 1,
2981
+ transid: 1,
2982
+ dstaddrmode: 2,
2983
+ dstpanid: 0,
2984
+ },
2985
+ undefined,
2986
+ );
2987
+ });
2988
+
2989
+ it("Send zcl frame network address transaction number shouldnt go higher than 255", async () => {
2990
+ basicMocks();
2991
+ await adapter.start();
2992
+ let transactionID = 0;
2993
+
2994
+ mockZnpRequest.mockClear();
2995
+ mockQueueExecute.mockClear();
2996
+
2997
+ for (let i = 0; i < 300; i++) {
2998
+ if (transactionID > 200) {
2999
+ transactionID = 0;
3000
+ }
3001
+
3002
+ const frame = Zcl.Frame.create(
3003
+ Zcl.FrameType.GLOBAL,
3004
+ Zcl.Direction.CLIENT_TO_SERVER,
3005
+ true,
3006
+ undefined,
3007
+ 100,
3008
+ "writeNoRsp",
3009
+ 0,
3010
+ [{attrId: 0, dataType: 0, attrData: null}],
3011
+ {},
3012
+ );
3013
+ await adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false);
3014
+ }
3015
+
3016
+ const got: number[] = [];
3017
+ for (let i = 0; i < 300; i++) {
3018
+ got.push(mockZnpRequest.mock.calls[i][2].transid);
3019
+ }
3020
+
3021
+ expect(got[0]).toBe(1);
3022
+ expect(got.find((g) => g === 0)).toBe(undefined);
3023
+ expect(got.find((g) => g > 255)).toBe(undefined);
3024
+ expect(got.filter((g) => g === 1).length).toBe(2);
3025
+ expect(got.filter((g) => g === 255).length).toBe(1);
3026
+ expect(mockZnpRequest).toHaveBeenCalledTimes(300);
3027
+ });
3028
+
3029
+ it("Send zcl frame group dataConfirm fails", async () => {
3030
+ basicMocks();
3031
+ await adapter.start();
3032
+ dataConfirmCode = 184;
3033
+ let error;
3034
+ mockZnpRequest.mockClear();
3035
+ mockQueueExecute.mockClear();
3036
+ const frame = Zcl.Frame.create(Zcl.FrameType.GLOBAL, Zcl.Direction.CLIENT_TO_SERVER, true, undefined, 100, "read", 0, [{attrId: 0}], {});
3037
+ try {
3038
+ await adapter.sendZclFrameToGroup(25, frame);
3039
+ } catch (e) {
3040
+ error = e;
3041
+ }
3042
+ expect(mockQueueExecute.mock.calls[0][1]).toBe(undefined);
3043
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
3044
+ expect(mockZnpRequest).toHaveBeenCalledWith(
3045
+ 4,
3046
+ "dataRequestExt",
3047
+ {
3048
+ clusterid: 0,
3049
+ data: frame.toBuffer(),
3050
+ destendpoint: 255,
3051
+ dstaddr: "0x0000000000000019",
3052
+ len: 5,
3053
+ options: 0,
3054
+ radius: 30,
3055
+ srcendpoint: 1,
3056
+ transid: 1,
3057
+ dstaddrmode: 1,
3058
+ dstpanid: 0,
3059
+ },
3060
+ 99,
3061
+ );
3062
+ expect(error.message).toStrictEqual("Data request failed with error: 'APS_DUPLICATE_ENTRY' (0xb8)");
3063
+ });
3064
+
3065
+ it("Send zcl frame network address and default response", async () => {
3066
+ basicMocks();
3067
+ await adapter.start();
3068
+
3069
+ mockZnpRequest.mockClear();
3070
+ mockQueueExecute.mockClear();
3071
+
3072
+ const responseMismatchFrame = Zcl.Frame.create(
3073
+ Zcl.FrameType.GLOBAL,
3074
+ Zcl.Direction.SERVER_TO_CLIENT,
3075
+ true,
3076
+ undefined,
3077
+ 102,
3078
+ "readRsp",
3079
+ 0,
3080
+ [{attrId: 0, attrData: 5, dataType: 32, status: 0}],
3081
+ {},
3082
+ );
3083
+ const responseFrame = Zcl.Frame.create(
3084
+ Zcl.FrameType.GLOBAL,
3085
+ Zcl.Direction.SERVER_TO_CLIENT,
3086
+ true,
3087
+ undefined,
3088
+ 100,
3089
+ "readRsp",
3090
+ 0,
3091
+ [{attrId: 0, attrData: 2, dataType: 32, status: 0}],
3092
+ {},
3093
+ );
3094
+ const frame = Zcl.Frame.create(Zcl.FrameType.GLOBAL, Zcl.Direction.CLIENT_TO_SERVER, true, undefined, 100, "read", 0, [{attrId: 0}], {});
3095
+ const object = mockZpiObject(Type.AREQ, Subsystem.AF, "incomingMsg", {
3096
+ clusterid: 0,
3097
+ srcendpoint: 20,
3098
+ srcaddr: 2,
3099
+ linkquality: 101,
3100
+ groupid: 12,
3101
+ data: responseFrame.toBuffer(),
3102
+ });
3103
+ const objectMismatch = mockZpiObject(Type.AREQ, Subsystem.AF, "incomingMsg", {
3104
+ clusterid: 0,
3105
+ srcendpoint: 20,
3106
+ srcaddr: 2,
3107
+ linkquality: 101,
3108
+ groupid: 12,
3109
+ data: responseMismatchFrame.toBuffer(),
3110
+ });
3111
+ const response = adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false);
3112
+ znpReceived(objectMismatch);
3113
+ znpReceived(object);
3114
+ const result = await response;
3115
+
3116
+ expect(mockZnpRequest).toHaveBeenCalledWith(
3117
+ 4,
3118
+ "dataRequest",
3119
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 5, options: 0, radius: 30, srcendpoint: 1, transid: 1},
3120
+ 99,
3121
+ );
3122
+ expect(mockQueueExecute.mock.calls[0][1]).toBe(2);
3123
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
3124
+ expect(result.endpoint).toStrictEqual(20);
3125
+ expect(result.groupID).toStrictEqual(12);
3126
+ expect(result.linkquality).toStrictEqual(101);
3127
+ expect(result.address).toStrictEqual(2);
3128
+ expect(result.groupID).toStrictEqual(12);
3129
+ expect(result.data).toStrictEqual(Buffer.from([24, 100, 1, 0, 0, 0, 32, 2]));
3130
+ });
3131
+
3132
+ it("Send zcl frame network address and default response", async () => {
3133
+ basicMocks();
3134
+ await adapter.start();
3135
+
3136
+ mockZnpRequest.mockClear();
3137
+ mockQueueExecute.mockClear();
3138
+
3139
+ const responseMismatchFrame = Zcl.Frame.create(
3140
+ Zcl.FrameType.GLOBAL,
3141
+ Zcl.Direction.SERVER_TO_CLIENT,
3142
+ true,
3143
+ undefined,
3144
+ 102,
3145
+ "readRsp",
3146
+ 0,
3147
+ [{attrId: 0, attrData: 5, dataType: 32, status: 0}],
3148
+ {},
3149
+ );
3150
+ const responseFrame = Zcl.Frame.create(
3151
+ Zcl.FrameType.GLOBAL,
3152
+ Zcl.Direction.SERVER_TO_CLIENT,
3153
+ true,
3154
+ undefined,
3155
+ 100,
3156
+ "readRsp",
3157
+ 0,
3158
+ [{attrId: 0, attrData: 2, dataType: 32, status: 0}],
3159
+ {},
3160
+ );
3161
+ const frame = Zcl.Frame.create(Zcl.FrameType.GLOBAL, Zcl.Direction.CLIENT_TO_SERVER, false, undefined, 100, "read", 0, [{attrId: 0}], {});
3162
+ const object = mockZpiObject(Type.AREQ, Subsystem.AF, "incomingMsg", {
3163
+ clusterid: 0,
3164
+ srcendpoint: 20,
3165
+ srcaddr: 2,
3166
+ linkquality: 101,
3167
+ groupid: 12,
3168
+ data: responseFrame.toBuffer(),
3169
+ });
3170
+ const objectMismatch = mockZpiObject(Type.AREQ, Subsystem.AF, "incomingMsg", {
3171
+ clusterid: 0,
3172
+ srcendpoint: 20,
3173
+ srcaddr: 2,
3174
+ linkquality: 101,
3175
+ groupid: 12,
3176
+ data: responseMismatchFrame.toBuffer(),
3177
+ });
3178
+ const defaultReponse = Zcl.Frame.create(
3179
+ Zcl.FrameType.GLOBAL,
3180
+ Zcl.Direction.SERVER_TO_CLIENT,
3181
+ true,
3182
+ undefined,
3183
+ 100,
3184
+ "defaultRsp",
3185
+ 0,
3186
+ {cmdId: 0, status: 0},
3187
+ {},
3188
+ );
3189
+ const defaultObject = mockZpiObject(Type.AREQ, Subsystem.AF, "incomingMsg", {
3190
+ clusterid: 0,
3191
+ srcendpoint: 20,
3192
+ srcaddr: 2,
3193
+ linkquality: 101,
3194
+ groupid: 12,
3195
+ data: defaultReponse.toBuffer(),
3196
+ });
3197
+ const response = adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false);
3198
+ znpReceived(objectMismatch);
3199
+ znpReceived(defaultObject);
3200
+ znpReceived(object);
3201
+ const result = await response;
3202
+
3203
+ expect(mockZnpRequest).toHaveBeenCalledWith(
3204
+ 4,
3205
+ "dataRequest",
3206
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 5, options: 0, radius: 30, srcendpoint: 1, transid: 1},
3207
+ 99,
3208
+ );
3209
+ expect(mockQueueExecute.mock.calls[0][1]).toBe(2);
3210
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
3211
+ expect(result.endpoint).toStrictEqual(20);
3212
+ expect(result.groupID).toStrictEqual(12);
3213
+ expect(result.linkquality).toStrictEqual(101);
3214
+ expect(result.address).toStrictEqual(2);
3215
+ expect(result.groupID).toStrictEqual(12);
3216
+ expect(result.data).toStrictEqual(Buffer.from([24, 100, 1, 0, 0, 0, 32, 2]));
3217
+ });
3218
+
3219
+ it("Send zcl frame network address data confirm fails with default response", async () => {
3220
+ basicMocks();
3221
+ await adapter.start();
3222
+ dataConfirmCode = 201;
3223
+ const frame = Zcl.Frame.create(Zcl.FrameType.GLOBAL, Zcl.Direction.CLIENT_TO_SERVER, false, undefined, 100, "read", 0, [{attrId: 0}], {});
3224
+ let error;
3225
+ try {
3226
+ await adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false);
3227
+ } catch (e) {
3228
+ error = e;
3229
+ }
3230
+ expect(error.message).toStrictEqual("Data request failed with error: 'NWK_UNSUPPORTED_ATTRIBUTE' (0xc9)");
3231
+ });
3232
+
3233
+ it("Send zcl frame network address data confirm fails without default response", async () => {
3234
+ basicMocks();
3235
+ await adapter.start();
3236
+ dataConfirmCode = 201;
3237
+ const frame = Zcl.Frame.create(Zcl.FrameType.GLOBAL, Zcl.Direction.CLIENT_TO_SERVER, true, undefined, 100, "read", 0, [{attrId: 0}], {});
3238
+ let error;
3239
+ try {
3240
+ await adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false);
3241
+ } catch (e) {
3242
+ error = e;
3243
+ }
3244
+ expect(error.message).toStrictEqual("Data request failed with error: 'NWK_UNSUPPORTED_ATTRIBUTE' (0xc9)");
3245
+ });
3246
+
3247
+ it("Send zcl frame network address timeout should discover route and retry", async () => {
3248
+ basicMocks();
3249
+ await adapter.start();
3250
+
3251
+ mockZnpRequest.mockClear();
3252
+ mockQueueExecute.mockClear();
3253
+ assocGetWithAddressNodeRelation = 2;
3254
+ const responseMismatchFrame = Zcl.Frame.create(
3255
+ Zcl.FrameType.GLOBAL,
3256
+ Zcl.Direction.SERVER_TO_CLIENT,
3257
+ true,
3258
+ undefined,
3259
+ 102,
3260
+ "readRsp",
3261
+ 0,
3262
+ [{attrId: 0, attrData: 5, dataType: 32, status: 0}],
3263
+ {},
3264
+ );
3265
+ const frame = Zcl.Frame.create(Zcl.FrameType.GLOBAL, Zcl.Direction.CLIENT_TO_SERVER, false, undefined, 100, "read", 0, [{attrId: 0}], {});
3266
+ const objectMismatch = mockZpiObject(Type.AREQ, Subsystem.AF, "incomingMsg", {
3267
+ clusterid: 0,
3268
+ srcendpoint: 20,
3269
+ srcaddr: 2,
3270
+ linkquality: 101,
3271
+ groupid: 12,
3272
+ data: responseMismatchFrame.toBuffer(),
3273
+ });
3274
+ let error;
3275
+ try {
3276
+ const spy = mockSetTimeout();
3277
+ const response = adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 1, false, false);
3278
+ znpReceived(objectMismatch);
3279
+ await response;
3280
+ spy.mockRestore();
3281
+ } catch (e) {
3282
+ error = e;
3283
+ }
3284
+
3285
+ expect(mockQueueExecute.mock.calls[0][1]).toBe(2);
3286
+ expect(mockZnpRequest).toHaveBeenCalledTimes(4);
3287
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
3288
+ 1,
3289
+ 4,
3290
+ "dataRequest",
3291
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 5, options: 0, radius: 30, srcendpoint: 1, transid: 1},
3292
+ 99,
3293
+ );
3294
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(2, 7, "assocGetWithAddress", {extaddr: "0x02", nwkaddr: 2});
3295
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(3, 5, "extRouteDisc", {dstAddr: 2, options: 0, radius: Constants.AF.DEFAULT_RADIUS});
3296
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
3297
+ 4,
3298
+ 4,
3299
+ "dataRequest",
3300
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 5, options: 0, radius: 30, srcendpoint: 1, transid: 2},
3301
+ 99,
3302
+ );
3303
+ expect(error).toStrictEqual(new Error("Timeout - 2 - 20 - 100 - 0 - 1 after 1ms"));
3304
+ });
3305
+
3306
+ it("Send zcl frame network address timeout should discover route, rewrite child entry and retry for sleepy end device", async () => {
3307
+ basicMocks();
3308
+ await adapter.start();
3309
+
3310
+ mockZnpRequest.mockClear();
3311
+ mockQueueExecute.mockClear();
3312
+
3313
+ const responseMismatchFrame = Zcl.Frame.create(
3314
+ Zcl.FrameType.GLOBAL,
3315
+ Zcl.Direction.SERVER_TO_CLIENT,
3316
+ true,
3317
+ undefined,
3318
+ 102,
3319
+ "readRsp",
3320
+ 0,
3321
+ [{attrId: 0, attrData: 5, dataType: 32, status: 0}],
3322
+ {},
3323
+ );
3324
+ const frame = Zcl.Frame.create(Zcl.FrameType.GLOBAL, Zcl.Direction.CLIENT_TO_SERVER, false, undefined, 100, "read", 0, [{attrId: 0}], {});
3325
+ const objectMismatch = mockZpiObject(Type.AREQ, Subsystem.AF, "incomingMsg", {
3326
+ clusterid: 0,
3327
+ srcendpoint: 20,
3328
+ srcaddr: 2,
3329
+ linkquality: 101,
3330
+ groupid: 12,
3331
+ data: responseMismatchFrame.toBuffer(),
3332
+ });
3333
+ let error;
3334
+ try {
3335
+ const spy = mockSetTimeout();
3336
+ const response = adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 1, false, false);
3337
+ znpReceived(objectMismatch);
3338
+ await response;
3339
+ spy.mockRestore();
3340
+ } catch (e) {
3341
+ error = e;
3342
+ }
3343
+
3344
+ expect(mockQueueExecute.mock.calls[0][1]).toBe(2);
3345
+ expect(mockZnpRequest).toHaveBeenCalledTimes(6);
3346
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
3347
+ 1,
3348
+ 4,
3349
+ "dataRequest",
3350
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 5, options: 0, radius: 30, srcendpoint: 1, transid: 1},
3351
+ 99,
3352
+ );
3353
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(2, 7, "assocGetWithAddress", {extaddr: "0x02", nwkaddr: 2});
3354
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(3, 7, "assocRemove", {ieeeadr: "0x02"});
3355
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(4, 7, "assocAdd", {ieeeadr: "0x02", nwkaddr: 2, noderelation: 1});
3356
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(5, 5, "extRouteDisc", {dstAddr: 2, options: 0, radius: Constants.AF.DEFAULT_RADIUS});
3357
+ expect(mockZnpRequest).toHaveBeenNthCalledWith(
3358
+ 6,
3359
+ 4,
3360
+ "dataRequest",
3361
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 5, options: 0, radius: 30, srcendpoint: 1, transid: 2},
3362
+ 99,
3363
+ );
3364
+ expect(error).toStrictEqual(new Error("Timeout - 2 - 20 - 100 - 0 - 1 after 1ms"));
3365
+ });
3366
+
3367
+ it("Send zcl frame network address with default response timeout shouldnt care because command has response", async () => {
3368
+ basicMocks();
3369
+ await adapter.start();
3370
+
3371
+ mockZnpRequest.mockClear();
3372
+ mockQueueExecute.mockClear();
3373
+ const responseFrame = Zcl.Frame.create(
3374
+ Zcl.FrameType.GLOBAL,
3375
+ Zcl.Direction.SERVER_TO_CLIENT,
3376
+ true,
3377
+ undefined,
3378
+ 100,
3379
+ "readRsp",
3380
+ 0,
3381
+ [{attrId: 0, attrData: 2, dataType: 32, status: 0}],
3382
+ {},
3383
+ );
3384
+ const frame = Zcl.Frame.create(Zcl.FrameType.GLOBAL, Zcl.Direction.CLIENT_TO_SERVER, false, undefined, 100, "read", 0, [{attrId: 0}], {});
3385
+ const object = mockZpiObject(Type.AREQ, Subsystem.AF, "incomingMsg", {
3386
+ clusterid: 0,
3387
+ srcendpoint: 20,
3388
+ srcaddr: 2,
3389
+ linkquality: 101,
3390
+ groupid: 12,
3391
+ data: responseFrame.toBuffer(),
3392
+ });
3393
+ const response = adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false);
3394
+ znpReceived(object);
3395
+
3396
+ let error = null;
3397
+ try {
3398
+ await response;
3399
+ } catch (e) {
3400
+ error = e;
3401
+ }
3402
+ expect(mockZnpRequest).toHaveBeenCalledWith(
3403
+ 4,
3404
+ "dataRequest",
3405
+ {clusterid: 0, data: frame.toBuffer(), destendpoint: 20, dstaddr: 2, len: 5, options: 0, radius: 30, srcendpoint: 1, transid: 1},
3406
+ 99,
3407
+ );
3408
+ expect(mockQueueExecute.mock.calls[0][1]).toBe(2);
3409
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
3410
+ expect(error).toStrictEqual(null);
3411
+ });
3412
+
3413
+ it("Supports backup", async () => {
3414
+ basicMocks();
3415
+ await adapter.start();
3416
+ expect(await adapter.supportsBackup()).toBeTruthy();
3417
+ });
3418
+
3419
+ it.each([
3420
+ [2, "0x1234567812345678", 0x5678],
3421
+ [3, "0x1234567812345678", "0x1234567812345678"],
3422
+ ])("Incoming message extended (inter PAN) - 16/64-bit address", async (srcAddrMode, addr, expParsedAddr) => {
3423
+ basicMocks();
3424
+ await adapter.start();
3425
+ let zclData;
3426
+ const responseFrame = Zcl.Frame.create(
3427
+ Zcl.FrameType.GLOBAL,
3428
+ Zcl.Direction.SERVER_TO_CLIENT,
3429
+ true,
3430
+ undefined,
3431
+ 100,
3432
+ "readRsp",
3433
+ 0,
3434
+ [{attrId: 0, attrData: 2, dataType: 32, status: 0}],
3435
+ {},
3436
+ );
3437
+ const responseBuffer = responseFrame.toBuffer();
3438
+ const object = mockZpiObject(Type.AREQ, Subsystem.AF, "incomingMsgExt", {
3439
+ groupid: 12,
3440
+ clusterid: 0,
3441
+ srcaddrmode: srcAddrMode,
3442
+ srcaddr: addr,
3443
+ srcendpoint: 20,
3444
+ //srcpanid
3445
+ dstendpoint: 1,
3446
+ //wasbroadcast
3447
+ linkquality: 101,
3448
+ //securityuse
3449
+ timestamp: 0x12345678,
3450
+ //transseqnumber
3451
+ len: responseBuffer.length,
3452
+ data: responseBuffer,
3453
+ });
3454
+ adapter.on("zclPayload", (p) => {
3455
+ zclData = p;
3456
+ });
3457
+ znpReceived(object);
3458
+ expect(zclData.endpoint).toStrictEqual(20);
3459
+ expect(zclData.groupID).toStrictEqual(12);
3460
+ expect(zclData.linkquality).toStrictEqual(101);
3461
+ expect(zclData.address).toStrictEqual(expParsedAddr);
3462
+ expect(zclData.groupID).toStrictEqual(12);
3463
+ expect(zclData.data).toStrictEqual(Buffer.from([24, 100, 1, 0, 0, 0, 32, 2]));
3464
+ expect(zclData.header.commandIdentifier).toBe(1);
3465
+ });
3466
+
3467
+ it.each([
3468
+ [2, "0x1234567812345678", 0x5678],
3469
+ [3, "0x1234567812345678", "0x1234567812345678"],
3470
+ ])("Incoming message extended (huge data byte count) - 16/64-bit address", async (srcAddrMode, addr, expParsedAddr) => {
3471
+ mockZnpRequestWith(incomingMsgExtHugeDataReqMock);
3472
+
3473
+ await adapter.start();
3474
+
3475
+ const responseFrame = Zcl.Frame.create(
3476
+ Zcl.FrameType.GLOBAL,
3477
+ Zcl.Direction.SERVER_TO_CLIENT,
3478
+ true,
3479
+ undefined,
3480
+ 100,
3481
+ "readRsp",
3482
+ 0,
3483
+ [
3484
+ {
3485
+ attrId: 0x1234,
3486
+ attrData: "", // can't put long string here - added below
3487
+ dataType: 0x44, // Long char string
3488
+ status: 0,
3489
+ },
3490
+ ],
3491
+ {},
3492
+ );
3493
+
3494
+ // Construct response frame manually as we exceed
3495
+ // the 250-byte limit of Zcl.Frame.toBuffer
3496
+
3497
+ const rspFrameBuf = responseFrame.toBuffer();
3498
+
3499
+ const zclLongString = Buffer.alloc(STR_500_BYTES.length + 2);
3500
+ zclLongString.writeUint16LE(Buffer.byteLength(STR_500_BYTES, "utf8"));
3501
+ zclLongString.write(STR_500_BYTES, 2, "utf8");
3502
+
3503
+ const response = Buffer.concat([
3504
+ rspFrameBuf.subarray(0, rspFrameBuf.length - 2), // remove existing ZCL long string len
3505
+ zclLongString,
3506
+ ]);
3507
+
3508
+ const object = mockZpiObject(Type.AREQ, Subsystem.AF, "incomingMsgExt", {
3509
+ groupid: 12,
3510
+ clusterid: 0,
3511
+ srcaddrmode: srcAddrMode,
3512
+ srcaddr: addr,
3513
+ srcendpoint: 20,
3514
+ //srcpanid
3515
+ dstendpoint: 1,
3516
+ //wasbroadcast
3517
+ linkquality: 101,
3518
+ //securityuse
3519
+ timestamp: 0x12345678,
3520
+ //transseqnumber
3521
+ len: response.length,
3522
+ data: Buffer.alloc(0),
3523
+ });
3524
+
3525
+ let resolveReceivedPayload: () => void;
3526
+ const receivedPayload = new Promise((resolve) => {
3527
+ resolveReceivedPayload = resolve;
3528
+ });
3529
+ let zclData;
3530
+ adapter.on("zclPayload", (p) => {
3531
+ zclData = p;
3532
+ resolveReceivedPayload();
3533
+ });
3534
+
3535
+ mockIncomingMsgExtSetHugeData(object.payload.timestamp, response);
3536
+ znpReceived(object);
3537
+
3538
+ await receivedPayload;
3539
+ expect(zclData.endpoint).toStrictEqual(20);
3540
+ expect(zclData.groupID).toStrictEqual(12);
3541
+ expect(zclData.linkquality).toStrictEqual(101);
3542
+ expect(zclData.address).toStrictEqual(expParsedAddr);
3543
+ expect(zclData.groupID).toStrictEqual(12);
3544
+ expect(zclData.data).toStrictEqual(
3545
+ Buffer.concat([
3546
+ Buffer.from([
3547
+ 24, // frame ctrl
3548
+ 100, // transseq
3549
+ 1, // read attr rsp
3550
+ 0x34, // attr id lsb
3551
+ 0x12, // attr id msb
3552
+ 0, // status
3553
+ 0x44, // data type
3554
+ ]),
3555
+ zclLongString, // 16-bit len + char data
3556
+ ]),
3557
+ );
3558
+ expect(zclData.header.commandIdentifier).toBe(1);
3559
+ });
3560
+
3561
+ it.each([
3562
+ [1, `dataRetrieve [timestamp: ${0x12345678}, index: ${0}, chunkSize: ${240}] error status: ${0x01}`],
3563
+ [2, `dataRetrieve length mismatch [${240} requested, ${240 + 1} returned`],
3564
+ ])("Incoming message extended (huge data byte count) with dataRetrieve error", async (mockErrType, expErrMsg) => {
3565
+ mockZnpRequestWith(incomingMsgExtHugeDataReqMock);
3566
+
3567
+ await adapter.start();
3568
+
3569
+ const responseFrame = Zcl.Frame.create(
3570
+ Zcl.FrameType.GLOBAL,
3571
+ Zcl.Direction.SERVER_TO_CLIENT,
3572
+ true,
3573
+ undefined,
3574
+ 100,
3575
+ "readRsp",
3576
+ 0,
3577
+ [
3578
+ {
3579
+ attrId: 0x1234,
3580
+ attrData: "", // can't put long string here - added below
3581
+ dataType: 0x44, // Long char string
3582
+ status: 0,
3583
+ },
3584
+ ],
3585
+ {},
3586
+ );
3587
+
3588
+ // Construct response frame manually as we exceed
3589
+ // the 250-byte limit of Zcl.Frame.toBuffer
3590
+
3591
+ const rspFrameBuf = responseFrame.toBuffer();
3592
+
3593
+ const zclLongString = Buffer.alloc(STR_500_BYTES.length + 2);
3594
+ zclLongString.writeUint16LE(Buffer.byteLength(STR_500_BYTES, "utf8"));
3595
+ zclLongString.write(STR_500_BYTES, 2, "utf8");
3596
+
3597
+ const response = Buffer.concat([
3598
+ rspFrameBuf.subarray(0, rspFrameBuf.length - 2), // remove existing ZCL long string len
3599
+ zclLongString,
3600
+ ]);
3601
+
3602
+ const object = mockZpiObject(Type.AREQ, Subsystem.AF, "incomingMsgExt", {
3603
+ groupid: 12,
3604
+ clusterid: 0,
3605
+ srcaddrmode: 2,
3606
+ srcaddr: "0x1234567812345678",
3607
+ srcendpoint: 20,
3608
+ //srcpanid
3609
+ dstendpoint: 1,
3610
+ //wasbroadcast
3611
+ linkquality: 101,
3612
+ //securityuse
3613
+ timestamp: 0x12345678,
3614
+ //transseqnumber
3615
+ len: response.length,
3616
+ data: Buffer.alloc(0),
3617
+ });
3618
+
3619
+ mockIncomingMsgExtSetHugeData(object.payload.timestamp, response, mockErrType);
3620
+ await znpReceived(object);
3621
+
3622
+ expect(mockLogger.error.mock.calls[0][0]).toBe(expErrMsg);
3623
+ // not captured by mock logger
3624
+ //expect(mockLogger.error.mock.calls[1][0]).toBe("Failed to retrieve chunked payload for incomingMsgExt");
3625
+ });
3626
+
3627
+ it("Incoming message raw (not ZCL)", async () => {
3628
+ basicMocks();
3629
+ await adapter.start();
3630
+ let rawData;
3631
+ const object = mockZpiObject(Type.AREQ, Subsystem.AF, "incomingMsg", {
3632
+ clusterid: 1,
3633
+ srcendpoint: 20,
3634
+ srcaddr: 2,
3635
+ linkquality: 101,
3636
+ groupid: 12,
3637
+ data: Buffer.from([0x0, 0x1]),
3638
+ });
3639
+ adapter.on("zclPayload", (p) => {
3640
+ rawData = p;
3641
+ });
3642
+ znpReceived(object);
3643
+ expect(rawData.clusterID).toStrictEqual(1);
3644
+ expect(rawData.endpoint).toStrictEqual(20);
3645
+ expect(rawData.groupID).toStrictEqual(12);
3646
+ expect(rawData.linkquality).toStrictEqual(101);
3647
+ expect(rawData.address).toStrictEqual(2);
3648
+ expect(rawData.data).toStrictEqual(Buffer.from([0x0, 0x01]));
3649
+ });
3650
+
3651
+ it("Adapter disconnected", async () => {
3652
+ basicMocks();
3653
+ await adapter.start();
3654
+ let closeEvent = false;
3655
+ adapter.on("disconnected", () => {
3656
+ closeEvent = true;
3657
+ });
3658
+ znpClose();
3659
+ expect(closeEvent).toBeTruthy();
3660
+ });
3661
+
3662
+ it("Adapter disconnected dont emit when closing", async () => {
3663
+ basicMocks();
3664
+ await adapter.start();
3665
+ await adapter.stop();
3666
+ let closeEvent = false;
3667
+ adapter.on("disconnected", () => {
3668
+ closeEvent = true;
3669
+ });
3670
+ znpClose();
3671
+ expect(closeEvent).toBeFalsy();
3672
+ });
3673
+
3674
+ it("Device joined", async () => {
3675
+ basicMocks();
3676
+ await adapter.start();
3677
+ let deviceJoin;
3678
+ const object = mockZpiObject(Type.AREQ, Subsystem.ZDO, "tcDeviceInd", {nwkaddr: 123, extaddr: "0x123"});
3679
+ adapter.on("deviceJoined", (p) => {
3680
+ deviceJoin = p;
3681
+ });
3682
+ znpReceived(object);
3683
+ expect(deviceJoin).toStrictEqual({ieeeAddr: "0x123", networkAddress: 123});
3684
+ });
3685
+
3686
+ it("Device announce", async () => {
3687
+ basicMocks();
3688
+ await adapter.start();
3689
+ mockZnpRequest.mockClear();
3690
+ mockQueueExecute.mockClear();
3691
+ const object = mockZdoZpiObject<EndDeviceAnnounce>("endDeviceAnnceInd", 123, [
3692
+ Zdo.Status.SUCCESS,
3693
+ {
3694
+ capabilities: DUMMY_NODE_DESC_RSP_CAPABILITIES,
3695
+ eui64: "0x123",
3696
+ nwkAddress: 123,
3697
+ },
3698
+ ]);
3699
+ adapter.on("zdoResponse", (clusterId, payload) => {
3700
+ expect(clusterId).toStrictEqual(Zdo.ClusterId.END_DEVICE_ANNOUNCE);
3701
+ expect(payload[0]).toStrictEqual(Zdo.Status.SUCCESS);
3702
+ expect(payload[1]).toStrictEqual({eui64: "0x123", nwkAddress: 123, capabilities: DUMMY_NODE_DESC_RSP_CAPABILITIES});
3703
+ });
3704
+ znpReceived(object);
3705
+ expect(mockZnpRequest).toHaveBeenCalledTimes(0);
3706
+ });
3707
+
3708
+ it("Device announce should discover route to end devices", async () => {
3709
+ basicMocks();
3710
+ await adapter.start();
3711
+ mockZnpRequest.mockClear();
3712
+ mockQueueExecute.mockClear();
3713
+ const object = mockZdoZpiObject<EndDeviceAnnounce>("endDeviceAnnceInd", 123, [
3714
+ Zdo.Status.SUCCESS,
3715
+ {
3716
+ capabilities: {...DUMMY_NODE_DESC_RSP_CAPABILITIES, deviceType: 0},
3717
+ eui64: "0x123",
3718
+ nwkAddress: 123,
3719
+ },
3720
+ ]);
3721
+ adapter.on("zdoResponse", (clusterId, payload) => {
3722
+ expect(clusterId).toStrictEqual(Zdo.ClusterId.END_DEVICE_ANNOUNCE);
3723
+ expect(payload[0]).toStrictEqual(Zdo.Status.SUCCESS);
3724
+ expect(payload[1]).toStrictEqual({eui64: "0x123", nwkAddress: 123, capabilities: {...DUMMY_NODE_DESC_RSP_CAPABILITIES, deviceType: 0}});
3725
+ });
3726
+ znpReceived(object);
3727
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
3728
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.ZDO, "extRouteDisc", {dstAddr: 123, options: 0, radius: 30});
3729
+
3730
+ // Should debounce route discovery.
3731
+ znpReceived(object);
3732
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
3733
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.ZDO, "extRouteDisc", {dstAddr: 123, options: 0, radius: 30});
3734
+ });
3735
+
3736
+ it("Network address response", async () => {
3737
+ basicMocks();
3738
+ await adapter.start();
3739
+ const object = mockZdoZpiObject<NetworkAddressResponse>("nwkAddrRsp", 124, [
3740
+ Zdo.Status.SUCCESS,
3741
+ {
3742
+ eui64: "0x123",
3743
+ nwkAddress: 124,
3744
+ assocDevList: [],
3745
+ startIndex: 0,
3746
+ },
3747
+ ]);
3748
+ adapter.on("zdoResponse", (clusterId, payload) => {
3749
+ expect(clusterId).toStrictEqual(Zdo.ClusterId.NETWORK_ADDRESS_RESPONSE);
3750
+ expect(payload[0]).toStrictEqual(Zdo.Status.SUCCESS);
3751
+ expect(payload[1]).toStrictEqual({eui64: "0x123", nwkAddress: 124, assocDevList: [], startIndex: 0});
3752
+ });
3753
+ znpReceived(object);
3754
+ });
3755
+
3756
+ it("Concentrator Callback Indication", async () => {
3757
+ basicMocks();
3758
+ await adapter.start();
3759
+ const object = mockZpiObject(Type.AREQ, Subsystem.ZDO, "concentratorIndCb", {srcaddr: 124, extaddr: "0x123"});
3760
+ adapter.on("zdoResponse", (clusterId, payload) => {
3761
+ expect(clusterId).toStrictEqual(Zdo.ClusterId.NETWORK_ADDRESS_RESPONSE);
3762
+ expect(payload[0]).toStrictEqual(Zdo.Status.SUCCESS);
3763
+ expect(payload[1]).toStrictEqual({eui64: "0x123", nwkAddress: 124, assocDevList: [], startIndex: 0});
3764
+ });
3765
+ znpReceived(object);
3766
+ });
3767
+
3768
+ it("Device leave", async () => {
3769
+ basicMocks();
3770
+ await adapter.start();
3771
+ let deviceAnnounce;
3772
+ const object = mockZpiObject(Type.AREQ, Subsystem.ZDO, "leaveInd", {srcaddr: 123, extaddr: "0x123"});
3773
+ adapter.on("deviceLeave", (p) => {
3774
+ deviceAnnounce = p;
3775
+ });
3776
+ znpReceived(object);
3777
+ expect(deviceAnnounce).toStrictEqual({ieeeAddr: "0x123", networkAddress: 123});
3778
+ });
3779
+
3780
+ it("Ignore device leave with rejoin", async () => {
3781
+ basicMocks();
3782
+ await adapter.start();
3783
+ let deviceAnnounce;
3784
+ const object = mockZpiObject(Type.AREQ, Subsystem.ZDO, "leaveInd", {srcaddr: 123, extaddr: "0x123", rejoin: true});
3785
+ adapter.on("deviceLeave", (p) => {
3786
+ deviceAnnounce = p;
3787
+ });
3788
+ znpReceived(object);
3789
+ expect(deviceAnnounce).toStrictEqual(undefined);
3790
+ });
3791
+
3792
+ it("Do nothing wiht non areq event", async () => {
3793
+ basicMocks();
3794
+ await adapter.start();
3795
+ let deviceLeave;
3796
+ const object = mockZpiObject(Type.SREQ, Subsystem.ZDO, "leaveInd", {srcaddr: 123, extaddr: "0x123"});
3797
+ adapter.on("deviceLeave", (p) => {
3798
+ deviceLeave = p;
3799
+ });
3800
+ znpReceived(object);
3801
+ expect(deviceLeave).toStrictEqual(undefined);
3802
+ });
3803
+
3804
+ it("Get network parameters", async () => {
3805
+ basicMocks();
3806
+ await adapter.start();
3807
+ mockZnpRequest.mockClear();
3808
+ mockQueueExecute.mockClear();
3809
+ const result = await adapter.getNetworkParameters();
3810
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
3811
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.ZDO, "extNwkInfo", {});
3812
+ expect(result).toStrictEqual({channel: 21, extendedPanID: "0x00124b0009d69f77", panID: 123, nwkUpdateID: 0});
3813
+ });
3814
+
3815
+ it("Set interpan channel", async () => {
3816
+ basicMocks();
3817
+ await adapter.start();
3818
+ mockZnpRequest.mockClear();
3819
+ mockQueueExecute.mockClear();
3820
+ await adapter.setChannelInterPAN(14);
3821
+ expect(mockZnpRequest).toHaveBeenCalledTimes(2);
3822
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.AF, "interPanCtl", {cmd: 1, data: [14]});
3823
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.AF, "interPanCtl", {cmd: 2, data: [12]});
3824
+
3825
+ mockZnpRequest.mockClear();
3826
+ mockQueueExecute.mockClear();
3827
+ await adapter.setChannelInterPAN(15);
3828
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
3829
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.AF, "interPanCtl", {cmd: 1, data: [15]});
3830
+ });
3831
+
3832
+ it("Restore interpan channel", async () => {
3833
+ basicMocks();
3834
+ await adapter.start();
3835
+ mockZnpRequest.mockClear();
3836
+ mockQueueExecute.mockClear();
3837
+ await adapter.restoreChannelInterPAN();
3838
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
3839
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.AF, "interPanCtl", {cmd: 0, data: []});
3840
+ });
3841
+
3842
+ it("Send zcl frame interpan", async () => {
3843
+ basicMocks();
3844
+ await adapter.start();
3845
+ mockZnpRequest.mockClear();
3846
+ mockQueueExecute.mockClear();
3847
+ await adapter.sendZclFrameInterPANToIeeeAddr(touchlinkIdentifyRequest, "0x0017880104c9cd33");
3848
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
3849
+ expect(mockZnpRequest).toHaveBeenCalledWith(
3850
+ 4,
3851
+ "dataRequestExt",
3852
+ {
3853
+ clusterid: 4096,
3854
+ data: touchlinkIdentifyRequest.toBuffer(),
3855
+ destendpoint: 254,
3856
+ dstaddr: "0x0017880104c9cd33",
3857
+ len: 9,
3858
+ options: 0,
3859
+ radius: 30,
3860
+ srcendpoint: 12,
3861
+ transid: 1,
3862
+ dstaddrmode: 3,
3863
+ dstpanid: 65535,
3864
+ },
3865
+ undefined,
3866
+ );
3867
+ });
3868
+
3869
+ it("Send zcl frame interpan with response", async () => {
3870
+ basicMocks();
3871
+ await adapter.start();
3872
+ mockZnpRequest.mockClear();
3873
+ mockQueueExecute.mockClear();
3874
+ const object = mockZpiObject(Type.AREQ, Subsystem.AF, "incomingMsgExt", {
3875
+ clusterid: 4096,
3876
+ srcendpoint: 0xfe,
3877
+ srcaddr: 12394,
3878
+ linkquality: 101,
3879
+ groupid: 0,
3880
+ data: touchlinkScanResponse.toBuffer(),
3881
+ });
3882
+
3883
+ let result: ZclPayload | Promise<ZclPayload> = adapter.sendZclFrameInterPANBroadcast(touchlinkScanRequest, 1000);
3884
+ znpReceived(object);
3885
+ result = await result;
3886
+
3887
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
3888
+ expect(mockZnpRequest).toHaveBeenCalledWith(
3889
+ 4,
3890
+ "dataRequestExt",
3891
+ {
3892
+ clusterid: 4096,
3893
+ data: touchlinkScanRequest.toBuffer(),
3894
+ destendpoint: 254,
3895
+ dstaddr: "0x000000000000ffff",
3896
+ len: 9,
3897
+ options: 0,
3898
+ radius: 30,
3899
+ srcendpoint: 12,
3900
+ transid: 1,
3901
+ dstaddrmode: 2,
3902
+ dstpanid: 65535,
3903
+ },
3904
+ undefined,
3905
+ );
3906
+ expect(deepClone(result)).toStrictEqual({
3907
+ clusterID: 4096,
3908
+ data: {
3909
+ type: "Buffer",
3910
+ data: [9, 12, 1, 1, 0, 0, 0, 10, 5, 6, 12, 0, 11, 0, 0, 0, 51, 205, 217, 4, 1, 33, 23, 0, 1, 12, 13, 0, 5, 0, 10, 5],
3911
+ },
3912
+ header: {
3913
+ frameControl: {frameType: 1, manufacturerSpecific: false, direction: 1, disableDefaultResponse: false, reservedBits: 0},
3914
+ transactionSequenceNumber: 12,
3915
+ commandIdentifier: 1,
3916
+ },
3917
+ address: 12394,
3918
+ endpoint: 254,
3919
+ linkquality: 101,
3920
+ groupID: 0,
3921
+ wasBroadcast: false,
3922
+ });
3923
+ });
3924
+
3925
+ it("Send zcl frame interpan throw exception when command has no response", async () => {
3926
+ basicMocks();
3927
+ await adapter.start();
3928
+ mockZnpRequest.mockClear();
3929
+ mockQueueExecute.mockClear();
3930
+ let error;
3931
+ try {
3932
+ await adapter.sendZclFrameInterPANBroadcast(touchlinkIdentifyRequest, 1000);
3933
+ } catch (e) {
3934
+ error = e;
3935
+ }
3936
+ expect(error).toStrictEqual(new Error(`Command 'identifyRequest' has no response, cannot wait for response`));
3937
+ });
3938
+
3939
+ it("Send zcl frame interpan throw exception data request fails", async () => {
3940
+ basicMocks();
3941
+ dataRequestExtCode = 99;
3942
+ await adapter.start();
3943
+ mockZnpRequest.mockClear();
3944
+ mockQueueExecute.mockClear();
3945
+ let error;
3946
+ try {
3947
+ await adapter.sendZclFrameInterPANBroadcast(touchlinkScanRequest, 1000);
3948
+ } catch (e) {
3949
+ error = e;
3950
+ }
3951
+ expect(error).toStrictEqual(new Error(`Data request failed with code '99'`));
3952
+ });
3953
+
3954
+ it("Refuse to start when ping fails", async () => {
3955
+ mockZnpRequest.mockImplementation((subsystem, command, payload, _expectedStatus) => {
3956
+ const missing = () => {
3957
+ const msg = `Not implemented - ${Subsystem[subsystem]} - ${command} - ${JSON.stringify(payload)}`;
3958
+ console.log(msg);
3959
+ throw new Error(msg);
3960
+ };
3961
+
3962
+ if (subsystem === Subsystem.SYS && command === "ping") {
3963
+ throw new Error("Couldnt lock port");
3964
+ }
3965
+
3966
+ missing();
3967
+ });
3968
+
3969
+ let error;
3970
+ try {
3971
+ await adapter.start();
3972
+ } catch (e) {
3973
+ error = e;
3974
+ }
3975
+ expect(error).toStrictEqual(new Error("Failed to connect to the adapter (Error: Couldnt lock port)"));
3976
+ });
3977
+
3978
+ it("Wait for", async () => {
3979
+ basicMocks();
3980
+ await adapter.start();
3981
+
3982
+ const responseFrame = Zcl.Frame.create(
3983
+ Zcl.FrameType.GLOBAL,
3984
+ Zcl.Direction.SERVER_TO_CLIENT,
3985
+ true,
3986
+ undefined,
3987
+ 100,
3988
+ "readRsp",
3989
+ 0,
3990
+ [{attrId: 0, attrData: 2, dataType: 32, status: 0}],
3991
+ {},
3992
+ );
3993
+ const object = mockZpiObject(Type.AREQ, Subsystem.AF, "incomingMsg", {
3994
+ clusterid: 0,
3995
+ srcendpoint: 20,
3996
+ srcaddr: 2,
3997
+ linkquality: 101,
3998
+ groupid: 12,
3999
+ data: responseFrame.toBuffer(),
4000
+ });
4001
+ const wait = adapter.waitFor(2, 20, 0, 1, 100, 0, 1, 10);
4002
+ znpReceived(object);
4003
+ const result = await wait.promise;
4004
+ expect(result.endpoint).toStrictEqual(20);
4005
+ expect(result.groupID).toStrictEqual(12);
4006
+ expect(result.linkquality).toStrictEqual(101);
4007
+ expect(result.address).toStrictEqual(2);
4008
+ expect(result.groupID).toStrictEqual(12);
4009
+ expect(result.data).toStrictEqual(Buffer.from([24, 100, 1, 0, 0, 0, 32, 2]));
4010
+ });
4011
+
4012
+ it("Command should fail when in interpan", async () => {
4013
+ const frame = Zcl.Frame.create(
4014
+ Zcl.FrameType.GLOBAL,
4015
+ Zcl.Direction.CLIENT_TO_SERVER,
4016
+ true,
4017
+ undefined,
4018
+ 100,
4019
+ "writeNoRsp",
4020
+ 0,
4021
+ [{attrId: 0, dataType: 0, attrData: null}],
4022
+ {},
4023
+ );
4024
+ basicMocks();
4025
+ await adapter.start();
4026
+
4027
+ await adapter.setChannelInterPAN(14);
4028
+ mockZnpRequest.mockClear();
4029
+ mockQueueExecute.mockClear();
4030
+ let error;
4031
+ try {
4032
+ await adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false);
4033
+ } catch (e) {
4034
+ error = e;
4035
+ }
4036
+ expect(error).toStrictEqual(new Error("Cannot execute command, in Inter-PAN mode"));
4037
+ expect(mockZnpRequest).toHaveBeenCalledTimes(0);
4038
+
4039
+ await adapter.restoreChannelInterPAN();
4040
+ mockZnpRequest.mockClear();
4041
+ mockQueueExecute.mockClear();
4042
+
4043
+ await adapter.sendZclFrameToEndpoint("0x02", 2, 20, frame, 10000, false, false);
4044
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
4045
+ });
4046
+
4047
+ it("Sends proper ZDO request payload for PERMIT_JOINING_REQUEST to target", async () => {
4048
+ basicMocks();
4049
+ await adapter.start();
4050
+ mockZnpRequestZdo.mockClear();
4051
+
4052
+ const clusterId = Zdo.ClusterId.PERMIT_JOINING_REQUEST;
4053
+ const zdoPayload = Zdo.Buffalo.buildRequest(false, clusterId, 250, 1, []);
4054
+
4055
+ await adapter.sendZdo("0x1122334455667788", 1234, clusterId, zdoPayload, true);
4056
+
4057
+ expect(mockZnpRequestZdo).toHaveBeenCalledWith(
4058
+ clusterId,
4059
+ Buffer.from([AddressMode.ADDR_16BIT, 1234 & 0xff, (1234 >> 8) & 0xff, ...zdoPayload]),
4060
+ undefined,
4061
+ );
4062
+ });
4063
+
4064
+ it("Sends proper ZDO request payload for PERMIT_JOINING_REQUEST broadcast", async () => {
4065
+ basicMocks();
4066
+ await adapter.start();
4067
+ mockZnpRequestZdo.mockClear();
4068
+
4069
+ const clusterId = Zdo.ClusterId.PERMIT_JOINING_REQUEST;
4070
+ const zdoPayload = Zdo.Buffalo.buildRequest(false, clusterId, 250, 1, []);
4071
+
4072
+ await adapter.sendZdo(ZSpec.BLANK_EUI64, ZSpec.BroadcastAddress.DEFAULT, clusterId, zdoPayload, true);
4073
+
4074
+ expect(mockZnpRequestZdo).toHaveBeenCalledWith(
4075
+ clusterId,
4076
+ Buffer.from([
4077
+ AddressMode.ADDR_BROADCAST,
4078
+ ZSpec.BroadcastAddress.DEFAULT & 0xff,
4079
+ (ZSpec.BroadcastAddress.DEFAULT >> 8) & 0xff,
4080
+ ...zdoPayload,
4081
+ ]),
4082
+ undefined,
4083
+ );
4084
+ });
4085
+
4086
+ it("Sends proper ZDO request payload for NWK_UPDATE_REQUEST UNICAST", async () => {
4087
+ basicMocks();
4088
+ await adapter.start();
4089
+ mockZnpRequestZdo.mockClear();
4090
+
4091
+ const clusterId = Zdo.ClusterId.NWK_UPDATE_REQUEST;
4092
+ const zdoPayload = Zdo.Buffalo.buildRequest(false, clusterId, [15], 0xfe, 0, undefined, 0);
4093
+ await adapter.sendZdo(ZSpec.BLANK_EUI64, 0x123, clusterId, zdoPayload, true);
4094
+
4095
+ expect(mockZnpRequestZdo).toHaveBeenCalledWith(
4096
+ clusterId,
4097
+ Buffer.from([
4098
+ 0x123 & 0xff,
4099
+ (0x123 >> 8) & 0xff,
4100
+ AddressMode.ADDR_16BIT,
4101
+ ...zdoPayload,
4102
+ 0, // scancount
4103
+ 0, // nwkmanageraddr
4104
+ 0, // nwkmanageraddr
4105
+ ]),
4106
+ undefined,
4107
+ );
4108
+ });
4109
+
4110
+ it("Sends proper ZDO request payload for NWK_UPDATE_REQUEST BROADCAST", async () => {
4111
+ basicMocks();
4112
+ await adapter.start();
4113
+ mockZnpRequestZdo.mockClear();
4114
+
4115
+ const clusterId = Zdo.ClusterId.NWK_UPDATE_REQUEST;
4116
+ const zdoPayload = Zdo.Buffalo.buildRequest(false, clusterId, [15], 0xfe, 0, undefined, 0);
4117
+ await adapter.sendZdo(ZSpec.BLANK_EUI64, ZSpec.BroadcastAddress.SLEEPY, clusterId, zdoPayload, true);
4118
+
4119
+ expect(mockZnpRequestZdo).toHaveBeenCalledWith(
4120
+ clusterId,
4121
+ Buffer.from([
4122
+ ZSpec.BroadcastAddress.SLEEPY & 0xff,
4123
+ (ZSpec.BroadcastAddress.SLEEPY >> 8) & 0xff,
4124
+ AddressMode.ADDR_BROADCAST,
4125
+ ...zdoPayload,
4126
+ 0, // scancount
4127
+ 0, // nwkmanageraddr
4128
+ 0, // nwkmanageraddr
4129
+ ]),
4130
+ undefined,
4131
+ );
4132
+ });
4133
+
4134
+ it("Sends proper ZDO request payload for BIND_REQUEST/UNBIND_REQUEST UNICAST", async () => {
4135
+ basicMocks();
4136
+ await adapter.start();
4137
+ mockZnpRequestZdo.mockClear();
4138
+
4139
+ const clusterId = Zdo.ClusterId.BIND_REQUEST;
4140
+ const zdoPayload = Zdo.Buffalo.buildRequest(
4141
+ false,
4142
+ clusterId,
4143
+ "0x1122334455667788",
4144
+ 3,
4145
+ Zcl.Clusters.barrierControl.ID,
4146
+ Zdo.UNICAST_BINDING,
4147
+ "0x5544332211667788",
4148
+ 0,
4149
+ 5,
4150
+ );
4151
+
4152
+ await adapter.sendZdo(ZSpec.BLANK_EUI64, 1234, clusterId, zdoPayload, true);
4153
+
4154
+ expect(mockZnpRequestZdo).toHaveBeenCalledWith(clusterId, Buffer.from([1234 & 0xff, (1234 >> 8) & 0xff, ...zdoPayload]), undefined);
4155
+ });
4156
+
4157
+ it("Sends proper ZDO request payload for BIND_REQUEST/UNBIND_REQUEST MULTICAST", async () => {
4158
+ basicMocks();
4159
+ await adapter.start();
4160
+ mockZnpRequestZdo.mockClear();
4161
+
4162
+ const clusterId = Zdo.ClusterId.BIND_REQUEST;
4163
+ const zdoPayload = Zdo.Buffalo.buildRequest(
4164
+ false,
4165
+ clusterId,
4166
+ "0x1122334455667788",
4167
+ 3,
4168
+ Zcl.Clusters.barrierControl.ID,
4169
+ Zdo.MULTICAST_BINDING,
4170
+ ZSpec.BLANK_EUI64,
4171
+ 32,
4172
+ 0,
4173
+ );
4174
+
4175
+ await adapter.sendZdo(ZSpec.BLANK_EUI64, 1234, clusterId, zdoPayload, true);
4176
+
4177
+ expect(mockZnpRequestZdo).toHaveBeenCalledWith(
4178
+ clusterId,
4179
+ Buffer.from([
4180
+ 1234 & 0xff,
4181
+ (1234 >> 8) & 0xff,
4182
+ ...zdoPayload,
4183
+ 0, // match destination EUI64 length
4184
+ 0, // match destination EUI64 length
4185
+ 0, // match destination EUI64 length
4186
+ 0, // match destination EUI64 length
4187
+ 0, // match destination EUI64 length
4188
+ 0, // match destination EUI64 length
4189
+ 0, // endpoint
4190
+ ]),
4191
+ undefined,
4192
+ );
4193
+ });
4194
+
4195
+ it("Sends proper ZDO request payload for NETWORK_ADDRESS_REQUEST", async () => {
4196
+ basicMocks();
4197
+ await adapter.start();
4198
+ mockZnpRequestZdo.mockClear();
4199
+
4200
+ const clusterId = Zdo.ClusterId.NETWORK_ADDRESS_REQUEST;
4201
+ const zdoPayload = Zdo.Buffalo.buildRequest(false, clusterId, "0x1122334455667788", false, 0);
4202
+
4203
+ await adapter.sendZdo(ZSpec.BLANK_EUI64, 1234, clusterId, zdoPayload, true);
4204
+
4205
+ expect(mockZnpRequestZdo).toHaveBeenCalledWith(clusterId, zdoPayload, undefined);
4206
+ });
4207
+
4208
+ it("Sends proper ZDO request payload for generic logic request", async () => {
4209
+ basicMocks();
4210
+ await adapter.start();
4211
+ mockZnpRequestZdo.mockClear();
4212
+
4213
+ const clusterId = Zdo.ClusterId.NODE_DESCRIPTOR_REQUEST;
4214
+ const zdoPayload = Zdo.Buffalo.buildRequest(false, clusterId, 1234);
4215
+
4216
+ await adapter.sendZdo(ZSpec.BLANK_EUI64, 1234, clusterId, zdoPayload, true);
4217
+
4218
+ expect(mockZnpRequestZdo).toHaveBeenCalledWith(clusterId, Buffer.from([1234 & 0xff, (1234 >> 8) & 0xff, ...zdoPayload]), undefined);
4219
+ });
4220
+
4221
+ it("Node descriptor request should discover route to fix potential fails", async () => {
4222
+ // https://github.com/Koenkk/zigbee2mqtt/issues/3276
4223
+ basicMocks();
4224
+ await adapter.start();
4225
+ mockZnpRequest.mockClear();
4226
+ mockZnpRequestZdo.mockClear();
4227
+ mockZnpRequestZdo.mockRejectedValueOnce(new Error("Failed"));
4228
+
4229
+ const clusterId = Zdo.ClusterId.NODE_DESCRIPTOR_REQUEST;
4230
+ const zdoPayload = Zdo.Buffalo.buildRequest(false, clusterId, 1234);
4231
+
4232
+ await adapter.sendZdo(ZSpec.BLANK_EUI64, 1234, clusterId, zdoPayload, true);
4233
+
4234
+ expect(mockZnpRequestZdo).toHaveBeenCalledTimes(2);
4235
+ expect(mockZnpRequestZdo).toHaveBeenNthCalledWith(1, clusterId, Buffer.from([1234 & 0xff, (1234 >> 8) & 0xff, ...zdoPayload]), undefined);
4236
+ expect(mockZnpRequestZdo).toHaveBeenNthCalledWith(2, clusterId, Buffer.from([1234 & 0xff, (1234 >> 8) & 0xff, ...zdoPayload]), undefined);
4237
+ expect(mockZnpRequest).toHaveBeenCalledTimes(1);
4238
+ expect(mockZnpRequest).toHaveBeenCalledWith(Subsystem.ZDO, "extRouteDisc", {dstAddr: 1234, options: 0, radius: 30});
4239
+ });
4240
+
4241
+ it("Should throw error when ZDO call fails", async () => {
4242
+ basicMocks();
4243
+ await adapter.start();
4244
+ mockZnpRequest.mockClear();
4245
+ mockZnpRequestZdo.mockClear();
4246
+ mockZnpRequestZdo.mockRejectedValueOnce(new Error("Failed"));
4247
+
4248
+ const clusterId = Zdo.ClusterId.SIMPLE_DESCRIPTOR_REQUEST;
4249
+ const zdoPayload = Zdo.Buffalo.buildRequest(false, clusterId, 123, 0);
4250
+
4251
+ await expect(adapter.sendZdo(ZSpec.BLANK_EUI64, 1234, clusterId, zdoPayload, true)).rejects.toThrow("Failed");
4252
+ });
4253
+
4254
+ it("Should throw error when registerEndpoints fails", async () => {
4255
+ basicMocks();
4256
+ vi.spyOn(adapter, "sendZdo").mockResolvedValueOnce([Zdo.Status.NOT_ACTIVE, undefined]);
4257
+
4258
+ await expect(adapter.start()).rejects.toThrow(`Status 'NOT_ACTIVE'`);
4259
+ });
4260
+ });