@willieee802/zigbee-herdsman 0.34.3 → 0.48.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +403 -0
- package/dist/adapter/adapter.d.ts +14 -13
- package/dist/adapter/adapter.d.ts.map +1 -1
- package/dist/adapter/adapter.js +15 -17
- package/dist/adapter/adapter.js.map +1 -1
- package/dist/adapter/deconz/adapter/deconzAdapter.d.ts +14 -12
- package/dist/adapter/deconz/adapter/deconzAdapter.d.ts.map +1 -1
- package/dist/adapter/deconz/adapter/deconzAdapter.js +118 -128
- package/dist/adapter/deconz/adapter/deconzAdapter.js.map +1 -1
- package/dist/adapter/deconz/driver/driver.d.ts.map +1 -1
- package/dist/adapter/deconz/driver/driver.js +44 -44
- package/dist/adapter/deconz/driver/driver.js.map +1 -1
- package/dist/adapter/deconz/driver/frameParser.js +43 -43
- package/dist/adapter/deconz/driver/frameParser.js.map +1 -1
- package/dist/adapter/deconz/driver/parser.js +6 -6
- package/dist/adapter/deconz/driver/parser.js.map +1 -1
- package/dist/adapter/deconz/driver/writer.js +3 -3
- package/dist/adapter/deconz/driver/writer.js.map +1 -1
- package/dist/adapter/ember/adapter/emberAdapter.d.ts +60 -71
- package/dist/adapter/ember/adapter/emberAdapter.d.ts.map +1 -1
- package/dist/adapter/ember/adapter/emberAdapter.js +453 -492
- package/dist/adapter/ember/adapter/emberAdapter.js.map +1 -1
- package/dist/adapter/ember/adapter/endpoints.d.ts +5 -3
- package/dist/adapter/ember/adapter/endpoints.d.ts.map +1 -1
- package/dist/adapter/ember/adapter/endpoints.js +33 -31
- package/dist/adapter/ember/adapter/endpoints.js.map +1 -1
- package/dist/adapter/ember/adapter/oneWaitress.d.ts +16 -5
- package/dist/adapter/ember/adapter/oneWaitress.d.ts.map +1 -1
- package/dist/adapter/ember/adapter/oneWaitress.js +19 -4
- package/dist/adapter/ember/adapter/oneWaitress.js.map +1 -1
- package/dist/adapter/ember/adapter/requestQueue.d.ts +2 -4
- package/dist/adapter/ember/adapter/requestQueue.d.ts.map +1 -1
- package/dist/adapter/ember/adapter/requestQueue.js +17 -22
- package/dist/adapter/ember/adapter/requestQueue.js.map +1 -1
- package/dist/adapter/ember/adapter/tokensManager.d.ts.map +1 -1
- package/dist/adapter/ember/adapter/tokensManager.js +23 -20
- package/dist/adapter/ember/adapter/tokensManager.js.map +1 -1
- package/dist/adapter/ember/consts.d.ts +0 -7
- package/dist/adapter/ember/consts.d.ts.map +1 -1
- package/dist/adapter/ember/consts.js +2 -9
- package/dist/adapter/ember/consts.js.map +1 -1
- package/dist/adapter/ember/enums.d.ts +133 -145
- package/dist/adapter/ember/enums.d.ts.map +1 -1
- package/dist/adapter/ember/enums.js +132 -148
- package/dist/adapter/ember/enums.js.map +1 -1
- package/dist/adapter/ember/ezsp/buffalo.js +4 -4
- package/dist/adapter/ember/ezsp/buffalo.js.map +1 -1
- package/dist/adapter/ember/ezsp/ezsp.d.ts +1 -3
- package/dist/adapter/ember/ezsp/ezsp.d.ts.map +1 -1
- package/dist/adapter/ember/ezsp/ezsp.js +224 -208
- package/dist/adapter/ember/ezsp/ezsp.js.map +1 -1
- package/dist/adapter/ember/types.d.ts +9 -9
- package/dist/adapter/ember/types.d.ts.map +1 -1
- package/dist/adapter/ember/uart/ash.d.ts +27 -14
- package/dist/adapter/ember/uart/ash.d.ts.map +1 -1
- package/dist/adapter/ember/uart/ash.js +158 -109
- package/dist/adapter/ember/uart/ash.js.map +1 -1
- package/dist/adapter/ember/uart/consts.d.ts +1 -1
- package/dist/adapter/ember/uart/consts.js +1 -1
- package/dist/adapter/ember/uart/parser.d.ts.map +1 -1
- package/dist/adapter/ember/uart/parser.js +5 -9
- package/dist/adapter/ember/uart/parser.js.map +1 -1
- package/dist/adapter/ember/uart/queues.d.ts.map +1 -1
- package/dist/adapter/ember/uart/queues.js +3 -1
- package/dist/adapter/ember/uart/queues.js.map +1 -1
- package/dist/adapter/ember/uart/writer.d.ts.map +1 -1
- package/dist/adapter/ember/uart/writer.js +4 -6
- package/dist/adapter/ember/uart/writer.js.map +1 -1
- package/dist/adapter/ember/zdo.d.ts +6 -2
- package/dist/adapter/ember/zdo.d.ts.map +1 -1
- package/dist/adapter/ember/zdo.js +2 -2
- package/dist/adapter/ember/zdo.js.map +1 -1
- package/dist/adapter/events.d.ts +17 -23
- package/dist/adapter/events.d.ts.map +1 -1
- package/dist/adapter/events.js +1 -2
- package/dist/adapter/events.js.map +1 -1
- package/dist/adapter/ezsp/adapter/backup.d.ts +4 -1
- package/dist/adapter/ezsp/adapter/backup.d.ts.map +1 -1
- package/dist/adapter/ezsp/adapter/backup.js +35 -7
- package/dist/adapter/ezsp/adapter/backup.js.map +1 -1
- package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts +12 -9
- package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts.map +1 -1
- package/dist/adapter/ezsp/adapter/ezspAdapter.js +79 -75
- package/dist/adapter/ezsp/adapter/ezspAdapter.js.map +1 -1
- package/dist/adapter/ezsp/driver/commands.d.ts.map +1 -1
- package/dist/adapter/ezsp/driver/commands.js +3 -5
- package/dist/adapter/ezsp/driver/commands.js.map +1 -1
- package/dist/adapter/ezsp/driver/driver.d.ts +4 -2
- package/dist/adapter/ezsp/driver/driver.d.ts.map +1 -1
- package/dist/adapter/ezsp/driver/driver.js +183 -119
- package/dist/adapter/ezsp/driver/driver.js.map +1 -1
- package/dist/adapter/ezsp/driver/ezsp.d.ts.map +1 -1
- package/dist/adapter/ezsp/driver/ezsp.js +62 -50
- package/dist/adapter/ezsp/driver/ezsp.js.map +1 -1
- package/dist/adapter/ezsp/driver/multicast.d.ts.map +1 -1
- package/dist/adapter/ezsp/driver/multicast.js +8 -12
- package/dist/adapter/ezsp/driver/multicast.js.map +1 -1
- package/dist/adapter/ezsp/driver/parser.js +5 -5
- package/dist/adapter/ezsp/driver/parser.js.map +1 -1
- package/dist/adapter/ezsp/driver/types/basic.js +1 -1
- package/dist/adapter/ezsp/driver/types/basic.js.map +1 -1
- package/dist/adapter/ezsp/driver/types/named.js +2 -2
- package/dist/adapter/ezsp/driver/types/named.js.map +1 -1
- package/dist/adapter/ezsp/driver/types/struct.d.ts +1 -1
- package/dist/adapter/ezsp/driver/types/struct.d.ts.map +1 -1
- package/dist/adapter/ezsp/driver/types/struct.js +2 -2
- package/dist/adapter/ezsp/driver/types/struct.js.map +1 -1
- package/dist/adapter/ezsp/driver/uart.d.ts.map +1 -1
- package/dist/adapter/ezsp/driver/uart.js +46 -46
- package/dist/adapter/ezsp/driver/uart.js.map +1 -1
- package/dist/adapter/ezsp/driver/utils/index.d.ts +2 -1
- package/dist/adapter/ezsp/driver/utils/index.d.ts.map +1 -1
- package/dist/adapter/ezsp/driver/utils/index.js +2 -2
- package/dist/adapter/ezsp/driver/utils/index.js.map +1 -1
- package/dist/adapter/ezsp/driver/writer.js +3 -6
- package/dist/adapter/ezsp/driver/writer.js.map +1 -1
- package/dist/adapter/serialPort.d.ts +3 -0
- package/dist/adapter/serialPort.d.ts.map +1 -1
- package/dist/adapter/serialPort.js +16 -23
- package/dist/adapter/serialPort.js.map +1 -1
- package/dist/adapter/z-stack/adapter/adapter-backup.d.ts +0 -1
- package/dist/adapter/z-stack/adapter/adapter-backup.d.ts.map +1 -1
- package/dist/adapter/z-stack/adapter/adapter-backup.js +25 -29
- package/dist/adapter/z-stack/adapter/adapter-backup.js.map +1 -1
- package/dist/adapter/z-stack/adapter/endpoints.js +4 -4
- package/dist/adapter/z-stack/adapter/endpoints.js.map +1 -1
- package/dist/adapter/z-stack/adapter/manager.d.ts +1 -4
- package/dist/adapter/z-stack/adapter/manager.d.ts.map +1 -1
- package/dist/adapter/z-stack/adapter/manager.js +52 -61
- package/dist/adapter/z-stack/adapter/manager.js.map +1 -1
- package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts +12 -10
- package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts.map +1 -1
- package/dist/adapter/z-stack/adapter/zStackAdapter.js +102 -84
- package/dist/adapter/z-stack/adapter/zStackAdapter.js.map +1 -1
- package/dist/adapter/z-stack/unpi/parser.js +6 -6
- package/dist/adapter/z-stack/unpi/parser.js.map +1 -1
- package/dist/adapter/z-stack/unpi/writer.js +4 -7
- package/dist/adapter/z-stack/unpi/writer.js.map +1 -1
- package/dist/adapter/z-stack/znp/buffaloZnp.d.ts +4 -2
- package/dist/adapter/z-stack/znp/buffaloZnp.d.ts.map +1 -1
- package/dist/adapter/z-stack/znp/buffaloZnp.js +154 -25
- package/dist/adapter/z-stack/znp/buffaloZnp.js.map +1 -1
- package/dist/adapter/z-stack/znp/definition.d.ts.map +1 -1
- package/dist/adapter/z-stack/znp/definition.js +2 -1
- package/dist/adapter/z-stack/znp/definition.js.map +1 -1
- package/dist/adapter/z-stack/znp/tstype.d.ts +4 -3
- package/dist/adapter/z-stack/znp/tstype.d.ts.map +1 -1
- package/dist/adapter/z-stack/znp/znp.d.ts.map +1 -1
- package/dist/adapter/z-stack/znp/znp.js +18 -25
- package/dist/adapter/z-stack/znp/znp.js.map +1 -1
- package/dist/adapter/z-stack/znp/zpiObject.js +2 -2
- package/dist/adapter/z-stack/znp/zpiObject.js.map +1 -1
- package/dist/adapter/zigate/adapter/zigateAdapter.d.ts +13 -12
- package/dist/adapter/zigate/adapter/zigateAdapter.d.ts.map +1 -1
- package/dist/adapter/zigate/adapter/zigateAdapter.js +81 -90
- package/dist/adapter/zigate/adapter/zigateAdapter.js.map +1 -1
- package/dist/adapter/zigate/driver/buffaloZiGate.d.ts +7 -8
- package/dist/adapter/zigate/driver/buffaloZiGate.d.ts.map +1 -1
- package/dist/adapter/zigate/driver/buffaloZiGate.js +150 -100
- package/dist/adapter/zigate/driver/buffaloZiGate.js.map +1 -1
- package/dist/adapter/zigate/driver/commandType.d.ts +2 -1
- package/dist/adapter/zigate/driver/commandType.d.ts.map +1 -1
- package/dist/adapter/zigate/driver/commandType.js +56 -52
- package/dist/adapter/zigate/driver/commandType.js.map +1 -1
- package/dist/adapter/zigate/driver/frame.d.ts.map +1 -1
- package/dist/adapter/zigate/driver/frame.js +8 -8
- package/dist/adapter/zigate/driver/frame.js.map +1 -1
- package/dist/adapter/zigate/driver/messageType.d.ts +2 -1
- package/dist/adapter/zigate/driver/messageType.d.ts.map +1 -1
- package/dist/adapter/zigate/driver/messageType.js +113 -108
- package/dist/adapter/zigate/driver/messageType.js.map +1 -1
- package/dist/adapter/zigate/driver/parameterType.d.ts +8 -1
- package/dist/adapter/zigate/driver/parameterType.d.ts.map +1 -1
- package/dist/adapter/zigate/driver/parameterType.js +9 -0
- package/dist/adapter/zigate/driver/parameterType.js.map +1 -1
- package/dist/adapter/zigate/driver/ziGateObject.d.ts.map +1 -1
- package/dist/adapter/zigate/driver/ziGateObject.js +9 -9
- package/dist/adapter/zigate/driver/ziGateObject.js.map +1 -1
- package/dist/adapter/zigate/driver/zigate.d.ts.map +1 -1
- package/dist/adapter/zigate/driver/zigate.js +23 -31
- package/dist/adapter/zigate/driver/zigate.js.map +1 -1
- package/dist/buffalo/buffalo.d.ts +23 -19
- package/dist/buffalo/buffalo.d.ts.map +1 -1
- package/dist/buffalo/buffalo.js +74 -169
- package/dist/buffalo/buffalo.js.map +1 -1
- package/dist/buffalo/index.d.ts +1 -2
- package/dist/buffalo/index.d.ts.map +1 -1
- package/dist/buffalo/index.js +1 -26
- package/dist/buffalo/index.js.map +1 -1
- package/dist/controller/controller.d.ts +8 -5
- package/dist/controller/controller.d.ts.map +1 -1
- package/dist/controller/controller.js +181 -126
- package/dist/controller/controller.js.map +1 -1
- package/dist/controller/database.d.ts +1 -0
- package/dist/controller/database.d.ts.map +1 -1
- package/dist/controller/database.js +7 -10
- package/dist/controller/database.js.map +1 -1
- package/dist/controller/events.d.ts +2 -2
- package/dist/controller/events.d.ts.map +1 -1
- package/dist/controller/events.js +4 -0
- package/dist/controller/events.js.map +1 -1
- package/dist/controller/greenPower.d.ts +2 -1
- package/dist/controller/greenPower.d.ts.map +1 -1
- package/dist/controller/greenPower.js +51 -57
- package/dist/controller/greenPower.js.map +1 -1
- package/dist/controller/helpers/request.d.ts +3 -3
- package/dist/controller/helpers/request.d.ts.map +1 -1
- package/dist/controller/helpers/request.js +2 -2
- package/dist/controller/helpers/request.js.map +1 -1
- package/dist/controller/helpers/requestQueue.d.ts.map +1 -1
- package/dist/controller/helpers/requestQueue.js +26 -36
- package/dist/controller/helpers/requestQueue.js.map +1 -1
- package/dist/controller/helpers/zclFrameConverter.d.ts +4 -3
- package/dist/controller/helpers/zclFrameConverter.d.ts.map +1 -1
- package/dist/controller/helpers/zclFrameConverter.js +33 -14
- package/dist/controller/helpers/zclFrameConverter.js.map +1 -1
- package/dist/controller/model/device.d.ts +12 -5
- package/dist/controller/model/device.d.ts.map +1 -1
- package/dist/controller/model/device.js +108 -87
- package/dist/controller/model/device.js.map +1 -1
- package/dist/controller/model/endpoint.d.ts +22 -17
- package/dist/controller/model/endpoint.d.ts.map +1 -1
- package/dist/controller/model/endpoint.js +139 -228
- package/dist/controller/model/endpoint.js.map +1 -1
- package/dist/controller/model/group.d.ts +1 -1
- package/dist/controller/model/group.d.ts.map +1 -1
- package/dist/controller/model/group.js +18 -18
- package/dist/controller/model/group.js.map +1 -1
- package/dist/controller/touchlink.js +25 -28
- package/dist/controller/touchlink.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -5
- package/dist/index.js.map +1 -1
- package/dist/utils/logger.d.ts +9 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +14 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/zspec/consts.d.ts +60 -0
- package/dist/zspec/consts.d.ts.map +1 -0
- package/dist/zspec/consts.js +64 -0
- package/dist/zspec/consts.js.map +1 -0
- package/dist/zspec/enums.d.ts +19 -0
- package/dist/zspec/enums.d.ts.map +1 -0
- package/dist/zspec/enums.js +28 -0
- package/dist/zspec/enums.js.map +1 -0
- package/dist/zspec/index.d.ts +4 -0
- package/dist/zspec/index.d.ts.map +1 -0
- package/dist/zspec/index.js +43 -0
- package/dist/zspec/index.js.map +1 -0
- package/dist/zspec/tstypes.d.ts +19 -0
- package/dist/zspec/tstypes.d.ts.map +1 -0
- package/dist/{buffalo/tstype.js → zspec/tstypes.js} +1 -1
- package/dist/zspec/tstypes.js.map +1 -0
- package/dist/zspec/utils.d.ts +14 -0
- package/dist/zspec/utils.d.ts.map +1 -0
- package/dist/zspec/utils.js +29 -0
- package/dist/zspec/utils.js.map +1 -0
- package/dist/zspec/zcl/buffaloZcl.d.ts +55 -0
- package/dist/zspec/zcl/buffaloZcl.d.ts.map +1 -0
- package/dist/zspec/zcl/buffaloZcl.js +929 -0
- package/dist/zspec/zcl/buffaloZcl.js.map +1 -0
- package/dist/zspec/zcl/definition/cluster.d.ts +3 -0
- package/dist/zspec/zcl/definition/cluster.d.ts.map +1 -0
- package/dist/zspec/zcl/definition/cluster.js +5500 -0
- package/dist/zspec/zcl/definition/cluster.js.map +1 -0
- package/dist/zspec/zcl/definition/consts.d.ts +9 -0
- package/dist/zspec/zcl/definition/consts.d.ts.map +1 -0
- package/dist/zspec/zcl/definition/consts.js +27 -0
- package/dist/zspec/zcl/definition/consts.js.map +1 -0
- package/dist/zspec/zcl/definition/enums.d.ts +177 -0
- package/dist/zspec/zcl/definition/enums.d.ts.map +1 -0
- package/dist/zspec/zcl/definition/enums.js +187 -0
- package/dist/zspec/zcl/definition/enums.js.map +1 -0
- package/dist/zspec/zcl/definition/foundation.d.ts +11 -0
- package/dist/zspec/zcl/definition/foundation.d.ts.map +1 -0
- package/dist/zspec/zcl/definition/foundation.js +241 -0
- package/dist/zspec/zcl/definition/foundation.js.map +1 -0
- package/dist/zspec/zcl/definition/manufacturerCode.d.ts +727 -0
- package/dist/zspec/zcl/definition/manufacturerCode.d.ts.map +1 -0
- package/dist/zspec/zcl/definition/manufacturerCode.js +733 -0
- package/dist/zspec/zcl/definition/manufacturerCode.js.map +1 -0
- package/dist/zspec/zcl/definition/status.d.ts +69 -0
- package/dist/zspec/zcl/definition/status.d.ts.map +1 -0
- package/dist/zspec/zcl/definition/status.js +74 -0
- package/dist/zspec/zcl/definition/status.js.map +1 -0
- package/dist/zspec/zcl/definition/tstype.d.ts +114 -0
- package/dist/zspec/zcl/definition/tstype.d.ts.map +1 -0
- package/dist/{zcl/zclHeader.js → zspec/zcl/definition/tstype.js} +2 -1
- package/dist/zspec/zcl/definition/tstype.js.map +1 -0
- package/dist/zspec/zcl/index.d.ts +11 -0
- package/dist/zspec/zcl/index.d.ts.map +1 -0
- package/dist/zspec/zcl/index.js +47 -0
- package/dist/zspec/zcl/index.js.map +1 -0
- package/dist/zspec/zcl/utils.d.ts +7 -0
- package/dist/zspec/zcl/utils.d.ts.map +1 -0
- package/dist/zspec/zcl/utils.js +234 -0
- package/dist/zspec/zcl/utils.js.map +1 -0
- package/dist/zspec/zcl/zclFrame.d.ts +36 -0
- package/dist/zspec/zcl/zclFrame.d.ts.map +1 -0
- package/dist/zspec/zcl/zclFrame.js +304 -0
- package/dist/zspec/zcl/zclFrame.js.map +1 -0
- package/dist/zspec/zcl/zclHeader.d.ts +17 -0
- package/dist/zspec/zcl/zclHeader.d.ts.map +1 -0
- package/dist/zspec/zcl/zclHeader.js +88 -0
- package/dist/zspec/zcl/zclHeader.js.map +1 -0
- package/dist/zspec/zcl/zclStatusError.d.ts +6 -0
- package/dist/zspec/zcl/zclStatusError.d.ts.map +1 -0
- package/dist/zspec/zcl/zclStatusError.js +13 -0
- package/dist/zspec/zcl/zclStatusError.js.map +1 -0
- package/dist/zspec/zdo/buffaloZdo.d.ts +438 -0
- package/dist/zspec/zdo/buffaloZdo.d.ts.map +1 -0
- package/dist/zspec/zdo/buffaloZdo.js +1892 -0
- package/dist/zspec/zdo/buffaloZdo.js.map +1 -0
- package/dist/zspec/zdo/definition/clusters.d.ts +624 -0
- package/dist/zspec/zdo/definition/clusters.d.ts.map +1 -0
- package/dist/zspec/zdo/definition/clusters.js +687 -0
- package/dist/zspec/zdo/definition/clusters.js.map +1 -0
- package/dist/zspec/zdo/definition/consts.d.ts +13 -0
- package/dist/zspec/zdo/definition/consts.d.ts.map +1 -0
- package/dist/zspec/zdo/definition/consts.js +16 -0
- package/dist/zspec/zdo/definition/consts.js.map +1 -0
- package/dist/zspec/zdo/definition/enums.d.ts +75 -0
- package/dist/zspec/zdo/definition/enums.d.ts.map +1 -0
- package/dist/zspec/zdo/definition/enums.js +97 -0
- package/dist/zspec/zdo/definition/enums.js.map +1 -0
- package/dist/zspec/zdo/definition/status.d.ts +99 -0
- package/dist/zspec/zdo/definition/status.d.ts.map +1 -0
- package/dist/zspec/zdo/definition/status.js +109 -0
- package/dist/zspec/zdo/definition/status.js.map +1 -0
- package/dist/zspec/zdo/definition/tstypes.d.ts +787 -0
- package/dist/zspec/zdo/definition/tstypes.d.ts.map +1 -0
- package/dist/{zcl/definition/tstype.js → zspec/zdo/definition/tstypes.js} +1 -1
- package/dist/zspec/zdo/definition/tstypes.js.map +1 -0
- package/dist/zspec/zdo/index.d.ts +7 -0
- package/dist/zspec/zdo/index.d.ts.map +1 -0
- package/dist/zspec/zdo/index.js +39 -0
- package/dist/zspec/zdo/index.js.map +1 -0
- package/dist/zspec/zdo/utils.d.ts +25 -0
- package/dist/zspec/zdo/utils.d.ts.map +1 -0
- package/dist/zspec/zdo/utils.js +75 -0
- package/dist/zspec/zdo/utils.js.map +1 -0
- package/dist/zspec/zdo/zdoStatusError.d.ts +6 -0
- package/dist/zspec/zdo/zdoStatusError.d.ts.map +1 -0
- package/dist/zspec/zdo/zdoStatusError.js +13 -0
- package/dist/zspec/zdo/zdoStatusError.js.map +1 -0
- package/examples/join-and-log.js +7 -12
- package/package.json +5 -5
- package/dist/adapter/zigate/debug.d.ts +0 -8
- package/dist/adapter/zigate/debug.d.ts.map +0 -1
- package/dist/adapter/zigate/debug.js +0 -20
- package/dist/adapter/zigate/debug.js.map +0 -1
- package/dist/buffalo/tstype.d.ts +0 -9
- package/dist/buffalo/tstype.d.ts.map +0 -1
- package/dist/buffalo/tstype.js.map +0 -1
- package/dist/controller/logger-stub.d.ts +0 -7
- package/dist/controller/logger-stub.d.ts.map +0 -1
- package/dist/controller/logger-stub.js +0 -3
- package/dist/controller/logger-stub.js.map +0 -1
- package/dist/zcl/buffaloZcl.d.ts +0 -42
- package/dist/zcl/buffaloZcl.d.ts.map +0 -1
- package/dist/zcl/buffaloZcl.js +0 -595
- package/dist/zcl/buffaloZcl.js.map +0 -1
- package/dist/zcl/definition/buffaloZclDataType.d.ts +0 -18
- package/dist/zcl/definition/buffaloZclDataType.d.ts.map +0 -1
- package/dist/zcl/definition/buffaloZclDataType.js +0 -21
- package/dist/zcl/definition/buffaloZclDataType.js.map +0 -1
- package/dist/zcl/definition/cluster.d.ts +0 -30
- package/dist/zcl/definition/cluster.d.ts.map +0 -1
- package/dist/zcl/definition/cluster.js +0 -5521
- package/dist/zcl/definition/cluster.js.map +0 -1
- package/dist/zcl/definition/dataType.d.ts +0 -60
- package/dist/zcl/definition/dataType.d.ts.map +0 -1
- package/dist/zcl/definition/dataType.js +0 -65
- package/dist/zcl/definition/dataType.js.map +0 -1
- package/dist/zcl/definition/direction.d.ts +0 -6
- package/dist/zcl/definition/direction.d.ts.map +0 -1
- package/dist/zcl/definition/direction.js +0 -9
- package/dist/zcl/definition/direction.js.map +0 -1
- package/dist/zcl/definition/endpointDeviceType.d.ts +0 -5
- package/dist/zcl/definition/endpointDeviceType.d.ts.map +0 -1
- package/dist/zcl/definition/endpointDeviceType.js +0 -16
- package/dist/zcl/definition/endpointDeviceType.js.map +0 -1
- package/dist/zcl/definition/foundation.d.ts +0 -12
- package/dist/zcl/definition/foundation.d.ts.map +0 -1
- package/dist/zcl/definition/foundation.js +0 -168
- package/dist/zcl/definition/foundation.js.map +0 -1
- package/dist/zcl/definition/frameControl.d.ts +0 -11
- package/dist/zcl/definition/frameControl.d.ts.map +0 -1
- package/dist/zcl/definition/frameControl.js +0 -3
- package/dist/zcl/definition/frameControl.js.map +0 -1
- package/dist/zcl/definition/frameType.d.ts +0 -6
- package/dist/zcl/definition/frameType.d.ts.map +0 -1
- package/dist/zcl/definition/frameType.js +0 -9
- package/dist/zcl/definition/frameType.js.map +0 -1
- package/dist/zcl/definition/index.d.ts +0 -14
- package/dist/zcl/definition/index.d.ts.map +0 -1
- package/dist/zcl/definition/index.js +0 -52
- package/dist/zcl/definition/index.js.map +0 -1
- package/dist/zcl/definition/manufacturerCode.d.ts +0 -1078
- package/dist/zcl/definition/manufacturerCode.d.ts.map +0 -1
- package/dist/zcl/definition/manufacturerCode.js +0 -1083
- package/dist/zcl/definition/manufacturerCode.js.map +0 -1
- package/dist/zcl/definition/powerSource.d.ts +0 -5
- package/dist/zcl/definition/powerSource.d.ts.map +0 -1
- package/dist/zcl/definition/powerSource.js +0 -13
- package/dist/zcl/definition/powerSource.js.map +0 -1
- package/dist/zcl/definition/status.d.ts +0 -39
- package/dist/zcl/definition/status.d.ts.map +0 -1
- package/dist/zcl/definition/status.js +0 -42
- package/dist/zcl/definition/status.js.map +0 -1
- package/dist/zcl/definition/tstype.d.ts +0 -17
- package/dist/zcl/definition/tstype.d.ts.map +0 -1
- package/dist/zcl/definition/tstype.js.map +0 -1
- package/dist/zcl/index.d.ts +0 -17
- package/dist/zcl/index.d.ts.map +0 -1
- package/dist/zcl/index.js +0 -56
- package/dist/zcl/index.js.map +0 -1
- package/dist/zcl/tstype.d.ts +0 -57
- package/dist/zcl/tstype.d.ts.map +0 -1
- package/dist/zcl/tstype.js +0 -10
- package/dist/zcl/tstype.js.map +0 -1
- package/dist/zcl/utils.d.ts +0 -7
- package/dist/zcl/utils.d.ts.map +0 -1
- package/dist/zcl/utils.js +0 -165
- package/dist/zcl/utils.js.map +0 -1
- package/dist/zcl/zclFrame.d.ts +0 -41
- package/dist/zcl/zclFrame.d.ts.map +0 -1
- package/dist/zcl/zclFrame.js +0 -352
- package/dist/zcl/zclFrame.js.map +0 -1
- package/dist/zcl/zclHeader.d.ts +0 -9
- package/dist/zcl/zclHeader.d.ts.map +0 -1
- package/dist/zcl/zclHeader.js.map +0 -1
- package/dist/zcl/zclStatusError.d.ts +0 -6
- package/dist/zcl/zclStatusError.d.ts.map +0 -1
- package/dist/zcl/zclStatusError.js +0 -15
- package/dist/zcl/zclStatusError.js.map +0 -1
|
@@ -1,19 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
5
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
29
|
exports.EmberAdapter = void 0;
|
|
7
30
|
/* istanbul ignore file */
|
|
8
|
-
const debug_1 = __importDefault(require("debug"));
|
|
9
31
|
const es6_1 = __importDefault(require("fast-deep-equal/es6"));
|
|
10
32
|
const mz_1 = require("mz");
|
|
11
33
|
const serialPortUtils_1 = __importDefault(require("../../serialPortUtils"));
|
|
12
34
|
const socketPortUtils_1 = __importDefault(require("../../socketPortUtils"));
|
|
13
35
|
const utils_1 = require("../../../utils");
|
|
14
36
|
const __1 = require("../..");
|
|
15
|
-
const
|
|
16
|
-
const cluster_1 = __importDefault(require("../../../zcl/definition/cluster"));
|
|
37
|
+
const Zcl = __importStar(require("../../../zspec/zcl"));
|
|
17
38
|
const events_1 = require("../../events");
|
|
18
39
|
const math_1 = require("../utils/math");
|
|
19
40
|
const ezsp_1 = require("../ezsp/ezsp");
|
|
@@ -28,7 +49,9 @@ const endpoints_1 = require("./endpoints");
|
|
|
28
49
|
const initters_1 = require("../utils/initters");
|
|
29
50
|
const crypto_1 = require("crypto");
|
|
30
51
|
const oneWaitress_1 = require("./oneWaitress");
|
|
31
|
-
const
|
|
52
|
+
const logger_1 = require("../../../utils/logger");
|
|
53
|
+
// import {EmberTokensManager} from "./tokensManager";
|
|
54
|
+
const NS = 'zh:ember';
|
|
32
55
|
/** Enum to pass strings from numbers up to Z2M. */
|
|
33
56
|
var RoutingTableStatus;
|
|
34
57
|
(function (RoutingTableStatus) {
|
|
@@ -42,15 +65,6 @@ var RoutingTableStatus;
|
|
|
42
65
|
RoutingTableStatus[RoutingTableStatus["RESERVED3"] = 7] = "RESERVED3";
|
|
43
66
|
})(RoutingTableStatus || (RoutingTableStatus = {}));
|
|
44
67
|
;
|
|
45
|
-
/** Events specific to OneWaitress usage. */
|
|
46
|
-
var OneWaitressEvents;
|
|
47
|
-
(function (OneWaitressEvents) {
|
|
48
|
-
OneWaitressEvents["STACK_STATUS_NETWORK_UP"] = "STACK_STATUS_NETWORK_UP";
|
|
49
|
-
OneWaitressEvents["STACK_STATUS_NETWORK_DOWN"] = "STACK_STATUS_NETWORK_DOWN";
|
|
50
|
-
OneWaitressEvents["STACK_STATUS_NETWORK_OPENED"] = "STACK_STATUS_NETWORK_OPENED";
|
|
51
|
-
OneWaitressEvents["STACK_STATUS_NETWORK_CLOSED"] = "STACK_STATUS_NETWORK_CLOSED";
|
|
52
|
-
})(OneWaitressEvents || (OneWaitressEvents = {}));
|
|
53
|
-
;
|
|
54
68
|
var NetworkInitAction;
|
|
55
69
|
(function (NetworkInitAction) {
|
|
56
70
|
/** Ain't that nice! */
|
|
@@ -116,11 +130,15 @@ const BACKUP_OLDEST_SUPPORTED_EZSP_VERSION = 12;
|
|
|
116
130
|
const BROADCAST_NETWORK_KEY_SWITCH_WAIT_TIME = 15000;
|
|
117
131
|
/**
|
|
118
132
|
* Stack configuration values for various supported stacks.
|
|
133
|
+
*
|
|
134
|
+
* https://github.com/darkxst/silabs-firmware-builder/tree/main/manifests
|
|
135
|
+
* https://github.com/NabuCasa/silabs-firmware/wiki/Zigbee-EmberZNet-NCP-firmware-configuration#skyconnect
|
|
136
|
+
* https://github.com/SiliconLabs/UnifySDK/blob/main/applications/zigbeed/project_files/zigbeed.slcp
|
|
119
137
|
*/
|
|
120
138
|
const STACK_CONFIGS = {
|
|
121
139
|
"default": {
|
|
122
140
|
/** <1-250> (Default: 2) @see EzspConfigId.ADDRESS_TABLE_SIZE */
|
|
123
|
-
ADDRESS_TABLE_SIZE: 16, // zigpc: 32, darkxst: 16
|
|
141
|
+
ADDRESS_TABLE_SIZE: 16, // zigpc: 32, darkxst: 16, nabucasa: 16
|
|
124
142
|
/** <0-4> (Default: 2) @see EzspConfigId.TRUST_CENTER_ADDRESS_CACHE_SIZE */
|
|
125
143
|
TRUST_CENTER_ADDRESS_CACHE_SIZE: 2,
|
|
126
144
|
/** (Default: USE_TOKEN) @see EzspConfigId.TX_POWER_MODE */
|
|
@@ -132,7 +150,7 @@ const STACK_CONFIGS = {
|
|
|
132
150
|
/** <-> (Default: ) @see EzspConfigId.SECURITY_LEVEL */
|
|
133
151
|
SECURITY_LEVEL: consts_2.SECURITY_LEVEL_Z3,
|
|
134
152
|
/** (Default: KEEP_ALIVE_SUPPORT_ALL) @see EzspValueId.END_DEVICE_KEEP_ALIVE_SUPPORT_MODE */
|
|
135
|
-
END_DEVICE_KEEP_ALIVE_SUPPORT_MODE: enums_2.EmberKeepAliveMode.KEEP_ALIVE_SUPPORT_ALL,
|
|
153
|
+
END_DEVICE_KEEP_ALIVE_SUPPORT_MODE: enums_2.EmberKeepAliveMode.KEEP_ALIVE_SUPPORT_ALL,
|
|
136
154
|
/** <-> (Default: MAXIMUM_APS_PAYLOAD_LENGTH) @see EzspValueId.MAXIMUM_INCOMING_TRANSFER_SIZE */
|
|
137
155
|
MAXIMUM_INCOMING_TRANSFER_SIZE: consts_2.MAXIMUM_APS_PAYLOAD_LENGTH,
|
|
138
156
|
/** <-> (Default: MAXIMUM_APS_PAYLOAD_LENGTH) @see EzspValueId.MAXIMUM_OUTGOING_TRANSFER_SIZE */
|
|
@@ -140,27 +158,27 @@ const STACK_CONFIGS = {
|
|
|
140
158
|
/** <-> (Default: 10000) @see EzspValueId.TRANSIENT_DEVICE_TIMEOUT */
|
|
141
159
|
TRANSIENT_DEVICE_TIMEOUT: 10000,
|
|
142
160
|
/** <0-127> (Default: 2) @see EzspConfigId.BINDING_TABLE_SIZE */
|
|
143
|
-
BINDING_TABLE_SIZE:
|
|
161
|
+
BINDING_TABLE_SIZE: 32, // zigpc: 2, Z3GatewayGPCombo: 5, nabucasa: 32
|
|
144
162
|
/** <0-127> (Default: 0) @see EzspConfigId.KEY_TABLE_SIZE */
|
|
145
163
|
KEY_TABLE_SIZE: 0, // zigpc: 4
|
|
146
164
|
/** <6-64> (Default: 6) @see EzspConfigId.MAX_END_DEVICE_CHILDREN */
|
|
147
|
-
MAX_END_DEVICE_CHILDREN:
|
|
165
|
+
MAX_END_DEVICE_CHILDREN: 32, // zigpc: 6, nabucasa: 32, Dongle-E (Sonoff firmware): 32
|
|
148
166
|
/** <1-255> (Default: 10) @see EzspConfigId.APS_UNICAST_MESSAGE_COUNT */
|
|
149
|
-
APS_UNICAST_MESSAGE_COUNT:
|
|
167
|
+
APS_UNICAST_MESSAGE_COUNT: 32, // zigpc: 10, darkxst: 20, nabucasa: 20
|
|
150
168
|
/** <15-254> (Default: 15) @see EzspConfigId.BROADCAST_TABLE_SIZE */
|
|
151
169
|
BROADCAST_TABLE_SIZE: 15, // zigpc: 15, Z3GatewayGPCombo: 35 - NOTE: Sonoff Dongle-E fails at 35
|
|
152
170
|
/** [1, 16, 26] (Default: 16). @see EzspConfigId.NEIGHBOR_TABLE_SIZE */
|
|
153
|
-
NEIGHBOR_TABLE_SIZE: 26, // zigpc: 16, darkxst: 26
|
|
171
|
+
NEIGHBOR_TABLE_SIZE: 26, // zigpc: 16, darkxst: 26, nabucasa: 26
|
|
154
172
|
/** (Default: 8) @see EzspConfigId.END_DEVICE_POLL_TIMEOUT */
|
|
155
173
|
END_DEVICE_POLL_TIMEOUT: 8, // zigpc: 8
|
|
156
174
|
/** <0-65535> (Default: 300) @see EzspConfigId.TRANSIENT_KEY_TIMEOUT_S */
|
|
157
175
|
TRANSIENT_KEY_TIMEOUT_S: 300, // zigpc: 65535
|
|
158
176
|
/** <-> (Default: 16) @see EzspConfigId.RETRY_QUEUE_SIZE */
|
|
159
|
-
RETRY_QUEUE_SIZE: 16,
|
|
177
|
+
RETRY_QUEUE_SIZE: 16, // nabucasa: 16
|
|
160
178
|
/** <0-255> (Default: 0) @see EzspConfigId.SOURCE_ROUTE_TABLE_SIZE */
|
|
161
|
-
SOURCE_ROUTE_TABLE_SIZE: 200, // Z3GatewayGPCombo: 100, darkxst: 200
|
|
179
|
+
SOURCE_ROUTE_TABLE_SIZE: 200, // Z3GatewayGPCombo: 100, darkxst: 200, nabucasa: 200
|
|
162
180
|
/** <1-250> (Default: 8) @see EzspConfigId.MULTICAST_TABLE_SIZE */
|
|
163
|
-
MULTICAST_TABLE_SIZE: 16, // darkxst: 16
|
|
181
|
+
MULTICAST_TABLE_SIZE: 16, // darkxst: 16, nabucasa: 16 - NOTE: should always be at least enough to register FIXED_ENDPOINTS multicastIds
|
|
164
182
|
},
|
|
165
183
|
"zigbeed": {
|
|
166
184
|
ADDRESS_TABLE_SIZE: 128,
|
|
@@ -184,18 +202,17 @@ const STACK_CONFIGS = {
|
|
|
184
202
|
RETRY_QUEUE_SIZE: 16,
|
|
185
203
|
SOURCE_ROUTE_TABLE_SIZE: 254,
|
|
186
204
|
MULTICAST_TABLE_SIZE: 128,
|
|
187
|
-
/*
|
|
188
|
-
ROUTE_TABLE_SIZE: 254,
|
|
189
|
-
DISCOVERY_TABLE_SIZE: 64,
|
|
190
|
-
PACKET_BUFFER_COUNT: 255,
|
|
191
|
-
CUSTOM_MAC_FILTER_TABLE_SIZE: 64,
|
|
192
|
-
MAC_FILTER_TABLE_SIZE: 32,
|
|
193
|
-
CHILD_TABLE_SIZE: 64,
|
|
194
|
-
PLUGIN_ZIGBEE_PRO_STACK_CHILD_TABLE_SIZE: 64,
|
|
195
|
-
APS_MESSAGE_COUNT: 64,
|
|
196
|
-
*/
|
|
197
205
|
},
|
|
198
206
|
};
|
|
207
|
+
/**
|
|
208
|
+
* NOTE: This from SDK is currently ignored here because of issues in below links:
|
|
209
|
+
* - BUGZID 12261: Concentrators use MTORRs for route discovery and should not enable route discovery in the APS options.
|
|
210
|
+
* - https://community.silabs.com/s/question/0D58Y00008DRfDCSA1/coordinator-cant-send-unicast-to-sleepy-node-after-reboot
|
|
211
|
+
* - https://community.silabs.com/s/question/0D58Y0000B4nTb7SQE/largedense-network-communication-problem-source-route-table-not-big-enough
|
|
212
|
+
*
|
|
213
|
+
* Removing `ENABLE_ROUTE_DISCOVERY` leads to devices that won't reconnect/go offline, and various other issues. Keeping it for now.
|
|
214
|
+
*/
|
|
215
|
+
const DEFAULT_APS_OPTIONS = (enums_2.EmberApsOption.RETRY | enums_2.EmberApsOption.ENABLE_ROUTE_DISCOVERY | enums_2.EmberApsOption.ENABLE_ADDRESS_DISCOVERY);
|
|
199
216
|
/**
|
|
200
217
|
* Enabling this allows to immediately reject requests that won't be able to get to their destination.
|
|
201
218
|
* However, it causes more NCP calls, notably to get the source route overhead.
|
|
@@ -210,12 +227,25 @@ const DEFAULT_ZCL_REQUEST_TIMEOUT = 15000; //msec
|
|
|
210
227
|
const DEFAULT_NETWORK_REQUEST_TIMEOUT = 10000; // nothing on the network to bother requests, should be much faster than this
|
|
211
228
|
/** Time between watchdog counters reading/clearing */
|
|
212
229
|
const WATCHDOG_COUNTERS_FEED_INTERVAL = 3600000; // every hour...
|
|
230
|
+
/** Default manufacturer code reported by coordinator. */
|
|
231
|
+
const DEFAULT_MANUFACTURER_CODE = Zcl.ManufacturerCode.SILICON_LABORATORIES;
|
|
232
|
+
/**
|
|
233
|
+
* Workaround for devices that require a specific manufacturer code to be reported by coordinator while interviewing...
|
|
234
|
+
* - Lumi/Aqara devices do not work properly otherwise (missing features): https://github.com/Koenkk/zigbee2mqtt/issues/9274
|
|
235
|
+
*/
|
|
236
|
+
const WORKAROUND_JOIN_MANUF_IEEE_PREFIX_TO_CODE = {
|
|
237
|
+
// NOTE: Lumi has a new prefix registered since 2021, in case they start using that one with new devices, it might need to be added here too...
|
|
238
|
+
// "0x18c23c" https://maclookup.app/vendors/lumi-united-technology-co-ltd
|
|
239
|
+
"0x54ef44": Zcl.ManufacturerCode.LUMI_UNITED_TECHOLOGY_LTD_SHENZHEN,
|
|
240
|
+
};
|
|
213
241
|
/**
|
|
214
242
|
* Relay calls between Z2M and EZSP-layer and handle any error that might occur via queue & waitress.
|
|
215
243
|
*
|
|
216
244
|
* Anything post `start` that requests anything from the EZSP layer must run through the request queue for proper execution flow.
|
|
217
245
|
*/
|
|
218
246
|
class EmberAdapter extends __1.Adapter {
|
|
247
|
+
/** Current manufacturer code assigned to the coordinator. Used for join workarounds... */
|
|
248
|
+
manufacturerCode;
|
|
219
249
|
/** Key in STACK_CONFIGS */
|
|
220
250
|
stackConfig;
|
|
221
251
|
/** EMBER_LOW_RAM_CONCENTRATOR or EMBER_HIGH_RAM_CONCENTRATOR. */
|
|
@@ -238,24 +268,19 @@ class EmberAdapter extends __1.Adapter {
|
|
|
238
268
|
* NOTE: Do not use directly, use getter functions for it that check if valid or need retrieval from NCP.
|
|
239
269
|
*/
|
|
240
270
|
networkCache;
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
multicastTable;
|
|
247
|
-
constructor(networkOptions, serialPortOptions, backupPath, adapterOptions, logger) {
|
|
248
|
-
super(networkOptions, serialPortOptions, backupPath, adapterOptions, logger);
|
|
249
|
-
// TODO config, should be fine like this for now?
|
|
250
|
-
this.stackConfig = socketPortUtils_1.default.isTcpPath(serialPortOptions.path) ? 'zigbeed' : 'default';
|
|
271
|
+
constructor(networkOptions, serialPortOptions, backupPath, adapterOptions) {
|
|
272
|
+
super(networkOptions, serialPortOptions, backupPath, adapterOptions);
|
|
273
|
+
// TODO config
|
|
274
|
+
// XXX: 'zigbeed': 4.4.x/7.4.x not supported by multiprotocol at the moment, will need refactoring when/if support is added
|
|
275
|
+
this.stackConfig = 'default';
|
|
251
276
|
// TODO config
|
|
252
277
|
this.concentratorType = consts_2.EMBER_HIGH_RAM_CONCENTRATOR;
|
|
253
|
-
|
|
254
|
-
|
|
278
|
+
const delay = (typeof this.adapterOptions.delay === 'number') ? Math.min(Math.max(this.adapterOptions.delay, 5), 60) : 5;
|
|
279
|
+
logger_1.logger.debug(`Using delay=${delay}.`, NS);
|
|
280
|
+
this.requestQueue = new requestQueue_1.EmberRequestQueue(delay);
|
|
255
281
|
this.oneWaitress = new oneWaitress_1.EmberOneWaitress();
|
|
256
282
|
this.zdoRequestBuffalo = new buffalo_1.EzspBuffalo(Buffer.alloc(consts_1.EZSP_MAX_FRAME_LENGTH));
|
|
257
|
-
|
|
258
|
-
this.ezsp = new ezsp_1.Ezsp(60, serialPortOptions);
|
|
283
|
+
this.ezsp = new ezsp_1.Ezsp(delay, serialPortOptions);
|
|
259
284
|
this.ezsp.on(ezsp_1.EzspEvents.STACK_STATUS, this.onStackStatus.bind(this));
|
|
260
285
|
this.ezsp.on(ezsp_1.EzspEvents.MESSAGE_SENT_DELIVERY_FAILED, this.onMessageSentDeliveryFailed.bind(this));
|
|
261
286
|
this.ezsp.on(ezsp_1.EzspEvents.ZDO_RESPONSE, this.onZDOResponse.bind(this));
|
|
@@ -274,36 +299,34 @@ class EmberAdapter extends __1.Adapter {
|
|
|
274
299
|
this.clearNetworkCache();
|
|
275
300
|
switch (status) {
|
|
276
301
|
case enums_2.EmberStatus.NETWORK_UP: {
|
|
277
|
-
this.oneWaitress.resolveEvent(OneWaitressEvents.STACK_STATUS_NETWORK_UP);
|
|
278
|
-
|
|
302
|
+
this.oneWaitress.resolveEvent(oneWaitress_1.OneWaitressEvents.STACK_STATUS_NETWORK_UP);
|
|
303
|
+
logger_1.logger.info(`[STACK STATUS] Network up.`, NS);
|
|
279
304
|
break;
|
|
280
305
|
}
|
|
281
306
|
case enums_2.EmberStatus.NETWORK_DOWN: {
|
|
282
|
-
this.oneWaitress.resolveEvent(OneWaitressEvents.STACK_STATUS_NETWORK_DOWN);
|
|
283
|
-
|
|
307
|
+
this.oneWaitress.resolveEvent(oneWaitress_1.OneWaitressEvents.STACK_STATUS_NETWORK_DOWN);
|
|
308
|
+
logger_1.logger.info(`[STACK STATUS] Network down.`, NS);
|
|
284
309
|
break;
|
|
285
310
|
}
|
|
286
311
|
case enums_2.EmberStatus.NETWORK_OPENED: {
|
|
287
|
-
this.oneWaitress.resolveEvent(OneWaitressEvents.STACK_STATUS_NETWORK_OPENED);
|
|
288
|
-
|
|
289
|
-
const setJPstatus = (await this.emberSetJoinPolicy(enums_2.EmberJoinDecision.USE_PRECONFIGURED_KEY));
|
|
290
|
-
if (setJPstatus !== enums_2.EzspStatus.SUCCESS) {
|
|
291
|
-
console.error(`[ZDO] Failed set join policy for with status=${enums_2.EzspStatus[setJPstatus]}.`);
|
|
292
|
-
return enums_2.EmberStatus.ERR_FATAL;
|
|
293
|
-
}
|
|
294
|
-
return enums_2.EmberStatus.SUCCESS;
|
|
295
|
-
}, console.error, // no reject, just log error if any
|
|
296
|
-
true);
|
|
297
|
-
console.log(`[STACK STATUS] Network opened.`);
|
|
312
|
+
this.oneWaitress.resolveEvent(oneWaitress_1.OneWaitressEvents.STACK_STATUS_NETWORK_OPENED);
|
|
313
|
+
logger_1.logger.info(`[STACK STATUS] Network opened.`, NS);
|
|
298
314
|
break;
|
|
299
315
|
}
|
|
300
316
|
case enums_2.EmberStatus.NETWORK_CLOSED: {
|
|
301
|
-
this.oneWaitress.resolveEvent(OneWaitressEvents.STACK_STATUS_NETWORK_CLOSED);
|
|
302
|
-
|
|
317
|
+
this.oneWaitress.resolveEvent(oneWaitress_1.OneWaitressEvents.STACK_STATUS_NETWORK_CLOSED);
|
|
318
|
+
logger_1.logger.info(`[STACK STATUS] Network closed.`, NS);
|
|
319
|
+
break;
|
|
320
|
+
}
|
|
321
|
+
case enums_2.EmberStatus.CHANNEL_CHANGED: {
|
|
322
|
+
this.oneWaitress.resolveEvent(oneWaitress_1.OneWaitressEvents.STACK_STATUS_CHANNEL_CHANGED);
|
|
323
|
+
// invalidate cache
|
|
324
|
+
this.networkCache.parameters.radioChannel = consts_2.INVALID_RADIO_CHANNEL;
|
|
325
|
+
logger_1.logger.info(`[STACK STATUS] Channel changed.`, NS);
|
|
303
326
|
break;
|
|
304
327
|
}
|
|
305
328
|
default: {
|
|
306
|
-
debug(`[STACK STATUS] ${enums_2.EmberStatus[status]}
|
|
329
|
+
logger_1.logger.debug(`[STACK STATUS] ${enums_2.EmberStatus[status]}.`, NS);
|
|
307
330
|
break;
|
|
308
331
|
}
|
|
309
332
|
}
|
|
@@ -324,8 +347,8 @@ class EmberAdapter extends __1.Adapter {
|
|
|
324
347
|
case enums_2.EmberOutgoingMessageType.MULTICAST:
|
|
325
348
|
case enums_2.EmberOutgoingMessageType.MULTICAST_WITH_ALIAS: {
|
|
326
349
|
// BC/MC not checking for message sent, avoid unnecessary waitress lookups
|
|
327
|
-
|
|
328
|
-
+ `[apsFrame=${JSON.stringify(apsFrame)} messageTag=${messageTag}]
|
|
350
|
+
logger_1.logger.error(`Delivery of ${enums_2.EmberOutgoingMessageType[type]} failed for "${indexOrDestination}" `
|
|
351
|
+
+ `[apsFrame=${JSON.stringify(apsFrame)} messageTag=${messageTag}]`, NS);
|
|
329
352
|
break;
|
|
330
353
|
}
|
|
331
354
|
default: {
|
|
@@ -369,32 +392,19 @@ class EmberAdapter extends __1.Adapter {
|
|
|
369
392
|
* @param messageContents
|
|
370
393
|
*/
|
|
371
394
|
async onIncomingMessage(type, apsFrame, lastHopLqi, sender, messageContents) {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
catch (error) {
|
|
386
|
-
const payload = {
|
|
387
|
-
clusterID: apsFrame.clusterId,
|
|
388
|
-
address: sender,
|
|
389
|
-
data: messageContents,
|
|
390
|
-
endpoint: apsFrame.sourceEndpoint,
|
|
391
|
-
linkquality: lastHopLqi,
|
|
392
|
-
groupID: apsFrame.groupId,
|
|
393
|
-
wasBroadcast: ((type === enums_2.EmberIncomingMessageType.BROADCAST) || (type === enums_2.EmberIncomingMessageType.BROADCAST_LOOPBACK)),
|
|
394
|
-
destinationEndpoint: apsFrame.destinationEndpoint,
|
|
395
|
-
};
|
|
396
|
-
this.emit(events_1.Events.rawData, payload);
|
|
397
|
-
}
|
|
395
|
+
const payload = {
|
|
396
|
+
clusterID: apsFrame.clusterId,
|
|
397
|
+
header: Zcl.Header.fromBuffer(messageContents),
|
|
398
|
+
address: sender,
|
|
399
|
+
data: messageContents,
|
|
400
|
+
endpoint: apsFrame.sourceEndpoint,
|
|
401
|
+
linkquality: lastHopLqi,
|
|
402
|
+
groupID: apsFrame.groupId,
|
|
403
|
+
wasBroadcast: ((type === enums_2.EmberIncomingMessageType.BROADCAST) || (type === enums_2.EmberIncomingMessageType.BROADCAST_LOOPBACK)),
|
|
404
|
+
destinationEndpoint: apsFrame.destinationEndpoint,
|
|
405
|
+
};
|
|
406
|
+
this.oneWaitress.resolveZCL(payload);
|
|
407
|
+
this.emit(events_1.Events.zclPayload, payload);
|
|
398
408
|
}
|
|
399
409
|
/**
|
|
400
410
|
* Emitted from @see Ezsp.ezspMacFilterMatchMessageHandler when the message is a valid InterPAN touchlink message.
|
|
@@ -407,7 +417,9 @@ class EmberAdapter extends __1.Adapter {
|
|
|
407
417
|
*/
|
|
408
418
|
async onTouchlinkMessage(sourcePanId, sourceAddress, groupId, lastHopLqi, messageContents) {
|
|
409
419
|
const payload = {
|
|
410
|
-
|
|
420
|
+
clusterID: Zcl.Clusters.touchlink.ID,
|
|
421
|
+
data: messageContents,
|
|
422
|
+
header: Zcl.Header.fromBuffer(messageContents),
|
|
411
423
|
address: sourceAddress,
|
|
412
424
|
endpoint: 1, // arbitrary since not sent over-the-air
|
|
413
425
|
linkquality: lastHopLqi,
|
|
@@ -416,7 +428,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
416
428
|
destinationEndpoint: endpoints_1.FIXED_ENDPOINTS[0].endpoint,
|
|
417
429
|
};
|
|
418
430
|
this.oneWaitress.resolveZCL(payload);
|
|
419
|
-
this.emit(events_1.Events.
|
|
431
|
+
this.emit(events_1.Events.zclPayload, payload);
|
|
420
432
|
}
|
|
421
433
|
/**
|
|
422
434
|
* Emitted from @see Ezsp.ezspGpepIncomingMessageHandler
|
|
@@ -442,27 +454,29 @@ class EmberAdapter extends __1.Adapter {
|
|
|
442
454
|
gpdHeader.writeUInt32LE(frameCounter, 9); // frameCounter
|
|
443
455
|
gpdHeader.writeUInt8(gpdCommandId, 13); // commandID
|
|
444
456
|
gpdHeader.writeUInt8(gpdCommandPayload.length, 14); // payloadSize
|
|
445
|
-
const
|
|
457
|
+
const data = Buffer.concat([gpdHeader, gpdCommandPayload]);
|
|
446
458
|
const payload = {
|
|
447
|
-
|
|
459
|
+
header: Zcl.Header.fromBuffer(data),
|
|
460
|
+
data,
|
|
461
|
+
clusterID: Zcl.Clusters.greenPower.ID,
|
|
448
462
|
address: sourceId,
|
|
449
463
|
endpoint: consts_2.GP_ENDPOINT,
|
|
450
464
|
linkquality: gpdLink,
|
|
451
465
|
groupID: this.greenPowerGroup,
|
|
452
|
-
|
|
453
|
-
wasBroadcast: (gpFrame.Payload.gppNwkAddr != null) ? false : true,
|
|
466
|
+
wasBroadcast: true,
|
|
454
467
|
destinationEndpoint: consts_2.GP_ENDPOINT,
|
|
455
468
|
};
|
|
456
469
|
this.oneWaitress.resolveZCL(payload);
|
|
457
|
-
this.emit(events_1.Events.
|
|
470
|
+
this.emit(events_1.Events.zclPayload, payload);
|
|
458
471
|
}
|
|
459
472
|
catch (err) {
|
|
460
|
-
|
|
473
|
+
logger_1.logger.error(`<~x~ [GP] Failed creating ZCL payload. Skipping. ${err}`, NS);
|
|
461
474
|
return;
|
|
462
475
|
}
|
|
463
476
|
}
|
|
464
477
|
/**
|
|
465
478
|
* Emitted from @see Ezsp.ezspTrustCenterJoinHandler
|
|
479
|
+
* Also from @see Ezsp.ezspIdConflictHandler as a DEVICE_LEFT
|
|
466
480
|
*
|
|
467
481
|
* @param newNodeId
|
|
468
482
|
* @param newNodeEui64
|
|
@@ -472,7 +486,6 @@ class EmberAdapter extends __1.Adapter {
|
|
|
472
486
|
*/
|
|
473
487
|
async onTrustCenterJoin(newNodeId, newNodeEui64, status, policyDecision, parentOfNewNodeId) {
|
|
474
488
|
if (status === enums_2.EmberDeviceUpdate.DEVICE_LEFT) {
|
|
475
|
-
// NOTE: `policyDecision` here is NO_ACTION and `parentOfNewNodeId` is 65535
|
|
476
489
|
const payload = {
|
|
477
490
|
networkAddress: newNodeId,
|
|
478
491
|
ieeeAddr: newNodeEui64,
|
|
@@ -485,24 +498,41 @@ class EmberAdapter extends __1.Adapter {
|
|
|
485
498
|
networkAddress: newNodeId,
|
|
486
499
|
ieeeAddr: newNodeEui64,
|
|
487
500
|
};
|
|
488
|
-
|
|
501
|
+
// set workaround manuf code if necessary, or revert to default if previous joined device required workaround and new one does not
|
|
502
|
+
const joinManufCode = WORKAROUND_JOIN_MANUF_IEEE_PREFIX_TO_CODE[newNodeEui64.substring(0, 8)] ?? DEFAULT_MANUFACTURER_CODE;
|
|
503
|
+
if (this.manufacturerCode !== joinManufCode) {
|
|
504
|
+
await new Promise((resolve, reject) => {
|
|
505
|
+
this.requestQueue.enqueue(async () => {
|
|
506
|
+
logger_1.logger.debug(`[WORKAROUND] Setting coordinator manufacturer code to ${Zcl.ManufacturerCode[joinManufCode]}.`, NS);
|
|
507
|
+
await this.ezsp.ezspSetManufacturerCode(joinManufCode);
|
|
508
|
+
this.manufacturerCode = joinManufCode;
|
|
509
|
+
this.emit(events_1.Events.deviceJoined, payload);
|
|
510
|
+
resolve();
|
|
511
|
+
return enums_2.EmberStatus.SUCCESS;
|
|
512
|
+
}, reject, true);
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
else {
|
|
516
|
+
this.emit(events_1.Events.deviceJoined, payload);
|
|
517
|
+
}
|
|
489
518
|
}
|
|
490
519
|
else {
|
|
491
|
-
|
|
520
|
+
logger_1.logger.warning(`[TRUST CENTER] Device ${newNodeId}:${newNodeEui64} was denied joining via ${parentOfNewNodeId}.`, NS);
|
|
492
521
|
}
|
|
493
522
|
}
|
|
494
523
|
}
|
|
495
524
|
async watchdogCounters() {
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
525
|
+
await new Promise((resolve, reject) => {
|
|
526
|
+
this.requestQueue.enqueue(async () => {
|
|
527
|
+
// listed as per EmberCounterType
|
|
528
|
+
const ncpCounters = (await this.ezsp.ezspReadAndClearCounters());
|
|
529
|
+
logger_1.logger.info(`[NCP COUNTERS] ${ncpCounters.join(',')}`, NS);
|
|
530
|
+
const ashCounters = this.ezsp.ash.readAndClearCounters();
|
|
531
|
+
logger_1.logger.info(`[ASH COUNTERS] ${ashCounters.join(',')}`, NS);
|
|
532
|
+
resolve();
|
|
533
|
+
return enums_2.EmberStatus.SUCCESS;
|
|
534
|
+
}, reject);
|
|
535
|
+
});
|
|
506
536
|
}
|
|
507
537
|
initVariables() {
|
|
508
538
|
this.ezsp.removeAllListeners(ezsp_1.EzspEvents.ncpNeedsResetAndInit);
|
|
@@ -512,9 +542,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
512
542
|
this.zdoRequestRadius = 255;
|
|
513
543
|
this.interpanLock = false;
|
|
514
544
|
this.networkCache = (0, initters_1.initNetworkCache)();
|
|
515
|
-
this.
|
|
516
|
-
// always at least length==1 because of allowed MULTICAST_TABLE_SIZE range
|
|
517
|
-
this.multicastTable = new Array(STACK_CONFIGS[this.stackConfig].MULTICAST_TABLE_SIZE).fill(null);
|
|
545
|
+
this.manufacturerCode = DEFAULT_MANUFACTURER_CODE; // will be set in NCP in initEzsp
|
|
518
546
|
this.ezsp.once(ezsp_1.EzspEvents.ncpNeedsResetAndInit, this.onNcpNeedsResetAndInit.bind(this));
|
|
519
547
|
}
|
|
520
548
|
/**
|
|
@@ -523,16 +551,10 @@ class EmberAdapter extends __1.Adapter {
|
|
|
523
551
|
*/
|
|
524
552
|
async initEzsp() {
|
|
525
553
|
let result = "resumed";
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
if (result !== enums_2.EzspStatus.SUCCESS) {
|
|
531
|
-
throw new Error(`Failed to start EZSP layer with status=${enums_2.EzspStatus[result]}.`);
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
catch (err) {
|
|
535
|
-
throw err;
|
|
554
|
+
// NOTE: something deep in this call can throw too
|
|
555
|
+
const startResult = (await this.ezsp.start());
|
|
556
|
+
if (startResult !== enums_2.EzspStatus.SUCCESS) {
|
|
557
|
+
throw new Error(`Failed to start EZSP layer with status=${enums_2.EzspStatus[startResult]}.`);
|
|
536
558
|
}
|
|
537
559
|
// call before any other command, else fails
|
|
538
560
|
await this.emberVersion();
|
|
@@ -540,7 +562,6 @@ class EmberAdapter extends __1.Adapter {
|
|
|
540
562
|
await this.initNCPAddressTable();
|
|
541
563
|
await this.initNCPConfiguration();
|
|
542
564
|
// WARNING: From here on EZSP commands that affect memory allocation on the NCP should no longer be called (like resizing tables)
|
|
543
|
-
await this.onNCPPostReset();
|
|
544
565
|
await this.registerFixedEndpoints();
|
|
545
566
|
this.clearNetworkCache();
|
|
546
567
|
result = (await this.initTrustCenter());
|
|
@@ -555,7 +576,9 @@ class EmberAdapter extends __1.Adapter {
|
|
|
555
576
|
this.networkCache.parameters = parameters;
|
|
556
577
|
this.networkCache.status = (await this.ezsp.ezspNetworkState());
|
|
557
578
|
this.networkCache.eui64 = (await this.ezsp.ezspGetEui64());
|
|
558
|
-
debug(`[INIT] Network Ready! ${JSON.stringify(this.networkCache)}
|
|
579
|
+
logger_1.logger.debug(`[INIT] Network Ready! ${JSON.stringify(this.networkCache)}`, NS);
|
|
580
|
+
this.watchdogCountersHandle = setInterval(this.watchdogCounters.bind(this), WATCHDOG_COUNTERS_FEED_INTERVAL);
|
|
581
|
+
this.requestQueue.startDispatching();
|
|
559
582
|
return result;
|
|
560
583
|
}
|
|
561
584
|
/**
|
|
@@ -584,9 +607,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
584
607
|
await this.emberSetEzspValue(enums_1.EzspValueId.MAXIMUM_INCOMING_TRANSFER_SIZE, 2, (0, math_1.lowHighBytes)(STACK_CONFIGS[this.stackConfig].MAXIMUM_INCOMING_TRANSFER_SIZE));
|
|
585
608
|
await this.emberSetEzspValue(enums_1.EzspValueId.MAXIMUM_OUTGOING_TRANSFER_SIZE, 2, (0, math_1.lowHighBytes)(STACK_CONFIGS[this.stackConfig].MAXIMUM_OUTGOING_TRANSFER_SIZE));
|
|
586
609
|
await this.emberSetEzspValue(enums_1.EzspValueId.TRANSIENT_DEVICE_TIMEOUT, 2, (0, math_1.lowHighBytes)(STACK_CONFIGS[this.stackConfig].TRANSIENT_DEVICE_TIMEOUT));
|
|
587
|
-
|
|
588
|
-
// Ember's ID is 0x1002 and is the default, but this can be overridden in App Builder.
|
|
589
|
-
await this.ezsp.ezspSetManufacturerCode(consts_2.MANUFACTURER_CODE);
|
|
610
|
+
await this.ezsp.ezspSetManufacturerCode(this.manufacturerCode);
|
|
590
611
|
// network security init
|
|
591
612
|
await this.emberSetEzspConfigValue(enums_1.EzspConfigId.STACK_PROFILE, STACK_CONFIGS[this.stackConfig].STACK_PROFILE);
|
|
592
613
|
await this.emberSetEzspConfigValue(enums_1.EzspConfigId.SECURITY_LEVEL, STACK_CONFIGS[this.stackConfig].SECURITY_LEVEL);
|
|
@@ -643,15 +664,16 @@ class EmberAdapter extends __1.Adapter {
|
|
|
643
664
|
throw new Error(`[CONCENTRATOR] Failed to set concentrator with status=${status}.`);
|
|
644
665
|
}
|
|
645
666
|
const remainTilMTORR = (await this.ezsp.ezspSetSourceRouteDiscoveryMode(enums_2.EmberSourceRouteDiscoveryMode.RESCHEDULE));
|
|
646
|
-
|
|
667
|
+
logger_1.logger.info(`[CONCENTRATOR] Started source route discovery. ${remainTilMTORR}ms until next broadcast.`, NS);
|
|
647
668
|
}
|
|
648
669
|
/**
|
|
649
670
|
* Register fixed endpoints and set any related multicast entries that need to be.
|
|
650
671
|
*/
|
|
651
672
|
async registerFixedEndpoints() {
|
|
673
|
+
let mcTableIdx = 0;
|
|
652
674
|
for (const ep of endpoints_1.FIXED_ENDPOINTS) {
|
|
653
675
|
if (ep.networkIndex !== 0x00) {
|
|
654
|
-
debug(`Multi-network not currently supported. Skipping endpoint ${JSON.stringify(ep)}
|
|
676
|
+
logger_1.logger.debug(`Multi-network not currently supported. Skipping endpoint ${JSON.stringify(ep)}.`, NS);
|
|
655
677
|
continue;
|
|
656
678
|
}
|
|
657
679
|
const [epStatus,] = (await this.ezsp.ezspGetEndpointFlags(ep.endpoint));
|
|
@@ -659,30 +681,29 @@ class EmberAdapter extends __1.Adapter {
|
|
|
659
681
|
if (epStatus !== enums_2.EzspStatus.SUCCESS) {
|
|
660
682
|
// check to see if ezspAddEndpoint needs to be called
|
|
661
683
|
// if ezspInit is called without NCP reset, ezspAddEndpoint is not necessary and will return an error
|
|
662
|
-
const status = (await this.ezsp.ezspAddEndpoint(ep.endpoint, ep.profileId, ep.deviceId, ep.deviceVersion, ep.inClusterList,
|
|
684
|
+
const status = (await this.ezsp.ezspAddEndpoint(ep.endpoint, ep.profileId, ep.deviceId, ep.deviceVersion, ep.inClusterList.slice(), // copy
|
|
685
|
+
ep.outClusterList.slice()));
|
|
663
686
|
if (status === enums_2.EzspStatus.SUCCESS) {
|
|
664
|
-
debug(`Registered endpoint "${ep.endpoint}" with status=${enums_2.EzspStatus[status]}
|
|
687
|
+
logger_1.logger.debug(`Registered endpoint "${ep.endpoint}" with status=${enums_2.EzspStatus[status]}.`, NS);
|
|
665
688
|
}
|
|
666
689
|
else {
|
|
667
690
|
throw new Error(`Failed to register endpoint "${ep.endpoint}" with status=${enums_2.EzspStatus[status]}.`);
|
|
668
691
|
}
|
|
669
692
|
}
|
|
670
693
|
else {
|
|
671
|
-
debug(`Endpoint "${ep.endpoint}" already registered
|
|
694
|
+
logger_1.logger.debug(`Endpoint "${ep.endpoint}" already registered.`, NS);
|
|
672
695
|
}
|
|
673
|
-
|
|
674
|
-
const
|
|
675
|
-
multicastId
|
|
696
|
+
for (const multicastId of ep.multicastIds) {
|
|
697
|
+
const multicastEntry = {
|
|
698
|
+
multicastId,
|
|
676
699
|
endpoint: ep.endpoint,
|
|
677
700
|
networkIndex: ep.networkIndex,
|
|
678
701
|
};
|
|
679
|
-
const status = (await this.ezsp.ezspSetMulticastTableEntry(
|
|
702
|
+
const status = (await this.ezsp.ezspSetMulticastTableEntry(mcTableIdx++, multicastEntry));
|
|
680
703
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
681
|
-
throw new Error(`Failed to register group "
|
|
704
|
+
throw new Error(`Failed to register group "${multicastId}" in multicast table with status=${enums_2.EmberStatus[status]}.`);
|
|
682
705
|
}
|
|
683
|
-
|
|
684
|
-
this.multicastTable[0] = gpMulticastEntry;
|
|
685
|
-
debug(`Registered multicast table entry: ${JSON.stringify(gpMulticastEntry)}.`);
|
|
706
|
+
logger_1.logger.debug(`Registered multicast table entry: ${JSON.stringify(multicastEntry)}.`, NS);
|
|
686
707
|
}
|
|
687
708
|
}
|
|
688
709
|
}
|
|
@@ -715,21 +736,19 @@ class EmberAdapter extends __1.Adapter {
|
|
|
715
736
|
bitmask: (enums_2.EmberNetworkInitBitmask.PARENT_INFO_IN_TOKEN | enums_2.EmberNetworkInitBitmask.END_DEVICE_REJOIN_ON_REBOOT)
|
|
716
737
|
};
|
|
717
738
|
const initStatus = (await this.ezsp.ezspNetworkInit(networkInitStruct));
|
|
718
|
-
debug(`[INIT TC] Network init status=${enums_2.EmberStatus[initStatus]}
|
|
739
|
+
logger_1.logger.debug(`[INIT TC] Network init status=${enums_2.EmberStatus[initStatus]}.`, NS);
|
|
719
740
|
if ((initStatus !== enums_2.EmberStatus.SUCCESS) && (initStatus !== enums_2.EmberStatus.NOT_JOINED)) {
|
|
720
741
|
throw new Error(`[INIT TC] Failed network init request with status=${enums_2.EmberStatus[initStatus]}.`);
|
|
721
742
|
}
|
|
722
743
|
let action = NetworkInitAction.DONE;
|
|
723
744
|
if (initStatus === enums_2.EmberStatus.SUCCESS) {
|
|
724
745
|
// network
|
|
725
|
-
await this.oneWaitress.startWaitingForEvent({ eventName: OneWaitressEvents.STACK_STATUS_NETWORK_UP }, DEFAULT_NETWORK_REQUEST_TIMEOUT, '[INIT TC] Network init');
|
|
746
|
+
await this.oneWaitress.startWaitingForEvent({ eventName: oneWaitress_1.OneWaitressEvents.STACK_STATUS_NETWORK_UP }, DEFAULT_NETWORK_REQUEST_TIMEOUT, '[INIT TC] Network init');
|
|
726
747
|
const [npStatus, nodeType, netParams] = (await this.ezsp.ezspGetNetworkParameters());
|
|
727
|
-
debug(`[INIT TC] Current network config=${JSON.stringify(this.networkOptions)}
|
|
728
|
-
debug(`[INIT TC] Current NCP network: nodeType=${enums_2.EmberNodeType[nodeType]} params=${JSON.stringify(netParams)}
|
|
729
|
-
// XXX: should not force a form when it's only a channel change, just change the channel, wait a sec, then continue the logic
|
|
748
|
+
logger_1.logger.debug(`[INIT TC] Current network config=${JSON.stringify(this.networkOptions)}`, NS);
|
|
749
|
+
logger_1.logger.debug(`[INIT TC] Current NCP network: nodeType=${enums_2.EmberNodeType[nodeType]} params=${JSON.stringify(netParams)}`, NS);
|
|
730
750
|
if ((npStatus === enums_2.EmberStatus.SUCCESS) && (nodeType === enums_2.EmberNodeType.COORDINATOR) && (this.networkOptions.panID === netParams.panId)
|
|
731
|
-
&& ((0, es6_1.default)(this.networkOptions.extendedPanID, netParams.extendedPanId))
|
|
732
|
-
&& (this.networkOptions.channelList.includes(netParams.radioChannel))) {
|
|
751
|
+
&& ((0, es6_1.default)(this.networkOptions.extendedPanID, netParams.extendedPanId))) {
|
|
733
752
|
// config matches adapter so far, no error, we can check the network key
|
|
734
753
|
const context = (0, initters_1.initSecurityManagerContext)();
|
|
735
754
|
context.coreKeyType = enums_2.SecManKeyType.NETWORK;
|
|
@@ -738,7 +757,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
738
757
|
if (nkStatus !== enums_2.SLStatus.OK) {
|
|
739
758
|
throw new Error(`[BACKUP] Failed to export Network Key with status=${enums_2.SLStatus[nkStatus]}.`);
|
|
740
759
|
}
|
|
741
|
-
debug(`[INIT TC] Current NCP network: networkKey=${networkKey.contents.toString('hex')}
|
|
760
|
+
logger_1.logger.debug(`[INIT TC] Current NCP network: networkKey=${networkKey.contents.toString('hex')}`, NS);
|
|
742
761
|
// config doesn't match adapter anymore
|
|
743
762
|
if (!networkKey.contents.equals(configNetworkKey)) {
|
|
744
763
|
action = NetworkInitAction.LEAVE;
|
|
@@ -749,12 +768,12 @@ class EmberAdapter extends __1.Adapter {
|
|
|
749
768
|
action = NetworkInitAction.LEAVE;
|
|
750
769
|
}
|
|
751
770
|
if (action === NetworkInitAction.LEAVE) {
|
|
752
|
-
|
|
771
|
+
logger_1.logger.info(`[INIT TC] NCP network does not match config. Leaving network...`, NS);
|
|
753
772
|
const leaveStatus = (await this.ezsp.ezspLeaveNetwork());
|
|
754
773
|
if (leaveStatus !== enums_2.EmberStatus.SUCCESS) {
|
|
755
774
|
throw new Error(`[INIT TC] Failed leave network request with status=${enums_2.EmberStatus[leaveStatus]}.`);
|
|
756
775
|
}
|
|
757
|
-
await this.oneWaitress.startWaitingForEvent({ eventName: OneWaitressEvents.STACK_STATUS_NETWORK_DOWN }, DEFAULT_NETWORK_REQUEST_TIMEOUT, '[INIT TC] Leave network');
|
|
776
|
+
await this.oneWaitress.startWaitingForEvent({ eventName: oneWaitress_1.OneWaitressEvents.STACK_STATUS_NETWORK_DOWN }, DEFAULT_NETWORK_REQUEST_TIMEOUT, '[INIT TC] Leave network');
|
|
758
777
|
await (0, utils_1.Wait)(200); // settle down
|
|
759
778
|
action = NetworkInitAction.LEFT;
|
|
760
779
|
}
|
|
@@ -772,24 +791,21 @@ class EmberAdapter extends __1.Adapter {
|
|
|
772
791
|
}
|
|
773
792
|
else {
|
|
774
793
|
// config doesn't match backup
|
|
775
|
-
|
|
794
|
+
logger_1.logger.info(`[INIT TC] Config does not match backup.`, NS);
|
|
776
795
|
action = NetworkInitAction.FORM_CONFIG;
|
|
777
796
|
}
|
|
778
797
|
}
|
|
779
798
|
else {
|
|
780
799
|
// no backup
|
|
781
|
-
|
|
800
|
+
logger_1.logger.info(`[INIT TC] No valid backup found.`, NS);
|
|
782
801
|
action = NetworkInitAction.FORM_CONFIG;
|
|
783
802
|
}
|
|
784
803
|
}
|
|
785
|
-
else {
|
|
786
|
-
action = NetworkInitAction.DONE; // just to be clear
|
|
787
|
-
}
|
|
788
804
|
//---- from here on, we assume everything is in place for whatever decision was taken above
|
|
789
805
|
let result = 'resumed';
|
|
790
806
|
switch (action) {
|
|
791
807
|
case NetworkInitAction.FORM_BACKUP: {
|
|
792
|
-
|
|
808
|
+
logger_1.logger.info(`[INIT TC] Forming from backup.`, NS);
|
|
793
809
|
const keyList = backup.devices.map((device) => {
|
|
794
810
|
const octets = Array.from(device.ieeeAddress.reverse());
|
|
795
811
|
const deviceEui64 = '0x' + octets.map(octet => octet.toString(16).padStart(2, '0')).join("");
|
|
@@ -808,13 +824,13 @@ class EmberAdapter extends __1.Adapter {
|
|
|
808
824
|
break;
|
|
809
825
|
}
|
|
810
826
|
case NetworkInitAction.FORM_CONFIG: {
|
|
811
|
-
|
|
827
|
+
logger_1.logger.info(`[INIT TC] Forming from config.`, NS);
|
|
812
828
|
await this.formNetwork(false, /*from config*/ configNetworkKey, 0, this.networkOptions.panID, this.networkOptions.extendedPanID, this.networkOptions.channelList[0], (0, crypto_1.randomBytes)(consts_1.EMBER_ENCRYPTION_KEY_SIZE));
|
|
813
829
|
result = 'reset';
|
|
814
830
|
break;
|
|
815
831
|
}
|
|
816
832
|
case NetworkInitAction.DONE: {
|
|
817
|
-
|
|
833
|
+
logger_1.logger.info(`[INIT TC] NCP network matches config.`, NS);
|
|
818
834
|
break;
|
|
819
835
|
}
|
|
820
836
|
default: {
|
|
@@ -826,17 +842,17 @@ class EmberAdapter extends __1.Adapter {
|
|
|
826
842
|
// XXX: while this remains a pretty low occurrence in most (small) networks,
|
|
827
843
|
// currently Z2M won't support the key update because of one-way config...
|
|
828
844
|
// need to investigate handling this properly
|
|
829
|
-
//
|
|
830
|
-
// + `This may result in some devices (especially battery-powered) temporarily losing connection
|
|
845
|
+
// logger.warning(`[INIT TC] Network key frame counter is reaching its limit. Scheduling broadcast to update network key. `
|
|
846
|
+
// + `This may result in some devices (especially battery-powered) temporarily losing connection.`, NS);
|
|
831
847
|
// // XXX: no idea here on the proper timer value, but this will block the network for several seconds on exec
|
|
832
848
|
// // (probably have to take the behavior of sleepy-end devices into account to improve chances of reaching everyone right away?)
|
|
833
849
|
// setTimeout(async () => {
|
|
834
850
|
// this.requestQueue.enqueue(async (): Promise<EmberStatus> => {
|
|
835
851
|
// await this.broadcastNetworkKeyUpdate();
|
|
836
852
|
// return EmberStatus.SUCCESS;
|
|
837
|
-
// },
|
|
853
|
+
// }, logger.error, true);// no reject just log error if any, will retry next start, & prioritize so we know it'll run when expected
|
|
838
854
|
// }, 300000);
|
|
839
|
-
|
|
855
|
+
logger_1.logger.warning(`[INIT TC] Network key frame counter is reaching its limit. A new network key will have to be instaured soon.`, NS);
|
|
840
856
|
}
|
|
841
857
|
return result;
|
|
842
858
|
}
|
|
@@ -881,15 +897,15 @@ class EmberAdapter extends __1.Adapter {
|
|
|
881
897
|
nwkUpdateId: 0,
|
|
882
898
|
channels: consts_2.EMBER_ALL_802_15_4_CHANNELS_MASK,
|
|
883
899
|
};
|
|
884
|
-
|
|
900
|
+
logger_1.logger.info(`[INIT FORM] Forming new network with: ${JSON.stringify(netParams)}`, NS);
|
|
885
901
|
emberStatus = (await this.ezsp.ezspFormNetwork(netParams));
|
|
886
902
|
if (emberStatus !== enums_2.EmberStatus.SUCCESS) {
|
|
887
903
|
throw new Error(`[INIT FORM] Failed form network request with status=${enums_2.EmberStatus[emberStatus]}.`);
|
|
888
904
|
}
|
|
889
|
-
await this.oneWaitress.startWaitingForEvent({ eventName: OneWaitressEvents.STACK_STATUS_NETWORK_UP }, DEFAULT_NETWORK_REQUEST_TIMEOUT, '[INIT FORM] Form network');
|
|
905
|
+
await this.oneWaitress.startWaitingForEvent({ eventName: oneWaitress_1.OneWaitressEvents.STACK_STATUS_NETWORK_UP }, DEFAULT_NETWORK_REQUEST_TIMEOUT, '[INIT FORM] Form network');
|
|
890
906
|
const stStatus = await this.ezsp.ezspStartWritingStackTokens();
|
|
891
|
-
debug(`[INIT FORM] Start writing stack tokens status=${enums_2.EzspStatus[stStatus]}
|
|
892
|
-
|
|
907
|
+
logger_1.logger.debug(`[INIT FORM] Start writing stack tokens status=${enums_2.EzspStatus[stStatus]}.`, NS);
|
|
908
|
+
logger_1.logger.info(`[INIT FORM] New network formed!`, NS);
|
|
893
909
|
}
|
|
894
910
|
/**
|
|
895
911
|
* Loads currently stored backup and returns it in internal backup model.
|
|
@@ -913,10 +929,10 @@ class EmberAdapter extends __1.Adapter {
|
|
|
913
929
|
throw new Error(`[BACKUP] Unsupported open coordinator backup version (version=${data.metadata?.version}).`);
|
|
914
930
|
}
|
|
915
931
|
if (!data.stack_specific?.ezsp || !data.metadata.internal.ezspVersion) {
|
|
916
|
-
throw new Error(`[BACKUP]
|
|
932
|
+
throw new Error(`[BACKUP] Current backup file is not for EmberZNet stack.`);
|
|
917
933
|
}
|
|
918
934
|
if (data.metadata.internal.ezspVersion < BACKUP_OLDEST_SUPPORTED_EZSP_VERSION) {
|
|
919
|
-
throw new Error(`[BACKUP]
|
|
935
|
+
throw new Error(`[BACKUP] Current backup file is from an unsupported EZSP version (min: ${BACKUP_OLDEST_SUPPORTED_EZSP_VERSION}).`);
|
|
920
936
|
}
|
|
921
937
|
return utils_1.BackupUtils.fromUnifiedBackup(data);
|
|
922
938
|
}
|
|
@@ -941,7 +957,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
941
957
|
const keyList = [];
|
|
942
958
|
for (let i = 0; i < keyTableSize; i++) {
|
|
943
959
|
[deviceEui64, plaintextKey, apsKeyMeta, status] = (await this.ezsp.ezspExportLinkKeyByIndex(i));
|
|
944
|
-
debug(`[BACKUP] Export link key at index ${i}, status=${enums_2.SLStatus[status]}
|
|
960
|
+
logger_1.logger.debug(`[BACKUP] Export link key at index ${i}, status=${enums_2.SLStatus[status]}.`, NS);
|
|
945
961
|
// only include key if we could retrieve one at index and hash it properly
|
|
946
962
|
if (status === enums_2.SLStatus.OK) {
|
|
947
963
|
// Rather than give the real link key, the backup contains a hashed version of the key.
|
|
@@ -958,11 +974,11 @@ class EmberAdapter extends __1.Adapter {
|
|
|
958
974
|
}
|
|
959
975
|
else {
|
|
960
976
|
// this should never happen?
|
|
961
|
-
|
|
977
|
+
logger_1.logger.error(`[BACKUP] Failed to hash link key at index ${i} with status=${enums_2.EmberStatus[hashStatus]}. Omitting from backup.`, NS);
|
|
962
978
|
}
|
|
963
979
|
}
|
|
964
980
|
}
|
|
965
|
-
|
|
981
|
+
logger_1.logger.info(`[BACKUP] Retrieved ${keyList.length} link keys.`, NS);
|
|
966
982
|
return keyList;
|
|
967
983
|
}
|
|
968
984
|
/**
|
|
@@ -1000,7 +1016,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1000
1016
|
+ `with status=${enums_2.EmberStatus[status]}`);
|
|
1001
1017
|
}
|
|
1002
1018
|
}
|
|
1003
|
-
|
|
1019
|
+
logger_1.logger.info(`[BACKUP] Imported ${backupData.length} keys.`, NS);
|
|
1004
1020
|
}
|
|
1005
1021
|
/**
|
|
1006
1022
|
* Routine to update the network key and broadcast the update to the network after a set time.
|
|
@@ -1011,11 +1027,11 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1011
1027
|
async broadcastNetworkKeyUpdate() {
|
|
1012
1028
|
return new Promise((resolve, reject) => {
|
|
1013
1029
|
this.requestQueue.enqueue(async () => {
|
|
1014
|
-
|
|
1030
|
+
logger_1.logger.warning(`[TRUST CENTER] Performing a network key update. This might take a while and disrupt normal operation.`, NS);
|
|
1015
1031
|
// zero-filled = let stack generate new random network key
|
|
1016
1032
|
let status = await this.ezsp.ezspBroadcastNextNetworkKey({ contents: Buffer.alloc(consts_1.EMBER_ENCRYPTION_KEY_SIZE) });
|
|
1017
1033
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
1018
|
-
|
|
1034
|
+
logger_1.logger.error(`[TRUST CENTER] Failed to broadcast next network key with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
1019
1035
|
return status;
|
|
1020
1036
|
}
|
|
1021
1037
|
// XXX: this will block other requests for a while, but should ensure the key propagates without interference?
|
|
@@ -1024,7 +1040,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1024
1040
|
status = (await this.ezsp.ezspBroadcastNetworkKeySwitch());
|
|
1025
1041
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
1026
1042
|
// XXX: Not sure how likely this is, but this is bad, probably should hard fail?
|
|
1027
|
-
|
|
1043
|
+
logger_1.logger.error(`[TRUST CENTER] Failed to broadcast network key switch with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
1028
1044
|
return status;
|
|
1029
1045
|
}
|
|
1030
1046
|
resolve();
|
|
@@ -1037,117 +1053,17 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1037
1053
|
* @param status
|
|
1038
1054
|
*/
|
|
1039
1055
|
async onNcpNeedsResetAndInit(status) {
|
|
1040
|
-
|
|
1056
|
+
logger_1.logger.error(`!!! NCP FATAL ERROR reason=${enums_2.EzspStatus[status]}. ATTEMPTING RESET... !!!`, NS);
|
|
1041
1057
|
try {
|
|
1042
1058
|
await this.stop();
|
|
1043
1059
|
await (0, utils_1.Wait)(500); // just because
|
|
1044
1060
|
await this.start();
|
|
1045
1061
|
}
|
|
1046
1062
|
catch (err) {
|
|
1047
|
-
|
|
1063
|
+
logger_1.logger.error(`Failed to reset and init NCP. ${err}`, NS);
|
|
1048
1064
|
this.emit(events_1.Events.disconnected);
|
|
1049
1065
|
}
|
|
1050
1066
|
}
|
|
1051
|
-
/**
|
|
1052
|
-
* Called right before a NCP reset.
|
|
1053
|
-
*/
|
|
1054
|
-
async onNCPPreReset() {
|
|
1055
|
-
this.requestQueue.stopDispatching();
|
|
1056
|
-
}
|
|
1057
|
-
/**
|
|
1058
|
-
* Called right after a NCP reset, right before the creation of endpoints.
|
|
1059
|
-
*/
|
|
1060
|
-
async onNCPPostReset() {
|
|
1061
|
-
this.requestQueue.startDispatching();
|
|
1062
|
-
this.watchdogCountersHandle = setInterval(this.watchdogCounters.bind(this), WATCHDOG_COUNTERS_FEED_INTERVAL);
|
|
1063
|
-
}
|
|
1064
|
-
/**
|
|
1065
|
-
* Handle changes in groups that needs to be propagated to the NCP multicast table.
|
|
1066
|
-
*
|
|
1067
|
-
* XXX: Since Z2M doesn't explicitly check-in downstream when groups are created/removed, we look at outgoing genGroups commands.
|
|
1068
|
-
* If the NCP doesn't know about groups, it can miss messages from some devices (remotes for example), so we add it...
|
|
1069
|
-
*
|
|
1070
|
-
* @param commandId
|
|
1071
|
-
* @param groupId
|
|
1072
|
-
*/
|
|
1073
|
-
async onGroupChange(commandId, groupId) {
|
|
1074
|
-
switch (commandId) {
|
|
1075
|
-
case cluster_1.default.genGroups.commands.add.ID: {
|
|
1076
|
-
// check if group already in multicast table, should not happen...
|
|
1077
|
-
const existingIndex = this.multicastTable.findIndex((e) => ((e != null) && (e.multicastId === groupId)));
|
|
1078
|
-
if (existingIndex == -1) {
|
|
1079
|
-
// find first unused index
|
|
1080
|
-
const newEntryIndex = this.multicastTable.findIndex((e) => (!e));
|
|
1081
|
-
if (newEntryIndex != -1) {
|
|
1082
|
-
const newEntry = {
|
|
1083
|
-
multicastId: groupId,
|
|
1084
|
-
endpoint: endpoints_1.FIXED_ENDPOINTS[0].endpoint,
|
|
1085
|
-
networkIndex: endpoints_1.FIXED_ENDPOINTS[0].networkIndex,
|
|
1086
|
-
};
|
|
1087
|
-
const status = (await this.ezsp.ezspSetMulticastTableEntry(newEntryIndex, newEntry));
|
|
1088
|
-
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
1089
|
-
console.error(`Failed to register group "${groupId}" in multicast table at index "${newEntryIndex}" with status=${enums_2.EmberStatus[status]}.`);
|
|
1090
|
-
}
|
|
1091
|
-
else {
|
|
1092
|
-
debug(`Registered multicast table entry: ${JSON.stringify(newEntry)}.`);
|
|
1093
|
-
}
|
|
1094
|
-
// always assume "it worked" to keep sync with Z2M first, NCP second, otherwise trouble might arise... should always work anyway
|
|
1095
|
-
this.multicastTable[newEntryIndex] = newEntry;
|
|
1096
|
-
}
|
|
1097
|
-
else {
|
|
1098
|
-
console.warn(`Coordinator multicast table is full (max: ${STACK_CONFIGS[this.stackConfig].MULTICAST_TABLE_SIZE}). `
|
|
1099
|
-
+ `Some devices in new groups may not work properly, including in group "${groupId}". `
|
|
1100
|
-
+ `If that happens, please remove groups to be below the limit. `
|
|
1101
|
-
+ `Removed groups are only removed from coordinator after a Zigbee2MQTT restart.`);
|
|
1102
|
-
}
|
|
1103
|
-
}
|
|
1104
|
-
else {
|
|
1105
|
-
debug(`Added group "${groupId}", but local table says it is already registered at index "${existingIndex}". Skipping.`);
|
|
1106
|
-
}
|
|
1107
|
-
break;
|
|
1108
|
-
}
|
|
1109
|
-
// NOTE: Can't remove groups, since we watch from command exec to group members, that would trigger from any removed member,
|
|
1110
|
-
// even though the group might still exist...
|
|
1111
|
-
// Leaving this here (since it's done...), just in case we get better notifications for groups from upstream.
|
|
1112
|
-
// case Cluster.genGroups.commands.remove.ID: {
|
|
1113
|
-
// const entryIndex = this.multicastTable.findIndex((e) => ((e != null) && (e.multicastId === groupId)));
|
|
1114
|
-
// // just in case, never remove GP at i zero, should never be the case...
|
|
1115
|
-
// if (entryIndex > 0) {
|
|
1116
|
-
// const entry = this.multicastTable[entryIndex];
|
|
1117
|
-
// entry.endpoint = 0;// signals "not in use" in the stack
|
|
1118
|
-
// const status = (await this.ezsp.ezspSetMulticastTableEntry(entryIndex, entry));
|
|
1119
|
-
// if (status !== EmberStatus.SUCCESS) {
|
|
1120
|
-
// console.error(`Failed to remove multicast table entry at index "${entryIndex}" for group "${groupId}".`);
|
|
1121
|
-
// } else {
|
|
1122
|
-
// debug(`Removed multicast table entry at index "${entryIndex}".`);
|
|
1123
|
-
// }
|
|
1124
|
-
// // always assume "it worked" to keep sync with Z2M first, NCP second, otherwise trouble might arise... should always work anyway
|
|
1125
|
-
// this.multicastTable[entryIndex] = null;
|
|
1126
|
-
// } else {
|
|
1127
|
-
// debug(`Removed group "${groupId}", but local table did not have a reference to it.`);
|
|
1128
|
-
// }
|
|
1129
|
-
// break;
|
|
1130
|
-
// }
|
|
1131
|
-
// case Cluster.genGroups.commands.removeAll.ID: {
|
|
1132
|
-
// // this can create quite a few NCP calls, but hopefully shouldn't happen often
|
|
1133
|
-
// // always skip green power at i==0
|
|
1134
|
-
// for (let i = 1; i < this.multicastTable.length; i++) {
|
|
1135
|
-
// const entry = this.multicastTable[i];
|
|
1136
|
-
// if (entry != null) {
|
|
1137
|
-
// entry.endpoint = 0;// signals "not in use" in the stack
|
|
1138
|
-
// const status = (await this.ezsp.ezspSetMulticastTableEntry(i, entry));
|
|
1139
|
-
// if (status !== EmberStatus.SUCCESS) {
|
|
1140
|
-
// console.error(`Failed to remove multicast entry at index "${i}" with status=${EmberStatus[status]}.`);
|
|
1141
|
-
// } else {
|
|
1142
|
-
// debug(`Removed multicast table entry at index "${i}".`);
|
|
1143
|
-
// }
|
|
1144
|
-
// }
|
|
1145
|
-
// this.multicastTable[i] = null;
|
|
1146
|
-
// }
|
|
1147
|
-
// break;
|
|
1148
|
-
// }
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1151
1067
|
//---- START Events
|
|
1152
1068
|
//---- END Events
|
|
1153
1069
|
//---- START Cache-enabled EZSP wrappers
|
|
@@ -1192,7 +1108,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1192
1108
|
this.networkCache.parameters = parameters;
|
|
1193
1109
|
}
|
|
1194
1110
|
else {
|
|
1195
|
-
|
|
1111
|
+
logger_1.logger.error(`Failed to get PAN ID (via network parameters) with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
1196
1112
|
}
|
|
1197
1113
|
}
|
|
1198
1114
|
return this.networkCache.parameters.panId;
|
|
@@ -1209,7 +1125,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1209
1125
|
this.networkCache.parameters = parameters;
|
|
1210
1126
|
}
|
|
1211
1127
|
else {
|
|
1212
|
-
|
|
1128
|
+
logger_1.logger.error(`Failed to get Extended PAN ID (via network parameters) with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
1213
1129
|
}
|
|
1214
1130
|
}
|
|
1215
1131
|
return this.networkCache.parameters.extendedPanId;
|
|
@@ -1226,7 +1142,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1226
1142
|
this.networkCache.parameters = parameters;
|
|
1227
1143
|
}
|
|
1228
1144
|
else {
|
|
1229
|
-
|
|
1145
|
+
logger_1.logger.error(`Failed to get radio channel (via network parameters) with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
1230
1146
|
}
|
|
1231
1147
|
}
|
|
1232
1148
|
return this.networkCache.parameters.radioChannel;
|
|
@@ -1237,7 +1153,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1237
1153
|
this.requestQueue.enqueue(async () => {
|
|
1238
1154
|
const status = (await this.ezsp.ezspStartScan(enums_2.EzspNetworkScanType.ENERGY_SCAN, consts_2.EMBER_ALL_802_15_4_CHANNELS_MASK, ENERGY_SCAN_DURATION));
|
|
1239
1155
|
if (status !== enums_2.SLStatus.OK) {
|
|
1240
|
-
|
|
1156
|
+
logger_1.logger.error(`Failed energy scan request with status=${enums_2.SLStatus[status]}.`, NS);
|
|
1241
1157
|
return enums_2.EmberStatus.ERR_FATAL;
|
|
1242
1158
|
}
|
|
1243
1159
|
// TODO: result in logs only atm, since UI doesn't support it
|
|
@@ -1271,34 +1187,21 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1271
1187
|
if (ncpEzspProtocolVer !== consts_1.EZSP_PROTOCOL_VERSION) {
|
|
1272
1188
|
throw new Error(`NCP EZSP protocol version of ${ncpEzspProtocolVer} does not match Host version ${hostEzspProtocolVer}`);
|
|
1273
1189
|
}
|
|
1274
|
-
debug(`NCP info: EZSPVersion=${ncpEzspProtocolVer} StackType=${ncpStackType} StackVersion=${ncpStackVer}
|
|
1190
|
+
logger_1.logger.debug(`NCP info: EZSPVersion=${ncpEzspProtocolVer} StackType=${ncpStackType} StackVersion=${ncpStackVer}`, NS);
|
|
1275
1191
|
const [status, versionStruct] = (await this.ezsp.ezspGetVersionStruct());
|
|
1276
1192
|
if (status !== enums_2.EzspStatus.SUCCESS) {
|
|
1277
|
-
//
|
|
1278
|
-
|
|
1279
|
-
this.version = {
|
|
1280
|
-
ezsp: ncpEzspProtocolVer,
|
|
1281
|
-
revision: `${ncpStackVer}`,
|
|
1282
|
-
major: ncpStackVer,
|
|
1283
|
-
minor: 0,
|
|
1284
|
-
patch: 0,
|
|
1285
|
-
special: 0,
|
|
1286
|
-
build: 0,
|
|
1287
|
-
type: enums_2.EmberVersionType.GA, // default...
|
|
1288
|
-
};
|
|
1193
|
+
// Should never happen with support of only EZSP v13+
|
|
1194
|
+
throw new Error(`NCP has old-style version number. Not supported.`);
|
|
1289
1195
|
}
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
};
|
|
1297
|
-
if (versionStruct.type !== enums_2.EmberVersionType.GA) {
|
|
1298
|
-
console.warn(`NCP is running a non-GA version (${enums_2.EmberVersionType[versionStruct.type]}).`);
|
|
1299
|
-
}
|
|
1196
|
+
this.version = {
|
|
1197
|
+
ezsp: ncpEzspProtocolVer,
|
|
1198
|
+
revision: `${versionStruct.major}.${versionStruct.minor}.${versionStruct.patch} [${enums_2.EmberVersionType[versionStruct.type]}]`,
|
|
1199
|
+
...versionStruct,
|
|
1200
|
+
};
|
|
1201
|
+
if (versionStruct.type !== enums_2.EmberVersionType.GA) {
|
|
1202
|
+
logger_1.logger.warning(`NCP is running a non-GA version (${enums_2.EmberVersionType[versionStruct.type]}).`, NS);
|
|
1300
1203
|
}
|
|
1301
|
-
debug(`NCP version info: ${JSON.stringify(this.version)}
|
|
1204
|
+
logger_1.logger.debug(`NCP version info: ${JSON.stringify(this.version)}`, NS);
|
|
1302
1205
|
}
|
|
1303
1206
|
/**
|
|
1304
1207
|
* This function sets an EZSP config value.
|
|
@@ -1310,14 +1213,14 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1310
1213
|
*/
|
|
1311
1214
|
async emberSetEzspConfigValue(configId, value) {
|
|
1312
1215
|
const status = (await this.ezsp.ezspSetConfigurationValue(configId, value));
|
|
1313
|
-
debug(`[EzspConfigId] SET "${enums_1.EzspConfigId[configId]}" TO "${value}" with status=${enums_2.EzspStatus[status]}
|
|
1216
|
+
logger_1.logger.debug(`[EzspConfigId] SET "${enums_1.EzspConfigId[configId]}" TO "${value}" with status=${enums_2.EzspStatus[status]}.`, NS);
|
|
1314
1217
|
if (status === enums_2.EzspStatus.ERROR_INVALID_ID) {
|
|
1315
1218
|
// can be ZLL where not all NCPs need or support it.
|
|
1316
|
-
|
|
1219
|
+
logger_1.logger.warning(`[EzspConfigId] Unsupported configuration ID ${enums_1.EzspConfigId[configId]} by NCP.`, NS);
|
|
1317
1220
|
}
|
|
1318
1221
|
else if (status !== enums_2.EzspStatus.SUCCESS) {
|
|
1319
|
-
|
|
1320
|
-
|
|
1222
|
+
logger_1.logger.warning(`[EzspConfigId] Failed to SET "${enums_1.EzspConfigId[configId]}" TO "${value}" with status=${enums_2.EzspStatus[status]}. `
|
|
1223
|
+
+ `Firmware value will be used instead.`, NS);
|
|
1321
1224
|
}
|
|
1322
1225
|
return status;
|
|
1323
1226
|
}
|
|
@@ -1330,7 +1233,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1330
1233
|
*/
|
|
1331
1234
|
async emberSetEzspValue(valueId, valueLength, value) {
|
|
1332
1235
|
const status = (await this.ezsp.ezspSetValue(valueId, valueLength, value));
|
|
1333
|
-
debug(`[EzspValueId] SET "${enums_1.EzspValueId[valueId]}" TO "${value}" with status=${enums_2.EzspStatus[status]}
|
|
1236
|
+
logger_1.logger.debug(`[EzspValueId] SET "${enums_1.EzspValueId[valueId]}" TO "${value}" with status=${enums_2.EzspStatus[status]}.`, NS);
|
|
1334
1237
|
return status;
|
|
1335
1238
|
}
|
|
1336
1239
|
/**
|
|
@@ -1341,7 +1244,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1341
1244
|
*/
|
|
1342
1245
|
async emberSetEzspPolicy(policyId, decisionId) {
|
|
1343
1246
|
const status = (await this.ezsp.ezspSetPolicy(policyId, decisionId));
|
|
1344
|
-
debug(`[EzspPolicyId] SET "${enums_1.EzspPolicyId[policyId]}" TO "${decisionId}" with status=${enums_2.EzspStatus[status]}
|
|
1247
|
+
logger_1.logger.debug(`[EzspPolicyId] SET "${enums_1.EzspPolicyId[policyId]}" TO "${decisionId}" with status=${enums_2.EzspStatus[status]}.`, NS);
|
|
1345
1248
|
return status;
|
|
1346
1249
|
}
|
|
1347
1250
|
/**
|
|
@@ -1433,10 +1336,10 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1433
1336
|
let status = (await this.ezsp.ezspPermitJoining(duration));
|
|
1434
1337
|
let apsFrame = null;
|
|
1435
1338
|
let messageTag = null;
|
|
1436
|
-
debug(`Permit joining for ${duration} sec. status=${[status]}
|
|
1339
|
+
logger_1.logger.debug(`Permit joining for ${duration} sec. status=${[status]}`, NS);
|
|
1437
1340
|
if (broadcastMgmtPermitJoin) {
|
|
1438
1341
|
// `authentication`: TC significance always 1 (zb specs)
|
|
1439
|
-
[status, apsFrame, messageTag] = (await this.emberPermitJoiningRequest(consts_2.EMBER_BROADCAST_ADDRESS, duration, 1,
|
|
1342
|
+
[status, apsFrame, messageTag] = (await this.emberPermitJoiningRequest(consts_2.EMBER_BROADCAST_ADDRESS, duration, 1, DEFAULT_APS_OPTIONS));
|
|
1440
1343
|
}
|
|
1441
1344
|
return [status, apsFrame, messageTag];
|
|
1442
1345
|
}
|
|
@@ -1477,7 +1380,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1477
1380
|
return value;
|
|
1478
1381
|
}
|
|
1479
1382
|
else {
|
|
1480
|
-
debug(`Failed to get source route overhead (via extended value), status=${enums_2.EzspStatus[status]}
|
|
1383
|
+
logger_1.logger.debug(`Failed to get source route overhead (via extended value), status=${enums_2.EzspStatus[status]}.`, NS);
|
|
1481
1384
|
}
|
|
1482
1385
|
return 0;
|
|
1483
1386
|
}
|
|
@@ -1595,17 +1498,17 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1595
1498
|
const messageContents = this.zdoRequestBuffalo.getWritten();
|
|
1596
1499
|
if (destination === consts_2.EMBER_BROADCAST_ADDRESS || destination === consts_2.EMBER_RX_ON_WHEN_IDLE_BROADCAST_ADDRESS
|
|
1597
1500
|
|| destination === consts_2.EMBER_SLEEPY_BROADCAST_ADDRESS) {
|
|
1598
|
-
debug(`~~~> [ZDO BROADCAST apsFrame=${JSON.stringify(apsFrame)} messageTag=${messageTag}]
|
|
1501
|
+
logger_1.logger.debug(`~~~> [ZDO BROADCAST apsFrame=${JSON.stringify(apsFrame)} messageTag=${messageTag}]`, NS);
|
|
1599
1502
|
const [status, apsSequence] = (await this.ezsp.ezspSendBroadcast(destination, apsFrame, this.getZDORequestRadius(), messageTag, messageContents));
|
|
1600
1503
|
apsFrame.sequence = apsSequence;
|
|
1601
|
-
debug(`~~~> [SENT ZDO type=BROADCAST apsFrame=${JSON.stringify(apsFrame)} messageTag=${messageTag} status=${enums_2.EmberStatus[status]}]
|
|
1504
|
+
logger_1.logger.debug(`~~~> [SENT ZDO type=BROADCAST apsFrame=${JSON.stringify(apsFrame)} messageTag=${messageTag} status=${enums_2.EmberStatus[status]}]`, NS);
|
|
1602
1505
|
return [status, apsFrame, messageTag];
|
|
1603
1506
|
}
|
|
1604
1507
|
else {
|
|
1605
|
-
debug(`~~~> [ZDO UNICAST apsFrame=${JSON.stringify(apsFrame)} messageTag=${messageTag}]
|
|
1508
|
+
logger_1.logger.debug(`~~~> [ZDO UNICAST apsFrame=${JSON.stringify(apsFrame)} messageTag=${messageTag}]`, NS);
|
|
1606
1509
|
const [status, apsSequence] = (await this.ezsp.ezspSendUnicast(enums_2.EmberOutgoingMessageType.DIRECT, destination, apsFrame, messageTag, messageContents));
|
|
1607
1510
|
apsFrame.sequence = apsSequence;
|
|
1608
|
-
debug(`~~~> [SENT ZDO type=DIRECT apsFrame=${JSON.stringify(apsFrame)} messageTag=${messageTag} status=${enums_2.EmberStatus[status]}]
|
|
1511
|
+
logger_1.logger.debug(`~~~> [SENT ZDO type=DIRECT apsFrame=${JSON.stringify(apsFrame)} messageTag=${messageTag} status=${enums_2.EmberStatus[status]}]`, NS);
|
|
1609
1512
|
return [status, apsFrame, messageTag];
|
|
1610
1513
|
}
|
|
1611
1514
|
}
|
|
@@ -1647,7 +1550,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1647
1550
|
this.zdoRequestBuffalo.writeListUInt16(inClusters);
|
|
1648
1551
|
this.zdoRequestBuffalo.writeUInt8(outClusters.length);
|
|
1649
1552
|
this.zdoRequestBuffalo.writeListUInt16(outClusters);
|
|
1650
|
-
debug(`~~~> [ZDO
|
|
1553
|
+
logger_1.logger.debug(`~~~> [ZDO MATCH_DESCRIPTORS_REQUEST target=${target} profile=${profile} inClusters=${inClusters} outClusters=${outClusters}]`, NS);
|
|
1651
1554
|
return this.sendZDORequestBuffer(target, zdo_1.MATCH_DESCRIPTORS_REQUEST, options);
|
|
1652
1555
|
}
|
|
1653
1556
|
/**
|
|
@@ -1672,7 +1575,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1672
1575
|
this.zdoRequestBuffalo.writeIeeeAddr(target);
|
|
1673
1576
|
this.zdoRequestBuffalo.writeUInt8(reportKids ? 1 : 0);
|
|
1674
1577
|
this.zdoRequestBuffalo.writeUInt8(childStartIndex);
|
|
1675
|
-
debug(`~~~> [ZDO
|
|
1578
|
+
logger_1.logger.debug(`~~~> [ZDO NETWORK_ADDRESS_REQUEST target=${target} reportKids=${reportKids} childStartIndex=${childStartIndex}]`, NS);
|
|
1676
1579
|
return this.sendZDORequestBuffer(consts_2.EMBER_RX_ON_WHEN_IDLE_BROADCAST_ADDRESS, zdo_1.NETWORK_ADDRESS_REQUEST, enums_2.EmberApsOption.SOURCE_EUI64);
|
|
1677
1580
|
}
|
|
1678
1581
|
/**
|
|
@@ -1698,7 +1601,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1698
1601
|
this.zdoRequestBuffalo.writeUInt16(target);
|
|
1699
1602
|
this.zdoRequestBuffalo.writeUInt8(reportKids ? 1 : 0);
|
|
1700
1603
|
this.zdoRequestBuffalo.writeUInt8(childStartIndex);
|
|
1701
|
-
debug(`~~~> [ZDO
|
|
1604
|
+
logger_1.logger.debug(`~~~> [ZDO IEEE_ADDRESS_REQUEST target=${target} reportKids=${reportKids} childStartIndex=${childStartIndex}]`, NS);
|
|
1702
1605
|
return this.sendZDORequestBuffer(target, zdo_1.IEEE_ADDRESS_REQUEST, options);
|
|
1703
1606
|
}
|
|
1704
1607
|
/**
|
|
@@ -1714,8 +1617,8 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1714
1617
|
this.zdoRequestBuffalo.writeUInt16(discoveryNodeId);
|
|
1715
1618
|
this.zdoRequestBuffalo.writeUInt8(reportKids ? 1 : 0);
|
|
1716
1619
|
this.zdoRequestBuffalo.writeUInt8(childStartIndex);
|
|
1717
|
-
debug(`~~~> [ZDO
|
|
1718
|
-
+ `reportKids=${reportKids} childStartIndex=${childStartIndex}]
|
|
1620
|
+
logger_1.logger.debug(`~~~> [ZDO IEEE_ADDRESS_REQUEST targetNodeIdOfRequest=${targetNodeIdOfRequest} discoveryNodeId=${discoveryNodeId} `
|
|
1621
|
+
+ `reportKids=${reportKids} childStartIndex=${childStartIndex}]`, NS);
|
|
1719
1622
|
return this.sendZDORequestBuffer(targetNodeIdOfRequest, zdo_1.IEEE_ADDRESS_REQUEST, options);
|
|
1720
1623
|
}
|
|
1721
1624
|
/**
|
|
@@ -1754,45 +1657,31 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1754
1657
|
this.zdoRequestBuffalo.setPosition(zdo_1.ZDO_MESSAGE_OVERHEAD);
|
|
1755
1658
|
this.zdoRequestBuffalo.writeUInt16(target);
|
|
1756
1659
|
this.zdoRequestBuffalo.writeUInt8(targetEndpoint);
|
|
1757
|
-
debug(`~~~> [ZDO
|
|
1660
|
+
logger_1.logger.debug(`~~~> [ZDO SIMPLE_DESCRIPTOR_REQUEST target=${target} targetEndpoint=${targetEndpoint}]`, NS);
|
|
1758
1661
|
return this.sendZDORequestBuffer(target, zdo_1.SIMPLE_DESCRIPTOR_REQUEST, options);
|
|
1759
1662
|
}
|
|
1760
1663
|
/**
|
|
1761
1664
|
* ZDO
|
|
1762
|
-
*
|
|
1763
|
-
* contents from the specified node.
|
|
1764
|
-
*
|
|
1765
|
-
* @param target The node on which the binding will be removed.
|
|
1766
|
-
* @param source The source EUI64 in the binding entry.
|
|
1767
|
-
* @param sourceEndpoint The source endpoint in the binding entry.
|
|
1768
|
-
* @param clusterId The cluster ID in the binding entry.
|
|
1769
|
-
* @param type The type of binding, either ::UNICAST_BINDING,
|
|
1770
|
-
* ::MULTICAST_BINDING, or ::UNICAST_MANY_TO_ONE_BINDING.
|
|
1771
|
-
* ::UNICAST_MANY_TO_ONE_BINDING is an Ember-specific extension
|
|
1772
|
-
* and should be used only when the target is an Ember device.
|
|
1773
|
-
* @param destination The destination EUI64 in the binding entry for the
|
|
1774
|
-
* ::UNICAST_BINDING or ::UNICAST_MANY_TO_ONE_BINDING.
|
|
1775
|
-
* @param groupAddress The group address for the ::MULTICAST_BINDING.
|
|
1776
|
-
* @param destinationEndpoint The destination endpoint in the binding entry for
|
|
1777
|
-
* the ::UNICAST_BINDING or ::UNICAST_MANY_TO_ONE_BINDING.
|
|
1778
|
-
* @param options The options to use when sending the request. See
|
|
1779
|
-
* emberSendUnicast() for a description.
|
|
1665
|
+
* Common logic used by `emberBindRequest` & `emberUnbindRequest`.
|
|
1780
1666
|
*
|
|
1781
|
-
* @return An ::EmberStatus value.
|
|
1782
|
-
* - ::EMBER_SUCCESS
|
|
1783
|
-
* - ::EMBER_NO_BUFFERS
|
|
1784
|
-
* _ ::EMBER_NETWORK_DOWN
|
|
1785
|
-
* - ::EMBER_NETWORK_BUSY
|
|
1786
1667
|
* @param target
|
|
1787
1668
|
* @param bindClusterId
|
|
1788
1669
|
* @param source
|
|
1789
|
-
* @param sourceEndpoint
|
|
1790
|
-
* @param clusterId
|
|
1791
|
-
* @param type
|
|
1670
|
+
* @param sourceEndpoint
|
|
1671
|
+
* @param clusterId
|
|
1672
|
+
* @param type
|
|
1792
1673
|
* @param destination
|
|
1793
|
-
* @param groupAddress
|
|
1794
|
-
* @param destinationEndpoint
|
|
1674
|
+
* @param groupAddress
|
|
1675
|
+
* @param destinationEndpoint
|
|
1795
1676
|
* @param options
|
|
1677
|
+
*
|
|
1678
|
+
* @returns An ::EmberStatus value.
|
|
1679
|
+
* - ::EMBER_SUCCESS
|
|
1680
|
+
* - ::EMBER_NO_BUFFERS
|
|
1681
|
+
* - ::EMBER_NETWORK_DOWN
|
|
1682
|
+
* - ::EMBER_NETWORK_BUSY
|
|
1683
|
+
* @returns APS frame created for the request
|
|
1684
|
+
* @returns The tag used on the message.
|
|
1796
1685
|
*/
|
|
1797
1686
|
async emberSendZigDevBindRequest(target, bindClusterId, source, sourceEndpoint, clusterId, type, destination, groupAddress, destinationEndpoint, options) {
|
|
1798
1687
|
this.zdoRequestBuffalo.setPosition(zdo_1.ZDO_MESSAGE_OVERHEAD);
|
|
@@ -1834,12 +1723,17 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1834
1723
|
* @param options The options to use when sending the request. See
|
|
1835
1724
|
* emberSendUnicast() for a description.
|
|
1836
1725
|
*
|
|
1837
|
-
* @
|
|
1838
|
-
*
|
|
1726
|
+
* @returns An ::EmberStatus value.
|
|
1727
|
+
* - ::EMBER_SUCCESS
|
|
1728
|
+
* - ::EMBER_NO_BUFFERS
|
|
1729
|
+
* - ::EMBER_NETWORK_DOWN
|
|
1730
|
+
* - ::EMBER_NETWORK_BUSY
|
|
1731
|
+
* @returns APS frame created for the request
|
|
1732
|
+
* @returns The tag used on the message.
|
|
1839
1733
|
*/
|
|
1840
1734
|
async emberBindRequest(target, source, sourceEndpoint, clusterId, type, destination, groupAddress, destinationEndpoint, options) {
|
|
1841
|
-
debug(`~~~> [ZDO
|
|
1842
|
-
+ `destination=${destination} groupAddress=${groupAddress} destinationEndpoint=${destinationEndpoint}]
|
|
1735
|
+
logger_1.logger.debug(`~~~> [ZDO BIND_REQUEST target=${target} source=${source} sourceEndpoint=${sourceEndpoint} clusterId=${clusterId} type=${type} `
|
|
1736
|
+
+ `destination=${destination} groupAddress=${groupAddress} destinationEndpoint=${destinationEndpoint}]`, NS);
|
|
1843
1737
|
return this.emberSendZigDevBindRequest(target, zdo_1.BIND_REQUEST, source, sourceEndpoint, clusterId, type, destination, groupAddress, destinationEndpoint, options);
|
|
1844
1738
|
}
|
|
1845
1739
|
/**
|
|
@@ -1863,15 +1757,17 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1863
1757
|
* @param options The options to use when sending the request. See
|
|
1864
1758
|
* emberSendUnicast() for a description.
|
|
1865
1759
|
*
|
|
1866
|
-
* @
|
|
1760
|
+
* @returns An ::EmberStatus value.
|
|
1867
1761
|
* - ::EMBER_SUCCESS
|
|
1868
1762
|
* - ::EMBER_NO_BUFFERS
|
|
1869
|
-
*
|
|
1763
|
+
* - ::EMBER_NETWORK_DOWN
|
|
1870
1764
|
* - ::EMBER_NETWORK_BUSY
|
|
1765
|
+
* @returns APS frame created for the request
|
|
1766
|
+
* @returns The tag used on the message.
|
|
1871
1767
|
*/
|
|
1872
1768
|
async emberUnbindRequest(target, source, sourceEndpoint, clusterId, type, destination, groupAddress, destinationEndpoint, options) {
|
|
1873
|
-
debug(`~~~> [ZDO
|
|
1874
|
-
+ `destination=${destination} groupAddress=${groupAddress} destinationEndpoint=${destinationEndpoint}]
|
|
1769
|
+
logger_1.logger.debug(`~~~> [ZDO UNBIND_REQUEST target=${target} source=${source} sourceEndpoint=${sourceEndpoint} clusterId=${clusterId} type=${type} `
|
|
1770
|
+
+ `destination=${destination} groupAddress=${groupAddress} destinationEndpoint=${destinationEndpoint}]`, NS);
|
|
1875
1771
|
return this.emberSendZigDevBindRequest(target, zdo_1.UNBIND_REQUEST, source, sourceEndpoint, clusterId, type, destination, groupAddress, destinationEndpoint, options);
|
|
1876
1772
|
}
|
|
1877
1773
|
/**
|
|
@@ -1888,7 +1784,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1888
1784
|
* ::EMBER_NETWORK_DOWN or ::EMBER_NETWORK_BUSY.
|
|
1889
1785
|
*/
|
|
1890
1786
|
async emberActiveEndpointsRequest(target, options) {
|
|
1891
|
-
debug(`~~~> [ZDO
|
|
1787
|
+
logger_1.logger.debug(`~~~> [ZDO ACTIVE_ENDPOINTS_REQUEST target=${target}]`, NS);
|
|
1892
1788
|
return this.emberSendZigDevRequestTarget(target, zdo_1.ACTIVE_ENDPOINTS_REQUEST, options);
|
|
1893
1789
|
}
|
|
1894
1790
|
/**
|
|
@@ -1908,7 +1804,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1908
1804
|
* ::EMBER_NETWORK_DOWN or ::EMBER_NETWORK_BUSY.
|
|
1909
1805
|
*/
|
|
1910
1806
|
async emberPowerDescriptorRequest(target, options) {
|
|
1911
|
-
debug(`~~~> [ZDO
|
|
1807
|
+
logger_1.logger.debug(`~~~> [ZDO POWER_DESCRIPTOR_REQUEST target=${target}]`, NS);
|
|
1912
1808
|
return this.emberSendZigDevRequestTarget(target, zdo_1.POWER_DESCRIPTOR_REQUEST, options);
|
|
1913
1809
|
}
|
|
1914
1810
|
/**
|
|
@@ -1927,7 +1823,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1927
1823
|
* ::EMBER_NETWORK_DOWN or ::EMBER_NETWORK_BUSY.
|
|
1928
1824
|
*/
|
|
1929
1825
|
async emberNodeDescriptorRequest(target, options) {
|
|
1930
|
-
debug(`~~~> [ZDO
|
|
1826
|
+
logger_1.logger.debug(`~~~> [ZDO NODE_DESCRIPTOR_REQUEST target=${target}]`, NS);
|
|
1931
1827
|
return this.emberSendZigDevRequestTarget(target, zdo_1.NODE_DESCRIPTOR_REQUEST, options);
|
|
1932
1828
|
}
|
|
1933
1829
|
/**
|
|
@@ -1948,7 +1844,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1948
1844
|
* ::EMBER_NETWORK_DOWN or ::EMBER_NETWORK_BUSY.
|
|
1949
1845
|
*/
|
|
1950
1846
|
async emberLqiTableRequest(target, startIndex, options) {
|
|
1951
|
-
debug(`~~~> [ZDO
|
|
1847
|
+
logger_1.logger.debug(`~~~> [ZDO LQI_TABLE_REQUEST target=${target} startIndex=${startIndex}]`, NS);
|
|
1952
1848
|
return this.emberTableRequest(zdo_1.LQI_TABLE_REQUEST, target, startIndex, options);
|
|
1953
1849
|
}
|
|
1954
1850
|
/**
|
|
@@ -1969,7 +1865,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1969
1865
|
* ::EMBER_NETWORK_DOWN or ::EMBER_NETWORK_BUSY.
|
|
1970
1866
|
*/
|
|
1971
1867
|
async emberRoutingTableRequest(target, startIndex, options) {
|
|
1972
|
-
debug(`~~~> [ZDO
|
|
1868
|
+
logger_1.logger.debug(`~~~> [ZDO ROUTING_TABLE_REQUEST target=${target} startIndex=${startIndex}]`, NS);
|
|
1973
1869
|
return this.emberTableRequest(zdo_1.ROUTING_TABLE_REQUEST, target, startIndex, options);
|
|
1974
1870
|
}
|
|
1975
1871
|
/**
|
|
@@ -1991,7 +1887,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
1991
1887
|
* ::EMBER_NETWORK_DOWN or ::EMBER_NETWORK_BUSY.
|
|
1992
1888
|
*/
|
|
1993
1889
|
async emberBindingTableRequest(target, startIndex, options) {
|
|
1994
|
-
debug(`~~~> [ZDO
|
|
1890
|
+
logger_1.logger.debug(`~~~> [ZDO BINDING_TABLE_REQUEST target=${target} startIndex=${startIndex}]`, NS);
|
|
1995
1891
|
return this.emberTableRequest(zdo_1.BINDING_TABLE_REQUEST, target, startIndex, options);
|
|
1996
1892
|
}
|
|
1997
1893
|
/**
|
|
@@ -2030,7 +1926,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2030
1926
|
this.zdoRequestBuffalo.setPosition(zdo_1.ZDO_MESSAGE_OVERHEAD);
|
|
2031
1927
|
this.zdoRequestBuffalo.writeIeeeAddr(deviceAddress);
|
|
2032
1928
|
this.zdoRequestBuffalo.writeUInt8(leaveRequestFlags);
|
|
2033
|
-
debug(`~~~> [ZDO
|
|
1929
|
+
logger_1.logger.debug(`~~~> [ZDO LEAVE_REQUEST target=${target} deviceAddress=${deviceAddress} leaveRequestFlags=${leaveRequestFlags}]`, NS);
|
|
2034
1930
|
return this.sendZDORequestBuffer(target, zdo_1.LEAVE_REQUEST, options);
|
|
2035
1931
|
}
|
|
2036
1932
|
/**
|
|
@@ -2054,9 +1950,42 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2054
1950
|
this.zdoRequestBuffalo.setPosition(zdo_1.ZDO_MESSAGE_OVERHEAD);
|
|
2055
1951
|
this.zdoRequestBuffalo.writeUInt8(duration);
|
|
2056
1952
|
this.zdoRequestBuffalo.writeUInt8(authentication);
|
|
2057
|
-
debug(`~~~> [ZDO
|
|
1953
|
+
logger_1.logger.debug(`~~~> [ZDO PERMIT_JOINING_REQUEST target=${target} duration=${duration} authentication=${authentication}]`, NS);
|
|
2058
1954
|
return this.sendZDORequestBuffer(target, zdo_1.PERMIT_JOINING_REQUEST, options);
|
|
2059
1955
|
}
|
|
1956
|
+
/**
|
|
1957
|
+
* ZDO
|
|
1958
|
+
*
|
|
1959
|
+
* @see NWK_UPDATE_REQUEST
|
|
1960
|
+
*
|
|
1961
|
+
* @param target
|
|
1962
|
+
* @param scanChannels uint8_t[]
|
|
1963
|
+
* @param duration uint8_t
|
|
1964
|
+
* @param count uint8_t
|
|
1965
|
+
* @param manager
|
|
1966
|
+
*/
|
|
1967
|
+
async emberNetworkUpdateRequest(target, scanChannels, duration, count, manager, options) {
|
|
1968
|
+
this.zdoRequestBuffalo.setPosition(zdo_1.ZDO_MESSAGE_OVERHEAD);
|
|
1969
|
+
this.zdoRequestBuffalo.writeUInt32(scanChannels.reduce((a, c) => a + (1 << c), 0)); // to uint32_t
|
|
1970
|
+
this.zdoRequestBuffalo.writeUInt8(duration);
|
|
1971
|
+
if (count != null) {
|
|
1972
|
+
this.zdoRequestBuffalo.writeUInt8(count);
|
|
1973
|
+
}
|
|
1974
|
+
if (manager != null) {
|
|
1975
|
+
this.zdoRequestBuffalo.writeUInt16(manager);
|
|
1976
|
+
}
|
|
1977
|
+
logger_1.logger.debug(`~~~> [ZDO NWK_UPDATE_REQUEST target=${target} scanChannels=${scanChannels} duration=${duration} count=${count} manager=${manager}]`, NS);
|
|
1978
|
+
return this.sendZDORequestBuffer(target, zdo_1.NWK_UPDATE_REQUEST, options);
|
|
1979
|
+
}
|
|
1980
|
+
async emberScanChannelsRequest(target, scanChannels, duration, count, options) {
|
|
1981
|
+
return this.emberNetworkUpdateRequest(target, scanChannels, duration, count, null, options);
|
|
1982
|
+
}
|
|
1983
|
+
async emberChannelChangeRequest(target, channel, options) {
|
|
1984
|
+
return this.emberNetworkUpdateRequest(target, [channel], 0xFE, null, null, options);
|
|
1985
|
+
}
|
|
1986
|
+
async emberSetActiveChannelsAndNwkManagerIdRequest(target, scanChannels, manager, options) {
|
|
1987
|
+
return this.emberNetworkUpdateRequest(target, scanChannels, 0xFF, null, manager, options);
|
|
1988
|
+
}
|
|
2060
1989
|
//---- END Ember ZDO
|
|
2061
1990
|
//-- START Adapter implementation
|
|
2062
1991
|
static async isValidPath(path) {
|
|
@@ -2068,7 +1997,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2068
1997
|
return serialPortUtils_1.default.is((0, utils_1.RealpathSync)(path), autoDetectDefinitions);
|
|
2069
1998
|
}
|
|
2070
1999
|
catch (error) {
|
|
2071
|
-
debug(`Failed to determine if path is valid: '${error}'
|
|
2000
|
+
logger_1.logger.debug(`Failed to determine if path is valid: '${error}'`, NS);
|
|
2072
2001
|
return false;
|
|
2073
2002
|
}
|
|
2074
2003
|
}
|
|
@@ -2078,16 +2007,17 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2078
2007
|
return paths.length > 0 ? paths[0] : null;
|
|
2079
2008
|
}
|
|
2080
2009
|
async start() {
|
|
2081
|
-
|
|
2010
|
+
logger_1.logger.info(`======== Ember Adapter Starting ========`, NS);
|
|
2082
2011
|
this.initVariables();
|
|
2083
|
-
debug(`Starting EZSP with stack configuration: "${this.stackConfig}"
|
|
2012
|
+
logger_1.logger.debug(`Starting EZSP with stack configuration: "${this.stackConfig}".`, NS);
|
|
2084
2013
|
const result = await this.initEzsp();
|
|
2085
2014
|
return result;
|
|
2086
2015
|
}
|
|
2087
2016
|
async stop() {
|
|
2017
|
+
this.requestQueue.stopDispatching();
|
|
2088
2018
|
await this.ezsp.stop();
|
|
2089
2019
|
this.initVariables();
|
|
2090
|
-
|
|
2020
|
+
logger_1.logger.info(`======== Ember Adapter Stopped ========`, NS);
|
|
2091
2021
|
}
|
|
2092
2022
|
// queued, non-InterPAN
|
|
2093
2023
|
async getCoordinator() {
|
|
@@ -2099,14 +2029,14 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2099
2029
|
resolve({
|
|
2100
2030
|
ieeeAddr,
|
|
2101
2031
|
networkAddress: consts_2.ZIGBEE_COORDINATOR_ADDRESS,
|
|
2102
|
-
manufacturerID:
|
|
2032
|
+
manufacturerID: DEFAULT_MANUFACTURER_CODE,
|
|
2103
2033
|
endpoints: endpoints_1.FIXED_ENDPOINTS.map((ep) => {
|
|
2104
2034
|
return {
|
|
2105
2035
|
profileID: ep.profileId,
|
|
2106
2036
|
ID: ep.endpoint,
|
|
2107
2037
|
deviceID: ep.deviceId,
|
|
2108
|
-
inputClusters: ep.inClusterList,
|
|
2109
|
-
outputClusters: ep.outClusterList,
|
|
2038
|
+
inputClusters: ep.inClusterList.slice(), // copy
|
|
2039
|
+
outputClusters: ep.outClusterList.slice(), // copy
|
|
2110
2040
|
};
|
|
2111
2041
|
}),
|
|
2112
2042
|
});
|
|
@@ -2115,7 +2045,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2115
2045
|
});
|
|
2116
2046
|
}
|
|
2117
2047
|
async getCoordinatorVersion() {
|
|
2118
|
-
return { type: `
|
|
2048
|
+
return { type: `EmberZNet`, meta: this.version };
|
|
2119
2049
|
}
|
|
2120
2050
|
// queued
|
|
2121
2051
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -2136,7 +2066,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2136
2066
|
// grab fresh version here, bypass cache
|
|
2137
2067
|
const [netStatus, , netParams] = (await this.ezsp.ezspGetNetworkParameters());
|
|
2138
2068
|
if (netStatus !== enums_2.EmberStatus.SUCCESS) {
|
|
2139
|
-
|
|
2069
|
+
logger_1.logger.error(`[BACKUP] Failed to get network parameters.`, NS);
|
|
2140
2070
|
return netStatus;
|
|
2141
2071
|
}
|
|
2142
2072
|
// update cache
|
|
@@ -2144,7 +2074,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2144
2074
|
this.networkCache.eui64 = (await this.ezsp.ezspGetEui64());
|
|
2145
2075
|
const [netKeyStatus, netKeyInfo] = (await this.ezsp.ezspGetNetworkKeyInfo());
|
|
2146
2076
|
if (netKeyStatus !== enums_2.SLStatus.OK) {
|
|
2147
|
-
|
|
2077
|
+
logger_1.logger.error(`[BACKUP] Failed to get network keys info.`, NS);
|
|
2148
2078
|
return ((netKeyStatus === enums_2.SLStatus.BUSY) || (netKeyStatus === enums_2.SLStatus.NOT_READY))
|
|
2149
2079
|
? enums_2.EmberStatus.NETWORK_BUSY : enums_2.EmberStatus.ERR_FATAL; // allow retry on statuses that should be temporary
|
|
2150
2080
|
}
|
|
@@ -2160,7 +2090,6 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2160
2090
|
// this.ezsp,
|
|
2161
2091
|
// Buffer.from(this.networkCache.eui64.substring(2/*0x*/), 'hex').reverse()
|
|
2162
2092
|
// ));
|
|
2163
|
-
// console.log(tokensBuf.toString('hex'));
|
|
2164
2093
|
let context = (0, initters_1.initSecurityManagerContext)();
|
|
2165
2094
|
context.coreKeyType = enums_2.SecManKeyType.TC_LINK;
|
|
2166
2095
|
const [tcLinkKey, tclkStatus] = (await this.ezsp.ezspExportKey(context));
|
|
@@ -2219,29 +2148,50 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2219
2148
|
this.checkInterpanLock();
|
|
2220
2149
|
// first call will cache for the others, but in all likelihood, it will all be from freshly cached after init
|
|
2221
2150
|
// since Controller caches this also.
|
|
2151
|
+
const channel = (await this.emberGetRadioChannel());
|
|
2222
2152
|
const panID = (await this.emberGetPanId());
|
|
2223
2153
|
const extendedPanID = (await this.emberGetExtendedPanId());
|
|
2224
|
-
const channel = (await this.emberGetRadioChannel());
|
|
2225
2154
|
resolve({
|
|
2226
|
-
panID
|
|
2155
|
+
panID,
|
|
2227
2156
|
extendedPanID: parseInt(Buffer.from(extendedPanID).toString('hex'), 16),
|
|
2228
|
-
channel
|
|
2157
|
+
channel,
|
|
2229
2158
|
});
|
|
2230
2159
|
return enums_2.EmberStatus.SUCCESS;
|
|
2231
2160
|
}, reject);
|
|
2232
2161
|
});
|
|
2233
2162
|
}
|
|
2163
|
+
async supportsChangeChannel() {
|
|
2164
|
+
return true;
|
|
2165
|
+
}
|
|
2166
|
+
// queued
|
|
2167
|
+
async changeChannel(newChannel) {
|
|
2168
|
+
return new Promise((resolve, reject) => {
|
|
2169
|
+
this.requestQueue.enqueue(async () => {
|
|
2170
|
+
this.checkInterpanLock();
|
|
2171
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2172
|
+
const [status, apsFrame, messageTag] = (await this.emberChannelChangeRequest(consts_2.EMBER_SLEEPY_BROADCAST_ADDRESS, newChannel, DEFAULT_APS_OPTIONS));
|
|
2173
|
+
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2174
|
+
logger_1.logger.error(`[ZDO] Failed broadcast channel change to "${newChannel}" with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2175
|
+
return status;
|
|
2176
|
+
}
|
|
2177
|
+
await this.oneWaitress.startWaitingForEvent({ eventName: oneWaitress_1.OneWaitressEvents.STACK_STATUS_CHANNEL_CHANGED }, DEFAULT_NETWORK_REQUEST_TIMEOUT * 2, // observed to ~9sec
|
|
2178
|
+
'[ZDO] Change Channel');
|
|
2179
|
+
resolve();
|
|
2180
|
+
return enums_2.EmberStatus.SUCCESS;
|
|
2181
|
+
}, reject);
|
|
2182
|
+
});
|
|
2183
|
+
}
|
|
2234
2184
|
// queued
|
|
2235
2185
|
async setTransmitPower(value) {
|
|
2236
2186
|
if (typeof value !== 'number') {
|
|
2237
|
-
|
|
2187
|
+
logger_1.logger.error(`Tried to set transmit power to non-number. Value ${value} of type ${typeof value}.`, NS);
|
|
2238
2188
|
return;
|
|
2239
2189
|
}
|
|
2240
2190
|
return new Promise((resolve, reject) => {
|
|
2241
2191
|
this.requestQueue.enqueue(async () => {
|
|
2242
2192
|
const status = await this.ezsp.ezspSetRadioPower(value);
|
|
2243
2193
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2244
|
-
|
|
2194
|
+
logger_1.logger.error(`Failed to set transmit power to ${value} status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2245
2195
|
return status;
|
|
2246
2196
|
}
|
|
2247
2197
|
resolve();
|
|
@@ -2252,48 +2202,45 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2252
2202
|
// queued
|
|
2253
2203
|
async addInstallCode(ieeeAddress, key) {
|
|
2254
2204
|
if (!key) {
|
|
2255
|
-
throw new Error(`[ADD INSTALL CODE] Failed for
|
|
2205
|
+
throw new Error(`[ADD INSTALL CODE] Failed for '${ieeeAddress}'; no code given.`);
|
|
2256
2206
|
}
|
|
2257
|
-
let
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2207
|
+
// codes with CRC, check CRC before sending to NCP, otherwise let NCP handle
|
|
2208
|
+
if (consts_2.EMBER_INSTALL_CODE_SIZES.indexOf(key.length) !== -1) {
|
|
2209
|
+
// Reverse the bits in a byte (uint8_t)
|
|
2210
|
+
const reverse = (b) => {
|
|
2211
|
+
return (((b * 0x0802 & 0x22110) | (b * 0x8020 & 0x88440)) * 0x10101 >> 16) & 0xFF;
|
|
2212
|
+
};
|
|
2213
|
+
let crc = 0xFFFF; // uint16_t
|
|
2214
|
+
// Compute the CRC and verify that it matches.
|
|
2215
|
+
// The bit reversals, byte swap, and ones' complement are due to differences between halCommonCrc16 and the Smart Energy version.
|
|
2216
|
+
for (let index = 0; index < (key.length - consts_2.EMBER_INSTALL_CODE_CRC_SIZE); index++) {
|
|
2217
|
+
crc = (0, math_1.halCommonCrc16)(reverse(key[index]), crc);
|
|
2218
|
+
}
|
|
2219
|
+
crc = (~(0, math_1.highLowToInt)(reverse((0, math_1.lowByte)(crc)), reverse((0, math_1.highByte)(crc)))) & 0xFFFF;
|
|
2220
|
+
if (key[key.length - consts_2.EMBER_INSTALL_CODE_CRC_SIZE] !== (0, math_1.lowByte)(crc)
|
|
2221
|
+
|| key[key.length - consts_2.EMBER_INSTALL_CODE_CRC_SIZE + 1] !== (0, math_1.highByte)(crc)) {
|
|
2222
|
+
throw new Error(`[ADD INSTALL CODE] Failed for '${ieeeAddress}'; invalid code CRC.`);
|
|
2223
|
+
}
|
|
2224
|
+
else {
|
|
2225
|
+
logger_1.logger.debug(`[ADD INSTALL CODE] CRC validated for '${ieeeAddress}'.`, NS);
|
|
2262
2226
|
}
|
|
2263
|
-
}
|
|
2264
|
-
if (!validInstallCodeSize) {
|
|
2265
|
-
throw new Error(`[ADD INSTALL CODE] Failed for "${ieeeAddress}"; invalid code size.`);
|
|
2266
|
-
}
|
|
2267
|
-
// Reverse the bits in a byte
|
|
2268
|
-
const reverse = (b) => {
|
|
2269
|
-
return ((b * 0x0802 & 0x22110) | (b * 0x8020 & 0x88440)) * 0x10101 >> 16;
|
|
2270
|
-
};
|
|
2271
|
-
let crc = 0xFFFF; // uint16_t
|
|
2272
|
-
// Compute the CRC and verify that it matches.
|
|
2273
|
-
// The bit reversals, byte swap, and ones' complement are due to differences between halCommonCrc16 and the Smart Energy version.
|
|
2274
|
-
for (let index = 0; index < (key.length - consts_2.EMBER_INSTALL_CODE_CRC_SIZE); index++) {
|
|
2275
|
-
crc = (0, math_1.halCommonCrc16)(reverse(key[index]), crc);
|
|
2276
|
-
}
|
|
2277
|
-
crc = ~(0, math_1.highLowToInt)(reverse((0, math_1.lowByte)(crc)), reverse((0, math_1.highByte)(crc)));
|
|
2278
|
-
if (key[key.length - consts_2.EMBER_INSTALL_CODE_CRC_SIZE] !== (0, math_1.lowByte)(crc) || key[key.length - consts_2.EMBER_INSTALL_CODE_CRC_SIZE + 1] !== (0, math_1.highByte)(crc)) {
|
|
2279
|
-
throw new Error(`[ADD INSTALL CODE] Failed for "${ieeeAddress}"; invalid code CRC.`);
|
|
2280
2227
|
}
|
|
2281
2228
|
return new Promise((resolve, reject) => {
|
|
2282
2229
|
this.requestQueue.enqueue(async () => {
|
|
2283
2230
|
// Compute the key from the install code and CRC.
|
|
2284
2231
|
const [aesStatus, keyContents] = (await this.emberAesHashSimple(key));
|
|
2285
2232
|
if (aesStatus !== enums_2.EmberStatus.SUCCESS) {
|
|
2286
|
-
|
|
2233
|
+
logger_1.logger.error(`[ADD INSTALL CODE] Failed AES hash for '${ieeeAddress}' with status=${enums_2.EmberStatus[aesStatus]}.`, NS);
|
|
2287
2234
|
return aesStatus;
|
|
2288
2235
|
}
|
|
2289
2236
|
// Add the key to the transient key table.
|
|
2290
2237
|
// This will be used while the DUT joins.
|
|
2291
2238
|
const impStatus = (await this.ezsp.ezspImportTransientKey(ieeeAddress, { contents: keyContents }, enums_2.SecManFlag.NONE));
|
|
2292
2239
|
if (impStatus == enums_2.SLStatus.OK) {
|
|
2293
|
-
debug(`[ADD INSTALL CODE] Success for
|
|
2240
|
+
logger_1.logger.debug(`[ADD INSTALL CODE] Success for '${ieeeAddress}'.`, NS);
|
|
2294
2241
|
}
|
|
2295
2242
|
else {
|
|
2296
|
-
|
|
2243
|
+
logger_1.logger.error(`[ADD INSTALL CODE] Failed for '${ieeeAddress}' with status=${enums_2.SLStatus[impStatus]}.`, NS);
|
|
2297
2244
|
return enums_2.EmberStatus.ERR_FATAL;
|
|
2298
2245
|
}
|
|
2299
2246
|
resolve();
|
|
@@ -2303,19 +2250,21 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2303
2250
|
}
|
|
2304
2251
|
/** WARNING: Adapter impl. Starts timer immediately upon returning */
|
|
2305
2252
|
waitFor(networkAddress, endpoint, frameType, direction, transactionSequenceNumber, clusterID, commandIdentifier, timeout) {
|
|
2253
|
+
const sourceEndpointInfo = endpoints_1.FIXED_ENDPOINTS[0];
|
|
2306
2254
|
const waiter = this.oneWaitress.waitFor({
|
|
2307
2255
|
target: networkAddress,
|
|
2308
2256
|
apsFrame: {
|
|
2309
2257
|
clusterId: clusterID,
|
|
2310
|
-
profileId:
|
|
2258
|
+
profileId: sourceEndpointInfo.profileId, // XXX: only used by OTA upstream
|
|
2311
2259
|
sequence: 0, // set by stack
|
|
2312
|
-
sourceEndpoint: endpoint,
|
|
2313
|
-
destinationEndpoint:
|
|
2260
|
+
sourceEndpoint: sourceEndpointInfo.endpoint,
|
|
2261
|
+
destinationEndpoint: endpoint,
|
|
2314
2262
|
groupId: 0,
|
|
2315
2263
|
options: enums_2.EmberApsOption.NONE,
|
|
2316
2264
|
},
|
|
2317
2265
|
zclSequence: transactionSequenceNumber,
|
|
2318
|
-
|
|
2266
|
+
commandIdentifier,
|
|
2267
|
+
}, timeout || DEFAULT_ZCL_REQUEST_TIMEOUT * 3); // XXX: since this is used by OTA...
|
|
2319
2268
|
return {
|
|
2320
2269
|
cancel: () => this.oneWaitress.remove(waiter.id),
|
|
2321
2270
|
promise: waiter.start().promise,
|
|
@@ -2328,34 +2277,47 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2328
2277
|
if (seconds) {
|
|
2329
2278
|
const plaintextKey = { contents: Buffer.from(consts_2.ZIGBEE_PROFILE_INTEROPERABILITY_LINK_KEY) };
|
|
2330
2279
|
const impKeyStatus = (await this.ezsp.ezspImportTransientKey(consts_2.BLANK_EUI64, plaintextKey, enums_2.SecManFlag.NONE));
|
|
2331
|
-
|
|
2332
|
-
|
|
2280
|
+
if (impKeyStatus !== enums_2.SLStatus.OK) {
|
|
2281
|
+
logger_1.logger.error(`[ZDO] Failed import transient key with status=${enums_2.SLStatus[impKeyStatus]}.`, NS);
|
|
2282
|
+
return enums_2.EmberStatus.ERR_FATAL;
|
|
2283
|
+
}
|
|
2284
|
+
const setJPstatus = (await this.emberSetJoinPolicy(enums_2.EmberJoinDecision.USE_PRECONFIGURED_KEY));
|
|
2285
|
+
if (setJPstatus !== enums_2.EzspStatus.SUCCESS) {
|
|
2286
|
+
logger_1.logger.error(`[ZDO] Failed set join policy with status=${enums_2.EzspStatus[setJPstatus]}.`, NS);
|
|
2287
|
+
return enums_2.EmberStatus.ERR_FATAL;
|
|
2288
|
+
}
|
|
2289
|
+
return enums_2.EmberStatus.SUCCESS;
|
|
2333
2290
|
}
|
|
2334
2291
|
else {
|
|
2292
|
+
if (this.manufacturerCode !== DEFAULT_MANUFACTURER_CODE) {
|
|
2293
|
+
logger_1.logger.debug(`[WORKAROUND] Reverting coordinator manufacturer code to default.`, NS);
|
|
2294
|
+
await this.ezsp.ezspSetManufacturerCode(DEFAULT_MANUFACTURER_CODE);
|
|
2295
|
+
this.manufacturerCode = DEFAULT_MANUFACTURER_CODE;
|
|
2296
|
+
}
|
|
2335
2297
|
await this.ezsp.ezspClearTransientLinkKeys();
|
|
2336
2298
|
const setJPstatus = (await this.emberSetJoinPolicy(enums_2.EmberJoinDecision.ALLOW_REJOINS_ONLY));
|
|
2337
2299
|
if (setJPstatus !== enums_2.EzspStatus.SUCCESS) {
|
|
2338
|
-
|
|
2300
|
+
logger_1.logger.error(`[ZDO] Failed set join policy for with status=${enums_2.EzspStatus[setJPstatus]}.`, NS);
|
|
2339
2301
|
return enums_2.EmberStatus.ERR_FATAL;
|
|
2340
2302
|
}
|
|
2341
2303
|
return enums_2.EmberStatus.SUCCESS;
|
|
2342
2304
|
}
|
|
2343
2305
|
};
|
|
2344
|
-
// NOTE: can't ZDO PJ on coordinator, so if network address is null or zero (coordinator), using local permit join
|
|
2345
2306
|
if (networkAddress) {
|
|
2307
|
+
// specific device that is not `Coordinator`
|
|
2346
2308
|
return new Promise((resolve, reject) => {
|
|
2347
2309
|
this.requestQueue.enqueue(async () => {
|
|
2348
2310
|
this.checkInterpanLock();
|
|
2349
2311
|
const pjStatus = (await preJoining());
|
|
2350
2312
|
if (pjStatus !== enums_2.EmberStatus.SUCCESS) {
|
|
2351
|
-
|
|
2313
|
+
logger_1.logger.error(`[ZDO] Failed pre joining request for "${networkAddress}" with status=${enums_2.EmberStatus[pjStatus]}.`, NS);
|
|
2352
2314
|
return pjStatus;
|
|
2353
2315
|
}
|
|
2354
2316
|
// `authentication`: TC significance always 1 (zb specs)
|
|
2355
2317
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2356
2318
|
const [status, apsFrame, messageTag] = (await this.emberPermitJoiningRequest(networkAddress, seconds, 1, 0));
|
|
2357
2319
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2358
|
-
|
|
2320
|
+
logger_1.logger.error(`[ZDO] Failed permit joining request for "${networkAddress}" with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2359
2321
|
return status;
|
|
2360
2322
|
}
|
|
2361
2323
|
(await this.oneWaitress.startWaitingFor({
|
|
@@ -2369,19 +2331,20 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2369
2331
|
});
|
|
2370
2332
|
}
|
|
2371
2333
|
else {
|
|
2372
|
-
//
|
|
2334
|
+
// coordinator-only, or all
|
|
2373
2335
|
return new Promise((resolve, reject) => {
|
|
2374
2336
|
this.requestQueue.enqueue(async () => {
|
|
2375
2337
|
this.checkInterpanLock();
|
|
2376
2338
|
const pjStatus = (await preJoining());
|
|
2377
2339
|
if (pjStatus !== enums_2.EmberStatus.SUCCESS) {
|
|
2378
|
-
|
|
2340
|
+
logger_1.logger.error(`[ZDO] Failed pre joining request for "${networkAddress}" with status=${enums_2.EmberStatus[pjStatus]}.`, NS);
|
|
2379
2341
|
return pjStatus;
|
|
2380
2342
|
}
|
|
2343
|
+
// local permit join if `Coordinator`-only requested, else local + broadcast
|
|
2381
2344
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2382
|
-
const [status, apsFrame, messageTag] = (await this.emberPermitJoining(seconds,
|
|
2345
|
+
const [status, apsFrame, messageTag] = (await this.emberPermitJoining(seconds, (networkAddress === consts_2.ZIGBEE_COORDINATOR_ADDRESS) ? false : true));
|
|
2383
2346
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2384
|
-
|
|
2347
|
+
logger_1.logger.error(`[ZDO] Failed permit joining request with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2385
2348
|
return status;
|
|
2386
2349
|
}
|
|
2387
2350
|
// NOTE: because Z2M is refreshing the permit join duration early to prevent it from closing
|
|
@@ -2412,9 +2375,9 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2412
2375
|
const neighbors = [];
|
|
2413
2376
|
const request = async (startIndex) => {
|
|
2414
2377
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2415
|
-
const [reqStatus, apsFrame, messageTag] = (await this.emberLqiTableRequest(networkAddress, startIndex,
|
|
2378
|
+
const [reqStatus, apsFrame, messageTag] = (await this.emberLqiTableRequest(networkAddress, startIndex, DEFAULT_APS_OPTIONS));
|
|
2416
2379
|
if (reqStatus !== enums_2.EmberStatus.SUCCESS) {
|
|
2417
|
-
|
|
2380
|
+
logger_1.logger.error(`[ZDO] Failed LQI request for "${networkAddress}" (index "${startIndex}") with status=${enums_2.EmberStatus[reqStatus]}.`, NS);
|
|
2418
2381
|
return [reqStatus, null, null];
|
|
2419
2382
|
}
|
|
2420
2383
|
const result = (await this.oneWaitress.startWaitingFor({
|
|
@@ -2459,9 +2422,9 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2459
2422
|
const table = [];
|
|
2460
2423
|
const request = async (startIndex) => {
|
|
2461
2424
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2462
|
-
const [reqStatus, apsFrame, messageTag] = (await this.emberRoutingTableRequest(networkAddress, startIndex,
|
|
2425
|
+
const [reqStatus, apsFrame, messageTag] = (await this.emberRoutingTableRequest(networkAddress, startIndex, DEFAULT_APS_OPTIONS));
|
|
2463
2426
|
if (reqStatus !== enums_2.EmberStatus.SUCCESS) {
|
|
2464
|
-
|
|
2427
|
+
logger_1.logger.error(`[ZDO] Failed routing table request for "${networkAddress}" (index "${startIndex}") with status=${enums_2.EmberStatus[reqStatus]}.`, NS);
|
|
2465
2428
|
return [reqStatus, null, null];
|
|
2466
2429
|
}
|
|
2467
2430
|
const result = (await this.oneWaitress.startWaitingFor({
|
|
@@ -2505,9 +2468,9 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2505
2468
|
this.requestQueue.enqueue(async () => {
|
|
2506
2469
|
this.checkInterpanLock();
|
|
2507
2470
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2508
|
-
const [status, apsFrame, messageTag] = (await this.emberNodeDescriptorRequest(networkAddress,
|
|
2471
|
+
const [status, apsFrame, messageTag] = (await this.emberNodeDescriptorRequest(networkAddress, DEFAULT_APS_OPTIONS));
|
|
2509
2472
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2510
|
-
|
|
2473
|
+
logger_1.logger.error(`[ZDO] Failed node descriptor for "${networkAddress}" with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2511
2474
|
return status;
|
|
2512
2475
|
}
|
|
2513
2476
|
const result = (await this.oneWaitress.startWaitingFor({
|
|
@@ -2529,9 +2492,9 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2529
2492
|
}
|
|
2530
2493
|
// always 0 before rev. 21 where field was added
|
|
2531
2494
|
if (result.stackRevision < CURRENT_ZIGBEE_SPEC_REVISION) {
|
|
2532
|
-
|
|
2495
|
+
logger_1.logger.warning(`[ZDO] Node descriptor for "${networkAddress}" reports device is only compliant to revision `
|
|
2533
2496
|
+ `"${(result.stackRevision < 21) ? 'pre-21' : result.stackRevision}" of the ZigBee specification `
|
|
2534
|
-
+ `(current revision: ${CURRENT_ZIGBEE_SPEC_REVISION})
|
|
2497
|
+
+ `(current revision: ${CURRENT_ZIGBEE_SPEC_REVISION}).`, NS);
|
|
2535
2498
|
}
|
|
2536
2499
|
resolve({ type, manufacturerCode: result.manufacturerCode });
|
|
2537
2500
|
return enums_2.EmberStatus.SUCCESS;
|
|
@@ -2544,9 +2507,9 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2544
2507
|
this.requestQueue.enqueue(async () => {
|
|
2545
2508
|
this.checkInterpanLock();
|
|
2546
2509
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2547
|
-
const [status, apsFrame, messageTag] = (await this.emberActiveEndpointsRequest(networkAddress,
|
|
2510
|
+
const [status, apsFrame, messageTag] = (await this.emberActiveEndpointsRequest(networkAddress, DEFAULT_APS_OPTIONS));
|
|
2548
2511
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2549
|
-
|
|
2512
|
+
logger_1.logger.error(`[ZDO] Failed active endpoints request for "${networkAddress}" with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2550
2513
|
return status;
|
|
2551
2514
|
}
|
|
2552
2515
|
const result = (await this.oneWaitress.startWaitingFor({
|
|
@@ -2565,10 +2528,10 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2565
2528
|
this.requestQueue.enqueue(async () => {
|
|
2566
2529
|
this.checkInterpanLock();
|
|
2567
2530
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2568
|
-
const [status, apsFrame, messageTag] = (await this.emberSimpleDescriptorRequest(networkAddress, endpointID,
|
|
2531
|
+
const [status, apsFrame, messageTag] = (await this.emberSimpleDescriptorRequest(networkAddress, endpointID, DEFAULT_APS_OPTIONS));
|
|
2569
2532
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2570
|
-
|
|
2571
|
-
+ `with status=${enums_2.EmberStatus[status]}
|
|
2533
|
+
logger_1.logger.error(`[ZDO] Failed simple descriptor request for "${networkAddress}" endpoint "${endpointID}" `
|
|
2534
|
+
+ `with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2572
2535
|
return status;
|
|
2573
2536
|
}
|
|
2574
2537
|
const result = (await this.oneWaitress.startWaitingFor({
|
|
@@ -2596,10 +2559,10 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2596
2559
|
this.checkInterpanLock();
|
|
2597
2560
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2598
2561
|
const [status, apsFrame, messageTag] = (await this.emberBindRequest(destinationNetworkAddress, sourceIeeeAddress, sourceEndpoint, clusterID, zdo_1.UNICAST_BINDING, destinationAddressOrGroup, null, // doesn't matter
|
|
2599
|
-
destinationEndpoint,
|
|
2562
|
+
destinationEndpoint, DEFAULT_APS_OPTIONS));
|
|
2600
2563
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2601
|
-
|
|
2602
|
-
+ `endpoint "${destinationEndpoint}" with status=${enums_2.EmberStatus[status]}
|
|
2564
|
+
logger_1.logger.error(`[ZDO] Failed bind request for "${destinationNetworkAddress}" destination "${destinationAddressOrGroup}" `
|
|
2565
|
+
+ `endpoint "${destinationEndpoint}" with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2603
2566
|
return status;
|
|
2604
2567
|
}
|
|
2605
2568
|
await this.oneWaitress.startWaitingFor({
|
|
@@ -2620,10 +2583,10 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2620
2583
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2621
2584
|
const [status, apsFrame, messageTag] = (await this.emberBindRequest(destinationNetworkAddress, sourceIeeeAddress, sourceEndpoint, clusterID, zdo_1.MULTICAST_BINDING, null, // doesn't matter
|
|
2622
2585
|
destinationAddressOrGroup, destinationEndpoint, // doesn't matter
|
|
2623
|
-
|
|
2586
|
+
DEFAULT_APS_OPTIONS));
|
|
2624
2587
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2625
|
-
|
|
2626
|
-
+ `with status=${enums_2.EmberStatus[status]}
|
|
2588
|
+
logger_1.logger.error(`[ZDO] Failed bind request for "${destinationNetworkAddress}" group "${destinationAddressOrGroup}" `
|
|
2589
|
+
+ `with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2627
2590
|
return status;
|
|
2628
2591
|
}
|
|
2629
2592
|
await this.oneWaitress.startWaitingFor({
|
|
@@ -2646,10 +2609,10 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2646
2609
|
this.checkInterpanLock();
|
|
2647
2610
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2648
2611
|
const [status, apsFrame, messageTag] = (await this.emberUnbindRequest(destinationNetworkAddress, sourceIeeeAddress, sourceEndpoint, clusterID, zdo_1.UNICAST_BINDING, destinationAddressOrGroup, null, // doesn't matter
|
|
2649
|
-
destinationEndpoint,
|
|
2612
|
+
destinationEndpoint, DEFAULT_APS_OPTIONS));
|
|
2650
2613
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2651
|
-
|
|
2652
|
-
+ `endpoint "${destinationEndpoint}" with status=${enums_2.EmberStatus[status]}
|
|
2614
|
+
logger_1.logger.error(`[ZDO] Failed unbind request for "${destinationNetworkAddress}" destination "${destinationAddressOrGroup}" `
|
|
2615
|
+
+ `endpoint "${destinationEndpoint}" with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2653
2616
|
return status;
|
|
2654
2617
|
}
|
|
2655
2618
|
await this.oneWaitress.startWaitingFor({
|
|
@@ -2670,10 +2633,10 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2670
2633
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2671
2634
|
const [status, apsFrame, messageTag] = (await this.emberUnbindRequest(destinationNetworkAddress, sourceIeeeAddress, sourceEndpoint, clusterID, zdo_1.MULTICAST_BINDING, null, // doesn't matter
|
|
2672
2635
|
destinationAddressOrGroup, destinationEndpoint, // doesn't matter
|
|
2673
|
-
|
|
2636
|
+
DEFAULT_APS_OPTIONS));
|
|
2674
2637
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2675
|
-
|
|
2676
|
-
+ `with status=${enums_2.EmberStatus[status]}
|
|
2638
|
+
logger_1.logger.error(`[ZDO] Failed unbind request for "${destinationNetworkAddress}" group "${destinationAddressOrGroup}" `
|
|
2639
|
+
+ `with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2677
2640
|
return status;
|
|
2678
2641
|
}
|
|
2679
2642
|
await this.oneWaitress.startWaitingFor({
|
|
@@ -2693,10 +2656,10 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2693
2656
|
this.requestQueue.enqueue(async () => {
|
|
2694
2657
|
this.checkInterpanLock();
|
|
2695
2658
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2696
|
-
const [status, apsFrame, messageTag] = (await this.emberLeaveRequest(networkAddress, ieeeAddr, enums_2.EmberLeaveRequestFlags.WITHOUT_REJOIN,
|
|
2659
|
+
const [status, apsFrame, messageTag] = (await this.emberLeaveRequest(networkAddress, ieeeAddr, enums_2.EmberLeaveRequestFlags.WITHOUT_REJOIN, DEFAULT_APS_OPTIONS));
|
|
2697
2660
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2698
|
-
|
|
2699
|
-
+ `with status=${enums_2.EmberStatus[status]}
|
|
2661
|
+
logger_1.logger.error(`[ZDO] Failed remove device request for "${networkAddress}" target "${ieeeAddr}" `
|
|
2662
|
+
+ `with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2700
2663
|
return status;
|
|
2701
2664
|
}
|
|
2702
2665
|
await this.oneWaitress.startWaitingFor({
|
|
@@ -2714,20 +2677,20 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2714
2677
|
async sendZclFrameToEndpoint(ieeeAddr, networkAddress, endpoint, zclFrame, timeout, disableResponse, disableRecovery, sourceEndpoint) {
|
|
2715
2678
|
const sourceEndpointInfo = typeof sourceEndpoint === 'number' ?
|
|
2716
2679
|
endpoints_1.FIXED_ENDPOINTS.find((epi) => (epi.endpoint === sourceEndpoint)) : endpoints_1.FIXED_ENDPOINTS[0];
|
|
2717
|
-
const command = zclFrame.
|
|
2680
|
+
const command = zclFrame.command;
|
|
2718
2681
|
let commandResponseId = null;
|
|
2719
2682
|
if (command.hasOwnProperty('response') && disableResponse === false) {
|
|
2720
2683
|
commandResponseId = command.response;
|
|
2721
2684
|
}
|
|
2722
|
-
else if (!zclFrame.
|
|
2723
|
-
commandResponseId =
|
|
2685
|
+
else if (!zclFrame.header.frameControl.disableDefaultResponse) {
|
|
2686
|
+
commandResponseId = Zcl.Foundation.defaultRsp.ID;
|
|
2724
2687
|
}
|
|
2725
2688
|
const apsFrame = {
|
|
2726
2689
|
profileId: sourceEndpointInfo.profileId,
|
|
2727
|
-
clusterId: zclFrame.
|
|
2690
|
+
clusterId: zclFrame.cluster.ID,
|
|
2728
2691
|
sourceEndpoint: sourceEndpointInfo.endpoint,
|
|
2729
2692
|
destinationEndpoint: (typeof endpoint === 'number') ? endpoint : endpoints_1.FIXED_ENDPOINTS[0].endpoint,
|
|
2730
|
-
options:
|
|
2693
|
+
options: DEFAULT_APS_OPTIONS,
|
|
2731
2694
|
groupId: 0,
|
|
2732
2695
|
sequence: 0, // set by stack
|
|
2733
2696
|
};
|
|
@@ -2745,16 +2708,12 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2745
2708
|
return enums_2.EmberStatus.MESSAGE_TOO_LONG; // queue will reject
|
|
2746
2709
|
}
|
|
2747
2710
|
}
|
|
2748
|
-
|
|
2749
|
-
if (apsFrame.clusterId === cluster_1.default.genGroups.ID) {
|
|
2750
|
-
await this.onGroupChange(command.ID, zclFrame.Payload.groupid);
|
|
2751
|
-
}
|
|
2752
|
-
debug(`~~~> [ZCL to=${networkAddress} apsFrame=${JSON.stringify(apsFrame)} header=${JSON.stringify(zclFrame.Header)}]`);
|
|
2711
|
+
logger_1.logger.debug(`~~~> [ZCL to=${networkAddress} apsFrame=${JSON.stringify(apsFrame)} header=${JSON.stringify(zclFrame.header)}]`, NS);
|
|
2753
2712
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2754
2713
|
const [status, messageTag] = (await this.ezsp.send(enums_2.EmberOutgoingMessageType.DIRECT, networkAddress, apsFrame, data, 0, // alias
|
|
2755
2714
|
0));
|
|
2756
2715
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2757
|
-
|
|
2716
|
+
logger_1.logger.error(`~x~> [ZCL to=${networkAddress}] Failed to send request with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2758
2717
|
return status; // let queue handle retry based on status
|
|
2759
2718
|
}
|
|
2760
2719
|
if (commandResponseId != null) {
|
|
@@ -2762,7 +2721,8 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2762
2721
|
const result = (await this.oneWaitress.startWaitingFor({
|
|
2763
2722
|
target: networkAddress,
|
|
2764
2723
|
apsFrame,
|
|
2765
|
-
zclSequence: zclFrame.
|
|
2724
|
+
zclSequence: zclFrame.header.transactionSequenceNumber,
|
|
2725
|
+
commandIdentifier: commandResponseId,
|
|
2766
2726
|
}, timeout || DEFAULT_ZCL_REQUEST_TIMEOUT));
|
|
2767
2727
|
resolve(result);
|
|
2768
2728
|
}
|
|
@@ -2779,10 +2739,10 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2779
2739
|
endpoints_1.FIXED_ENDPOINTS.find((epi) => (epi.endpoint === sourceEndpoint)) : endpoints_1.FIXED_ENDPOINTS[0];
|
|
2780
2740
|
const apsFrame = {
|
|
2781
2741
|
profileId: sourceEndpointInfo.profileId,
|
|
2782
|
-
clusterId: zclFrame.
|
|
2742
|
+
clusterId: zclFrame.cluster.ID,
|
|
2783
2743
|
sourceEndpoint: sourceEndpointInfo.endpoint,
|
|
2784
2744
|
destinationEndpoint: endpoints_1.FIXED_ENDPOINTS[0].endpoint,
|
|
2785
|
-
options:
|
|
2745
|
+
options: DEFAULT_APS_OPTIONS,
|
|
2786
2746
|
groupId: groupID,
|
|
2787
2747
|
sequence: 0, // set by stack
|
|
2788
2748
|
};
|
|
@@ -2796,13 +2756,13 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2796
2756
|
return enums_2.EmberStatus.MESSAGE_TOO_LONG; // queue will reject
|
|
2797
2757
|
}
|
|
2798
2758
|
}
|
|
2799
|
-
debug(`~~~> [ZCL GROUP apsFrame=${JSON.stringify(apsFrame)} header=${JSON.stringify(zclFrame.
|
|
2759
|
+
logger_1.logger.debug(`~~~> [ZCL GROUP apsFrame=${JSON.stringify(apsFrame)} header=${JSON.stringify(zclFrame.header)}]`, NS);
|
|
2800
2760
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2801
2761
|
const [status, messageTag] = (await this.ezsp.send(enums_2.EmberOutgoingMessageType.MULTICAST, apsFrame.groupId, // not used for MC
|
|
2802
2762
|
apsFrame, data, 0, // alias
|
|
2803
2763
|
0));
|
|
2804
2764
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2805
|
-
|
|
2765
|
+
logger_1.logger.error(`~x~> [ZCL GROUP] Failed to send with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2806
2766
|
return status; // let queue handle retry based on status
|
|
2807
2767
|
}
|
|
2808
2768
|
// NOTE: since ezspMessageSentHandler could take a while here, we don't block, it'll just be logged if the delivery failed
|
|
@@ -2812,16 +2772,16 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2812
2772
|
});
|
|
2813
2773
|
}
|
|
2814
2774
|
// queued, non-InterPAN
|
|
2815
|
-
async sendZclFrameToAll(endpoint, zclFrame, sourceEndpoint) {
|
|
2775
|
+
async sendZclFrameToAll(endpoint, zclFrame, sourceEndpoint, destination) {
|
|
2816
2776
|
const sourceEndpointInfo = typeof sourceEndpoint === 'number' ?
|
|
2817
2777
|
endpoints_1.FIXED_ENDPOINTS.find((epi) => (epi.endpoint === sourceEndpoint)) : endpoints_1.FIXED_ENDPOINTS[0];
|
|
2818
2778
|
const apsFrame = {
|
|
2819
2779
|
profileId: sourceEndpointInfo.profileId,
|
|
2820
|
-
clusterId: zclFrame.
|
|
2780
|
+
clusterId: zclFrame.cluster.ID,
|
|
2821
2781
|
sourceEndpoint: sourceEndpointInfo.endpoint,
|
|
2822
2782
|
destinationEndpoint: (typeof endpoint === 'number') ? endpoint : endpoints_1.FIXED_ENDPOINTS[0].endpoint,
|
|
2823
|
-
options:
|
|
2824
|
-
groupId:
|
|
2783
|
+
options: DEFAULT_APS_OPTIONS,
|
|
2784
|
+
groupId: destination,
|
|
2825
2785
|
sequence: 0, // set by stack
|
|
2826
2786
|
};
|
|
2827
2787
|
const data = zclFrame.toBuffer();
|
|
@@ -2829,17 +2789,17 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2829
2789
|
this.requestQueue.enqueue(async () => {
|
|
2830
2790
|
this.checkInterpanLock();
|
|
2831
2791
|
if (CHECK_APS_PAYLOAD_LENGTH) {
|
|
2832
|
-
const maxPayloadLength = (await this.maximumApsPayloadLength(enums_2.EmberOutgoingMessageType.BROADCAST,
|
|
2792
|
+
const maxPayloadLength = (await this.maximumApsPayloadLength(enums_2.EmberOutgoingMessageType.BROADCAST, destination, apsFrame));
|
|
2833
2793
|
if (data.length > maxPayloadLength) {
|
|
2834
2794
|
return enums_2.EmberStatus.MESSAGE_TOO_LONG; // queue will reject
|
|
2835
2795
|
}
|
|
2836
2796
|
}
|
|
2837
|
-
debug(`~~~> [ZCL BROADCAST apsFrame=${JSON.stringify(apsFrame)} header=${JSON.stringify(zclFrame.
|
|
2797
|
+
logger_1.logger.debug(`~~~> [ZCL BROADCAST apsFrame=${JSON.stringify(apsFrame)} header=${JSON.stringify(zclFrame.header)}]`, NS);
|
|
2838
2798
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2839
|
-
const [status, messageTag] = (await this.ezsp.send(enums_2.EmberOutgoingMessageType.BROADCAST,
|
|
2799
|
+
const [status, messageTag] = (await this.ezsp.send(enums_2.EmberOutgoingMessageType.BROADCAST, destination, apsFrame, data, 0, // alias
|
|
2840
2800
|
0));
|
|
2841
2801
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2842
|
-
|
|
2802
|
+
logger_1.logger.error(`~x~> [ZCL BROADCAST] Failed to send with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2843
2803
|
return status; // let queue handle retry based on status
|
|
2844
2804
|
}
|
|
2845
2805
|
// NOTE: since ezspMessageSentHandler could take a while here, we don't block, it'll just be logged if the delivery failed
|
|
@@ -2854,7 +2814,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2854
2814
|
// queued
|
|
2855
2815
|
async setChannelInterPAN(channel) {
|
|
2856
2816
|
if (typeof channel !== 'number') {
|
|
2857
|
-
|
|
2817
|
+
logger_1.logger.error(`Tried to set channel InterPAN to non-number. Channel ${channel} of type ${typeof channel}.`, NS);
|
|
2858
2818
|
return;
|
|
2859
2819
|
}
|
|
2860
2820
|
return new Promise((resolve, reject) => {
|
|
@@ -2863,7 +2823,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2863
2823
|
const status = (await this.ezsp.ezspSetLogicalAndRadioChannel(channel));
|
|
2864
2824
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2865
2825
|
this.interpanLock = false; // XXX: ok?
|
|
2866
|
-
|
|
2826
|
+
logger_1.logger.error(`Failed to set InterPAN channel to ${channel} with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2867
2827
|
return status;
|
|
2868
2828
|
}
|
|
2869
2829
|
resolve();
|
|
@@ -2887,12 +2847,12 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2887
2847
|
msgBuffalo.writeIeeeAddr(sourceEui64); // sourceAddress
|
|
2888
2848
|
msgBuffalo.writeUInt16(consts_2.STUB_NWK_FRAME_CONTROL); // nwkFrameControl
|
|
2889
2849
|
msgBuffalo.writeUInt8((enums_2.EmberInterpanMessageType.UNICAST | consts_2.INTERPAN_APS_FRAME_TYPE)); // apsFrameControl
|
|
2890
|
-
msgBuffalo.writeUInt16(zclFrame.
|
|
2850
|
+
msgBuffalo.writeUInt16(zclFrame.cluster.ID);
|
|
2891
2851
|
msgBuffalo.writeUInt16(consts_2.TOUCHLINK_PROFILE_ID);
|
|
2892
|
-
debug(`~~~> [ZCL TOUCHLINK to=${ieeeAddress} header=${JSON.stringify(zclFrame.
|
|
2852
|
+
logger_1.logger.debug(`~~~> [ZCL TOUCHLINK to=${ieeeAddress} header=${JSON.stringify(zclFrame.header)}]`, NS);
|
|
2893
2853
|
const status = (await this.ezsp.ezspSendRawMessage(Buffer.concat([msgBuffalo.getWritten(), zclFrame.toBuffer()])));
|
|
2894
2854
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2895
|
-
|
|
2855
|
+
logger_1.logger.error(`~x~> [ZCL TOUCHLINK to=${ieeeAddress}] Failed to send with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2896
2856
|
return status;
|
|
2897
2857
|
}
|
|
2898
2858
|
// NOTE: can use ezspRawTransmitCompleteHandler if needed here
|
|
@@ -2903,14 +2863,14 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2903
2863
|
}
|
|
2904
2864
|
// queued
|
|
2905
2865
|
async sendZclFrameInterPANBroadcast(zclFrame, timeout) {
|
|
2906
|
-
const command = zclFrame.
|
|
2866
|
+
const command = zclFrame.command;
|
|
2907
2867
|
if (!command.hasOwnProperty('response')) {
|
|
2908
2868
|
throw new Error(`Command '${command.name}' has no response, cannot wait for response.`);
|
|
2909
2869
|
}
|
|
2910
2870
|
// just for waitress
|
|
2911
2871
|
const apsFrame = {
|
|
2912
2872
|
profileId: consts_2.TOUCHLINK_PROFILE_ID,
|
|
2913
|
-
clusterId: zclFrame.
|
|
2873
|
+
clusterId: zclFrame.cluster.ID,
|
|
2914
2874
|
sourceEndpoint: 0,
|
|
2915
2875
|
destinationEndpoint: 0,
|
|
2916
2876
|
options: enums_2.EmberApsOption.NONE,
|
|
@@ -2934,17 +2894,18 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2934
2894
|
msgBuffalo.writeUInt16(apsFrame.clusterId);
|
|
2935
2895
|
msgBuffalo.writeUInt16(apsFrame.profileId);
|
|
2936
2896
|
const data = Buffer.concat([msgBuffalo.getWritten(), zclFrame.toBuffer()]);
|
|
2937
|
-
debug(`~~~> [ZCL TOUCHLINK BROADCAST header=${JSON.stringify(zclFrame.
|
|
2897
|
+
logger_1.logger.debug(`~~~> [ZCL TOUCHLINK BROADCAST header=${JSON.stringify(zclFrame.header)}]`, NS);
|
|
2938
2898
|
const status = (await this.ezsp.ezspSendRawMessage(data));
|
|
2939
2899
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2940
|
-
|
|
2900
|
+
logger_1.logger.error(`~x~> [ZCL TOUCHLINK BROADCAST] Failed to send with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2941
2901
|
return status;
|
|
2942
2902
|
}
|
|
2943
2903
|
// NOTE: can use ezspRawTransmitCompleteHandler if needed here
|
|
2944
2904
|
const result = (await this.oneWaitress.startWaitingFor({
|
|
2945
2905
|
target: null,
|
|
2946
2906
|
apsFrame: apsFrame,
|
|
2947
|
-
zclSequence: zclFrame.
|
|
2907
|
+
zclSequence: zclFrame.header.transactionSequenceNumber,
|
|
2908
|
+
commandIdentifier: command.response,
|
|
2948
2909
|
}, timeout || DEFAULT_ZCL_REQUEST_TIMEOUT * 2)); // XXX: touchlink timeout?
|
|
2949
2910
|
resolve(result);
|
|
2950
2911
|
return enums_2.EmberStatus.SUCCESS;
|
|
@@ -2957,7 +2918,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2957
2918
|
this.requestQueue.enqueue(async () => {
|
|
2958
2919
|
const status = (await this.ezsp.ezspSetLogicalAndRadioChannel(this.networkOptions.channelList[0]));
|
|
2959
2920
|
if (status !== enums_2.EmberStatus.SUCCESS) {
|
|
2960
|
-
|
|
2921
|
+
logger_1.logger.error(`Failed to restore InterPAN channel to ${this.networkOptions.channelList[0]} with status=${enums_2.EmberStatus[status]}.`, NS);
|
|
2961
2922
|
return status;
|
|
2962
2923
|
}
|
|
2963
2924
|
// let adapter settle down
|
|
@@ -2971,7 +2932,7 @@ class EmberAdapter extends __1.Adapter {
|
|
|
2971
2932
|
//-- END Adapter implementation
|
|
2972
2933
|
checkInterpanLock() {
|
|
2973
2934
|
if (this.interpanLock) {
|
|
2974
|
-
|
|
2935
|
+
logger_1.logger.error(`[INTERPAN MODE] Cannot execute non-InterPAN commands.`, NS);
|
|
2975
2936
|
// will be caught by request queue and rejected internally.
|
|
2976
2937
|
throw new Error(enums_2.EzspStatus[enums_2.EzspStatus.ERROR_INVALID_CALL]);
|
|
2977
2938
|
}
|