zigbee-herdsman 0.50.1 → 0.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/.release-please-manifest.json +1 -1
  2. package/CHANGELOG.md +7 -0
  3. package/dist/adapter/ember/adapter/emberAdapter.d.ts +23 -441
  4. package/dist/adapter/ember/adapter/emberAdapter.d.ts.map +1 -1
  5. package/dist/adapter/ember/adapter/emberAdapter.js +446 -1083
  6. package/dist/adapter/ember/adapter/emberAdapter.js.map +1 -1
  7. package/dist/adapter/ember/adapter/oneWaitress.d.ts +5 -4
  8. package/dist/adapter/ember/adapter/oneWaitress.d.ts.map +1 -1
  9. package/dist/adapter/ember/adapter/oneWaitress.js +28 -14
  10. package/dist/adapter/ember/adapter/oneWaitress.js.map +1 -1
  11. package/dist/adapter/ember/adapter/requestQueue.d.ts +14 -4
  12. package/dist/adapter/ember/adapter/requestQueue.d.ts.map +1 -1
  13. package/dist/adapter/ember/adapter/requestQueue.js +55 -35
  14. package/dist/adapter/ember/adapter/requestQueue.js.map +1 -1
  15. package/dist/adapter/ember/adapter/tokensManager.d.ts +10 -9
  16. package/dist/adapter/ember/adapter/tokensManager.d.ts.map +1 -1
  17. package/dist/adapter/ember/adapter/tokensManager.js +34 -34
  18. package/dist/adapter/ember/adapter/tokensManager.js.map +1 -1
  19. package/dist/adapter/ember/consts.d.ts +1 -0
  20. package/dist/adapter/ember/consts.d.ts.map +1 -1
  21. package/dist/adapter/ember/consts.js +2 -0
  22. package/dist/adapter/ember/consts.js.map +1 -1
  23. package/dist/adapter/ember/enums.d.ts +128 -407
  24. package/dist/adapter/ember/enums.d.ts.map +1 -1
  25. package/dist/adapter/ember/enums.js +140 -436
  26. package/dist/adapter/ember/enums.js.map +1 -1
  27. package/dist/adapter/ember/ezsp/buffalo.d.ts +13 -2
  28. package/dist/adapter/ember/ezsp/buffalo.d.ts.map +1 -1
  29. package/dist/adapter/ember/ezsp/buffalo.js +137 -28
  30. package/dist/adapter/ember/ezsp/buffalo.js.map +1 -1
  31. package/dist/adapter/ember/ezsp/consts.d.ts +2 -1
  32. package/dist/adapter/ember/ezsp/consts.d.ts.map +1 -1
  33. package/dist/adapter/ember/ezsp/consts.js +4 -3
  34. package/dist/adapter/ember/ezsp/consts.js.map +1 -1
  35. package/dist/adapter/ember/ezsp/enums.d.ts +160 -49
  36. package/dist/adapter/ember/ezsp/enums.d.ts.map +1 -1
  37. package/dist/adapter/ember/ezsp/enums.js +177 -47
  38. package/dist/adapter/ember/ezsp/enums.js.map +1 -1
  39. package/dist/adapter/ember/ezsp/ezsp.d.ts +975 -716
  40. package/dist/adapter/ember/ezsp/ezsp.d.ts.map +1 -1
  41. package/dist/adapter/ember/ezsp/ezsp.js +2413 -1882
  42. package/dist/adapter/ember/ezsp/ezsp.js.map +1 -1
  43. package/dist/adapter/ember/ezspError.d.ts +6 -0
  44. package/dist/adapter/ember/ezspError.d.ts.map +1 -0
  45. package/dist/adapter/ember/ezspError.js +13 -0
  46. package/dist/adapter/ember/ezspError.js.map +1 -0
  47. package/dist/adapter/ember/types.d.ts +89 -42
  48. package/dist/adapter/ember/types.d.ts.map +1 -1
  49. package/dist/adapter/ember/uart/ash.d.ts +11 -7
  50. package/dist/adapter/ember/uart/ash.d.ts.map +1 -1
  51. package/dist/adapter/ember/uart/ash.js +15 -17
  52. package/dist/adapter/ember/uart/ash.js.map +1 -1
  53. package/dist/adapter/ember/utils/math.d.ts +0 -8
  54. package/dist/adapter/ember/utils/math.d.ts.map +1 -1
  55. package/dist/adapter/ember/utils/math.js +1 -20
  56. package/dist/adapter/ember/utils/math.js.map +1 -1
  57. package/package.json +1 -1
  58. package/dist/adapter/ember/zdo.d.ts +0 -925
  59. package/dist/adapter/ember/zdo.d.ts.map +0 -1
  60. package/dist/adapter/ember/zdo.js +0 -723
  61. package/dist/adapter/ember/zdo.js.map +0 -1
@@ -35,17 +35,16 @@ const serialPortUtils_1 = __importDefault(require("../../serialPortUtils"));
35
35
  const socketPortUtils_1 = __importDefault(require("../../socketPortUtils"));
36
36
  const utils_1 = require("../../../utils");
37
37
  const __1 = require("../..");
38
+ const ZSpec = __importStar(require("../../../zspec"));
38
39
  const Zcl = __importStar(require("../../../zspec/zcl"));
39
- const enums_1 = require("../../../zspec/enums");
40
- const ZSpec = __importStar(require("../../../zspec/consts"));
40
+ const Zdo = __importStar(require("../../../zspec/zdo"));
41
41
  const events_1 = require("../../events");
42
42
  const math_1 = require("../utils/math");
43
43
  const ezsp_1 = require("../ezsp/ezsp");
44
44
  const consts_1 = require("../ezsp/consts");
45
- const enums_2 = require("../ezsp/enums");
45
+ const enums_1 = require("../ezsp/enums");
46
46
  const buffalo_1 = require("../ezsp/buffalo");
47
- const enums_3 = require("../enums");
48
- const zdo_1 = require("../zdo");
47
+ const enums_2 = require("../enums");
49
48
  const consts_2 = require("../consts");
50
49
  const requestQueue_1 = require("./requestQueue");
51
50
  const endpoints_1 = require("./endpoints");
@@ -53,7 +52,9 @@ const initters_1 = require("../utils/initters");
53
52
  const crypto_1 = require("crypto");
54
53
  const oneWaitress_1 = require("./oneWaitress");
55
54
  const logger_1 = require("../../../utils/logger");
56
- // import {EmberTokensManager} from "./tokensManager";
55
+ const ezspError_1 = require("../ezspError");
56
+ const buffaloZdo_1 = require("../../../zspec/zdo/buffaloZdo");
57
+ // import {EmberTokensManager} from './tokensManager';
57
58
  const NS = 'zh:ember';
58
59
  /** Enum to pass strings from numbers up to Z2M. */
59
60
  var RoutingTableStatus;
@@ -96,8 +97,8 @@ const autoDetectDefinitions = [
96
97
  * messages with non-conflicting sequence numbers.
97
98
  */
98
99
  const APPLICATION_ZDO_SEQUENCE_MASK = 0x7F;
99
- /** Current revision of the spec by zigbee alliance. XXX: what are `Zigbee Pro 2023` devices reporting?? */
100
- const CURRENT_ZIGBEE_SPEC_REVISION = 23;
100
+ /** Current revision of the spec by zigbee alliance supported by Z2M. */
101
+ const CURRENT_ZIGBEE_SPEC_REVISION = 22;
101
102
  /** Each scan period is 15.36ms. Scan for at least 200ms (2^4 + 1 periods) to pick up WiFi beacon frames. */
102
103
  const ENERGY_SCAN_DURATION = 4;
103
104
  /** Oldest supported EZSP version for backups. Don't take the risk to restore a broken network until older backup versions can be investigated. */
@@ -123,20 +124,12 @@ const DEFAULT_STACK_CONFIG = {
123
124
  CONCENTRATOR_DELIVERY_FAILURE_THRESHOLD: 1, // zigpc: 1, ZigbeeMinimalHost: 3
124
125
  CONCENTRATOR_MAX_HOPS: 0, // zigpc: 0
125
126
  MAX_END_DEVICE_CHILDREN: 32, // zigpc: 6, nabucasa: 32, Dongle-E (Sonoff firmware): 32
126
- APS_UNICAST_MESSAGE_COUNT: 32, // zigpc: 10, darkxst: 20, nabucasa: 20
127
- RETRY_QUEUE_SIZE: 16, // nabucasa: 16
128
- ADDRESS_TABLE_SIZE: 16, // zigpc: 32, darkxst: 16, nabucasa: 16
129
- TRUST_CENTER_ADDRESS_CACHE_SIZE: 2,
130
- KEY_TABLE_SIZE: 0, // zigpc: 4
131
- BINDING_TABLE_SIZE: 32, // zigpc: 2, Z3GatewayGPCombo: 5, nabucasa: 32
132
- BROADCAST_TABLE_SIZE: 15, // zigpc: 15, Z3GatewayGPCombo: 35 - NOTE: Sonoff Dongle-E fails at 35
133
- MULTICAST_TABLE_SIZE: 16, // darkxst: 16, nabucasa: 16 - NOTE: should always be at least enough to register FIXED_ENDPOINTS multicastIds
134
- NEIGHBOR_TABLE_SIZE: 26, // zigpc: 16, darkxst: 26, nabucasa: 26
135
- SOURCE_ROUTE_TABLE_SIZE: 200, // Z3GatewayGPCombo: 100, darkxst: 200, nabucasa: 200
136
127
  TRANSIENT_DEVICE_TIMEOUT: 10000,
137
128
  END_DEVICE_POLL_TIMEOUT: 8, // zigpc: 8
138
129
  TRANSIENT_KEY_TIMEOUT_S: 300, // zigpc: 65535
139
130
  };
131
+ /** Default behavior is to disable app key requests */
132
+ const ALLOW_APP_KEY_REQUESTS = false;
140
133
  /**
141
134
  * NOTE: This from SDK is currently ignored here because of issues in below links:
142
135
  * - BUGZID 12261: Concentrators use MTORRs for route discovery and should not enable route discovery in the APS options.
@@ -145,13 +138,7 @@ const DEFAULT_STACK_CONFIG = {
145
138
  *
146
139
  * Removing `ENABLE_ROUTE_DISCOVERY` leads to devices that won't reconnect/go offline, and various other issues. Keeping it for now.
147
140
  */
148
- const DEFAULT_APS_OPTIONS = (enums_3.EmberApsOption.RETRY | enums_3.EmberApsOption.ENABLE_ROUTE_DISCOVERY | enums_3.EmberApsOption.ENABLE_ADDRESS_DISCOVERY);
149
- /**
150
- * Enabling this allows to immediately reject requests that won't be able to get to their destination.
151
- * However, it causes more NCP calls, notably to get the source route overhead.
152
- * XXX: Needs further testing before enabling
153
- */
154
- const CHECK_APS_PAYLOAD_LENGTH = false;
141
+ const DEFAULT_APS_OPTIONS = (enums_2.EmberApsOption.RETRY | enums_2.EmberApsOption.ENABLE_ROUTE_DISCOVERY | enums_2.EmberApsOption.ENABLE_ADDRESS_DISCOVERY);
155
142
  /** Time for a ZDO request to get a callback response. ASH is 2400*6 for ACK timeout. */
156
143
  const DEFAULT_ZDO_REQUEST_TIMEOUT = 15000; // msec
157
144
  /** Time for a ZCL request to get a callback response. ASH is 2400*6 for ACK timeout. */
@@ -186,8 +173,6 @@ class EmberAdapter extends __1.Adapter {
186
173
  oneWaitress;
187
174
  /** Periodically retrieve counters then clear them. */
188
175
  watchdogCountersHandle;
189
- /** Hold ZDO request in process. */
190
- zdoRequestBuffalo;
191
176
  /** Sequence number used for ZDO requests. static uint8_t */
192
177
  zdoRequestSequence;
193
178
  /** Default radius used for broadcast ZDO requests. uint8_t */
@@ -206,16 +191,14 @@ class EmberAdapter extends __1.Adapter {
206
191
  logger_1.logger.debug(`Using delay=${delay}.`, NS);
207
192
  this.requestQueue = new requestQueue_1.EmberRequestQueue(delay);
208
193
  this.oneWaitress = new oneWaitress_1.EmberOneWaitress();
209
- this.zdoRequestBuffalo = new buffalo_1.EzspBuffalo(Buffer.alloc(consts_1.EZSP_MAX_FRAME_LENGTH));
210
- this.ezsp = new ezsp_1.Ezsp(delay, serialPortOptions);
211
- this.ezsp.on(ezsp_1.EzspEvents.STACK_STATUS, this.onStackStatus.bind(this));
212
- this.ezsp.on(ezsp_1.EzspEvents.MESSAGE_SENT, this.onMessageSent.bind(this));
194
+ this.ezsp = new ezsp_1.Ezsp(serialPortOptions);
213
195
  this.ezsp.on(ezsp_1.EzspEvents.ZDO_RESPONSE, this.onZDOResponse.bind(this));
214
- this.ezsp.on(ezsp_1.EzspEvents.END_DEVICE_ANNOUNCE, this.onEndDeviceAnnounce.bind(this));
215
196
  this.ezsp.on(ezsp_1.EzspEvents.INCOMING_MESSAGE, this.onIncomingMessage.bind(this));
216
197
  this.ezsp.on(ezsp_1.EzspEvents.TOUCHLINK_MESSAGE, this.onTouchlinkMessage.bind(this));
217
- this.ezsp.on(ezsp_1.EzspEvents.GREENPOWER_MESSAGE, this.onGreenpowerMessage.bind(this));
198
+ this.ezsp.on(ezsp_1.EzspEvents.STACK_STATUS, this.onStackStatus.bind(this));
218
199
  this.ezsp.on(ezsp_1.EzspEvents.TRUST_CENTER_JOIN, this.onTrustCenterJoin.bind(this));
200
+ this.ezsp.on(ezsp_1.EzspEvents.MESSAGE_SENT, this.onMessageSent.bind(this));
201
+ this.ezsp.on(ezsp_1.EzspEvents.GREENPOWER_MESSAGE, this.onGreenpowerMessage.bind(this));
219
202
  }
220
203
  loadStackConfig() {
221
204
  // store stack config in same dir as backup
@@ -253,47 +236,6 @@ class EmberAdapter extends __1.Adapter {
253
236
  config.MAX_END_DEVICE_CHILDREN = DEFAULT_STACK_CONFIG.MAX_END_DEVICE_CHILDREN;
254
237
  logger_1.logger.error(`[STACK CONFIG] Invalid MAX_END_DEVICE_CHILDREN, using default.`, NS);
255
238
  }
256
- if (!inRange(config.APS_UNICAST_MESSAGE_COUNT, 1, 255)) {
257
- config.APS_UNICAST_MESSAGE_COUNT = DEFAULT_STACK_CONFIG.APS_UNICAST_MESSAGE_COUNT;
258
- logger_1.logger.error(`[STACK CONFIG] Invalid APS_UNICAST_MESSAGE_COUNT, using default.`, NS);
259
- }
260
- if (!inRange(config.RETRY_QUEUE_SIZE, 0, 255)) {
261
- config.RETRY_QUEUE_SIZE = DEFAULT_STACK_CONFIG.RETRY_QUEUE_SIZE;
262
- logger_1.logger.error(`[STACK CONFIG] Invalid RETRY_QUEUE_SIZE, using default.`, NS);
263
- }
264
- if (!inRange(config.ADDRESS_TABLE_SIZE, 1, 250)) {
265
- config.ADDRESS_TABLE_SIZE = DEFAULT_STACK_CONFIG.ADDRESS_TABLE_SIZE;
266
- logger_1.logger.error(`[STACK CONFIG] Invalid ADDRESS_TABLE_SIZE, using default.`, NS);
267
- }
268
- if (!inRange(config.TRUST_CENTER_ADDRESS_CACHE_SIZE, 0, 4)) {
269
- config.TRUST_CENTER_ADDRESS_CACHE_SIZE = DEFAULT_STACK_CONFIG.TRUST_CENTER_ADDRESS_CACHE_SIZE;
270
- logger_1.logger.error(`[STACK CONFIG] Invalid TRUST_CENTER_ADDRESS_CACHE_SIZE, using default.`, NS);
271
- }
272
- if (!inRange(config.KEY_TABLE_SIZE, 0, 127)) {
273
- config.KEY_TABLE_SIZE = DEFAULT_STACK_CONFIG.KEY_TABLE_SIZE;
274
- logger_1.logger.error(`[STACK CONFIG] Invalid KEY_TABLE_SIZE, using default.`, NS);
275
- }
276
- if (!inRange(config.BINDING_TABLE_SIZE, 0, 127)) {
277
- config.BINDING_TABLE_SIZE = DEFAULT_STACK_CONFIG.BINDING_TABLE_SIZE;
278
- logger_1.logger.error(`[STACK CONFIG] Invalid BINDING_TABLE_SIZE, using default.`, NS);
279
- }
280
- if (!inRange(config.BROADCAST_TABLE_SIZE, 15, 254)) {
281
- config.BROADCAST_TABLE_SIZE = DEFAULT_STACK_CONFIG.BROADCAST_TABLE_SIZE;
282
- logger_1.logger.error(`[STACK CONFIG] Invalid BROADCAST_TABLE_SIZE, using default.`, NS);
283
- }
284
- // min should always be enough to cover `multicastIds` in `FIXED_ENDPOINTS`
285
- if (!inRange(config.MULTICAST_TABLE_SIZE, 5, 250)) {
286
- config.MULTICAST_TABLE_SIZE = DEFAULT_STACK_CONFIG.MULTICAST_TABLE_SIZE;
287
- logger_1.logger.error(`[STACK CONFIG] Invalid MULTICAST_TABLE_SIZE, using default.`, NS);
288
- }
289
- if (![16, 26].includes(config.NEIGHBOR_TABLE_SIZE)) {
290
- config.NEIGHBOR_TABLE_SIZE = DEFAULT_STACK_CONFIG.NEIGHBOR_TABLE_SIZE;
291
- logger_1.logger.error(`[STACK CONFIG] Invalid NEIGHBOR_TABLE_SIZE, using default.`, NS);
292
- }
293
- if (!inRange(config.SOURCE_ROUTE_TABLE_SIZE, 0, 254)) {
294
- config.SOURCE_ROUTE_TABLE_SIZE = DEFAULT_STACK_CONFIG.SOURCE_ROUTE_TABLE_SIZE;
295
- logger_1.logger.error(`[STACK CONFIG] Invalid SOURCE_ROUTE_TABLE_SIZE, using default.`, NS);
296
- }
297
239
  if (!inRange(config.TRANSIENT_DEVICE_TIMEOUT, 0, 65535)) {
298
240
  config.TRANSIENT_DEVICE_TIMEOUT = DEFAULT_STACK_CONFIG.TRANSIENT_DEVICE_TIMEOUT;
299
241
  logger_1.logger.error(`[STACK CONFIG] Invalid TRANSIENT_DEVICE_TIMEOUT, using default.`, NS);
@@ -321,27 +263,27 @@ class EmberAdapter extends __1.Adapter {
321
263
  // to be extra careful, should clear network cache upon receiving this.
322
264
  this.clearNetworkCache();
323
265
  switch (status) {
324
- case enums_3.EmberStatus.NETWORK_UP: {
266
+ case enums_2.SLStatus.NETWORK_UP: {
325
267
  this.oneWaitress.resolveEvent(oneWaitress_1.OneWaitressEvents.STACK_STATUS_NETWORK_UP);
326
268
  logger_1.logger.info(`[STACK STATUS] Network up.`, NS);
327
269
  break;
328
270
  }
329
- case enums_3.EmberStatus.NETWORK_DOWN: {
271
+ case enums_2.SLStatus.NETWORK_DOWN: {
330
272
  this.oneWaitress.resolveEvent(oneWaitress_1.OneWaitressEvents.STACK_STATUS_NETWORK_DOWN);
331
273
  logger_1.logger.info(`[STACK STATUS] Network down.`, NS);
332
274
  break;
333
275
  }
334
- case enums_3.EmberStatus.NETWORK_OPENED: {
276
+ case enums_2.SLStatus.ZIGBEE_NETWORK_OPENED: {
335
277
  this.oneWaitress.resolveEvent(oneWaitress_1.OneWaitressEvents.STACK_STATUS_NETWORK_OPENED);
336
278
  logger_1.logger.info(`[STACK STATUS] Network opened.`, NS);
337
279
  break;
338
280
  }
339
- case enums_3.EmberStatus.NETWORK_CLOSED: {
281
+ case enums_2.SLStatus.ZIGBEE_NETWORK_CLOSED: {
340
282
  this.oneWaitress.resolveEvent(oneWaitress_1.OneWaitressEvents.STACK_STATUS_NETWORK_CLOSED);
341
283
  logger_1.logger.info(`[STACK STATUS] Network closed.`, NS);
342
284
  break;
343
285
  }
344
- case enums_3.EmberStatus.CHANNEL_CHANGED: {
286
+ case enums_2.SLStatus.ZIGBEE_CHANNEL_CHANGED: {
345
287
  this.oneWaitress.resolveEvent(oneWaitress_1.OneWaitressEvents.STACK_STATUS_CHANNEL_CHANGED);
346
288
  // invalidate cache
347
289
  this.networkCache.parameters.radioChannel = consts_2.INVALID_RADIO_CHANNEL;
@@ -349,7 +291,7 @@ class EmberAdapter extends __1.Adapter {
349
291
  break;
350
292
  }
351
293
  default: {
352
- logger_1.logger.debug(`[STACK STATUS] ${enums_3.EmberStatus[status]}.`, NS);
294
+ logger_1.logger.debug(`[STACK STATUS] ${enums_2.SLStatus[status]}.`, NS);
353
295
  break;
354
296
  }
355
297
  }
@@ -364,16 +306,16 @@ class EmberAdapter extends __1.Adapter {
364
306
  * @param messageTag
365
307
  * @param status
366
308
  */
367
- async onMessageSent(type, indexOrDestination, apsFrame, messageTag, status) {
368
- if (status === enums_3.EmberStatus.DELIVERY_FAILED) {
309
+ async onMessageSent(status, type, indexOrDestination, apsFrame, messageTag) {
310
+ if (status === enums_2.SLStatus.ZIGBEE_DELIVERY_FAILED) {
369
311
  // no ACK was received from the destination
370
312
  switch (type) {
371
- case enums_3.EmberOutgoingMessageType.BROADCAST:
372
- case enums_3.EmberOutgoingMessageType.BROADCAST_WITH_ALIAS:
373
- case enums_3.EmberOutgoingMessageType.MULTICAST:
374
- case enums_3.EmberOutgoingMessageType.MULTICAST_WITH_ALIAS: {
313
+ case enums_2.EmberOutgoingMessageType.BROADCAST:
314
+ case enums_2.EmberOutgoingMessageType.BROADCAST_WITH_ALIAS:
315
+ case enums_2.EmberOutgoingMessageType.MULTICAST:
316
+ case enums_2.EmberOutgoingMessageType.MULTICAST_WITH_ALIAS: {
375
317
  // BC/MC not checking for message sent, avoid unnecessary waitress lookups
376
- logger_1.logger.error(`Delivery of ${enums_3.EmberOutgoingMessageType[type]} failed for "${indexOrDestination}" `
318
+ logger_1.logger.error(`Delivery of ${enums_2.EmberOutgoingMessageType[type]} failed for "${indexOrDestination}" `
377
319
  + `[apsFrame=${JSON.stringify(apsFrame)} messageTag=${messageTag}]`, NS);
378
320
  break;
379
321
  }
@@ -384,8 +326,8 @@ class EmberAdapter extends __1.Adapter {
384
326
  }
385
327
  }
386
328
  }
387
- else if (status === enums_3.EmberStatus.SUCCESS) {
388
- if (type === enums_3.EmberOutgoingMessageType.MULTICAST && apsFrame.destinationEndpoint === 0xFF &&
329
+ else if (status === enums_2.SLStatus.OK) {
330
+ if (type === enums_2.EmberOutgoingMessageType.MULTICAST && apsFrame.destinationEndpoint === 0xFF &&
389
331
  apsFrame.groupId < consts_2.EMBER_MIN_BROADCAST_ADDRESS && !this.multicastTable.includes(apsFrame.groupId)) {
390
332
  // workaround for devices using multicast for state update (coordinator passthrough)
391
333
  const tableIdx = this.multicastTable.length;
@@ -399,13 +341,13 @@ class EmberAdapter extends __1.Adapter {
399
341
  await new Promise((resolve, reject) => {
400
342
  this.requestQueue.enqueue(async () => {
401
343
  const status = (await this.ezsp.ezspSetMulticastTableEntry(tableIdx, multicastEntry));
402
- if (status !== enums_3.EmberStatus.SUCCESS) {
403
- logger_1.logger.error(`Failed to register group "${multicastEntry.multicastId}" in multicast table with status=${enums_3.EmberStatus[status]}.`, NS);
344
+ if (status !== enums_2.SLStatus.OK) {
345
+ logger_1.logger.error(`Failed to register group "${multicastEntry.multicastId}" in multicast table with status=${enums_2.SLStatus[status]}.`, NS);
404
346
  return status;
405
347
  }
406
348
  logger_1.logger.debug(`Registered multicast table entry (${tableIdx}): ${JSON.stringify(multicastEntry)}.`, NS);
407
349
  resolve();
408
- return enums_3.EmberStatus.SUCCESS;
350
+ return enums_2.SLStatus.OK;
409
351
  }, (reason) => {
410
352
  // remove to allow retry on next occurrence
411
353
  this.multicastTable.splice(tableIdx, 1);
@@ -419,26 +361,31 @@ class EmberAdapter extends __1.Adapter {
419
361
  /**
420
362
  * Emitted from @see Ezsp.ezspIncomingMessageHandler
421
363
  *
422
- * @param clusterId The ZDO response cluster ID.
364
+ * @param apsFrame The APS frame associated with the response.
423
365
  * @param sender The sender of the response. Should match `payload.nodeId` in many responses.
424
- * @param payload If null, the response indicated a failure.
366
+ * @param messageContents The content of the response.
425
367
  */
426
- async onZDOResponse(status, sender, apsFrame, payload) {
427
- this.oneWaitress.resolveZDO(status, sender, apsFrame, payload);
428
- }
429
- /**
430
- * Emitted from @see Ezsp.ezspIncomingMessageHandler
431
- *
432
- * @param sender
433
- * @param nodeId
434
- * @param eui64
435
- * @param macCapFlags
436
- */
437
- async onEndDeviceAnnounce(sender, apsFrame, payload) {
438
- // reduced function device
439
- // if ((payload.capabilities.deviceType === 0)) {
440
- // }
441
- this.emit(events_1.Events.deviceAnnounce, { networkAddress: payload.nodeId, ieeeAddr: payload.eui64 });
368
+ async onZDOResponse(apsFrame, sender, messageContents) {
369
+ try {
370
+ const payload = buffaloZdo_1.BuffaloZdo.readResponse(apsFrame.clusterId, messageContents);
371
+ logger_1.logger.debug(`<~~~ [ZDO ${Zdo.ClusterId[apsFrame.clusterId]} from=${sender} ${payload ? JSON.stringify(payload) : 'OK'}]`, NS);
372
+ this.oneWaitress.resolveZDO(sender, apsFrame, payload);
373
+ if (apsFrame.clusterId === Zdo.ClusterId.NETWORK_ADDRESS_RESPONSE) {
374
+ this.emit(events_1.Events.networkAddress, {
375
+ networkAddress: payload.nwkAddress,
376
+ ieeeAddr: payload.eui64
377
+ });
378
+ }
379
+ else if (apsFrame.clusterId === Zdo.ClusterId.END_DEVICE_ANNOUNCE) {
380
+ this.emit(events_1.Events.deviceAnnounce, {
381
+ networkAddress: payload.nwkAddress,
382
+ ieeeAddr: payload.eui64
383
+ });
384
+ }
385
+ }
386
+ catch (error) {
387
+ this.oneWaitress.resolveZDO(sender, apsFrame, error);
388
+ }
442
389
  }
443
390
  /**
444
391
  * Emitted from @see Ezsp.ezspIncomingMessageHandler
@@ -458,7 +405,7 @@ class EmberAdapter extends __1.Adapter {
458
405
  endpoint: apsFrame.sourceEndpoint,
459
406
  linkquality: lastHopLqi,
460
407
  groupID: apsFrame.groupId,
461
- wasBroadcast: ((type === enums_3.EmberIncomingMessageType.BROADCAST) || (type === enums_3.EmberIncomingMessageType.BROADCAST_LOOPBACK)),
408
+ wasBroadcast: ((type === enums_2.EmberIncomingMessageType.BROADCAST) || (type === enums_2.EmberIncomingMessageType.BROADCAST_LOOPBACK)),
462
409
  destinationEndpoint: apsFrame.destinationEndpoint,
463
410
  };
464
411
  this.oneWaitress.resolveZCL(payload);
@@ -543,7 +490,7 @@ class EmberAdapter extends __1.Adapter {
543
490
  * @param parentOfNewNodeId
544
491
  */
545
492
  async onTrustCenterJoin(newNodeId, newNodeEui64, status, policyDecision, parentOfNewNodeId) {
546
- if (status === enums_3.EmberDeviceUpdate.DEVICE_LEFT) {
493
+ if (status === enums_2.EmberDeviceUpdate.DEVICE_LEFT) {
547
494
  const payload = {
548
495
  networkAddress: newNodeId,
549
496
  ieeeAddr: newNodeEui64,
@@ -551,7 +498,7 @@ class EmberAdapter extends __1.Adapter {
551
498
  this.emit(events_1.Events.deviceLeave, payload);
552
499
  }
553
500
  else {
554
- if (policyDecision !== enums_3.EmberJoinDecision.DENY_JOIN) {
501
+ if (policyDecision !== enums_2.EmberJoinDecision.DENY_JOIN) {
555
502
  const payload = {
556
503
  networkAddress: newNodeId,
557
504
  ieeeAddr: newNodeEui64,
@@ -566,7 +513,7 @@ class EmberAdapter extends __1.Adapter {
566
513
  this.manufacturerCode = joinManufCode;
567
514
  this.emit(events_1.Events.deviceJoined, payload);
568
515
  resolve();
569
- return enums_3.EmberStatus.SUCCESS;
516
+ return enums_2.SLStatus.OK;
570
517
  }, reject, true);
571
518
  });
572
519
  }
@@ -588,14 +535,13 @@ class EmberAdapter extends __1.Adapter {
588
535
  const ashCounters = this.ezsp.ash.readAndClearCounters();
589
536
  logger_1.logger.info(`[ASH COUNTERS] ${ashCounters.join(',')}`, NS);
590
537
  resolve();
591
- return enums_3.EmberStatus.SUCCESS;
538
+ return enums_2.SLStatus.OK;
592
539
  }, reject);
593
540
  });
594
541
  }
595
542
  initVariables() {
596
543
  this.ezsp.removeAllListeners(ezsp_1.EzspEvents.NCP_NEEDS_RESET_AND_INIT);
597
544
  clearInterval(this.watchdogCountersHandle);
598
- this.zdoRequestBuffalo.setPosition(0);
599
545
  this.zdoRequestSequence = 0; // start at 1
600
546
  this.zdoRequestRadius = 255;
601
547
  this.interpanLock = false;
@@ -612,25 +558,39 @@ class EmberAdapter extends __1.Adapter {
612
558
  let result = "resumed";
613
559
  // NOTE: something deep in this call can throw too
614
560
  const startResult = (await this.ezsp.start());
615
- if (startResult !== enums_3.EzspStatus.SUCCESS) {
616
- throw new Error(`Failed to start EZSP layer with status=${enums_3.EzspStatus[startResult]}.`);
561
+ if (startResult !== enums_2.EzspStatus.SUCCESS) {
562
+ throw new Error(`Failed to start EZSP layer with status=${enums_2.EzspStatus[startResult]}.`);
617
563
  }
618
564
  // call before any other command, else fails
619
565
  await this.emberVersion();
620
- await this.initNCPPreConfiguration();
621
- await this.initNCPAddressTable();
622
- await this.initNCPConfiguration();
566
+ /** MAC indirect timeout should be 7.68 secs (STACK_PROFILE_ZIGBEE_PRO) */
567
+ await this.emberSetEzspConfigValue(enums_1.EzspConfigId.INDIRECT_TRANSMISSION_TIMEOUT, 7680);
568
+ /** Max hops should be 2 * nwkMaxDepth, where nwkMaxDepth is 15 (STACK_PROFILE_ZIGBEE_PRO) */
569
+ await this.emberSetEzspConfigValue(enums_1.EzspConfigId.MAX_HOPS, 30);
570
+ await this.emberSetEzspConfigValue(enums_1.EzspConfigId.SUPPORTED_NETWORKS, 1);
571
+ // allow other devices to modify the binding table
572
+ await this.emberSetEzspPolicy(enums_1.EzspPolicyId.BINDING_MODIFICATION_POLICY, enums_1.EzspDecisionId.CHECK_BINDING_MODIFICATIONS_ARE_VALID_ENDPOINT_CLUSTERS);
573
+ // return message tag only in ezspMessageSentHandler()
574
+ await this.emberSetEzspPolicy(enums_1.EzspPolicyId.MESSAGE_CONTENTS_IN_CALLBACK_POLICY, enums_1.EzspDecisionId.MESSAGE_TAG_ONLY_IN_CALLBACK);
575
+ await this.emberSetEzspValue(enums_1.EzspValueId.TRANSIENT_DEVICE_TIMEOUT, 2, (0, math_1.lowHighBytes)(this.stackConfig.TRANSIENT_DEVICE_TIMEOUT));
576
+ await this.ezsp.ezspSetManufacturerCode(this.manufacturerCode);
577
+ // network security init
578
+ await this.emberSetEzspConfigValue(enums_1.EzspConfigId.STACK_PROFILE, consts_2.STACK_PROFILE_ZIGBEE_PRO);
579
+ await this.emberSetEzspConfigValue(enums_1.EzspConfigId.SECURITY_LEVEL, consts_2.SECURITY_LEVEL_Z3);
580
+ // common configs
581
+ await this.emberSetEzspConfigValue(enums_1.EzspConfigId.MAX_END_DEVICE_CHILDREN, this.stackConfig.MAX_END_DEVICE_CHILDREN);
582
+ await this.emberSetEzspConfigValue(enums_1.EzspConfigId.END_DEVICE_POLL_TIMEOUT, this.stackConfig.END_DEVICE_POLL_TIMEOUT);
583
+ await this.emberSetEzspConfigValue(enums_1.EzspConfigId.TRANSIENT_KEY_TIMEOUT_S, this.stackConfig.TRANSIENT_KEY_TIMEOUT_S);
623
584
  // WARNING: From here on EZSP commands that affect memory allocation on the NCP should no longer be called (like resizing tables)
624
585
  await this.registerFixedEndpoints();
625
586
  this.clearNetworkCache();
626
587
  result = (await this.initTrustCenter());
627
588
  // after network UP, as per SDK, ensures clean slate
628
589
  await this.initNCPConcentrator();
629
- // await (this.emberStartEnergyScan());// TODO: via config of some kind, better off waiting for UI supports though
630
590
  // populate network cache info
631
591
  const [status, , parameters] = (await this.ezsp.ezspGetNetworkParameters());
632
- if (status !== enums_3.EmberStatus.SUCCESS) {
633
- throw new Error(`Failed to get network parameters with status=${enums_3.EmberStatus[status]}.`);
592
+ if (status !== enums_2.SLStatus.OK) {
593
+ throw new Error(`Failed to get network parameters with status=${enums_2.SLStatus[status]}.`);
634
594
  }
635
595
  this.networkCache.parameters = parameters;
636
596
  this.networkCache.status = (await this.ezsp.ezspNetworkState());
@@ -640,66 +600,6 @@ class EmberAdapter extends __1.Adapter {
640
600
  this.requestQueue.startDispatching();
641
601
  return result;
642
602
  }
643
- /**
644
- * NCP Config init. Should always be called first in the init stack (after version cmd).
645
- * @returns
646
- */
647
- async initNCPPreConfiguration() {
648
- // this can only decrease, not increase, NCP-side value
649
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.ADDRESS_TABLE_SIZE, this.stackConfig.ADDRESS_TABLE_SIZE);
650
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.TRUST_CENTER_ADDRESS_CACHE_SIZE, this.stackConfig.TRUST_CENTER_ADDRESS_CACHE_SIZE);
651
- // BUG 14222: If stack profile is 2 (ZigBee Pro), we need to enforce
652
- // the standard stack configuration values for that feature set.
653
- /** MAC indirect timeout should be 7.68 secs */
654
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.INDIRECT_TRANSMISSION_TIMEOUT, 7680);
655
- /** Max hops should be 2 * nwkMaxDepth, where nwkMaxDepth is 15 */
656
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.MAX_HOPS, 30);
657
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.TX_POWER_MODE, enums_3.EmberTXPowerMode.USE_TOKEN);
658
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.SUPPORTED_NETWORKS, 1);
659
- await this.emberSetEzspValue(enums_2.EzspValueId.END_DEVICE_KEEP_ALIVE_SUPPORT_MODE, 1, [enums_3.EmberKeepAliveMode.KEEP_ALIVE_SUPPORT_ALL]);
660
- // allow other devices to modify the binding table
661
- await this.emberSetEzspPolicy(enums_2.EzspPolicyId.BINDING_MODIFICATION_POLICY, enums_2.EzspDecisionId.CHECK_BINDING_MODIFICATIONS_ARE_VALID_ENDPOINT_CLUSTERS);
662
- // return message tag and message contents in ezspMessageSentHandler()
663
- await this.emberSetEzspPolicy(enums_2.EzspPolicyId.MESSAGE_CONTENTS_IN_CALLBACK_POLICY, enums_2.EzspDecisionId.MESSAGE_TAG_AND_CONTENTS_IN_CALLBACK);
664
- await this.emberSetEzspValue(enums_2.EzspValueId.MAXIMUM_INCOMING_TRANSFER_SIZE, 2, (0, math_1.lowHighBytes)(consts_2.MAXIMUM_APS_PAYLOAD_LENGTH));
665
- await this.emberSetEzspValue(enums_2.EzspValueId.MAXIMUM_OUTGOING_TRANSFER_SIZE, 2, (0, math_1.lowHighBytes)(consts_2.MAXIMUM_APS_PAYLOAD_LENGTH));
666
- await this.emberSetEzspValue(enums_2.EzspValueId.TRANSIENT_DEVICE_TIMEOUT, 2, (0, math_1.lowHighBytes)(this.stackConfig.TRANSIENT_DEVICE_TIMEOUT));
667
- await this.ezsp.ezspSetManufacturerCode(this.manufacturerCode);
668
- // network security init
669
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.STACK_PROFILE, consts_2.STACK_PROFILE_ZIGBEE_PRO);
670
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.SECURITY_LEVEL, consts_2.SECURITY_LEVEL_Z3);
671
- }
672
- /**
673
- * NCP Address table init.
674
- * @returns
675
- */
676
- async initNCPAddressTable() {
677
- const desiredTableSize = this.stackConfig.ADDRESS_TABLE_SIZE;
678
- // If the host and the ncp disagree on the address table size, explode.
679
- const [status, addressTableSize] = (await this.ezsp.ezspGetConfigurationValue(enums_2.EzspConfigId.ADDRESS_TABLE_SIZE));
680
- // After the change of ncp memory model in UC, we can not increase the default NCP table sizes anymore.
681
- // Therefore, checking for desiredTableSize == (ncp)addressTableSize might not be always true anymore
682
- // assert(desiredTableSize <= addressTableSize);
683
- if ((status !== enums_3.EzspStatus.SUCCESS) || (addressTableSize > desiredTableSize)) {
684
- throw new Error(`[INIT] NCP (${addressTableSize}) disagrees with Host (min ${desiredTableSize}) on table size. status=${enums_3.EzspStatus[status]}`);
685
- }
686
- }
687
- /**
688
- * NCP configuration init
689
- */
690
- async initNCPConfiguration() {
691
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.BINDING_TABLE_SIZE, this.stackConfig.BINDING_TABLE_SIZE);
692
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.KEY_TABLE_SIZE, this.stackConfig.KEY_TABLE_SIZE);
693
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.MAX_END_DEVICE_CHILDREN, this.stackConfig.MAX_END_DEVICE_CHILDREN);
694
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.APS_UNICAST_MESSAGE_COUNT, this.stackConfig.APS_UNICAST_MESSAGE_COUNT);
695
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.BROADCAST_TABLE_SIZE, this.stackConfig.BROADCAST_TABLE_SIZE);
696
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.NEIGHBOR_TABLE_SIZE, this.stackConfig.NEIGHBOR_TABLE_SIZE);
697
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.END_DEVICE_POLL_TIMEOUT, this.stackConfig.END_DEVICE_POLL_TIMEOUT);
698
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.TRANSIENT_KEY_TIMEOUT_S, this.stackConfig.TRANSIENT_KEY_TIMEOUT_S);
699
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.RETRY_QUEUE_SIZE, this.stackConfig.RETRY_QUEUE_SIZE);
700
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.SOURCE_ROUTE_TABLE_SIZE, this.stackConfig.SOURCE_ROUTE_TABLE_SIZE);
701
- await this.emberSetEzspConfigValue(enums_2.EzspConfigId.MULTICAST_TABLE_SIZE, this.stackConfig.MULTICAST_TABLE_SIZE);
702
- }
703
603
  /**
704
604
  * NCP concentrator init. Also enables source route discovery mode with RESCHEDULE.
705
605
  *
@@ -716,10 +616,10 @@ class EmberAdapter extends __1.Adapter {
716
616
  */
717
617
  async initNCPConcentrator() {
718
618
  const status = (await this.ezsp.ezspSetConcentrator(true, (this.stackConfig.CONCENTRATOR_RAM_TYPE === 'low') ? consts_2.EMBER_LOW_RAM_CONCENTRATOR : consts_2.EMBER_HIGH_RAM_CONCENTRATOR, this.stackConfig.CONCENTRATOR_MIN_TIME, this.stackConfig.CONCENTRATOR_MAX_TIME, this.stackConfig.CONCENTRATOR_ROUTE_ERROR_THRESHOLD, this.stackConfig.CONCENTRATOR_DELIVERY_FAILURE_THRESHOLD, this.stackConfig.CONCENTRATOR_MAX_HOPS));
719
- if (status !== enums_3.EmberStatus.SUCCESS) {
720
- throw new Error(`[CONCENTRATOR] Failed to set concentrator with status=${status}.`);
619
+ if (status !== enums_2.SLStatus.OK) {
620
+ throw new Error(`[CONCENTRATOR] Failed to set concentrator with status=${enums_2.SLStatus[status]}.`);
721
621
  }
722
- const remainTilMTORR = (await this.ezsp.ezspSetSourceRouteDiscoveryMode(enums_3.EmberSourceRouteDiscoveryMode.RESCHEDULE));
622
+ const remainTilMTORR = (await this.ezsp.ezspSetSourceRouteDiscoveryMode(enums_2.EmberSourceRouteDiscoveryMode.RESCHEDULE));
723
623
  logger_1.logger.info(`[CONCENTRATOR] Started source route discovery. ${remainTilMTORR}ms until next broadcast.`, NS);
724
624
  }
725
625
  /**
@@ -733,16 +633,16 @@ class EmberAdapter extends __1.Adapter {
733
633
  }
734
634
  const [epStatus,] = (await this.ezsp.ezspGetEndpointFlags(ep.endpoint));
735
635
  // endpoint not already registered
736
- if (epStatus !== enums_3.EzspStatus.SUCCESS) {
636
+ if (epStatus !== enums_2.SLStatus.OK) {
737
637
  // check to see if ezspAddEndpoint needs to be called
738
638
  // if ezspInit is called without NCP reset, ezspAddEndpoint is not necessary and will return an error
739
639
  const status = (await this.ezsp.ezspAddEndpoint(ep.endpoint, ep.profileId, ep.deviceId, ep.deviceVersion, ep.inClusterList.slice(), // copy
740
640
  ep.outClusterList.slice()));
741
- if (status === enums_3.EzspStatus.SUCCESS) {
742
- logger_1.logger.debug(`Registered endpoint "${ep.endpoint}" with status=${enums_3.EzspStatus[status]}.`, NS);
641
+ if (status === enums_2.SLStatus.OK) {
642
+ logger_1.logger.debug(`Registered endpoint '${ep.endpoint}'.`, NS);
743
643
  }
744
644
  else {
745
- throw new Error(`Failed to register endpoint "${ep.endpoint}" with status=${enums_3.EzspStatus[status]}.`);
645
+ throw new Error(`Failed to register endpoint "${ep.endpoint}" with status=${enums_2.SLStatus[status]}.`);
746
646
  }
747
647
  }
748
648
  else {
@@ -755,8 +655,8 @@ class EmberAdapter extends __1.Adapter {
755
655
  networkIndex: ep.networkIndex,
756
656
  };
757
657
  const status = (await this.ezsp.ezspSetMulticastTableEntry(this.multicastTable.length, multicastEntry));
758
- if (status !== enums_3.EmberStatus.SUCCESS) {
759
- throw new Error(`Failed to register group "${multicastId}" in multicast table with status=${enums_3.EmberStatus[status]}.`);
658
+ if (status !== enums_2.SLStatus.OK) {
659
+ throw new Error(`Failed to register group "${multicastId}" in multicast table with status=${enums_2.SLStatus[status]}.`);
760
660
  }
761
661
  logger_1.logger.debug(`Registered multicast table entry (${this.multicastTable.length}): ${JSON.stringify(multicastEntry)}.`, NS);
762
662
  this.multicastTable.push(multicastEntry.multicastId);
@@ -770,49 +670,47 @@ class EmberAdapter extends __1.Adapter {
770
670
  async initTrustCenter() {
771
671
  // init TC policies
772
672
  {
773
- let status = (await this.emberSetEzspPolicy(enums_2.EzspPolicyId.TC_KEY_REQUEST_POLICY, enums_2.EzspDecisionId.ALLOW_TC_KEY_REQUESTS_AND_SEND_CURRENT_KEY));
774
- if (status !== enums_3.EzspStatus.SUCCESS) {
673
+ let status = (await this.emberSetEzspPolicy(enums_1.EzspPolicyId.TC_KEY_REQUEST_POLICY, enums_1.EzspDecisionId.ALLOW_TC_KEY_REQUESTS_AND_SEND_CURRENT_KEY));
674
+ if (status !== enums_2.SLStatus.OK) {
775
675
  throw new Error(`[INIT TC] Failed to set EzspPolicyId TC_KEY_REQUEST_POLICY to ALLOW_TC_KEY_REQUESTS_AND_SEND_CURRENT_KEY `
776
- + `with status=${enums_3.EzspStatus[status]}.`);
676
+ + `with status=${enums_2.SLStatus[status]}.`);
777
677
  }
778
- const appKeyPolicy = this.stackConfig.KEY_TABLE_SIZE ? enums_2.EzspDecisionId.ALLOW_APP_KEY_REQUESTS : enums_2.EzspDecisionId.DENY_APP_KEY_REQUESTS;
779
- status = (await this.emberSetEzspPolicy(enums_2.EzspPolicyId.APP_KEY_REQUEST_POLICY, appKeyPolicy));
780
- if (status !== enums_3.EzspStatus.SUCCESS) {
781
- throw new Error(`[INIT TC] Failed to set EzspPolicyId APP_KEY_REQUEST_POLICY to ${enums_2.EzspDecisionId[appKeyPolicy]} `
782
- + `with status=${enums_3.EzspStatus[status]}.`);
678
+ const appKeyRequestsPolicy = ALLOW_APP_KEY_REQUESTS ? enums_1.EzspDecisionId.ALLOW_APP_KEY_REQUESTS : enums_1.EzspDecisionId.DENY_APP_KEY_REQUESTS;
679
+ status = await this.emberSetEzspPolicy(enums_1.EzspPolicyId.APP_KEY_REQUEST_POLICY, appKeyRequestsPolicy);
680
+ if (status !== enums_2.SLStatus.OK) {
681
+ throw new Error(`[INIT TC] Failed to set EzspPolicyId APP_KEY_REQUEST_POLICY to ${enums_1.EzspDecisionId[appKeyRequestsPolicy]} `
682
+ + `with status=${enums_2.SLStatus[status]}.`);
783
683
  }
784
- status = (await this.emberSetJoinPolicy(enums_3.EmberJoinDecision.USE_PRECONFIGURED_KEY));
785
- if (status !== enums_3.EzspStatus.SUCCESS) {
786
- throw new Error(`[INIT TC] Failed to set join policy to USE_PRECONFIGURED_KEY with status=${enums_3.EzspStatus[status]}.`);
684
+ status = (await this.emberSetJoinPolicy(enums_2.EmberJoinDecision.USE_PRECONFIGURED_KEY));
685
+ if (status !== enums_2.SLStatus.OK) {
686
+ throw new Error(`[INIT TC] Failed to set join policy to USE_PRECONFIGURED_KEY with status=${enums_2.SLStatus[status]}.`);
787
687
  }
788
688
  }
789
689
  const configNetworkKey = Buffer.from(this.networkOptions.networkKey);
790
690
  const networkInitStruct = {
791
- bitmask: (enums_3.EmberNetworkInitBitmask.PARENT_INFO_IN_TOKEN | enums_3.EmberNetworkInitBitmask.END_DEVICE_REJOIN_ON_REBOOT)
691
+ bitmask: (enums_2.EmberNetworkInitBitmask.PARENT_INFO_IN_TOKEN | enums_2.EmberNetworkInitBitmask.END_DEVICE_REJOIN_ON_REBOOT)
792
692
  };
793
693
  const initStatus = (await this.ezsp.ezspNetworkInit(networkInitStruct));
794
- logger_1.logger.debug(`[INIT TC] Network init status=${enums_3.EmberStatus[initStatus]}.`, NS);
795
- if ((initStatus !== enums_3.EmberStatus.SUCCESS) && (initStatus !== enums_3.EmberStatus.NOT_JOINED)) {
796
- throw new Error(`[INIT TC] Failed network init request with status=${enums_3.EmberStatus[initStatus]}.`);
694
+ logger_1.logger.debug(`[INIT TC] Network init status=${enums_2.SLStatus[initStatus]}.`, NS);
695
+ if ((initStatus !== enums_2.SLStatus.OK) && (initStatus !== enums_2.SLStatus.NOT_JOINED)) {
696
+ throw new Error(`[INIT TC] Failed network init request with status=${enums_2.SLStatus[initStatus]}.`);
797
697
  }
798
698
  let action = NetworkInitAction.DONE;
799
- if (initStatus === enums_3.EmberStatus.SUCCESS) {
699
+ if (initStatus === enums_2.SLStatus.OK) {
800
700
  // network
801
701
  await this.oneWaitress.startWaitingForEvent({ eventName: oneWaitress_1.OneWaitressEvents.STACK_STATUS_NETWORK_UP }, DEFAULT_NETWORK_REQUEST_TIMEOUT, '[INIT TC] Network init');
802
702
  const [npStatus, nodeType, netParams] = (await this.ezsp.ezspGetNetworkParameters());
803
- logger_1.logger.debug(`[INIT TC] Current network config=${JSON.stringify(this.networkOptions)}`, NS);
804
- logger_1.logger.debug(`[INIT TC] Current NCP network: nodeType=${enums_3.EmberNodeType[nodeType]} params=${JSON.stringify(netParams)}`, NS);
805
- if ((npStatus === enums_3.EmberStatus.SUCCESS) && (nodeType === enums_3.EmberNodeType.COORDINATOR) && (this.networkOptions.panID === netParams.panId)
703
+ logger_1.logger.debug(`[INIT TC] Current adapter network: nodeType=${enums_2.EmberNodeType[nodeType]} params=${JSON.stringify(netParams)}`, NS);
704
+ if ((npStatus === enums_2.SLStatus.OK) && (nodeType === enums_2.EmberNodeType.COORDINATOR) && (this.networkOptions.panID === netParams.panId)
806
705
  && ((0, es6_1.default)(this.networkOptions.extendedPanID, netParams.extendedPanId))) {
807
706
  // config matches adapter so far, no error, we can check the network key
808
707
  const context = (0, initters_1.initSecurityManagerContext)();
809
- context.coreKeyType = enums_3.SecManKeyType.NETWORK;
708
+ context.coreKeyType = enums_2.SecManKeyType.NETWORK;
810
709
  context.keyIndex = 0;
811
- const [networkKey, nkStatus] = (await this.ezsp.ezspExportKey(context));
812
- if (nkStatus !== enums_3.SLStatus.OK) {
813
- throw new Error(`[BACKUP] Failed to export Network Key with status=${enums_3.SLStatus[nkStatus]}.`);
710
+ const [nkStatus, networkKey] = (await this.ezsp.ezspExportKey(context));
711
+ if (nkStatus !== enums_2.SLStatus.OK) {
712
+ throw new Error(`[BACKUP] Failed to export Network Key with status=${enums_2.SLStatus[nkStatus]}.`);
814
713
  }
815
- logger_1.logger.debug(`[INIT TC] Current NCP network: networkKey=${networkKey.contents.toString('hex')}`, NS);
816
714
  // config doesn't match adapter anymore
817
715
  if (!networkKey.contents.equals(configNetworkKey)) {
818
716
  action = NetworkInitAction.LEAVE;
@@ -823,10 +721,10 @@ class EmberAdapter extends __1.Adapter {
823
721
  action = NetworkInitAction.LEAVE;
824
722
  }
825
723
  if (action === NetworkInitAction.LEAVE) {
826
- logger_1.logger.info(`[INIT TC] NCP network does not match config. Leaving network...`, NS);
724
+ logger_1.logger.info(`[INIT TC] Adapter network does not match config. Leaving network...`, NS);
827
725
  const leaveStatus = (await this.ezsp.ezspLeaveNetwork());
828
- if (leaveStatus !== enums_3.EmberStatus.SUCCESS) {
829
- throw new Error(`[INIT TC] Failed leave network request with status=${enums_3.EmberStatus[leaveStatus]}.`);
726
+ if (leaveStatus !== enums_2.SLStatus.OK) {
727
+ throw new Error(`[INIT TC] Failed leave network request with status=${enums_2.SLStatus[leaveStatus]}.`);
830
728
  }
831
729
  await this.oneWaitress.startWaitingForEvent({ eventName: oneWaitress_1.OneWaitressEvents.STACK_STATUS_NETWORK_DOWN }, DEFAULT_NETWORK_REQUEST_TIMEOUT, '[INIT TC] Leave network');
832
730
  await (0, utils_1.Wait)(200); // settle down
@@ -834,7 +732,7 @@ class EmberAdapter extends __1.Adapter {
834
732
  }
835
733
  }
836
734
  const backup = this.getStoredBackup();
837
- if ((initStatus === enums_3.EmberStatus.NOT_JOINED) || (action === NetworkInitAction.LEFT)) {
735
+ if ((initStatus === enums_2.SLStatus.NOT_JOINED) || (action === NetworkInitAction.LEFT)) {
838
736
  // no network
839
737
  if (backup != null) {
840
738
  if ((this.networkOptions.panID === backup.networkOptions.panId)
@@ -863,14 +761,12 @@ class EmberAdapter extends __1.Adapter {
863
761
  logger_1.logger.info(`[INIT TC] Forming from backup.`, NS);
864
762
  const keyList = backup.devices.map((device) => {
865
763
  const octets = Array.from(device.ieeeAddress.reverse());
866
- const deviceEui64 = '0x' + octets.map(octet => octet.toString(16).padStart(2, '0')).join("");
867
- const key = {
868
- deviceEui64,
764
+ return {
765
+ deviceEui64: `0x${octets.map(octet => octet.toString(16).padStart(2, '0')).join('')}`,
869
766
  key: { contents: device.linkKey.key },
870
767
  outgoingFrameCounter: device.linkKey.txCounter,
871
768
  incomingFrameCounter: device.linkKey.rxCounter,
872
769
  };
873
- return key;
874
770
  });
875
771
  // before forming
876
772
  await this.importLinkKeys(keyList);
@@ -885,7 +781,7 @@ class EmberAdapter extends __1.Adapter {
885
781
  break;
886
782
  }
887
783
  case NetworkInitAction.DONE: {
888
- logger_1.logger.info(`[INIT TC] NCP network matches config.`, NS);
784
+ logger_1.logger.info(`[INIT TC] Adapter network matches config.`, NS);
889
785
  break;
890
786
  }
891
787
  default: {
@@ -902,9 +798,9 @@ class EmberAdapter extends __1.Adapter {
902
798
  // // XXX: no idea here on the proper timer value, but this will block the network for several seconds on exec
903
799
  // // (probably have to take the behavior of sleepy-end devices into account to improve chances of reaching everyone right away?)
904
800
  // setTimeout(async () => {
905
- // this.requestQueue.enqueue(async (): Promise<EmberStatus> => {
801
+ // this.requestQueue.enqueue(async (): Promise<SLStatus> => {
906
802
  // await this.broadcastNetworkKeyUpdate();
907
- // return EmberStatus.SUCCESS;
803
+ // return SLStatus.OK;
908
804
  // }, logger.error, true);// no reject just log error if any, will retry next start, & prioritize so we know it'll run when expected
909
805
  // }, 300000);
910
806
  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);
@@ -916,30 +812,30 @@ class EmberAdapter extends __1.Adapter {
916
812
  */
917
813
  async formNetwork(fromBackup, networkKey, networkKeySequenceNumber, panId, extendedPanId, radioChannel, tcLinkKey) {
918
814
  const state = {
919
- bitmask: (enums_3.EmberInitialSecurityBitmask.TRUST_CENTER_GLOBAL_LINK_KEY | enums_3.EmberInitialSecurityBitmask.HAVE_PRECONFIGURED_KEY
920
- | enums_3.EmberInitialSecurityBitmask.HAVE_NETWORK_KEY | enums_3.EmberInitialSecurityBitmask.TRUST_CENTER_USES_HASHED_LINK_KEY
921
- | enums_3.EmberInitialSecurityBitmask.REQUIRE_ENCRYPTED_KEY),
815
+ bitmask: (enums_2.EmberInitialSecurityBitmask.TRUST_CENTER_GLOBAL_LINK_KEY | enums_2.EmberInitialSecurityBitmask.HAVE_PRECONFIGURED_KEY
816
+ | enums_2.EmberInitialSecurityBitmask.HAVE_NETWORK_KEY | enums_2.EmberInitialSecurityBitmask.TRUST_CENTER_USES_HASHED_LINK_KEY
817
+ | enums_2.EmberInitialSecurityBitmask.REQUIRE_ENCRYPTED_KEY),
922
818
  preconfiguredKey: { contents: tcLinkKey },
923
819
  networkKey: { contents: networkKey },
924
820
  networkKeySequenceNumber: networkKeySequenceNumber,
925
821
  preconfiguredTrustCenterEui64: ZSpec.BLANK_EUI64,
926
822
  };
927
823
  if (fromBackup) {
928
- state.bitmask |= enums_3.EmberInitialSecurityBitmask.NO_FRAME_COUNTER_RESET;
824
+ state.bitmask |= enums_2.EmberInitialSecurityBitmask.NO_FRAME_COUNTER_RESET;
929
825
  }
930
- let emberStatus = (await this.ezsp.ezspSetInitialSecurityState(state));
931
- if (emberStatus !== enums_3.EmberStatus.SUCCESS) {
932
- throw new Error(`[INIT FORM] Failed to set initial security state with status=${enums_3.EmberStatus[emberStatus]}.`);
826
+ let status = (await this.ezsp.ezspSetInitialSecurityState(state));
827
+ if (status !== enums_2.SLStatus.OK) {
828
+ throw new Error(`[INIT FORM] Failed to set initial security state with status=${enums_2.SLStatus[status]}.`);
933
829
  }
934
- const extended = (enums_3.EmberExtendedSecurityBitmask.JOINER_GLOBAL_LINK_KEY | enums_3.EmberExtendedSecurityBitmask.NWK_LEAVE_REQUEST_NOT_ALLOWED);
935
- const extSecStatus = (await this.ezsp.ezspSetExtendedSecurityBitmask(extended));
936
- if (extSecStatus !== enums_3.EzspStatus.SUCCESS) {
937
- throw new Error(`[INIT FORM] Failed to set extended security bitmask to ${extended} with status=${enums_3.EzspStatus[extSecStatus]}.`);
830
+ const extended = (enums_2.EmberExtendedSecurityBitmask.JOINER_GLOBAL_LINK_KEY | enums_2.EmberExtendedSecurityBitmask.NWK_LEAVE_REQUEST_NOT_ALLOWED);
831
+ status = (await this.ezsp.ezspSetExtendedSecurityBitmask(extended));
832
+ if (status !== enums_2.SLStatus.OK) {
833
+ throw new Error(`[INIT FORM] Failed to set extended security bitmask to ${extended} with status=${enums_2.SLStatus[status]}.`);
938
834
  }
939
- if (!fromBackup && this.stackConfig.KEY_TABLE_SIZE > 0) {
940
- emberStatus = await this.ezsp.ezspClearKeyTable();
941
- if (emberStatus !== enums_3.EmberStatus.SUCCESS) {
942
- throw new Error(`[INIT FORM] Failed to clear key table with status=${enums_3.EmberStatus[emberStatus]}.`);
835
+ if (!fromBackup) {
836
+ status = await this.ezsp.ezspClearKeyTable();
837
+ if (status !== enums_2.SLStatus.OK) {
838
+ logger_1.logger.error(`[INIT FORM] Failed to clear key table with status=${enums_2.SLStatus[status]}.`, NS);
943
839
  }
944
840
  }
945
841
  const netParams = {
@@ -947,19 +843,19 @@ class EmberAdapter extends __1.Adapter {
947
843
  extendedPanId,
948
844
  radioTxPower: 5,
949
845
  radioChannel,
950
- joinMethod: enums_3.EmberJoinMethod.MAC_ASSOCIATION,
846
+ joinMethod: enums_2.EmberJoinMethod.MAC_ASSOCIATION,
951
847
  nwkManagerId: ZSpec.COORDINATOR_ADDRESS,
952
848
  nwkUpdateId: 0,
953
849
  channels: consts_2.EMBER_ALL_802_15_4_CHANNELS_MASK,
954
850
  };
955
851
  logger_1.logger.info(`[INIT FORM] Forming new network with: ${JSON.stringify(netParams)}`, NS);
956
- emberStatus = (await this.ezsp.ezspFormNetwork(netParams));
957
- if (emberStatus !== enums_3.EmberStatus.SUCCESS) {
958
- throw new Error(`[INIT FORM] Failed form network request with status=${enums_3.EmberStatus[emberStatus]}.`);
852
+ status = (await this.ezsp.ezspFormNetwork(netParams));
853
+ if (status !== enums_2.SLStatus.OK) {
854
+ throw new Error(`[INIT FORM] Failed form network request with status=${enums_2.SLStatus[status]}.`);
959
855
  }
960
856
  await this.oneWaitress.startWaitingForEvent({ eventName: oneWaitress_1.OneWaitressEvents.STACK_STATUS_NETWORK_UP }, DEFAULT_NETWORK_REQUEST_TIMEOUT, '[INIT FORM] Form network');
961
- const stStatus = await this.ezsp.ezspStartWritingStackTokens();
962
- logger_1.logger.debug(`[INIT FORM] Start writing stack tokens status=${enums_3.EzspStatus[stStatus]}.`, NS);
857
+ status = await this.ezsp.ezspStartWritingStackTokens();
858
+ logger_1.logger.debug(`[INIT FORM] Start writing stack tokens status=${enums_2.SLStatus[status]}.`, NS);
963
859
  logger_1.logger.info(`[INIT FORM] New network formed!`, NS);
964
860
  }
965
861
  /**
@@ -1000,27 +896,27 @@ class EmberAdapter extends __1.Adapter {
1000
896
  * @return List of keys data with AES hashed keys
1001
897
  */
1002
898
  async exportLinkKeys() {
1003
- const [confStatus, keyTableSize] = (await this.ezsp.ezspGetConfigurationValue(enums_2.EzspConfigId.KEY_TABLE_SIZE));
1004
- if (confStatus !== enums_3.EzspStatus.SUCCESS) {
1005
- throw new Error(`[BACKUP] Failed to retrieve key table size from NCP with status=${enums_3.EzspStatus[confStatus]}.`);
899
+ const [confStatus, keyTableSize] = (await this.ezsp.ezspGetConfigurationValue(enums_1.EzspConfigId.KEY_TABLE_SIZE));
900
+ if (confStatus !== enums_2.SLStatus.OK) {
901
+ throw new Error(`[BACKUP] Failed to retrieve key table size from NCP with status=${enums_2.SLStatus[confStatus]}.`);
1006
902
  }
1007
- let deviceEui64;
903
+ let context;
1008
904
  let plaintextKey;
1009
905
  let apsKeyMeta;
1010
906
  let status;
1011
907
  const keyList = [];
1012
908
  for (let i = 0; i < keyTableSize; i++) {
1013
- [deviceEui64, plaintextKey, apsKeyMeta, status] = (await this.ezsp.ezspExportLinkKeyByIndex(i));
1014
- logger_1.logger.debug(`[BACKUP] Export link key at index ${i}, status=${enums_3.SLStatus[status]}.`, NS);
909
+ [status, context, plaintextKey, apsKeyMeta] = (await this.ezsp.ezspExportLinkKeyByIndex(i));
910
+ logger_1.logger.debug(`[BACKUP] Export link key at index ${i}, status=${enums_2.SLStatus[status]}.`, NS);
1015
911
  // only include key if we could retrieve one at index and hash it properly
1016
- if (status === enums_3.SLStatus.OK) {
912
+ if (status === enums_2.SLStatus.OK) {
1017
913
  // Rather than give the real link key, the backup contains a hashed version of the key.
1018
914
  // This is done to prevent a compromise of the backup data from compromising the current link keys.
1019
915
  // This is per the Smart Energy spec.
1020
916
  const [hashStatus, hashedKey] = (await this.emberAesHashSimple(plaintextKey.contents));
1021
- if (hashStatus === enums_3.EmberStatus.SUCCESS) {
917
+ if (hashStatus === enums_2.SLStatus.OK) {
1022
918
  keyList.push({
1023
- deviceEui64,
919
+ deviceEui64: context.eui64,
1024
920
  key: { contents: hashedKey },
1025
921
  outgoingFrameCounter: apsKeyMeta.outgoingFrameCounter,
1026
922
  incomingFrameCounter: apsKeyMeta.incomingFrameCounter,
@@ -1028,7 +924,7 @@ class EmberAdapter extends __1.Adapter {
1028
924
  }
1029
925
  else {
1030
926
  // this should never happen?
1031
- logger_1.logger.error(`[BACKUP] Failed to hash link key at index ${i} with status=${enums_3.EmberStatus[hashStatus]}. Omitting from backup.`, NS);
927
+ logger_1.logger.error(`[BACKUP] Failed to hash link key at index ${i} with status=${enums_2.SLStatus[hashStatus]}. Omitting from backup.`, NS);
1032
928
  }
1033
929
  }
1034
930
  }
@@ -1044,30 +940,25 @@ class EmberAdapter extends __1.Adapter {
1044
940
  if (!backupData?.length) {
1045
941
  return;
1046
942
  }
1047
- const [confStatus, keyTableSize] = (await this.ezsp.ezspGetConfigurationValue(enums_2.EzspConfigId.KEY_TABLE_SIZE));
1048
- if (confStatus !== enums_3.EzspStatus.SUCCESS) {
1049
- throw new Error(`[BACKUP] Failed to retrieve key table size from NCP with status=${enums_3.EzspStatus[confStatus]}.`);
943
+ const [confStatus, keyTableSize] = (await this.ezsp.ezspGetConfigurationValue(enums_1.EzspConfigId.KEY_TABLE_SIZE));
944
+ if (confStatus !== enums_2.SLStatus.OK) {
945
+ throw new Error(`[BACKUP] Failed to retrieve key table size from NCP with status=${enums_2.SLStatus[confStatus]}.`);
1050
946
  }
1051
947
  if (backupData.length > keyTableSize) {
1052
948
  throw new Error(`[BACKUP] Current key table of ${keyTableSize} is too small to import backup of ${backupData.length}!`);
1053
949
  }
1054
950
  const networkStatus = (await this.emberNetworkState());
1055
- if (networkStatus !== enums_3.EmberNetworkStatus.NO_NETWORK) {
1056
- throw new Error(`[BACKUP] Cannot import TC data while network is up, networkStatus=${enums_3.EmberNetworkStatus[networkStatus]}.`);
951
+ if (networkStatus !== enums_2.EmberNetworkStatus.NO_NETWORK) {
952
+ throw new Error(`[BACKUP] Cannot import TC data while network is up, networkStatus=${enums_2.EmberNetworkStatus[networkStatus]}.`);
1057
953
  }
1058
954
  let status;
1059
955
  for (let i = 0; i < keyTableSize; i++) {
1060
- if (i >= backupData.length) {
1061
- // erase any key index not present in backup but available on the NCP
1062
- status = (await this.ezsp.ezspEraseKeyTableEntry(i));
1063
- }
1064
- else {
1065
- const importStatus = (await this.ezsp.ezspImportLinkKey(i, backupData[i].deviceEui64, backupData[i].key));
1066
- status = ((importStatus === enums_3.SLStatus.OK) ? enums_3.EmberStatus.SUCCESS : enums_3.EmberStatus.KEY_TABLE_INVALID_ADDRESS);
1067
- }
1068
- if (status !== enums_3.EmberStatus.SUCCESS) {
956
+ // erase any key index not present in backup but available on the NCP
957
+ status = (i >= backupData.length) ? await this.ezsp.ezspEraseKeyTableEntry(i) :
958
+ await this.ezsp.ezspImportLinkKey(i, backupData[i].deviceEui64, backupData[i].key);
959
+ if (status !== enums_2.SLStatus.OK) {
1069
960
  throw new Error(`[BACKUP] Failed to ${((i >= backupData.length) ? "erase" : "set")} key table entry at index ${i} `
1070
- + `with status=${enums_3.EmberStatus[status]}`);
961
+ + `with status=${enums_2.SLStatus[status]}`);
1071
962
  }
1072
963
  }
1073
964
  logger_1.logger.info(`[BACKUP] Imported ${backupData.length} keys.`, NS);
@@ -1084,17 +975,17 @@ class EmberAdapter extends __1.Adapter {
1084
975
  logger_1.logger.warning(`[TRUST CENTER] Performing a network key update. This might take a while and disrupt normal operation.`, NS);
1085
976
  // zero-filled = let stack generate new random network key
1086
977
  let status = await this.ezsp.ezspBroadcastNextNetworkKey({ contents: Buffer.alloc(consts_1.EMBER_ENCRYPTION_KEY_SIZE) });
1087
- if (status !== enums_3.EmberStatus.SUCCESS) {
1088
- logger_1.logger.error(`[TRUST CENTER] Failed to broadcast next network key with status=${enums_3.EmberStatus[status]}.`, NS);
978
+ if (status !== enums_2.SLStatus.OK) {
979
+ logger_1.logger.error(`[TRUST CENTER] Failed to broadcast next network key with status=${enums_2.SLStatus[status]}.`, NS);
1089
980
  return status;
1090
981
  }
1091
982
  // XXX: this will block other requests for a while, but should ensure the key propagates without interference?
1092
983
  // could also stop dispatching entirely and do this outside the queue if necessary/better
1093
984
  await (0, utils_1.Wait)(BROADCAST_NETWORK_KEY_SWITCH_WAIT_TIME);
1094
985
  status = (await this.ezsp.ezspBroadcastNetworkKeySwitch());
1095
- if (status !== enums_3.EmberStatus.SUCCESS) {
986
+ if (status !== enums_2.SLStatus.OK) {
1096
987
  // XXX: Not sure how likely this is, but this is bad, probably should hard fail?
1097
- logger_1.logger.error(`[TRUST CENTER] Failed to broadcast network key switch with status=${enums_3.EmberStatus[status]}.`, NS);
988
+ logger_1.logger.error(`[TRUST CENTER] Failed to broadcast network key switch with status=${enums_2.SLStatus[status]}.`, NS);
1098
989
  return status;
1099
990
  }
1100
991
  resolve();
@@ -1107,16 +998,23 @@ class EmberAdapter extends __1.Adapter {
1107
998
  * @param status
1108
999
  */
1109
1000
  async onNcpNeedsResetAndInit(status) {
1110
- logger_1.logger.error(`!!! NCP FATAL ERROR reason=${enums_3.EzspStatus[status]}. ATTEMPTING RESET... !!!`, NS);
1111
- try {
1112
- await this.stop();
1113
- await (0, utils_1.Wait)(500); // just because
1114
- await this.start();
1115
- }
1116
- catch (err) {
1117
- logger_1.logger.error(`Failed to reset and init NCP. ${err}`, NS);
1001
+ logger_1.logger.error(`!!! ADAPTER FATAL ERROR reason=${enums_2.EzspStatus[status]}. !!!`, NS);
1002
+ if (this.requestQueue.isHigh) {
1003
+ logger_1.logger.info(`Request queue is high (${this.requestQueue.totalQueued}), triggering full restart to prevent stressing the adapter.`, NS);
1118
1004
  this.emit(events_1.Events.disconnected);
1119
1005
  }
1006
+ else {
1007
+ logger_1.logger.info(`Attempting adapter reset...`, NS);
1008
+ try {
1009
+ await this.stop();
1010
+ await (0, utils_1.Wait)(500); // just because
1011
+ await this.start();
1012
+ }
1013
+ catch (err) {
1014
+ logger_1.logger.error(`Failed to reset and init adapter. ${err}`, NS);
1015
+ this.emit(events_1.Events.disconnected);
1016
+ }
1017
+ }
1120
1018
  }
1121
1019
  //---- START Events
1122
1020
  //---- END Events
@@ -1158,11 +1056,11 @@ class EmberAdapter extends __1.Adapter {
1158
1056
  async emberGetPanId() {
1159
1057
  if (this.networkCache.parameters.panId === ZSpec.INVALID_PAN_ID) {
1160
1058
  const [status, , parameters] = (await this.ezsp.ezspGetNetworkParameters());
1161
- if (status === enums_3.EmberStatus.SUCCESS) {
1059
+ if (status === enums_2.SLStatus.OK) {
1162
1060
  this.networkCache.parameters = parameters;
1163
1061
  }
1164
1062
  else {
1165
- logger_1.logger.error(`Failed to get PAN ID (via network parameters) with status=${enums_3.EmberStatus[status]}.`, NS);
1063
+ logger_1.logger.error(`Failed to get PAN ID (via network parameters) with status=${enums_2.SLStatus[status]}.`, NS);
1166
1064
  }
1167
1065
  }
1168
1066
  return this.networkCache.parameters.panId;
@@ -1175,11 +1073,11 @@ class EmberAdapter extends __1.Adapter {
1175
1073
  async emberGetExtendedPanId() {
1176
1074
  if ((0, es6_1.default)(this.networkCache.parameters.extendedPanId, ZSpec.BLANK_EXTENDED_PAN_ID)) {
1177
1075
  const [status, , parameters] = (await this.ezsp.ezspGetNetworkParameters());
1178
- if (status === enums_3.EmberStatus.SUCCESS) {
1076
+ if (status === enums_2.SLStatus.OK) {
1179
1077
  this.networkCache.parameters = parameters;
1180
1078
  }
1181
1079
  else {
1182
- logger_1.logger.error(`Failed to get Extended PAN ID (via network parameters) with status=${enums_3.EmberStatus[status]}.`, NS);
1080
+ logger_1.logger.error(`Failed to get Extended PAN ID (via network parameters) with status=${enums_2.SLStatus[status]}.`, NS);
1183
1081
  }
1184
1082
  }
1185
1083
  return this.networkCache.parameters.extendedPanId;
@@ -1192,11 +1090,11 @@ class EmberAdapter extends __1.Adapter {
1192
1090
  async emberGetRadioChannel() {
1193
1091
  if (this.networkCache.parameters.radioChannel === consts_2.INVALID_RADIO_CHANNEL) {
1194
1092
  const [status, , parameters] = (await this.ezsp.ezspGetNetworkParameters());
1195
- if (status === enums_3.EmberStatus.SUCCESS) {
1093
+ if (status === enums_2.SLStatus.OK) {
1196
1094
  this.networkCache.parameters = parameters;
1197
1095
  }
1198
1096
  else {
1199
- logger_1.logger.error(`Failed to get radio channel (via network parameters) with status=${enums_3.EmberStatus[status]}.`, NS);
1097
+ logger_1.logger.error(`Failed to get radio channel (via network parameters) with status=${enums_2.SLStatus[status]}.`, NS);
1200
1098
  }
1201
1099
  }
1202
1100
  return this.networkCache.parameters.radioChannel;
@@ -1205,14 +1103,14 @@ class EmberAdapter extends __1.Adapter {
1205
1103
  async emberStartEnergyScan() {
1206
1104
  return new Promise((resolve, reject) => {
1207
1105
  this.requestQueue.enqueue(async () => {
1208
- const status = (await this.ezsp.ezspStartScan(enums_3.EzspNetworkScanType.ENERGY_SCAN, consts_2.EMBER_ALL_802_15_4_CHANNELS_MASK, ENERGY_SCAN_DURATION));
1209
- if (status !== enums_3.SLStatus.OK) {
1210
- logger_1.logger.error(`Failed energy scan request with status=${enums_3.SLStatus[status]}.`, NS);
1211
- return enums_3.EmberStatus.ERR_FATAL;
1106
+ const status = (await this.ezsp.ezspStartScan(enums_2.EzspNetworkScanType.ENERGY_SCAN, consts_2.EMBER_ALL_802_15_4_CHANNELS_MASK, ENERGY_SCAN_DURATION));
1107
+ if (status !== enums_2.SLStatus.OK) {
1108
+ logger_1.logger.error(`Failed energy scan request with status=${enums_2.SLStatus[status]}.`, NS);
1109
+ return enums_2.SLStatus.FAIL;
1212
1110
  }
1213
1111
  // TODO: result in logs only atm, since UI doesn't support it
1214
1112
  resolve();
1215
- return enums_3.EmberStatus.SUCCESS;
1113
+ return enums_2.SLStatus.OK;
1216
1114
  }, reject);
1217
1115
  });
1218
1116
  }
@@ -1227,35 +1125,40 @@ class EmberAdapter extends __1.Adapter {
1227
1125
  * Does nothing if ncpNeedsResetAndInit == true.
1228
1126
  */
1229
1127
  async emberVersion() {
1230
- // Note that NCP == Network Co-Processor
1231
- // the EZSP protocol version that the Host is running, we are the host so we set this value
1232
- const hostEzspProtocolVer = consts_1.EZSP_PROTOCOL_VERSION;
1233
1128
  // send the Host version number to the NCP.
1234
1129
  // The NCP returns the EZSP version that the NCP is running along with the stackType and stackVersion
1235
- const [ncpEzspProtocolVer, ncpStackType, ncpStackVer] = (await this.ezsp.ezspVersion(hostEzspProtocolVer));
1130
+ let [ncpEzspProtocolVer, ncpStackType, ncpStackVer] = await this.ezsp.ezspVersion(consts_1.EZSP_PROTOCOL_VERSION);
1236
1131
  // verify that the stack type is what is expected
1237
1132
  if (ncpStackType !== consts_1.EZSP_STACK_TYPE_MESH) {
1238
1133
  throw new Error(`Stack type ${ncpStackType} is not expected!`);
1239
1134
  }
1240
- // verify that the NCP EZSP Protocol version is what is expected
1241
- if (ncpEzspProtocolVer !== consts_1.EZSP_PROTOCOL_VERSION) {
1242
- throw new Error(`NCP EZSP protocol version of ${ncpEzspProtocolVer} does not match Host version ${hostEzspProtocolVer}`);
1135
+ if (ncpEzspProtocolVer === consts_1.EZSP_PROTOCOL_VERSION) {
1136
+ logger_1.logger.debug(`Adapter EZSP protocol version (${ncpEzspProtocolVer}) matches Host.`, NS);
1243
1137
  }
1244
- logger_1.logger.debug(`NCP info: EZSPVersion=${ncpEzspProtocolVer} StackType=${ncpStackType} StackVersion=${ncpStackVer}`, NS);
1138
+ else if (ncpEzspProtocolVer < consts_1.EZSP_PROTOCOL_VERSION && ncpEzspProtocolVer >= consts_1.EZSP_MIN_PROTOCOL_VERSION) {
1139
+ [ncpEzspProtocolVer, ncpStackType, ncpStackVer] = await this.ezsp.ezspVersion(ncpEzspProtocolVer);
1140
+ logger_1.logger.info(`Adapter EZSP protocol version (${ncpEzspProtocolVer}) lower than Host. Switched.`, NS);
1141
+ }
1142
+ else {
1143
+ throw new Error(`Adapter EZSP protocol version (${ncpEzspProtocolVer}) is not supported `
1144
+ + `by Host [${consts_1.EZSP_MIN_PROTOCOL_VERSION}-${consts_1.EZSP_PROTOCOL_VERSION}].`);
1145
+ }
1146
+ this.ezsp.setProtocolVersion(ncpEzspProtocolVer);
1147
+ logger_1.logger.debug(`Adapter info: EZSPVersion=${ncpEzspProtocolVer} StackType=${ncpStackType} StackVersion=${ncpStackVer}`, NS);
1245
1148
  const [status, versionStruct] = (await this.ezsp.ezspGetVersionStruct());
1246
- if (status !== enums_3.EzspStatus.SUCCESS) {
1149
+ if (status !== enums_2.SLStatus.OK) {
1247
1150
  // Should never happen with support of only EZSP v13+
1248
1151
  throw new Error(`NCP has old-style version number. Not supported.`);
1249
1152
  }
1250
1153
  this.version = {
1251
1154
  ezsp: ncpEzspProtocolVer,
1252
- revision: `${versionStruct.major}.${versionStruct.minor}.${versionStruct.patch} [${enums_3.EmberVersionType[versionStruct.type]}]`,
1155
+ revision: `${versionStruct.major}.${versionStruct.minor}.${versionStruct.patch} [${enums_2.EmberVersionType[versionStruct.type]}]`,
1253
1156
  ...versionStruct,
1254
1157
  };
1255
- if (versionStruct.type !== enums_3.EmberVersionType.GA) {
1256
- logger_1.logger.warning(`NCP is running a non-GA version (${enums_3.EmberVersionType[versionStruct.type]}).`, NS);
1158
+ if (versionStruct.type !== enums_2.EmberVersionType.GA) {
1159
+ logger_1.logger.warning(`Adapter is running a non-GA version (${enums_2.EmberVersionType[versionStruct.type]}).`, NS);
1257
1160
  }
1258
- logger_1.logger.debug(`NCP version info: ${JSON.stringify(this.version)}`, NS);
1161
+ logger_1.logger.info(`Adapter version info: ${JSON.stringify(this.version)}`, NS);
1259
1162
  }
1260
1163
  /**
1261
1164
  * This function sets an EZSP config value.
@@ -1267,13 +1170,9 @@ class EmberAdapter extends __1.Adapter {
1267
1170
  */
1268
1171
  async emberSetEzspConfigValue(configId, value) {
1269
1172
  const status = (await this.ezsp.ezspSetConfigurationValue(configId, value));
1270
- logger_1.logger.debug(`[EzspConfigId] SET "${enums_2.EzspConfigId[configId]}" TO "${value}" with status=${enums_3.EzspStatus[status]}.`, NS);
1271
- if (status === enums_3.EzspStatus.ERROR_INVALID_ID) {
1272
- // can be ZLL where not all NCPs need or support it.
1273
- logger_1.logger.warning(`[EzspConfigId] Unsupported configuration ID ${enums_2.EzspConfigId[configId]} by NCP.`, NS);
1274
- }
1275
- else if (status !== enums_3.EzspStatus.SUCCESS) {
1276
- logger_1.logger.warning(`[EzspConfigId] Failed to SET "${enums_2.EzspConfigId[configId]}" TO "${value}" with status=${enums_3.EzspStatus[status]}. `
1173
+ logger_1.logger.debug(`[EzspConfigId] SET "${enums_1.EzspConfigId[configId]}" TO "${value}" with status=${enums_2.SLStatus[status]}.`, NS);
1174
+ if (status !== enums_2.SLStatus.OK) {
1175
+ logger_1.logger.info(`[EzspConfigId] Failed to SET "${enums_1.EzspConfigId[configId]}" TO "${value}" with status=${enums_2.SLStatus[status]}. `
1277
1176
  + `Firmware value will be used instead.`, NS);
1278
1177
  }
1279
1178
  return status;
@@ -1287,7 +1186,7 @@ class EmberAdapter extends __1.Adapter {
1287
1186
  */
1288
1187
  async emberSetEzspValue(valueId, valueLength, value) {
1289
1188
  const status = (await this.ezsp.ezspSetValue(valueId, valueLength, value));
1290
- logger_1.logger.debug(`[EzspValueId] SET "${enums_2.EzspValueId[valueId]}" TO "${value}" with status=${enums_3.EzspStatus[status]}.`, NS);
1189
+ logger_1.logger.debug(`[EzspValueId] SET "${enums_1.EzspValueId[valueId]}" TO "${value}" with status=${enums_2.SLStatus[status]}.`, NS);
1291
1190
  return status;
1292
1191
  }
1293
1192
  /**
@@ -1298,7 +1197,7 @@ class EmberAdapter extends __1.Adapter {
1298
1197
  */
1299
1198
  async emberSetEzspPolicy(policyId, decisionId) {
1300
1199
  const status = (await this.ezsp.ezspSetPolicy(policyId, decisionId));
1301
- logger_1.logger.debug(`[EzspPolicyId] SET "${enums_2.EzspPolicyId[policyId]}" TO "${decisionId}" with status=${enums_3.EzspStatus[status]}.`, NS);
1200
+ logger_1.logger.debug(`[EzspPolicyId] SET "${enums_1.EzspPolicyId[policyId]}" TO "${decisionId}" with status=${enums_2.SLStatus[status]}.`, NS);
1302
1201
  return status;
1303
1202
  }
1304
1203
  /**
@@ -1314,7 +1213,8 @@ class EmberAdapter extends __1.Adapter {
1314
1213
  */
1315
1214
  async aesMmoHash(context, finalize, data) {
1316
1215
  if (data.length > 255) {
1317
- throw new Error(enums_3.EzspStatus[enums_3.EzspStatus.ERROR_INVALID_CALL]);
1216
+ // will be caught by request queue and rejected internally.
1217
+ throw new ezspError_1.EzspError(enums_2.EzspStatus.ERROR_INVALID_CALL);
1318
1218
  }
1319
1219
  const [status, reContext] = (await this.ezsp.ezspAesMmoHash(context, finalize, data));
1320
1220
  return [status, reContext];
@@ -1327,7 +1227,7 @@ class EmberAdapter extends __1.Adapter {
1327
1227
  * @param context EmberAesMmoHashContext* A pointer to the location of the hash context to update.
1328
1228
  * @param data const uint8_t* A pointer to the location of the data to hash.
1329
1229
  *
1330
- * @returns An ::EmberStatus value indicating EMBER_SUCCESS if the hash was
1230
+ * @returns An ::SLStatus value indicating EMBER_SUCCESS if the hash was
1331
1231
  * calculated successfully. EMBER_INVALID_CALL if the block size is not a
1332
1232
  * multiple of 16 bytes, and EMBER_INDEX_OUT_OF_RANGE is returned when the
1333
1233
  * data exceeds the maximum limits of the hash function.
@@ -1347,7 +1247,7 @@ class EmberAdapter extends __1.Adapter {
1347
1247
  * @param context EmberAesMmoHashContext * A pointer to the location of the hash context to finalize.
1348
1248
  * @param data uint8_t * A pointer to the location of data to hash. May be NULL.
1349
1249
  *
1350
- * @returns An ::EmberStatus value indicating EMBER_SUCCESS if the hash was
1250
+ * @returns An ::SLStatus value indicating EMBER_SUCCESS if the hash was
1351
1251
  * calculated successfully. EMBER_INVALID_CALL if the block size is not a
1352
1252
  * multiple of 16 bytes, and EMBER_INDEX_OUT_OF_RANGE is returned when the
1353
1253
  * data exceeds the maximum limits of the hash function.
@@ -1362,7 +1262,7 @@ class EmberAdapter extends __1.Adapter {
1362
1262
  *
1363
1263
  * @param data const uint8_t* The data to hash. Expected of valid length (as in, not larger alloc)
1364
1264
  *
1365
- * @returns An ::EmberStatus value indicating EMBER_SUCCESS if the hash was
1265
+ * @returns An ::SLStatus value indicating EMBER_SUCCESS if the hash was
1366
1266
  * calculated successfully. EMBER_INVALID_CALL if the block size is not a
1367
1267
  * multiple of 16 bytes, and EMBER_INDEX_OUT_OF_RANGE is returned when the
1368
1268
  * data exceeds the maximum limits of the hash function.
@@ -1393,7 +1293,9 @@ class EmberAdapter extends __1.Adapter {
1393
1293
  logger_1.logger.debug(`Permit joining for ${duration} sec. status=${[status]}`, NS);
1394
1294
  if (broadcastMgmtPermitJoin) {
1395
1295
  // `authentication`: TC significance always 1 (zb specs)
1396
- [status, apsFrame, messageTag] = (await this.emberPermitJoiningRequest(enums_1.BroadcastAddress.DEFAULT, duration, 1, DEFAULT_APS_OPTIONS));
1296
+ const zdoPayload = buffaloZdo_1.BuffaloZdo.buildPermitJoining(duration, 1, []);
1297
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1298
+ [status, apsFrame, messageTag] = await this.sendZDORequest(ZSpec.BroadcastAddress.DEFAULT, Zdo.ClusterId.PERMIT_JOINING_REQUEST, zdoPayload, DEFAULT_APS_OPTIONS);
1397
1299
  }
1398
1300
  return [status, apsFrame, messageTag];
1399
1301
  }
@@ -1403,92 +1305,17 @@ class EmberAdapter extends __1.Adapter {
1403
1305
  * @returns
1404
1306
  */
1405
1307
  async emberSetJoinPolicy(decision) {
1406
- let policy = enums_2.EzspDecisionBitmask.DEFAULT_CONFIGURATION;
1407
- if (decision == enums_3.EmberJoinDecision.USE_PRECONFIGURED_KEY) {
1408
- policy = (enums_2.EzspDecisionBitmask.ALLOW_JOINS | enums_2.EzspDecisionBitmask.ALLOW_UNSECURED_REJOINS);
1308
+ let policy = enums_1.EzspDecisionBitmask.DEFAULT_CONFIGURATION;
1309
+ if (decision == enums_2.EmberJoinDecision.USE_PRECONFIGURED_KEY) {
1310
+ policy = (enums_1.EzspDecisionBitmask.ALLOW_JOINS | enums_1.EzspDecisionBitmask.ALLOW_UNSECURED_REJOINS);
1409
1311
  }
1410
- else if (decision == enums_3.EmberJoinDecision.SEND_KEY_IN_THE_CLEAR) {
1411
- policy = (enums_2.EzspDecisionBitmask.ALLOW_JOINS | enums_2.EzspDecisionBitmask.ALLOW_UNSECURED_REJOINS | enums_2.EzspDecisionBitmask.SEND_KEY_IN_CLEAR);
1312
+ else if (decision == enums_2.EmberJoinDecision.SEND_KEY_IN_THE_CLEAR) {
1313
+ policy = (enums_1.EzspDecisionBitmask.ALLOW_JOINS | enums_1.EzspDecisionBitmask.ALLOW_UNSECURED_REJOINS | enums_1.EzspDecisionBitmask.SEND_KEY_IN_CLEAR);
1412
1314
  }
1413
- else if (decision == enums_3.EmberJoinDecision.ALLOW_REJOINS_ONLY) {
1414
- policy = enums_2.EzspDecisionBitmask.ALLOW_UNSECURED_REJOINS;
1415
- }
1416
- return this.emberSetEzspPolicy(enums_2.EzspPolicyId.TRUST_CENTER_POLICY, policy);
1417
- }
1418
- /**
1419
- * Get Source Route Overhead
1420
- *
1421
- * Returns the number of bytes needed in a packet for source routing.
1422
- * Since each hop consumes 2 bytes in the packet, this routine calculates the
1423
- * total number of bytes needed based on number of hops to reach the destination.
1424
- *
1425
- * This function is called by the framework to determine the overhead required
1426
- * in the network frame for source routing to a particular destination.
1427
- *
1428
- * @param destination The node id of the destination Ver.: always
1429
- * @returns int8u The number of bytes needed for source routing in a packet.
1430
- */
1431
- async emberGetSourceRouteOverhead(destination) {
1432
- const [status, value] = (await this.ezsp.ezspGetSourceRouteOverhead(destination));
1433
- if (status === enums_3.EzspStatus.SUCCESS) {
1434
- return value;
1435
- }
1436
- else {
1437
- logger_1.logger.debug(`Failed to get source route overhead (via extended value), status=${enums_3.EzspStatus[status]}.`, NS);
1315
+ else if (decision == enums_2.EmberJoinDecision.ALLOW_REJOINS_ONLY) {
1316
+ policy = enums_1.EzspDecisionBitmask.ALLOW_UNSECURED_REJOINS;
1438
1317
  }
1439
- return 0;
1440
- }
1441
- /**
1442
- * Return the maximum size of the payload that the Application Support sub-layer will accept for
1443
- * the given message type, destination, and APS frame.
1444
- *
1445
- * The size depends on multiple factors, including the security level in use and additional information
1446
- * added to the message to support the various options.
1447
- *
1448
- * @param type The outgoing message type.
1449
- * @param indexOrDestination uint16_t Depending on the message type, this is either the
1450
- * EmberNodeId of the destination, an index into the address table, an index
1451
- * into the binding table, the multicast identifier, or a broadcast address.
1452
- * @param apsFrame EmberApsFrame *The APS frame for the message.
1453
- * @return uint8_t The maximum APS payload length for the given message.
1454
- */
1455
- async maximumApsPayloadLength(type, indexOrDestination, apsFrame) {
1456
- let destination = consts_2.EMBER_UNKNOWN_NODE_ID;
1457
- let max = consts_2.MAXIMUM_APS_PAYLOAD_LENGTH; // uint8_t
1458
- if ((apsFrame.options & enums_3.EmberApsOption.ENCRYPTION) !== 0) {
1459
- max -= consts_2.APS_ENCRYPTION_OVERHEAD;
1460
- }
1461
- if ((apsFrame.options & enums_3.EmberApsOption.SOURCE_EUI64) !== 0) {
1462
- max -= consts_1.EUI64_SIZE;
1463
- }
1464
- if ((apsFrame.options & enums_3.EmberApsOption.DESTINATION_EUI64) !== 0) {
1465
- max -= consts_1.EUI64_SIZE;
1466
- }
1467
- if ((apsFrame.options & enums_3.EmberApsOption.FRAGMENT) !== 0) {
1468
- max -= consts_2.APS_FRAGMENTATION_OVERHEAD;
1469
- }
1470
- switch (type) {
1471
- case enums_3.EmberOutgoingMessageType.DIRECT:
1472
- destination = indexOrDestination;
1473
- break;
1474
- case enums_3.EmberOutgoingMessageType.VIA_ADDRESS_TABLE:
1475
- destination = (await this.ezsp.ezspGetAddressTableRemoteNodeId(indexOrDestination));
1476
- break;
1477
- case enums_3.EmberOutgoingMessageType.VIA_BINDING:
1478
- destination = (await this.ezsp.ezspGetBindingRemoteNodeId(indexOrDestination));
1479
- break;
1480
- case enums_3.EmberOutgoingMessageType.MULTICAST:
1481
- // APS multicast messages include the two-byte group id and exclude the one-byte destination endpoint,
1482
- // for a net loss of an extra byte.
1483
- max--;
1484
- break;
1485
- case enums_3.EmberOutgoingMessageType.BROADCAST:
1486
- break;
1487
- default:
1488
- break;
1489
- }
1490
- max -= (await this.emberGetSourceRouteOverhead(destination));
1491
- return max;
1318
+ return this.emberSetEzspPolicy(enums_1.EzspPolicyId.TRUST_CENTER_POLICY, policy);
1492
1319
  }
1493
1320
  //---- END EZSP wrappers
1494
1321
  //---- START Ember ZDO
@@ -1528,518 +1355,47 @@ class EmberAdapter extends __1.Adapter {
1528
1355
  *
1529
1356
  * @param destination
1530
1357
  * @param clusterId uint16_t
1358
+ * @param messageContents Content of the ZDO request (sequence to be assigned at index zero)
1531
1359
  * @param options
1532
- * @param length uint8_t
1533
1360
  * @returns status Indicates success or failure (with reason) of send
1534
1361
  * @returns apsFrame The APS Frame resulting of the request being built and sent (`sequence` set from stack-given value).
1535
1362
  * @returns messageTag The tag passed to ezspSend${x} function.
1536
1363
  */
1537
- async sendZDORequestBuffer(destination, clusterId, options) {
1538
- if (this.zdoRequestBuffalo.getPosition() > consts_1.EZSP_MAX_FRAME_LENGTH) {
1539
- return [enums_3.EmberStatus.MESSAGE_TOO_LONG, null, null];
1364
+ async sendZDORequest(destination, clusterId, messageContents, options) {
1365
+ if (messageContents.length > consts_1.EZSP_MAX_FRAME_LENGTH) {
1366
+ return [enums_2.SLStatus.MESSAGE_TOO_LONG, null, null];
1540
1367
  }
1541
1368
  const messageTag = this.nextZDORequestSequence();
1542
- this.zdoRequestBuffalo.setCommandByte(0, messageTag);
1369
+ messageContents[0] = messageTag;
1543
1370
  const apsFrame = {
1544
- profileId: zdo_1.ZDO_PROFILE_ID,
1545
- clusterId: clusterId,
1546
- sourceEndpoint: zdo_1.ZDO_ENDPOINT,
1547
- destinationEndpoint: zdo_1.ZDO_ENDPOINT,
1548
- options: options,
1371
+ profileId: Zdo.ZDO_PROFILE_ID,
1372
+ clusterId,
1373
+ sourceEndpoint: Zdo.ZDO_ENDPOINT,
1374
+ destinationEndpoint: Zdo.ZDO_ENDPOINT,
1375
+ options,
1549
1376
  groupId: 0,
1550
1377
  sequence: 0, // set by stack
1551
1378
  };
1552
- const messageContents = this.zdoRequestBuffalo.getWritten();
1553
- if (destination === enums_1.BroadcastAddress.DEFAULT || destination === enums_1.BroadcastAddress.RX_ON_WHEN_IDLE
1554
- || destination === enums_1.BroadcastAddress.SLEEPY) {
1555
- logger_1.logger.debug(`~~~> [ZDO BROADCAST apsFrame=${JSON.stringify(apsFrame)} messageTag=${messageTag}]`, NS);
1556
- const [status, apsSequence] = (await this.ezsp.ezspSendBroadcast(destination, apsFrame, this.getZDORequestRadius(), messageTag, messageContents));
1379
+ if (destination === ZSpec.BroadcastAddress.DEFAULT || destination === ZSpec.BroadcastAddress.RX_ON_WHEN_IDLE
1380
+ || destination === ZSpec.BroadcastAddress.SLEEPY) {
1381
+ logger_1.logger.debug(`~~~> [ZDO ${Zdo.ClusterId[clusterId]} BROADCAST to=${destination} messageTag=${messageTag} `
1382
+ + `messageContents=${messageContents.toString('hex')}]`, NS);
1383
+ const [status, apsSequence] = await this.ezsp.ezspSendBroadcast(ZSpec.NULL_NODE_ID, // alias
1384
+ destination, 0, // nwkSequence
1385
+ apsFrame, this.getZDORequestRadius(), messageTag, messageContents);
1557
1386
  apsFrame.sequence = apsSequence;
1558
- logger_1.logger.debug(`~~~> [SENT ZDO type=BROADCAST apsFrame=${JSON.stringify(apsFrame)} messageTag=${messageTag} status=${enums_3.EmberStatus[status]}]`, NS);
1387
+ logger_1.logger.debug(`~~~> [SENT ZDO type=BROADCAST apsSequence=${apsSequence} messageTag=${messageTag} status=${enums_2.SLStatus[status]}`, NS);
1559
1388
  return [status, apsFrame, messageTag];
1560
1389
  }
1561
1390
  else {
1562
- logger_1.logger.debug(`~~~> [ZDO UNICAST apsFrame=${JSON.stringify(apsFrame)} messageTag=${messageTag}]`, NS);
1563
- const [status, apsSequence] = (await this.ezsp.ezspSendUnicast(enums_3.EmberOutgoingMessageType.DIRECT, destination, apsFrame, messageTag, messageContents));
1391
+ logger_1.logger.debug(`~~~> [ZDO ${Zdo.ClusterId[clusterId]} UNICAST to=${destination} messageTag=${messageTag} `
1392
+ + `messageContents=${messageContents.toString('hex')}]`, NS);
1393
+ const [status, apsSequence] = await this.ezsp.ezspSendUnicast(enums_2.EmberOutgoingMessageType.DIRECT, destination, apsFrame, messageTag, messageContents);
1564
1394
  apsFrame.sequence = apsSequence;
1565
- logger_1.logger.debug(`~~~> [SENT ZDO type=DIRECT apsFrame=${JSON.stringify(apsFrame)} messageTag=${messageTag} status=${enums_3.EmberStatus[status]}]`, NS);
1395
+ logger_1.logger.debug(`~~~> [SENT ZDO type=DIRECT apsSequence=${apsSequence} messageTag=${messageTag} status=${enums_2.SLStatus[status]}`, NS);
1566
1396
  return [status, apsFrame, messageTag];
1567
1397
  }
1568
1398
  }
1569
- /**
1570
- * ZDO
1571
- * Service Discovery Functions
1572
- * Request the specified node to send a list of its endpoints that
1573
- * match the specified application profile and, optionally, lists of input
1574
- * and/or output clusters.
1575
- * @param target The node whose matching endpoints are desired. The request can
1576
- * be sent unicast or broadcast ONLY to the "RX-on-when-idle-address" (0xFFFD)
1577
- * If sent as a broadcast, any node that has matching endpoints will send a
1578
- * response.
1579
- * @param profile uint16_t The application profile to match.
1580
- * @param inCount uint8_t The number of input clusters. To not match any input
1581
- * clusters, set this value to 0.
1582
- * @param outCount uint8_t The number of output clusters. To not match any output
1583
- * clusters, set this value to 0.
1584
- * @param inClusters uint16_t * The list of input clusters.
1585
- * @param outClusters uint16_t * The list of output clusters.
1586
- * @param options The options to use when sending the unicast request. See
1587
- * emberSendUnicast() for a description. This parameter is ignored if the target
1588
- * is a broadcast address.
1589
- * @returns An EmberStatus value. EMBER_SUCCESS, MESSAGE_TOO_LONG,
1590
- * EMBER_NETWORK_DOWN or EMBER_NETWORK_BUSY.
1591
- */
1592
- async emberMatchDescriptorsRequest(target, profile, inClusters, outClusters, options) {
1593
- // 2 bytes for NWK Address + 2 bytes for Profile Id + 1 byte for in Cluster Count
1594
- // + in times 2 for 2 byte Clusters + out Cluster Count + out times 2 for 2 byte Clusters
1595
- const length = (zdo_1.ZDO_MESSAGE_OVERHEAD + 2 + 2 + 1 + (inClusters.length * 2) + 1 + (outClusters.length * 2));
1596
- // sanity check
1597
- if (length > consts_1.EZSP_MAX_FRAME_LENGTH) {
1598
- return [enums_3.EmberStatus.MESSAGE_TOO_LONG, null, null];
1599
- }
1600
- this.zdoRequestBuffalo.setPosition(zdo_1.ZDO_MESSAGE_OVERHEAD);
1601
- this.zdoRequestBuffalo.writeUInt16(target);
1602
- this.zdoRequestBuffalo.writeUInt16(profile);
1603
- this.zdoRequestBuffalo.writeUInt8(inClusters.length);
1604
- this.zdoRequestBuffalo.writeListUInt16(inClusters);
1605
- this.zdoRequestBuffalo.writeUInt8(outClusters.length);
1606
- this.zdoRequestBuffalo.writeListUInt16(outClusters);
1607
- logger_1.logger.debug(`~~~> [ZDO MATCH_DESCRIPTORS_REQUEST target=${target} profile=${profile} inClusters=${inClusters} outClusters=${outClusters}]`, NS);
1608
- return this.sendZDORequestBuffer(target, zdo_1.MATCH_DESCRIPTORS_REQUEST, options);
1609
- }
1610
- /**
1611
- * ZDO
1612
- * Device Discovery Functions
1613
- * Request the 16 bit network address of a node whose EUI64 is known.
1614
- *
1615
- * @param target The EUI64 of the node.
1616
- * @param reportKids true to request that the target list their children
1617
- * in the response.
1618
- * @param childStartIndex uint8_t The index of the first child to list in the response.
1619
- * Ignored if @c reportKids is false.
1620
- *
1621
- * @return An ::EmberStatus value.
1622
- * - ::EMBER_SUCCESS - The request was transmitted successfully.
1623
- * - ::EMBER_NO_BUFFERS - Insufficient message buffers were available to construct the request.
1624
- * - ::EMBER_NETWORK_DOWN - The node is not part of a network.
1625
- * - ::EMBER_NETWORK_BUSY - Transmission of the request failed.
1626
- */
1627
- async emberNetworkAddressRequest(target, reportKids, childStartIndex) {
1628
- this.zdoRequestBuffalo.setPosition(zdo_1.ZDO_MESSAGE_OVERHEAD);
1629
- this.zdoRequestBuffalo.writeIeeeAddr(target);
1630
- this.zdoRequestBuffalo.writeUInt8(reportKids ? 1 : 0);
1631
- this.zdoRequestBuffalo.writeUInt8(childStartIndex);
1632
- logger_1.logger.debug(`~~~> [ZDO NETWORK_ADDRESS_REQUEST target=${target} reportKids=${reportKids} childStartIndex=${childStartIndex}]`, NS);
1633
- return this.sendZDORequestBuffer(enums_1.BroadcastAddress.RX_ON_WHEN_IDLE, zdo_1.NETWORK_ADDRESS_REQUEST, enums_3.EmberApsOption.SOURCE_EUI64);
1634
- }
1635
- /**
1636
- * ZDO
1637
- * Device Discovery Functions
1638
- * @brief Request the EUI64 of a node whose 16 bit network address is known.
1639
- *
1640
- * @param target uint16_t The network address of the node.
1641
- * @param reportKids uint8_t true to request that the target list their children
1642
- * in the response.
1643
- * @param childStartIndex uint8_t The index of the first child to list in the response.
1644
- * Ignored if reportKids is false.
1645
- * @param options The options to use when sending the request. See ::emberSendUnicast() for a description.
1646
- *
1647
- * @return An ::EmberStatus value.
1648
- * - ::EMBER_SUCCESS
1649
- * - ::EMBER_NO_BUFFERS
1650
- * - ::EMBER_NETWORK_DOWN
1651
- * - ::EMBER_NETWORK_BUSY
1652
- */
1653
- async emberIeeeAddressRequest(target, reportKids, childStartIndex, options) {
1654
- this.zdoRequestBuffalo.setPosition(zdo_1.ZDO_MESSAGE_OVERHEAD);
1655
- this.zdoRequestBuffalo.writeUInt16(target);
1656
- this.zdoRequestBuffalo.writeUInt8(reportKids ? 1 : 0);
1657
- this.zdoRequestBuffalo.writeUInt8(childStartIndex);
1658
- logger_1.logger.debug(`~~~> [ZDO IEEE_ADDRESS_REQUEST target=${target} reportKids=${reportKids} childStartIndex=${childStartIndex}]`, NS);
1659
- return this.sendZDORequestBuffer(target, zdo_1.IEEE_ADDRESS_REQUEST, options);
1660
- }
1661
- /**
1662
- * ZDO
1663
- * @param discoveryNodeId uint16_t
1664
- * @param reportKids uint8_t
1665
- * @param childStartIndex uint8_t
1666
- * @param options
1667
- * @param targetNodeIdOfRequest
1668
- */
1669
- async emberIeeeAddressRequestToTarget(discoveryNodeId, reportKids, childStartIndex, options, targetNodeIdOfRequest) {
1670
- this.zdoRequestBuffalo.setPosition(zdo_1.ZDO_MESSAGE_OVERHEAD);
1671
- this.zdoRequestBuffalo.writeUInt16(discoveryNodeId);
1672
- this.zdoRequestBuffalo.writeUInt8(reportKids ? 1 : 0);
1673
- this.zdoRequestBuffalo.writeUInt8(childStartIndex);
1674
- logger_1.logger.debug(`~~~> [ZDO IEEE_ADDRESS_REQUEST targetNodeIdOfRequest=${targetNodeIdOfRequest} discoveryNodeId=${discoveryNodeId} `
1675
- + `reportKids=${reportKids} childStartIndex=${childStartIndex}]`, NS);
1676
- return this.sendZDORequestBuffer(targetNodeIdOfRequest, zdo_1.IEEE_ADDRESS_REQUEST, options);
1677
- }
1678
- /**
1679
- * ZDO
1680
- *
1681
- * @param target uint16_t
1682
- * @param clusterId uint16_t
1683
- * @param options
1684
- * @returns
1685
- */
1686
- async emberSendZigDevRequestTarget(target, clusterId, options) {
1687
- this.zdoRequestBuffalo.setPosition(zdo_1.ZDO_MESSAGE_OVERHEAD);
1688
- this.zdoRequestBuffalo.writeUInt16(target);
1689
- return this.sendZDORequestBuffer(target, clusterId, options);
1690
- }
1691
- /**
1692
- * ZDO
1693
- * @brief Request the specified node to send the simple descriptor for
1694
- * the specified endpoint.
1695
- * The simple descriptor contains information specific
1696
- * to a single endpoint. It describes the application profile identifier,
1697
- * application device identifier, application device version, application flags,
1698
- * application input clusters and application output clusters. It is defined in
1699
- * the ZigBee Application Framework Specification.
1700
- *
1701
- * @param target uint16_t The node of interest.
1702
- * @param targetEndpoint uint8_t The endpoint on the target node whose simple
1703
- * descriptor is desired.
1704
- * @param options The options to use when sending the request. See
1705
- * emberSendUnicast() for a description.
1706
- *
1707
- * @return An EmberStatus value. ::EMBER_SUCCESS, ::EMBER_NO_BUFFERS,
1708
- * ::EMBER_NETWORK_DOWN or ::EMBER_NETWORK_BUSY.
1709
- */
1710
- async emberSimpleDescriptorRequest(target, targetEndpoint, options) {
1711
- this.zdoRequestBuffalo.setPosition(zdo_1.ZDO_MESSAGE_OVERHEAD);
1712
- this.zdoRequestBuffalo.writeUInt16(target);
1713
- this.zdoRequestBuffalo.writeUInt8(targetEndpoint);
1714
- logger_1.logger.debug(`~~~> [ZDO SIMPLE_DESCRIPTOR_REQUEST target=${target} targetEndpoint=${targetEndpoint}]`, NS);
1715
- return this.sendZDORequestBuffer(target, zdo_1.SIMPLE_DESCRIPTOR_REQUEST, options);
1716
- }
1717
- /**
1718
- * ZDO
1719
- * Common logic used by `emberBindRequest` & `emberUnbindRequest`.
1720
- *
1721
- * @param target
1722
- * @param bindClusterId
1723
- * @param source
1724
- * @param sourceEndpoint
1725
- * @param clusterId
1726
- * @param type
1727
- * @param destination
1728
- * @param groupAddress
1729
- * @param destinationEndpoint
1730
- * @param options
1731
- *
1732
- * @returns An ::EmberStatus value.
1733
- * - ::EMBER_SUCCESS
1734
- * - ::EMBER_NO_BUFFERS
1735
- * - ::EMBER_NETWORK_DOWN
1736
- * - ::EMBER_NETWORK_BUSY
1737
- * @returns APS frame created for the request
1738
- * @returns The tag used on the message.
1739
- */
1740
- async emberSendZigDevBindRequest(target, bindClusterId, source, sourceEndpoint, clusterId, type, destination, groupAddress, destinationEndpoint, options) {
1741
- this.zdoRequestBuffalo.setPosition(zdo_1.ZDO_MESSAGE_OVERHEAD);
1742
- this.zdoRequestBuffalo.writeIeeeAddr(source);
1743
- this.zdoRequestBuffalo.writeUInt8(sourceEndpoint);
1744
- this.zdoRequestBuffalo.writeUInt16(clusterId);
1745
- this.zdoRequestBuffalo.writeUInt8(type);
1746
- switch (type) {
1747
- case zdo_1.UNICAST_BINDING:
1748
- this.zdoRequestBuffalo.writeIeeeAddr(destination);
1749
- this.zdoRequestBuffalo.writeUInt8(destinationEndpoint);
1750
- break;
1751
- case zdo_1.MULTICAST_BINDING:
1752
- this.zdoRequestBuffalo.writeUInt16(groupAddress);
1753
- break;
1754
- default:
1755
- return [enums_3.EmberStatus.ERR_FATAL, null, null];
1756
- }
1757
- return this.sendZDORequestBuffer(target, bindClusterId, options);
1758
- }
1759
- /**
1760
- * ZDO
1761
- * Send a request to create a binding entry with the specified
1762
- * contents on the specified node.
1763
- *
1764
- * @param target The node on which the binding will be created.
1765
- * @param source The source EUI64 in the binding entry.
1766
- * @param sourceEndpoint The source endpoint in the binding entry.
1767
- * @param clusterId The cluster ID in the binding entry.
1768
- * @param type The type of binding, either ::UNICAST_BINDING,
1769
- * ::MULTICAST_BINDING, or ::UNICAST_MANY_TO_ONE_BINDING.
1770
- * ::UNICAST_MANY_TO_ONE_BINDING is an Ember-specific extension
1771
- * and should be used only when the target is an Ember device.
1772
- * @param destination The destination EUI64 in the binding entry for
1773
- * ::UNICAST_BINDING or ::UNICAST_MANY_TO_ONE_BINDING.
1774
- * @param groupAddress The group address for the ::MULTICAST_BINDING.
1775
- * @param destinationEndpoint The destination endpoint in the binding entry for
1776
- * the ::UNICAST_BINDING or ::UNICAST_MANY_TO_ONE_BINDING.
1777
- * @param options The options to use when sending the request. See
1778
- * emberSendUnicast() for a description.
1779
- *
1780
- * @returns An ::EmberStatus value.
1781
- * - ::EMBER_SUCCESS
1782
- * - ::EMBER_NO_BUFFERS
1783
- * - ::EMBER_NETWORK_DOWN
1784
- * - ::EMBER_NETWORK_BUSY
1785
- * @returns APS frame created for the request
1786
- * @returns The tag used on the message.
1787
- */
1788
- async emberBindRequest(target, source, sourceEndpoint, clusterId, type, destination, groupAddress, destinationEndpoint, options) {
1789
- logger_1.logger.debug(`~~~> [ZDO BIND_REQUEST target=${target} source=${source} sourceEndpoint=${sourceEndpoint} clusterId=${clusterId} type=${type} `
1790
- + `destination=${destination} groupAddress=${groupAddress} destinationEndpoint=${destinationEndpoint}]`, NS);
1791
- return this.emberSendZigDevBindRequest(target, zdo_1.BIND_REQUEST, source, sourceEndpoint, clusterId, type, destination, groupAddress, destinationEndpoint, options);
1792
- }
1793
- /**
1794
- * ZDO
1795
- * Send a request to remove a binding entry with the specified
1796
- * contents from the specified node.
1797
- *
1798
- * @param target The node on which the binding will be removed.
1799
- * @param source The source EUI64 in the binding entry.
1800
- * @param sourceEndpoint uint8_t The source endpoint in the binding entry.
1801
- * @param clusterId uint16_t The cluster ID in the binding entry.
1802
- * @param type uint8_t The type of binding, either ::UNICAST_BINDING,
1803
- * ::MULTICAST_BINDING, or ::UNICAST_MANY_TO_ONE_BINDING.
1804
- * ::UNICAST_MANY_TO_ONE_BINDING is an Ember-specific extension
1805
- * and should be used only when the target is an Ember device.
1806
- * @param destination The destination EUI64 in the binding entry for the
1807
- * ::UNICAST_BINDING or ::UNICAST_MANY_TO_ONE_BINDING.
1808
- * @param groupAddress The group address for the ::MULTICAST_BINDING.
1809
- * @param destinationEndpoint uint8_t The destination endpoint in the binding entry for
1810
- * the ::UNICAST_BINDING or ::UNICAST_MANY_TO_ONE_BINDING.
1811
- * @param options The options to use when sending the request. See
1812
- * emberSendUnicast() for a description.
1813
- *
1814
- * @returns An ::EmberStatus value.
1815
- * - ::EMBER_SUCCESS
1816
- * - ::EMBER_NO_BUFFERS
1817
- * - ::EMBER_NETWORK_DOWN
1818
- * - ::EMBER_NETWORK_BUSY
1819
- * @returns APS frame created for the request
1820
- * @returns The tag used on the message.
1821
- */
1822
- async emberUnbindRequest(target, source, sourceEndpoint, clusterId, type, destination, groupAddress, destinationEndpoint, options) {
1823
- logger_1.logger.debug(`~~~> [ZDO UNBIND_REQUEST target=${target} source=${source} sourceEndpoint=${sourceEndpoint} clusterId=${clusterId} type=${type} `
1824
- + `destination=${destination} groupAddress=${groupAddress} destinationEndpoint=${destinationEndpoint}]`, NS);
1825
- return this.emberSendZigDevBindRequest(target, zdo_1.UNBIND_REQUEST, source, sourceEndpoint, clusterId, type, destination, groupAddress, destinationEndpoint, options);
1826
- }
1827
- /**
1828
- * ZDO
1829
- * Request the specified node to send a list of its active
1830
- * endpoints. An active endpoint is one for which a simple descriptor is
1831
- * available.
1832
- *
1833
- * @param target The node whose active endpoints are desired.
1834
- * @param options The options to use when sending the request. See
1835
- * emberSendUnicast() for a description.
1836
- *
1837
- * @return An EmberStatus value. ::EMBER_SUCCESS, ::EMBER_NO_BUFFERS,
1838
- * ::EMBER_NETWORK_DOWN or ::EMBER_NETWORK_BUSY.
1839
- */
1840
- async emberActiveEndpointsRequest(target, options) {
1841
- logger_1.logger.debug(`~~~> [ZDO ACTIVE_ENDPOINTS_REQUEST target=${target}]`, NS);
1842
- return this.emberSendZigDevRequestTarget(target, zdo_1.ACTIVE_ENDPOINTS_REQUEST, options);
1843
- }
1844
- /**
1845
- * ZDO
1846
- * Request the specified node to send its power descriptor.
1847
- * The power descriptor gives a dynamic indication of the power
1848
- * status of the node. It describes current power mode,
1849
- * available power sources, current power source and
1850
- * current power source level. It is defined in the ZigBee
1851
- * Application Framework Specification.
1852
- *
1853
- * @param target The node whose power descriptor is desired.
1854
- * @param options The options to use when sending the request. See
1855
- * emberSendUnicast() for a description.
1856
- *
1857
- * @return An EmberStatus value. ::EMBER_SUCCESS, ::EMBER_NO_BUFFERS,
1858
- * ::EMBER_NETWORK_DOWN or ::EMBER_NETWORK_BUSY.
1859
- */
1860
- async emberPowerDescriptorRequest(target, options) {
1861
- logger_1.logger.debug(`~~~> [ZDO POWER_DESCRIPTOR_REQUEST target=${target}]`, NS);
1862
- return this.emberSendZigDevRequestTarget(target, zdo_1.POWER_DESCRIPTOR_REQUEST, options);
1863
- }
1864
- /**
1865
- * ZDO
1866
- * Request the specified node to send its node descriptor.
1867
- * The node descriptor contains information about the capabilities of the ZigBee
1868
- * node. It describes logical type, APS flags, frequency band, MAC capabilities
1869
- * flags, manufacturer code and maximum buffer size. It is defined in the ZigBee
1870
- * Application Framework Specification.
1871
- *
1872
- * @param target The node whose node descriptor is desired.
1873
- * @param options The options to use when sending the request. See
1874
- * emberSendUnicast() for a description.
1875
- *
1876
- * @return An ::EmberStatus value. ::EMBER_SUCCESS, ::EMBER_NO_BUFFERS,
1877
- * ::EMBER_NETWORK_DOWN or ::EMBER_NETWORK_BUSY.
1878
- */
1879
- async emberNodeDescriptorRequest(target, options) {
1880
- logger_1.logger.debug(`~~~> [ZDO NODE_DESCRIPTOR_REQUEST target=${target}]`, NS);
1881
- return this.emberSendZigDevRequestTarget(target, zdo_1.NODE_DESCRIPTOR_REQUEST, options);
1882
- }
1883
- /**
1884
- * ZDO
1885
- * Request the specified node to send its LQI (neighbor) table.
1886
- * The response gives PAN ID, EUI64, node ID and cost for each neighbor. The
1887
- * EUI64 is only available if security is enabled. The other fields in the
1888
- * response are set to zero. The response format is defined in the ZigBee Device
1889
- * Profile Specification.
1890
- *
1891
- * @param target The node whose LQI table is desired.
1892
- * @param startIndex uint8_t The index of the first neighbor to include in the
1893
- * response.
1894
- * @param options The options to use when sending the request. See
1895
- * emberSendUnicast() for a description.
1896
- *
1897
- * @return An EmberStatus value. ::EMBER_SUCCESS, ::EMBER_NO_BUFFERS,
1898
- * ::EMBER_NETWORK_DOWN or ::EMBER_NETWORK_BUSY.
1899
- */
1900
- async emberLqiTableRequest(target, startIndex, options) {
1901
- logger_1.logger.debug(`~~~> [ZDO LQI_TABLE_REQUEST target=${target} startIndex=${startIndex}]`, NS);
1902
- return this.emberTableRequest(zdo_1.LQI_TABLE_REQUEST, target, startIndex, options);
1903
- }
1904
- /**
1905
- * ZDO
1906
- * Request the specified node to send its routing table.
1907
- * The response gives destination node ID, status and many-to-one flags,
1908
- * and the next hop node ID.
1909
- * The response format is defined in the ZigBee Device
1910
- * Profile Specification.
1911
- *
1912
- * @param target The node whose routing table is desired.
1913
- * @param startIndex uint8_t The index of the first route entry to include in the
1914
- * response.
1915
- * @param options The options to use when sending the request. See
1916
- * emberSendUnicast() for a description.
1917
- *
1918
- * @return An EmberStatus value. ::EMBER_SUCCESS, ::EMBER_NO_BUFFERS,
1919
- * ::EMBER_NETWORK_DOWN or ::EMBER_NETWORK_BUSY.
1920
- */
1921
- async emberRoutingTableRequest(target, startIndex, options) {
1922
- logger_1.logger.debug(`~~~> [ZDO ROUTING_TABLE_REQUEST target=${target} startIndex=${startIndex}]`, NS);
1923
- return this.emberTableRequest(zdo_1.ROUTING_TABLE_REQUEST, target, startIndex, options);
1924
- }
1925
- /**
1926
- * ZDO
1927
- * Request the specified node to send its nonvolatile bindings.
1928
- * The response gives source address, source endpoint, cluster ID, destination
1929
- * address and destination endpoint for each binding entry. The response format
1930
- * is defined in the ZigBee Device Profile Specification.
1931
- * Note that bindings that have the Ember-specific ::UNICAST_MANY_TO_ONE_BINDING
1932
- * type are reported as having the standard ::UNICAST_BINDING type.
1933
- *
1934
- * @param target The node whose binding table is desired.
1935
- * @param startIndex uint8_t The index of the first binding entry to include in the
1936
- * response.
1937
- * @param options The options to use when sending the request. See
1938
- * emberSendUnicast() for a description.
1939
- *
1940
- * @return An EmberStatus value. ::EMBER_SUCCESS, ::EMBER_NO_BUFFERS,
1941
- * ::EMBER_NETWORK_DOWN or ::EMBER_NETWORK_BUSY.
1942
- */
1943
- async emberBindingTableRequest(target, startIndex, options) {
1944
- logger_1.logger.debug(`~~~> [ZDO BINDING_TABLE_REQUEST target=${target} startIndex=${startIndex}]`, NS);
1945
- return this.emberTableRequest(zdo_1.BINDING_TABLE_REQUEST, target, startIndex, options);
1946
- }
1947
- /**
1948
- * ZDO
1949
- *
1950
- * @param clusterId uint16_t
1951
- * @param target
1952
- * @param startIndex uint8_t
1953
- * @param options
1954
- * @returns
1955
- */
1956
- async emberTableRequest(clusterId, target, startIndex, options) {
1957
- this.zdoRequestBuffalo.setPosition(zdo_1.ZDO_MESSAGE_OVERHEAD);
1958
- this.zdoRequestBuffalo.writeUInt8(startIndex);
1959
- return this.sendZDORequestBuffer(target, clusterId, options);
1960
- }
1961
- /**
1962
- * ZDO
1963
- * Request the specified node to remove the specified device from
1964
- * the network. The device to be removed must be the node to which the request
1965
- * is sent or one of its children.
1966
- *
1967
- * @param target The node which will remove the device.
1968
- * @param deviceAddress All zeros if the target is to remove itself from
1969
- * the network or the EUI64 of a child of the target device to remove
1970
- * that child.
1971
- * @param leaveRequestFlags uint8_t A bitmask of leave options.
1972
- * Include ::AND_REJOIN if the target is to rejoin the network immediately after leaving.
1973
- * @param options The options to use when sending the request. See
1974
- * emberSendUnicast() for a description.
1975
- *
1976
- * @return An EmberStatus value. ::EMBER_SUCCESS, ::EMBER_NO_BUFFERS,
1977
- * ::EMBER_NETWORK_DOWN or ::EMBER_NETWORK_BUSY.
1978
- */
1979
- async emberLeaveRequest(target, deviceAddress, leaveRequestFlags, options) {
1980
- this.zdoRequestBuffalo.setPosition(zdo_1.ZDO_MESSAGE_OVERHEAD);
1981
- this.zdoRequestBuffalo.writeIeeeAddr(deviceAddress);
1982
- this.zdoRequestBuffalo.writeUInt8(leaveRequestFlags);
1983
- logger_1.logger.debug(`~~~> [ZDO LEAVE_REQUEST target=${target} deviceAddress=${deviceAddress} leaveRequestFlags=${leaveRequestFlags}]`, NS);
1984
- return this.sendZDORequestBuffer(target, zdo_1.LEAVE_REQUEST, options);
1985
- }
1986
- /**
1987
- * ZDO
1988
- * Request the specified node to allow or disallow association.
1989
- *
1990
- * @param target The node which will allow or disallow association. The request
1991
- * can be broadcast by using a broadcast address (0xFFFC/0xFFFD/0xFFFF). No
1992
- * response is sent if the request is broadcast.
1993
- * @param duration uint8_t A value of 0x00 disables joining. A value of 0xFF enables
1994
- * joining. Any other value enables joining for that number of seconds.
1995
- * @param authentication uint8_t Controls Trust Center authentication behavior.
1996
- * @param options The options to use when sending the request. See
1997
- * emberSendUnicast() for a description. This parameter is ignored if the target
1998
- * is a broadcast address.
1999
- *
2000
- * @return An EmberStatus value. ::EMBER_SUCCESS, ::EMBER_NO_BUFFERS,
2001
- * ::EMBER_NETWORK_DOWN or ::EMBER_NETWORK_BUSY.
2002
- */
2003
- async emberPermitJoiningRequest(target, duration, authentication, options) {
2004
- this.zdoRequestBuffalo.setPosition(zdo_1.ZDO_MESSAGE_OVERHEAD);
2005
- this.zdoRequestBuffalo.writeUInt8(duration);
2006
- this.zdoRequestBuffalo.writeUInt8(authentication);
2007
- logger_1.logger.debug(`~~~> [ZDO PERMIT_JOINING_REQUEST target=${target} duration=${duration} authentication=${authentication}]`, NS);
2008
- return this.sendZDORequestBuffer(target, zdo_1.PERMIT_JOINING_REQUEST, options);
2009
- }
2010
- /**
2011
- * ZDO
2012
- *
2013
- * @see NWK_UPDATE_REQUEST
2014
- *
2015
- * @param target
2016
- * @param scanChannels uint8_t[]
2017
- * @param duration uint8_t
2018
- * @param count uint8_t
2019
- * @param manager
2020
- */
2021
- async emberNetworkUpdateRequest(target, scanChannels, duration, count, manager, options) {
2022
- this.zdoRequestBuffalo.setPosition(zdo_1.ZDO_MESSAGE_OVERHEAD);
2023
- this.zdoRequestBuffalo.writeUInt32(scanChannels.reduce((a, c) => a + (1 << c), 0)); // to uint32_t
2024
- this.zdoRequestBuffalo.writeUInt8(duration);
2025
- if (count != null) {
2026
- this.zdoRequestBuffalo.writeUInt8(count);
2027
- }
2028
- if (manager != null) {
2029
- this.zdoRequestBuffalo.writeUInt16(manager);
2030
- }
2031
- logger_1.logger.debug(`~~~> [ZDO NWK_UPDATE_REQUEST target=${target} scanChannels=${scanChannels} duration=${duration} count=${count} manager=${manager}]`, NS);
2032
- return this.sendZDORequestBuffer(target, zdo_1.NWK_UPDATE_REQUEST, options);
2033
- }
2034
- async emberScanChannelsRequest(target, scanChannels, duration, count, options) {
2035
- return this.emberNetworkUpdateRequest(target, scanChannels, duration, count, null, options);
2036
- }
2037
- async emberChannelChangeRequest(target, channel, options) {
2038
- return this.emberNetworkUpdateRequest(target, [channel], 0xFE, null, null, options);
2039
- }
2040
- async emberSetActiveChannelsAndNwkManagerIdRequest(target, scanChannels, manager, options) {
2041
- return this.emberNetworkUpdateRequest(target, scanChannels, 0xFF, null, manager, options);
2042
- }
2043
1399
  //---- END Ember ZDO
2044
1400
  //-- START Adapter implementation
2045
1401
  static async isValidPath(path) {
@@ -2093,7 +1449,7 @@ class EmberAdapter extends __1.Adapter {
2093
1449
  };
2094
1450
  }),
2095
1451
  });
2096
- return enums_3.EmberStatus.SUCCESS;
1452
+ return enums_2.SLStatus.OK;
2097
1453
  }, reject);
2098
1454
  });
2099
1455
  }
@@ -2118,43 +1474,34 @@ class EmberAdapter extends __1.Adapter {
2118
1474
  this.requestQueue.enqueue(async () => {
2119
1475
  // grab fresh version here, bypass cache
2120
1476
  const [netStatus, , netParams] = (await this.ezsp.ezspGetNetworkParameters());
2121
- if (netStatus !== enums_3.EmberStatus.SUCCESS) {
2122
- logger_1.logger.error(`[BACKUP] Failed to get network parameters.`, NS);
1477
+ if (netStatus !== enums_2.SLStatus.OK) {
1478
+ logger_1.logger.error(`[BACKUP] Failed to get network parameters with status=${enums_2.SLStatus[netStatus]}.`, NS);
2123
1479
  return netStatus;
2124
1480
  }
2125
1481
  // update cache
2126
1482
  this.networkCache.parameters = netParams;
2127
1483
  this.networkCache.eui64 = (await this.ezsp.ezspGetEui64());
2128
1484
  const [netKeyStatus, netKeyInfo] = (await this.ezsp.ezspGetNetworkKeyInfo());
2129
- if (netKeyStatus !== enums_3.SLStatus.OK) {
2130
- logger_1.logger.error(`[BACKUP] Failed to get network keys info.`, NS);
2131
- return ((netKeyStatus === enums_3.SLStatus.BUSY) || (netKeyStatus === enums_3.SLStatus.NOT_READY))
2132
- ? enums_3.EmberStatus.NETWORK_BUSY : enums_3.EmberStatus.ERR_FATAL; // allow retry on statuses that should be temporary
1485
+ if (netKeyStatus !== enums_2.SLStatus.OK) {
1486
+ logger_1.logger.error(`[BACKUP] Failed to get network keys info with status=${enums_2.SLStatus[netKeyStatus]}.`, NS);
1487
+ return netKeyStatus;
2133
1488
  }
2134
1489
  if (!netKeyInfo.networkKeySet) {
2135
1490
  throw new Error(`[BACKUP] No network key set.`);
2136
1491
  }
2137
- let keyList = [];
2138
- if (this.stackConfig.KEY_TABLE_SIZE > 0) {
2139
- keyList = (await this.exportLinkKeys());
2140
- }
2141
- // XXX: this only makes sense on stop (if that), not hourly/on start, plus network needs to be at near-standstill @see AN1387
2142
- // const tokensBuf = (await EmberTokensManager.saveTokens(
2143
- // this.ezsp,
2144
- // Buffer.from(this.networkCache.eui64.substring(2/*0x*/), 'hex').reverse()
2145
- // ));
1492
+ const keyList = ALLOW_APP_KEY_REQUESTS ? await this.exportLinkKeys() : [];
2146
1493
  let context = (0, initters_1.initSecurityManagerContext)();
2147
- context.coreKeyType = enums_3.SecManKeyType.TC_LINK;
2148
- const [tcLinkKey, tclkStatus] = (await this.ezsp.ezspExportKey(context));
2149
- if (tclkStatus !== enums_3.SLStatus.OK) {
2150
- throw new Error(`[BACKUP] Failed to export TC Link Key with status=${enums_3.SLStatus[tclkStatus]}.`);
1494
+ context.coreKeyType = enums_2.SecManKeyType.TC_LINK;
1495
+ const [tclkStatus, tcLinkKey] = (await this.ezsp.ezspExportKey(context));
1496
+ if (tclkStatus !== enums_2.SLStatus.OK) {
1497
+ throw new Error(`[BACKUP] Failed to export TC Link Key with status=${enums_2.SLStatus[tclkStatus]}.`);
2151
1498
  }
2152
1499
  context = (0, initters_1.initSecurityManagerContext)(); // make sure it's back to zeroes
2153
- context.coreKeyType = enums_3.SecManKeyType.NETWORK;
1500
+ context.coreKeyType = enums_2.SecManKeyType.NETWORK;
2154
1501
  context.keyIndex = 0;
2155
- const [networkKey, nkStatus] = (await this.ezsp.ezspExportKey(context));
2156
- if (nkStatus !== enums_3.SLStatus.OK) {
2157
- throw new Error(`[BACKUP] Failed to export Network Key with status=${enums_3.SLStatus[nkStatus]}.`);
1502
+ const [nkStatus, networkKey] = (await this.ezsp.ezspExportKey(context));
1503
+ if (nkStatus !== enums_2.SLStatus.OK) {
1504
+ throw new Error(`[BACKUP] Failed to export Network Key with status=${enums_2.SLStatus[nkStatus]}.`);
2158
1505
  }
2159
1506
  const zbChannels = Array.from(Array(consts_2.EMBER_NUM_802_15_4_CHANNELS), (e, i) => i + consts_2.EMBER_MIN_802_15_4_CHANNEL_NUMBER);
2160
1507
  resolve({
@@ -2190,7 +1537,7 @@ class EmberAdapter extends __1.Adapter {
2190
1537
  // altNetworkKey: altNetworkKey.contents,
2191
1538
  }
2192
1539
  });
2193
- return enums_3.EmberStatus.SUCCESS;
1540
+ return enums_2.SLStatus.OK;
2194
1541
  }, reject, true);
2195
1542
  });
2196
1543
  }
@@ -2209,7 +1556,7 @@ class EmberAdapter extends __1.Adapter {
2209
1556
  extendedPanID: parseInt(Buffer.from(extendedPanID).toString('hex'), 16),
2210
1557
  channel,
2211
1558
  });
2212
- return enums_3.EmberStatus.SUCCESS;
1559
+ return enums_2.SLStatus.OK;
2213
1560
  }, reject);
2214
1561
  });
2215
1562
  }
@@ -2221,16 +1568,39 @@ class EmberAdapter extends __1.Adapter {
2221
1568
  return new Promise((resolve, reject) => {
2222
1569
  this.requestQueue.enqueue(async () => {
2223
1570
  this.checkInterpanLock();
1571
+ const zdoPayload = buffaloZdo_1.BuffaloZdo.buildChannelChangeRequest(newChannel, null);
2224
1572
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2225
- const [status, apsFrame, messageTag] = (await this.emberChannelChangeRequest(enums_1.BroadcastAddress.SLEEPY, newChannel, DEFAULT_APS_OPTIONS));
2226
- if (status !== enums_3.EmberStatus.SUCCESS) {
2227
- logger_1.logger.error(`[ZDO] Failed broadcast channel change to "${newChannel}" with status=${enums_3.EmberStatus[status]}.`, NS);
1573
+ const [status, apsFrame, messageTag] = await this.sendZDORequest(ZSpec.BroadcastAddress.SLEEPY, Zdo.ClusterId.NWK_UPDATE_REQUEST, zdoPayload, DEFAULT_APS_OPTIONS);
1574
+ if (status !== enums_2.SLStatus.OK) {
1575
+ logger_1.logger.error(`[ZDO] Failed broadcast channel change to "${newChannel}" with status=${enums_2.SLStatus[status]}.`, NS);
2228
1576
  return status;
2229
1577
  }
2230
1578
  await this.oneWaitress.startWaitingForEvent({ eventName: oneWaitress_1.OneWaitressEvents.STACK_STATUS_CHANNEL_CHANGED }, DEFAULT_NETWORK_REQUEST_TIMEOUT * 2, // observed to ~9sec
2231
1579
  '[ZDO] Change Channel');
2232
1580
  resolve();
2233
- return enums_3.EmberStatus.SUCCESS;
1581
+ return enums_2.SLStatus.OK;
1582
+ }, reject);
1583
+ });
1584
+ }
1585
+ // queued
1586
+ async scanChannels(networkAddress, channels, duration, count) {
1587
+ return new Promise((resolve, reject) => {
1588
+ this.requestQueue.enqueue(async () => {
1589
+ this.checkInterpanLock();
1590
+ const zdoPayload = buffaloZdo_1.BuffaloZdo.buildScanChannelsRequest(channels, duration, count);
1591
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1592
+ const [status, apsFrame, messageTag] = await this.sendZDORequest(networkAddress, Zdo.ClusterId.NWK_UPDATE_REQUEST, zdoPayload, DEFAULT_APS_OPTIONS);
1593
+ if (status !== enums_2.SLStatus.OK) {
1594
+ logger_1.logger.error(`[ZDO] Failed to scan channels '${channels}' on '${networkAddress} with status=${enums_2.SLStatus[status]}.`, NS);
1595
+ return status;
1596
+ }
1597
+ const result = await this.oneWaitress.startWaitingFor({
1598
+ target: networkAddress,
1599
+ apsFrame,
1600
+ responseClusterId: Zdo.ClusterId.NWK_UPDATE_RESPONSE,
1601
+ }, DEFAULT_ZDO_REQUEST_TIMEOUT + (((((2 ** duration) + 1) * (16 * 960)) / 1000) * count * channels.length)); // time for scan
1602
+ resolve(result);
1603
+ return enums_2.SLStatus.OK;
2234
1604
  }, reject);
2235
1605
  });
2236
1606
  }
@@ -2243,12 +1613,12 @@ class EmberAdapter extends __1.Adapter {
2243
1613
  return new Promise((resolve, reject) => {
2244
1614
  this.requestQueue.enqueue(async () => {
2245
1615
  const status = await this.ezsp.ezspSetRadioPower(value);
2246
- if (status !== enums_3.EmberStatus.SUCCESS) {
2247
- logger_1.logger.error(`Failed to set transmit power to ${value} status=${enums_3.EmberStatus[status]}.`, NS);
1616
+ if (status !== enums_2.SLStatus.OK) {
1617
+ logger_1.logger.error(`Failed to set transmit power to ${value} status=${enums_2.SLStatus[status]}.`, NS);
2248
1618
  return status;
2249
1619
  }
2250
1620
  resolve();
2251
- return enums_3.EmberStatus.SUCCESS;
1621
+ return enums_2.SLStatus.OK;
2252
1622
  }, reject);
2253
1623
  });
2254
1624
  }
@@ -2282,22 +1652,22 @@ class EmberAdapter extends __1.Adapter {
2282
1652
  this.requestQueue.enqueue(async () => {
2283
1653
  // Compute the key from the install code and CRC.
2284
1654
  const [aesStatus, keyContents] = (await this.emberAesHashSimple(key));
2285
- if (aesStatus !== enums_3.EmberStatus.SUCCESS) {
2286
- logger_1.logger.error(`[ADD INSTALL CODE] Failed AES hash for '${ieeeAddress}' with status=${enums_3.EmberStatus[aesStatus]}.`, NS);
1655
+ if (aesStatus !== enums_2.SLStatus.OK) {
1656
+ logger_1.logger.error(`[ADD INSTALL CODE] Failed AES hash for '${ieeeAddress}' with status=${enums_2.SLStatus[aesStatus]}.`, NS);
2287
1657
  return aesStatus;
2288
1658
  }
2289
1659
  // Add the key to the transient key table.
2290
1660
  // This will be used while the DUT joins.
2291
- const impStatus = (await this.ezsp.ezspImportTransientKey(ieeeAddress, { contents: keyContents }, enums_3.SecManFlag.NONE));
2292
- if (impStatus == enums_3.SLStatus.OK) {
1661
+ const impStatus = (await this.ezsp.ezspImportTransientKey(ieeeAddress, { contents: keyContents }));
1662
+ if (impStatus == enums_2.SLStatus.OK) {
2293
1663
  logger_1.logger.debug(`[ADD INSTALL CODE] Success for '${ieeeAddress}'.`, NS);
2294
1664
  }
2295
1665
  else {
2296
- logger_1.logger.error(`[ADD INSTALL CODE] Failed for '${ieeeAddress}' with status=${enums_3.SLStatus[impStatus]}.`, NS);
2297
- return enums_3.EmberStatus.ERR_FATAL;
1666
+ logger_1.logger.error(`[ADD INSTALL CODE] Failed for '${ieeeAddress}' with status=${enums_2.SLStatus[impStatus]}.`, NS);
1667
+ return enums_2.SLStatus.FAIL;
2298
1668
  }
2299
1669
  resolve();
2300
- return enums_3.EmberStatus.SUCCESS;
1670
+ return enums_2.SLStatus.OK;
2301
1671
  }, reject);
2302
1672
  });
2303
1673
  }
@@ -2313,7 +1683,7 @@ class EmberAdapter extends __1.Adapter {
2313
1683
  sourceEndpoint: sourceEndpointInfo.endpoint,
2314
1684
  destinationEndpoint: endpoint,
2315
1685
  groupId: 0,
2316
- options: enums_3.EmberApsOption.NONE,
1686
+ options: enums_2.EmberApsOption.NONE,
2317
1687
  },
2318
1688
  zclSequence: transactionSequenceNumber,
2319
1689
  commandIdentifier,
@@ -2329,17 +1699,17 @@ class EmberAdapter extends __1.Adapter {
2329
1699
  const preJoining = async () => {
2330
1700
  if (seconds) {
2331
1701
  const plaintextKey = { contents: Buffer.from(consts_2.ZIGBEE_PROFILE_INTEROPERABILITY_LINK_KEY) };
2332
- const impKeyStatus = (await this.ezsp.ezspImportTransientKey(ZSpec.BLANK_EUI64, plaintextKey, enums_3.SecManFlag.NONE));
2333
- if (impKeyStatus !== enums_3.SLStatus.OK) {
2334
- logger_1.logger.error(`[ZDO] Failed import transient key with status=${enums_3.SLStatus[impKeyStatus]}.`, NS);
2335
- return enums_3.EmberStatus.ERR_FATAL;
1702
+ const impKeyStatus = (await this.ezsp.ezspImportTransientKey(ZSpec.BLANK_EUI64, plaintextKey));
1703
+ if (impKeyStatus !== enums_2.SLStatus.OK) {
1704
+ logger_1.logger.error(`[ZDO] Failed import transient key with status=${enums_2.SLStatus[impKeyStatus]}.`, NS);
1705
+ return enums_2.SLStatus.FAIL;
2336
1706
  }
2337
- const setJPstatus = (await this.emberSetJoinPolicy(enums_3.EmberJoinDecision.USE_PRECONFIGURED_KEY));
2338
- if (setJPstatus !== enums_3.EzspStatus.SUCCESS) {
2339
- logger_1.logger.error(`[ZDO] Failed set join policy with status=${enums_3.EzspStatus[setJPstatus]}.`, NS);
2340
- return enums_3.EmberStatus.ERR_FATAL;
1707
+ const setJPstatus = (await this.emberSetJoinPolicy(enums_2.EmberJoinDecision.USE_PRECONFIGURED_KEY));
1708
+ if (setJPstatus !== enums_2.SLStatus.OK) {
1709
+ logger_1.logger.error(`[ZDO] Failed set join policy with status=${enums_2.SLStatus[setJPstatus]}.`, NS);
1710
+ return enums_2.SLStatus.FAIL;
2341
1711
  }
2342
- return enums_3.EmberStatus.SUCCESS;
1712
+ return enums_2.SLStatus.OK;
2343
1713
  }
2344
1714
  else {
2345
1715
  if (this.manufacturerCode !== DEFAULT_MANUFACTURER_CODE) {
@@ -2348,12 +1718,12 @@ class EmberAdapter extends __1.Adapter {
2348
1718
  this.manufacturerCode = DEFAULT_MANUFACTURER_CODE;
2349
1719
  }
2350
1720
  await this.ezsp.ezspClearTransientLinkKeys();
2351
- const setJPstatus = (await this.emberSetJoinPolicy(enums_3.EmberJoinDecision.ALLOW_REJOINS_ONLY));
2352
- if (setJPstatus !== enums_3.EzspStatus.SUCCESS) {
2353
- logger_1.logger.error(`[ZDO] Failed set join policy for with status=${enums_3.EzspStatus[setJPstatus]}.`, NS);
2354
- return enums_3.EmberStatus.ERR_FATAL;
1721
+ const setJPstatus = (await this.emberSetJoinPolicy(enums_2.EmberJoinDecision.ALLOW_REJOINS_ONLY));
1722
+ if (setJPstatus !== enums_2.SLStatus.OK) {
1723
+ logger_1.logger.error(`[ZDO] Failed set join policy for with status=${enums_2.SLStatus[setJPstatus]}.`, NS);
1724
+ return enums_2.SLStatus.FAIL;
2355
1725
  }
2356
- return enums_3.EmberStatus.SUCCESS;
1726
+ return enums_2.SLStatus.OK;
2357
1727
  }
2358
1728
  };
2359
1729
  if (networkAddress) {
@@ -2362,24 +1732,25 @@ class EmberAdapter extends __1.Adapter {
2362
1732
  this.requestQueue.enqueue(async () => {
2363
1733
  this.checkInterpanLock();
2364
1734
  const pjStatus = (await preJoining());
2365
- if (pjStatus !== enums_3.EmberStatus.SUCCESS) {
2366
- logger_1.logger.error(`[ZDO] Failed pre joining request for "${networkAddress}" with status=${enums_3.EmberStatus[pjStatus]}.`, NS);
1735
+ if (pjStatus !== enums_2.SLStatus.OK) {
1736
+ logger_1.logger.error(`[ZDO] Failed pre joining request for "${networkAddress}" with status=${enums_2.SLStatus[pjStatus]}.`, NS);
2367
1737
  return pjStatus;
2368
1738
  }
2369
1739
  // `authentication`: TC significance always 1 (zb specs)
1740
+ const zdoPayload = buffaloZdo_1.BuffaloZdo.buildPermitJoining(seconds, 1, []);
2370
1741
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2371
- const [status, apsFrame, messageTag] = (await this.emberPermitJoiningRequest(networkAddress, seconds, 1, 0));
2372
- if (status !== enums_3.EmberStatus.SUCCESS) {
2373
- logger_1.logger.error(`[ZDO] Failed permit joining request for "${networkAddress}" with status=${enums_3.EmberStatus[status]}.`, NS);
1742
+ const [status, apsFrame, messageTag] = await this.sendZDORequest(networkAddress, Zdo.ClusterId.PERMIT_JOINING_REQUEST, zdoPayload, DEFAULT_APS_OPTIONS);
1743
+ if (status !== enums_2.SLStatus.OK) {
1744
+ logger_1.logger.error(`[ZDO] Failed permit joining request for "${networkAddress}" with status=${enums_2.SLStatus[status]}.`, NS);
2374
1745
  return status;
2375
1746
  }
2376
1747
  (await this.oneWaitress.startWaitingFor({
2377
1748
  target: networkAddress,
2378
1749
  apsFrame,
2379
- responseClusterId: zdo_1.PERMIT_JOINING_RESPONSE,
1750
+ responseClusterId: Zdo.ClusterId.PERMIT_JOINING_RESPONSE,
2380
1751
  }, DEFAULT_ZDO_REQUEST_TIMEOUT));
2381
1752
  resolve();
2382
- return enums_3.EmberStatus.SUCCESS;
1753
+ return enums_2.SLStatus.OK;
2383
1754
  }, reject);
2384
1755
  });
2385
1756
  }
@@ -2389,15 +1760,15 @@ class EmberAdapter extends __1.Adapter {
2389
1760
  this.requestQueue.enqueue(async () => {
2390
1761
  this.checkInterpanLock();
2391
1762
  const pjStatus = (await preJoining());
2392
- if (pjStatus !== enums_3.EmberStatus.SUCCESS) {
2393
- logger_1.logger.error(`[ZDO] Failed pre joining request for "${networkAddress}" with status=${enums_3.EmberStatus[pjStatus]}.`, NS);
1763
+ if (pjStatus !== enums_2.SLStatus.OK) {
1764
+ logger_1.logger.error(`[ZDO] Failed pre joining request for "${networkAddress}" with status=${enums_2.SLStatus[pjStatus]}.`, NS);
2394
1765
  return pjStatus;
2395
1766
  }
2396
1767
  // local permit join if `Coordinator`-only requested, else local + broadcast
2397
1768
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2398
1769
  const [status, apsFrame, messageTag] = (await this.emberPermitJoining(seconds, (networkAddress === ZSpec.COORDINATOR_ADDRESS) ? false : true));
2399
- if (status !== enums_3.EmberStatus.SUCCESS) {
2400
- logger_1.logger.error(`[ZDO] Failed permit joining request with status=${enums_3.EmberStatus[status]}.`, NS);
1770
+ if (status !== enums_2.SLStatus.OK) {
1771
+ logger_1.logger.error(`[ZDO] Failed permit joining request with status=${enums_2.SLStatus[status]}.`, NS);
2401
1772
  return status;
2402
1773
  }
2403
1774
  // NOTE: because Z2M is refreshing the permit join duration early to prevent it from closing
@@ -2418,7 +1789,7 @@ class EmberAdapter extends __1.Adapter {
2418
1789
  // // same kind of problem as described above (upstream always tries to close after start, but EZSP already is)
2419
1790
  // }
2420
1791
  resolve();
2421
- return enums_3.EmberStatus.SUCCESS;
1792
+ return enums_2.SLStatus.OK;
2422
1793
  }, reject);
2423
1794
  });
2424
1795
  }
@@ -2427,40 +1798,41 @@ class EmberAdapter extends __1.Adapter {
2427
1798
  async lqi(networkAddress) {
2428
1799
  const neighbors = [];
2429
1800
  const request = async (startIndex) => {
1801
+ const zdoPayload = buffaloZdo_1.BuffaloZdo.buildLqiTableRequest(startIndex);
2430
1802
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2431
- const [reqStatus, apsFrame, messageTag] = (await this.emberLqiTableRequest(networkAddress, startIndex, DEFAULT_APS_OPTIONS));
2432
- if (reqStatus !== enums_3.EmberStatus.SUCCESS) {
2433
- logger_1.logger.error(`[ZDO] Failed LQI request for "${networkAddress}" (index "${startIndex}") with status=${enums_3.EmberStatus[reqStatus]}.`, NS);
2434
- return [reqStatus, null, null];
1803
+ const [status, apsFrame, messageTag] = await this.sendZDORequest(networkAddress, Zdo.ClusterId.LQI_TABLE_REQUEST, zdoPayload, DEFAULT_APS_OPTIONS);
1804
+ if (status !== enums_2.SLStatus.OK) {
1805
+ logger_1.logger.error(`[ZDO] Failed LQI request for "${networkAddress}" (index "${startIndex}") with status=${enums_2.SLStatus[status]}.`, NS);
1806
+ return [status, null, null];
2435
1807
  }
2436
1808
  const result = (await this.oneWaitress.startWaitingFor({
2437
1809
  target: networkAddress,
2438
1810
  apsFrame,
2439
- responseClusterId: zdo_1.LQI_TABLE_RESPONSE,
1811
+ responseClusterId: Zdo.ClusterId.LQI_TABLE_RESPONSE,
2440
1812
  }, DEFAULT_ZDO_REQUEST_TIMEOUT));
2441
1813
  for (const entry of result.entryList) {
2442
1814
  neighbors.push({
2443
1815
  ieeeAddr: entry.eui64,
2444
- networkAddress: entry.nodeId,
1816
+ networkAddress: entry.nwkAddress,
2445
1817
  linkquality: entry.lqi,
2446
1818
  relationship: entry.relationship,
2447
1819
  depth: entry.depth,
2448
1820
  });
2449
1821
  }
2450
- return [enums_3.EmberStatus.SUCCESS, result.neighborTableEntries, result.entryList.length];
1822
+ return [enums_2.SLStatus.OK, result.neighborTableEntries, result.entryList.length];
2451
1823
  };
2452
1824
  return new Promise((resolve, reject) => {
2453
1825
  this.requestQueue.enqueue(async () => {
2454
1826
  this.checkInterpanLock();
2455
1827
  let [status, tableEntries, entryCount] = (await request(0));
2456
- if (status !== enums_3.EmberStatus.SUCCESS) {
1828
+ if (status !== enums_2.SLStatus.OK) {
2457
1829
  return status;
2458
1830
  }
2459
1831
  const size = tableEntries;
2460
1832
  let nextStartIndex = entryCount;
2461
1833
  while (neighbors.length < size) {
2462
1834
  [status, tableEntries, entryCount] = (await request(nextStartIndex));
2463
- if (status !== enums_3.EmberStatus.SUCCESS) {
1835
+ if (status !== enums_2.SLStatus.OK) {
2464
1836
  return status;
2465
1837
  }
2466
1838
  nextStartIndex += entryCount;
@@ -2474,16 +1846,17 @@ class EmberAdapter extends __1.Adapter {
2474
1846
  async routingTable(networkAddress) {
2475
1847
  const table = [];
2476
1848
  const request = async (startIndex) => {
1849
+ const zdoPayload = buffaloZdo_1.BuffaloZdo.buildRoutingTableRequest(startIndex);
2477
1850
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2478
- const [reqStatus, apsFrame, messageTag] = (await this.emberRoutingTableRequest(networkAddress, startIndex, DEFAULT_APS_OPTIONS));
2479
- if (reqStatus !== enums_3.EmberStatus.SUCCESS) {
2480
- logger_1.logger.error(`[ZDO] Failed routing table request for "${networkAddress}" (index "${startIndex}") with status=${enums_3.EmberStatus[reqStatus]}.`, NS);
2481
- return [reqStatus, null, null];
1851
+ const [status, apsFrame, messageTag] = await this.sendZDORequest(networkAddress, Zdo.ClusterId.ROUTING_TABLE_REQUEST, zdoPayload, DEFAULT_APS_OPTIONS);
1852
+ if (status !== enums_2.SLStatus.OK) {
1853
+ logger_1.logger.error(`[ZDO] Failed routing table request for "${networkAddress}" (index "${startIndex}") with status=${enums_2.SLStatus[status]}.`, NS);
1854
+ return [status, null, null];
2482
1855
  }
2483
1856
  const result = (await this.oneWaitress.startWaitingFor({
2484
1857
  target: networkAddress,
2485
1858
  apsFrame,
2486
- responseClusterId: zdo_1.ROUTING_TABLE_RESPONSE,
1859
+ responseClusterId: Zdo.ClusterId.ROUTING_TABLE_RESPONSE,
2487
1860
  }, DEFAULT_ZDO_REQUEST_TIMEOUT));
2488
1861
  for (const entry of result.entryList) {
2489
1862
  table.push({
@@ -2492,26 +1865,26 @@ class EmberAdapter extends __1.Adapter {
2492
1865
  nextHop: entry.nextHopAddress,
2493
1866
  });
2494
1867
  }
2495
- return [enums_3.EmberStatus.SUCCESS, result.routingTableEntries, result.entryList.length];
1868
+ return [enums_2.SLStatus.OK, result.routingTableEntries, result.entryList.length];
2496
1869
  };
2497
1870
  return new Promise((resolve, reject) => {
2498
1871
  this.requestQueue.enqueue(async () => {
2499
1872
  this.checkInterpanLock();
2500
1873
  let [status, tableEntries, entryCount] = (await request(0));
2501
- if (status !== enums_3.EmberStatus.SUCCESS) {
1874
+ if (status !== enums_2.SLStatus.OK) {
2502
1875
  return status;
2503
1876
  }
2504
1877
  const size = tableEntries;
2505
1878
  let nextStartIndex = entryCount;
2506
1879
  while (table.length < size) {
2507
1880
  [status, tableEntries, entryCount] = (await request(nextStartIndex));
2508
- if (status !== enums_3.EmberStatus.SUCCESS) {
1881
+ if (status !== enums_2.SLStatus.OK) {
2509
1882
  return status;
2510
1883
  }
2511
1884
  nextStartIndex += entryCount;
2512
1885
  }
2513
1886
  resolve({ table });
2514
- return enums_3.EmberStatus.SUCCESS;
1887
+ return enums_2.SLStatus.OK;
2515
1888
  }, reject);
2516
1889
  });
2517
1890
  }
@@ -2520,16 +1893,17 @@ class EmberAdapter extends __1.Adapter {
2520
1893
  return new Promise((resolve, reject) => {
2521
1894
  this.requestQueue.enqueue(async () => {
2522
1895
  this.checkInterpanLock();
2523
- /* eslint-disable @typescript-eslint/no-unused-vars */
2524
- const [status, apsFrame, messageTag] = (await this.emberNodeDescriptorRequest(networkAddress, DEFAULT_APS_OPTIONS));
2525
- if (status !== enums_3.EmberStatus.SUCCESS) {
2526
- logger_1.logger.error(`[ZDO] Failed node descriptor for "${networkAddress}" with status=${enums_3.EmberStatus[status]}.`, NS);
1896
+ const zdoPayload = buffaloZdo_1.BuffaloZdo.buildNodeDescriptorRequest(networkAddress);
1897
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1898
+ const [status, apsFrame, messageTag] = await this.sendZDORequest(networkAddress, Zdo.ClusterId.NODE_DESCRIPTOR_REQUEST, zdoPayload, DEFAULT_APS_OPTIONS);
1899
+ if (status !== enums_2.SLStatus.OK) {
1900
+ logger_1.logger.error(`[ZDO] Failed node descriptor for "${networkAddress}" with status=${enums_2.SLStatus[status]}.`, NS);
2527
1901
  return status;
2528
1902
  }
2529
1903
  const result = (await this.oneWaitress.startWaitingFor({
2530
1904
  target: networkAddress,
2531
1905
  apsFrame,
2532
- responseClusterId: zdo_1.NODE_DESCRIPTOR_RESPONSE,
1906
+ responseClusterId: Zdo.ClusterId.NODE_DESCRIPTOR_RESPONSE,
2533
1907
  }, DEFAULT_ZDO_REQUEST_TIMEOUT));
2534
1908
  let type = 'Unknown';
2535
1909
  switch (result.logicalType) {
@@ -2544,13 +1918,13 @@ class EmberAdapter extends __1.Adapter {
2544
1918
  break;
2545
1919
  }
2546
1920
  // always 0 before rev. 21 where field was added
2547
- if (result.stackRevision < CURRENT_ZIGBEE_SPEC_REVISION) {
2548
- logger_1.logger.warning(`[ZDO] Node descriptor for "${networkAddress}" reports device is only compliant to revision `
2549
- + `"${(result.stackRevision < 21) ? 'pre-21' : result.stackRevision}" of the ZigBee specification `
2550
- + `(current revision: ${CURRENT_ZIGBEE_SPEC_REVISION}).`, NS);
1921
+ if (result.serverMask.stackComplianceResivion < CURRENT_ZIGBEE_SPEC_REVISION) {
1922
+ logger_1.logger.warning(`[ZDO] Node descriptor for '${networkAddress}' reports device is only compliant to revision `
1923
+ + `'${(result.serverMask.stackComplianceResivion < 21) ? 'pre-21' : result.serverMask.stackComplianceResivion}' `
1924
+ + `of the ZigBee specification (current revision: ${CURRENT_ZIGBEE_SPEC_REVISION}).`, NS);
2551
1925
  }
2552
1926
  resolve({ type, manufacturerCode: result.manufacturerCode });
2553
- return enums_3.EmberStatus.SUCCESS;
1927
+ return enums_2.SLStatus.OK;
2554
1928
  }, reject);
2555
1929
  });
2556
1930
  }
@@ -2559,19 +1933,20 @@ class EmberAdapter extends __1.Adapter {
2559
1933
  return new Promise((resolve, reject) => {
2560
1934
  this.requestQueue.enqueue(async () => {
2561
1935
  this.checkInterpanLock();
1936
+ const zdoPayload = buffaloZdo_1.BuffaloZdo.buildActiveEndpointsRequest(networkAddress);
2562
1937
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2563
- const [status, apsFrame, messageTag] = (await this.emberActiveEndpointsRequest(networkAddress, DEFAULT_APS_OPTIONS));
2564
- if (status !== enums_3.EmberStatus.SUCCESS) {
2565
- logger_1.logger.error(`[ZDO] Failed active endpoints request for "${networkAddress}" with status=${enums_3.EmberStatus[status]}.`, NS);
1938
+ const [status, apsFrame, messageTag] = await this.sendZDORequest(networkAddress, Zdo.ClusterId.ACTIVE_ENDPOINTS_REQUEST, zdoPayload, DEFAULT_APS_OPTIONS);
1939
+ if (status !== enums_2.SLStatus.OK) {
1940
+ logger_1.logger.error(`[ZDO] Failed active endpoints request for "${networkAddress}" with status=${enums_2.SLStatus[status]}.`, NS);
2566
1941
  return status;
2567
1942
  }
2568
1943
  const result = (await this.oneWaitress.startWaitingFor({
2569
1944
  target: networkAddress,
2570
1945
  apsFrame,
2571
- responseClusterId: zdo_1.ACTIVE_ENDPOINTS_RESPONSE,
1946
+ responseClusterId: Zdo.ClusterId.ACTIVE_ENDPOINTS_RESPONSE,
2572
1947
  }, DEFAULT_ZDO_REQUEST_TIMEOUT));
2573
1948
  resolve({ endpoints: result.endpointList });
2574
- return enums_3.EmberStatus.SUCCESS;
1949
+ return enums_2.SLStatus.OK;
2575
1950
  }, reject);
2576
1951
  });
2577
1952
  }
@@ -2580,17 +1955,18 @@ class EmberAdapter extends __1.Adapter {
2580
1955
  return new Promise((resolve, reject) => {
2581
1956
  this.requestQueue.enqueue(async () => {
2582
1957
  this.checkInterpanLock();
1958
+ const zdoPayload = buffaloZdo_1.BuffaloZdo.buildSimpleDescriptorRequest(networkAddress, endpointID);
2583
1959
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2584
- const [status, apsFrame, messageTag] = (await this.emberSimpleDescriptorRequest(networkAddress, endpointID, DEFAULT_APS_OPTIONS));
2585
- if (status !== enums_3.EmberStatus.SUCCESS) {
1960
+ const [status, apsFrame, messageTag] = await this.sendZDORequest(networkAddress, Zdo.ClusterId.SIMPLE_DESCRIPTOR_REQUEST, zdoPayload, DEFAULT_APS_OPTIONS);
1961
+ if (status !== enums_2.SLStatus.OK) {
2586
1962
  logger_1.logger.error(`[ZDO] Failed simple descriptor request for "${networkAddress}" endpoint "${endpointID}" `
2587
- + `with status=${enums_3.EmberStatus[status]}.`, NS);
1963
+ + `with status=${enums_2.SLStatus[status]}.`, NS);
2588
1964
  return status;
2589
1965
  }
2590
1966
  const result = (await this.oneWaitress.startWaitingFor({
2591
1967
  target: networkAddress,
2592
1968
  apsFrame,
2593
- responseClusterId: zdo_1.SIMPLE_DESCRIPTOR_RESPONSE,
1969
+ responseClusterId: Zdo.ClusterId.SIMPLE_DESCRIPTOR_RESPONSE,
2594
1970
  }, DEFAULT_ZDO_REQUEST_TIMEOUT));
2595
1971
  resolve({
2596
1972
  profileID: result.profileId,
@@ -2599,7 +1975,7 @@ class EmberAdapter extends __1.Adapter {
2599
1975
  inputClusters: result.inClusterList,
2600
1976
  outputClusters: result.outClusterList,
2601
1977
  });
2602
- return enums_3.EmberStatus.SUCCESS;
1978
+ return enums_2.SLStatus.OK;
2603
1979
  }, reject);
2604
1980
  });
2605
1981
  }
@@ -2610,21 +1986,22 @@ class EmberAdapter extends __1.Adapter {
2610
1986
  return new Promise((resolve, reject) => {
2611
1987
  this.requestQueue.enqueue(async () => {
2612
1988
  this.checkInterpanLock();
1989
+ const zdoPayload = buffaloZdo_1.BuffaloZdo.buildBindRequest(sourceIeeeAddress, sourceEndpoint, clusterID, Zdo.UNICAST_BINDING, destinationAddressOrGroup, undefined, // not used with UNICAST_BINDING
1990
+ destinationEndpoint);
2613
1991
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2614
- const [status, apsFrame, messageTag] = (await this.emberBindRequest(destinationNetworkAddress, sourceIeeeAddress, sourceEndpoint, clusterID, zdo_1.UNICAST_BINDING, destinationAddressOrGroup, null, // doesn't matter
2615
- destinationEndpoint, DEFAULT_APS_OPTIONS));
2616
- if (status !== enums_3.EmberStatus.SUCCESS) {
1992
+ const [status, apsFrame, messageTag] = await this.sendZDORequest(destinationNetworkAddress, Zdo.ClusterId.BIND_REQUEST, zdoPayload, DEFAULT_APS_OPTIONS);
1993
+ if (status !== enums_2.SLStatus.OK) {
2617
1994
  logger_1.logger.error(`[ZDO] Failed bind request for "${destinationNetworkAddress}" destination "${destinationAddressOrGroup}" `
2618
- + `endpoint "${destinationEndpoint}" with status=${enums_3.EmberStatus[status]}.`, NS);
1995
+ + `endpoint "${destinationEndpoint}" with status=${enums_2.SLStatus[status]}.`, NS);
2619
1996
  return status;
2620
1997
  }
2621
1998
  await this.oneWaitress.startWaitingFor({
2622
1999
  target: destinationNetworkAddress,
2623
2000
  apsFrame,
2624
- responseClusterId: zdo_1.BIND_RESPONSE,
2001
+ responseClusterId: Zdo.ClusterId.BIND_RESPONSE,
2625
2002
  }, DEFAULT_ZDO_REQUEST_TIMEOUT);
2626
2003
  resolve();
2627
- return enums_3.EmberStatus.SUCCESS;
2004
+ return enums_2.SLStatus.OK;
2628
2005
  }, reject);
2629
2006
  });
2630
2007
  }
@@ -2633,22 +2010,23 @@ class EmberAdapter extends __1.Adapter {
2633
2010
  return new Promise((resolve, reject) => {
2634
2011
  this.requestQueue.enqueue(async () => {
2635
2012
  this.checkInterpanLock();
2013
+ const zdoPayload = buffaloZdo_1.BuffaloZdo.buildBindRequest(sourceIeeeAddress, sourceEndpoint, clusterID, Zdo.MULTICAST_BINDING, undefined, // not used with MULTICAST_BINDING
2014
+ destinationAddressOrGroup, undefined // not used with MULTICAST_BINDING
2015
+ );
2636
2016
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2637
- const [status, apsFrame, messageTag] = (await this.emberBindRequest(destinationNetworkAddress, sourceIeeeAddress, sourceEndpoint, clusterID, zdo_1.MULTICAST_BINDING, null, // doesn't matter
2638
- destinationAddressOrGroup, destinationEndpoint, // doesn't matter
2639
- DEFAULT_APS_OPTIONS));
2640
- if (status !== enums_3.EmberStatus.SUCCESS) {
2017
+ const [status, apsFrame, messageTag] = await this.sendZDORequest(destinationNetworkAddress, Zdo.ClusterId.BIND_REQUEST, zdoPayload, DEFAULT_APS_OPTIONS);
2018
+ if (status !== enums_2.SLStatus.OK) {
2641
2019
  logger_1.logger.error(`[ZDO] Failed bind request for "${destinationNetworkAddress}" group "${destinationAddressOrGroup}" `
2642
- + `with status=${enums_3.EmberStatus[status]}.`, NS);
2020
+ + `with status=${enums_2.SLStatus[status]}.`, NS);
2643
2021
  return status;
2644
2022
  }
2645
2023
  await this.oneWaitress.startWaitingFor({
2646
2024
  target: destinationNetworkAddress,
2647
2025
  apsFrame,
2648
- responseClusterId: zdo_1.BIND_RESPONSE,
2026
+ responseClusterId: Zdo.ClusterId.BIND_RESPONSE,
2649
2027
  }, DEFAULT_ZDO_REQUEST_TIMEOUT);
2650
2028
  resolve();
2651
- return enums_3.EmberStatus.SUCCESS;
2029
+ return enums_2.SLStatus.OK;
2652
2030
  }, reject);
2653
2031
  });
2654
2032
  }
@@ -2660,21 +2038,22 @@ class EmberAdapter extends __1.Adapter {
2660
2038
  return new Promise((resolve, reject) => {
2661
2039
  this.requestQueue.enqueue(async () => {
2662
2040
  this.checkInterpanLock();
2041
+ const zdoPayload = buffaloZdo_1.BuffaloZdo.buildUnbindRequest(sourceIeeeAddress, sourceEndpoint, clusterID, Zdo.UNICAST_BINDING, destinationAddressOrGroup, undefined, // not used with UNICAST_BINDING
2042
+ destinationEndpoint);
2663
2043
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2664
- const [status, apsFrame, messageTag] = (await this.emberUnbindRequest(destinationNetworkAddress, sourceIeeeAddress, sourceEndpoint, clusterID, zdo_1.UNICAST_BINDING, destinationAddressOrGroup, null, // doesn't matter
2665
- destinationEndpoint, DEFAULT_APS_OPTIONS));
2666
- if (status !== enums_3.EmberStatus.SUCCESS) {
2044
+ const [status, apsFrame, messageTag] = await this.sendZDORequest(destinationNetworkAddress, Zdo.ClusterId.UNBIND_REQUEST, zdoPayload, DEFAULT_APS_OPTIONS);
2045
+ if (status !== enums_2.SLStatus.OK) {
2667
2046
  logger_1.logger.error(`[ZDO] Failed unbind request for "${destinationNetworkAddress}" destination "${destinationAddressOrGroup}" `
2668
- + `endpoint "${destinationEndpoint}" with status=${enums_3.EmberStatus[status]}.`, NS);
2047
+ + `endpoint "${destinationEndpoint}" with status=${enums_2.SLStatus[status]}.`, NS);
2669
2048
  return status;
2670
2049
  }
2671
2050
  await this.oneWaitress.startWaitingFor({
2672
2051
  target: destinationNetworkAddress,
2673
2052
  apsFrame,
2674
- responseClusterId: zdo_1.UNBIND_RESPONSE,
2053
+ responseClusterId: Zdo.ClusterId.UNBIND_RESPONSE,
2675
2054
  }, DEFAULT_ZDO_REQUEST_TIMEOUT);
2676
2055
  resolve();
2677
- return enums_3.EmberStatus.SUCCESS;
2056
+ return enums_2.SLStatus.OK;
2678
2057
  }, reject);
2679
2058
  });
2680
2059
  }
@@ -2683,22 +2062,23 @@ class EmberAdapter extends __1.Adapter {
2683
2062
  return new Promise((resolve, reject) => {
2684
2063
  this.requestQueue.enqueue(async () => {
2685
2064
  this.checkInterpanLock();
2065
+ const zdoPayload = buffaloZdo_1.BuffaloZdo.buildUnbindRequest(sourceIeeeAddress, sourceEndpoint, clusterID, Zdo.MULTICAST_BINDING, undefined, // not used with MULTICAST_BINDING
2066
+ destinationAddressOrGroup, undefined // not used with MULTICAST_BINDING
2067
+ );
2686
2068
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2687
- const [status, apsFrame, messageTag] = (await this.emberUnbindRequest(destinationNetworkAddress, sourceIeeeAddress, sourceEndpoint, clusterID, zdo_1.MULTICAST_BINDING, null, // doesn't matter
2688
- destinationAddressOrGroup, destinationEndpoint, // doesn't matter
2689
- DEFAULT_APS_OPTIONS));
2690
- if (status !== enums_3.EmberStatus.SUCCESS) {
2069
+ const [status, apsFrame, messageTag] = await this.sendZDORequest(destinationNetworkAddress, Zdo.ClusterId.UNBIND_REQUEST, zdoPayload, DEFAULT_APS_OPTIONS);
2070
+ if (status !== enums_2.SLStatus.OK) {
2691
2071
  logger_1.logger.error(`[ZDO] Failed unbind request for "${destinationNetworkAddress}" group "${destinationAddressOrGroup}" `
2692
- + `with status=${enums_3.EmberStatus[status]}.`, NS);
2072
+ + `with status=${enums_2.SLStatus[status]}.`, NS);
2693
2073
  return status;
2694
2074
  }
2695
2075
  await this.oneWaitress.startWaitingFor({
2696
2076
  target: destinationNetworkAddress,
2697
2077
  apsFrame,
2698
- responseClusterId: zdo_1.UNBIND_RESPONSE,
2078
+ responseClusterId: Zdo.ClusterId.UNBIND_RESPONSE,
2699
2079
  }, DEFAULT_ZDO_REQUEST_TIMEOUT);
2700
2080
  resolve();
2701
- return enums_3.EmberStatus.SUCCESS;
2081
+ return enums_2.SLStatus.OK;
2702
2082
  }, reject);
2703
2083
  });
2704
2084
  }
@@ -2708,20 +2088,21 @@ class EmberAdapter extends __1.Adapter {
2708
2088
  return new Promise((resolve, reject) => {
2709
2089
  this.requestQueue.enqueue(async () => {
2710
2090
  this.checkInterpanLock();
2091
+ const zdoPayload = buffaloZdo_1.BuffaloZdo.buildLeaveRequest(ieeeAddr, Zdo.LeaveRequestFlags.WITHOUT_REJOIN);
2711
2092
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2712
- const [status, apsFrame, messageTag] = (await this.emberLeaveRequest(networkAddress, ieeeAddr, enums_3.EmberLeaveRequestFlags.WITHOUT_REJOIN, DEFAULT_APS_OPTIONS));
2713
- if (status !== enums_3.EmberStatus.SUCCESS) {
2093
+ const [status, apsFrame, messageTag] = await this.sendZDORequest(networkAddress, Zdo.ClusterId.LEAVE_REQUEST, zdoPayload, DEFAULT_APS_OPTIONS);
2094
+ if (status !== enums_2.SLStatus.OK) {
2714
2095
  logger_1.logger.error(`[ZDO] Failed remove device request for "${networkAddress}" target "${ieeeAddr}" `
2715
- + `with status=${enums_3.EmberStatus[status]}.`, NS);
2096
+ + `with status=${enums_2.SLStatus[status]}.`, NS);
2716
2097
  return status;
2717
2098
  }
2718
2099
  await this.oneWaitress.startWaitingFor({
2719
2100
  target: networkAddress,
2720
2101
  apsFrame,
2721
- responseClusterId: zdo_1.LEAVE_RESPONSE,
2102
+ responseClusterId: Zdo.ClusterId.LEAVE_RESPONSE,
2722
2103
  }, DEFAULT_ZDO_REQUEST_TIMEOUT);
2723
2104
  resolve();
2724
- return enums_3.EmberStatus.SUCCESS;
2105
+ return enums_2.SLStatus.OK;
2725
2106
  }, reject);
2726
2107
  });
2727
2108
  }
@@ -2749,24 +2130,18 @@ class EmberAdapter extends __1.Adapter {
2749
2130
  };
2750
2131
  // don't RETRY if no response expected
2751
2132
  if (commandResponseId == null) {
2752
- apsFrame.options &= ~enums_3.EmberApsOption.RETRY;
2133
+ apsFrame.options &= ~enums_2.EmberApsOption.RETRY;
2753
2134
  }
2754
2135
  const data = zclFrame.toBuffer();
2755
2136
  return new Promise((resolve, reject) => {
2756
2137
  this.requestQueue.enqueue(async () => {
2757
2138
  this.checkInterpanLock();
2758
- if (CHECK_APS_PAYLOAD_LENGTH) {
2759
- const maxPayloadLength = (await this.maximumApsPayloadLength(enums_3.EmberOutgoingMessageType.DIRECT, networkAddress, apsFrame));
2760
- if (data.length > maxPayloadLength) {
2761
- return enums_3.EmberStatus.MESSAGE_TOO_LONG; // queue will reject
2762
- }
2763
- }
2764
2139
  logger_1.logger.debug(`~~~> [ZCL to=${networkAddress} apsFrame=${JSON.stringify(apsFrame)} header=${JSON.stringify(zclFrame.header)}]`, NS);
2765
2140
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2766
- const [status, messageTag] = (await this.ezsp.send(enums_3.EmberOutgoingMessageType.DIRECT, networkAddress, apsFrame, data, 0, // alias
2141
+ const [status, messageTag] = (await this.ezsp.send(enums_2.EmberOutgoingMessageType.DIRECT, networkAddress, apsFrame, data, 0, // alias
2767
2142
  0));
2768
- if (status !== enums_3.EmberStatus.SUCCESS) {
2769
- logger_1.logger.error(`~x~> [ZCL to=${networkAddress}] Failed to send request with status=${enums_3.EmberStatus[status]}.`, NS);
2143
+ if (status !== enums_2.SLStatus.OK) {
2144
+ logger_1.logger.error(`~x~> [ZCL to=${networkAddress}] Failed to send request with status=${enums_2.SLStatus[status]}.`, NS);
2770
2145
  return status; // let queue handle retry based on status
2771
2146
  }
2772
2147
  if (commandResponseId != null) {
@@ -2781,7 +2156,7 @@ class EmberAdapter extends __1.Adapter {
2781
2156
  }
2782
2157
  else {
2783
2158
  resolve(null); // don't expect a response
2784
- return enums_3.EmberStatus.SUCCESS;
2159
+ return enums_2.SLStatus.OK;
2785
2160
  }
2786
2161
  }, reject);
2787
2162
  });
@@ -2803,24 +2178,18 @@ class EmberAdapter extends __1.Adapter {
2803
2178
  return new Promise((resolve, reject) => {
2804
2179
  this.requestQueue.enqueue(async () => {
2805
2180
  this.checkInterpanLock();
2806
- if (CHECK_APS_PAYLOAD_LENGTH) {
2807
- const maxPayloadLength = (await this.maximumApsPayloadLength(enums_3.EmberOutgoingMessageType.MULTICAST, groupID, apsFrame));
2808
- if (data.length > maxPayloadLength) {
2809
- return enums_3.EmberStatus.MESSAGE_TOO_LONG; // queue will reject
2810
- }
2811
- }
2812
2181
  logger_1.logger.debug(`~~~> [ZCL GROUP apsFrame=${JSON.stringify(apsFrame)} header=${JSON.stringify(zclFrame.header)}]`, NS);
2813
2182
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2814
- const [status, messageTag] = (await this.ezsp.send(enums_3.EmberOutgoingMessageType.MULTICAST, apsFrame.groupId, // not used for MC
2183
+ const [status, messageTag] = (await this.ezsp.send(enums_2.EmberOutgoingMessageType.MULTICAST, apsFrame.groupId, // not used with MULTICAST
2815
2184
  apsFrame, data, 0, // alias
2816
2185
  0));
2817
- if (status !== enums_3.EmberStatus.SUCCESS) {
2818
- logger_1.logger.error(`~x~> [ZCL GROUP] Failed to send with status=${enums_3.EmberStatus[status]}.`, NS);
2186
+ if (status !== enums_2.SLStatus.OK) {
2187
+ logger_1.logger.error(`~x~> [ZCL GROUP] Failed to send with status=${enums_2.SLStatus[status]}.`, NS);
2819
2188
  return status; // let queue handle retry based on status
2820
2189
  }
2821
2190
  // NOTE: since ezspMessageSentHandler could take a while here, we don't block, it'll just be logged if the delivery failed
2822
2191
  resolve();
2823
- return enums_3.EmberStatus.SUCCESS;
2192
+ return enums_2.SLStatus.OK;
2824
2193
  }, reject);
2825
2194
  });
2826
2195
  }
@@ -2841,23 +2210,17 @@ class EmberAdapter extends __1.Adapter {
2841
2210
  return new Promise((resolve, reject) => {
2842
2211
  this.requestQueue.enqueue(async () => {
2843
2212
  this.checkInterpanLock();
2844
- if (CHECK_APS_PAYLOAD_LENGTH) {
2845
- const maxPayloadLength = (await this.maximumApsPayloadLength(enums_3.EmberOutgoingMessageType.BROADCAST, destination, apsFrame));
2846
- if (data.length > maxPayloadLength) {
2847
- return enums_3.EmberStatus.MESSAGE_TOO_LONG; // queue will reject
2848
- }
2849
- }
2850
2213
  logger_1.logger.debug(`~~~> [ZCL BROADCAST apsFrame=${JSON.stringify(apsFrame)} header=${JSON.stringify(zclFrame.header)}]`, NS);
2851
2214
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2852
- const [status, messageTag] = (await this.ezsp.send(enums_3.EmberOutgoingMessageType.BROADCAST, destination, apsFrame, data, 0, // alias
2215
+ const [status, messageTag] = (await this.ezsp.send(enums_2.EmberOutgoingMessageType.BROADCAST, destination, apsFrame, data, 0, // alias
2853
2216
  0));
2854
- if (status !== enums_3.EmberStatus.SUCCESS) {
2855
- logger_1.logger.error(`~x~> [ZCL BROADCAST] Failed to send with status=${enums_3.EmberStatus[status]}.`, NS);
2217
+ if (status !== enums_2.SLStatus.OK) {
2218
+ logger_1.logger.error(`~x~> [ZCL BROADCAST] Failed to send with status=${enums_2.SLStatus[status]}.`, NS);
2856
2219
  return status; // let queue handle retry based on status
2857
2220
  }
2858
2221
  // NOTE: since ezspMessageSentHandler could take a while here, we don't block, it'll just be logged if the delivery failed
2859
2222
  resolve();
2860
- return enums_3.EmberStatus.SUCCESS;
2223
+ return enums_2.SLStatus.OK;
2861
2224
  }, reject);
2862
2225
  });
2863
2226
  }
@@ -2874,9 +2237,9 @@ class EmberAdapter extends __1.Adapter {
2874
2237
  this.requestQueue.enqueue(async () => {
2875
2238
  this.interpanLock = true;
2876
2239
  const status = (await this.ezsp.ezspSetLogicalAndRadioChannel(channel));
2877
- if (status !== enums_3.EmberStatus.SUCCESS) {
2240
+ if (status !== enums_2.SLStatus.OK) {
2878
2241
  this.interpanLock = false; // XXX: ok?
2879
- logger_1.logger.error(`Failed to set InterPAN channel to ${channel} with status=${enums_3.EmberStatus[status]}.`, NS);
2242
+ logger_1.logger.error(`Failed to set InterPAN channel to ${channel} with status=${enums_2.SLStatus[status]}.`, NS);
2880
2243
  return status;
2881
2244
  }
2882
2245
  resolve();
@@ -2899,13 +2262,13 @@ class EmberAdapter extends __1.Adapter {
2899
2262
  msgBuffalo.writeUInt16(sourcePanId); // sourcePanId
2900
2263
  msgBuffalo.writeIeeeAddr(sourceEui64); // sourceAddress
2901
2264
  msgBuffalo.writeUInt16(consts_2.STUB_NWK_FRAME_CONTROL); // nwkFrameControl
2902
- msgBuffalo.writeUInt8((enums_3.EmberInterpanMessageType.UNICAST | consts_2.INTERPAN_APS_FRAME_TYPE)); // apsFrameControl
2265
+ msgBuffalo.writeUInt8((enums_2.EmberInterpanMessageType.UNICAST | consts_2.INTERPAN_APS_FRAME_TYPE)); // apsFrameControl
2903
2266
  msgBuffalo.writeUInt16(zclFrame.cluster.ID);
2904
2267
  msgBuffalo.writeUInt16(ZSpec.TOUCHLINK_PROFILE_ID);
2905
2268
  logger_1.logger.debug(`~~~> [ZCL TOUCHLINK to=${ieeeAddress} header=${JSON.stringify(zclFrame.header)}]`, NS);
2906
- const status = (await this.ezsp.ezspSendRawMessage(Buffer.concat([msgBuffalo.getWritten(), zclFrame.toBuffer()])));
2907
- if (status !== enums_3.EmberStatus.SUCCESS) {
2908
- logger_1.logger.error(`~x~> [ZCL TOUCHLINK to=${ieeeAddress}] Failed to send with status=${enums_3.EmberStatus[status]}.`, NS);
2269
+ const status = await this.ezsp.ezspSendRawMessage(Buffer.concat([msgBuffalo.getWritten(), zclFrame.toBuffer()]), enums_2.EmberTransmitPriority.NORMAL, true);
2270
+ if (status !== enums_2.SLStatus.OK) {
2271
+ logger_1.logger.error(`~x~> [ZCL TOUCHLINK to=${ieeeAddress}] Failed to send with status=${enums_2.SLStatus[status]}.`, NS);
2909
2272
  return status;
2910
2273
  }
2911
2274
  // NOTE: can use ezspRawTransmitCompleteHandler if needed here
@@ -2926,8 +2289,8 @@ class EmberAdapter extends __1.Adapter {
2926
2289
  clusterId: zclFrame.cluster.ID,
2927
2290
  sourceEndpoint: 0,
2928
2291
  destinationEndpoint: 0,
2929
- options: enums_3.EmberApsOption.NONE,
2930
- groupId: enums_1.BroadcastAddress.SLEEPY,
2292
+ options: enums_2.EmberApsOption.NONE,
2293
+ groupId: ZSpec.BroadcastAddress.SLEEPY,
2931
2294
  sequence: 0, // set by stack
2932
2295
  };
2933
2296
  return new Promise((resolve, reject) => {
@@ -2943,14 +2306,14 @@ class EmberAdapter extends __1.Adapter {
2943
2306
  msgBuffalo.writeUInt16(sourcePanId); // sourcePanId
2944
2307
  msgBuffalo.writeIeeeAddr(sourceEui64); // sourceAddress
2945
2308
  msgBuffalo.writeUInt16(consts_2.STUB_NWK_FRAME_CONTROL); // nwkFrameControl
2946
- msgBuffalo.writeUInt8((enums_3.EmberInterpanMessageType.BROADCAST | consts_2.INTERPAN_APS_FRAME_TYPE)); // apsFrameControl
2309
+ msgBuffalo.writeUInt8((enums_2.EmberInterpanMessageType.BROADCAST | consts_2.INTERPAN_APS_FRAME_TYPE)); // apsFrameControl
2947
2310
  msgBuffalo.writeUInt16(apsFrame.clusterId);
2948
2311
  msgBuffalo.writeUInt16(apsFrame.profileId);
2949
2312
  const data = Buffer.concat([msgBuffalo.getWritten(), zclFrame.toBuffer()]);
2950
2313
  logger_1.logger.debug(`~~~> [ZCL TOUCHLINK BROADCAST header=${JSON.stringify(zclFrame.header)}]`, NS);
2951
- const status = (await this.ezsp.ezspSendRawMessage(data));
2952
- if (status !== enums_3.EmberStatus.SUCCESS) {
2953
- logger_1.logger.error(`~x~> [ZCL TOUCHLINK BROADCAST] Failed to send with status=${enums_3.EmberStatus[status]}.`, NS);
2314
+ const status = (await this.ezsp.ezspSendRawMessage(data, enums_2.EmberTransmitPriority.NORMAL, true));
2315
+ if (status !== enums_2.SLStatus.OK) {
2316
+ logger_1.logger.error(`~x~> [ZCL TOUCHLINK BROADCAST] Failed to send with status=${enums_2.SLStatus[status]}.`, NS);
2954
2317
  return status;
2955
2318
  }
2956
2319
  // NOTE: can use ezspRawTransmitCompleteHandler if needed here
@@ -2961,7 +2324,7 @@ class EmberAdapter extends __1.Adapter {
2961
2324
  commandIdentifier: command.response,
2962
2325
  }, timeout || DEFAULT_ZCL_REQUEST_TIMEOUT * 2)); // XXX: touchlink timeout?
2963
2326
  resolve(result);
2964
- return enums_3.EmberStatus.SUCCESS;
2327
+ return enums_2.SLStatus.OK;
2965
2328
  }, reject);
2966
2329
  });
2967
2330
  }
@@ -2970,8 +2333,8 @@ class EmberAdapter extends __1.Adapter {
2970
2333
  return new Promise((resolve, reject) => {
2971
2334
  this.requestQueue.enqueue(async () => {
2972
2335
  const status = (await this.ezsp.ezspSetLogicalAndRadioChannel(this.networkOptions.channelList[0]));
2973
- if (status !== enums_3.EmberStatus.SUCCESS) {
2974
- logger_1.logger.error(`Failed to restore InterPAN channel to ${this.networkOptions.channelList[0]} with status=${enums_3.EmberStatus[status]}.`, NS);
2336
+ if (status !== enums_2.SLStatus.OK) {
2337
+ logger_1.logger.error(`Failed to restore InterPAN channel to ${this.networkOptions.channelList[0]} with status=${enums_2.SLStatus[status]}.`, NS);
2975
2338
  return status;
2976
2339
  }
2977
2340
  // let adapter settle down
@@ -2987,7 +2350,7 @@ class EmberAdapter extends __1.Adapter {
2987
2350
  if (this.interpanLock) {
2988
2351
  logger_1.logger.error(`[INTERPAN MODE] Cannot execute non-InterPAN commands.`, NS);
2989
2352
  // will be caught by request queue and rejected internally.
2990
- throw new Error(enums_3.EzspStatus[enums_3.EzspStatus.ERROR_INVALID_CALL]);
2353
+ throw new ezspError_1.EzspError(enums_2.EzspStatus.ERROR_INVALID_CALL);
2991
2354
  }
2992
2355
  }
2993
2356
  }