zigbee-herdsman 6.0.1 → 6.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/adapter/ezsp/driver/uart.js +1 -1
- package/dist/adapter/ezsp/driver/uart.js.map +1 -1
- package/dist/adapter/z-stack/adapter/zStackAdapter.js +4 -4
- package/dist/adapter/z-stack/adapter/zStackAdapter.js.map +1 -1
- package/dist/adapter/zigate/adapter/zigateAdapter.js +4 -4
- package/dist/adapter/zigate/adapter/zigateAdapter.js.map +1 -1
- package/dist/controller/model/device.d.ts.map +1 -1
- package/dist/controller/model/device.js +1 -0
- package/dist/controller/model/device.js.map +1 -1
- package/package.json +14 -6
- package/.github/ISSUE_TEMPLATE/config.yml +0 -5
- package/.github/dependabot.yml +0 -22
- package/.github/workflows/ci.yml +0 -64
- package/.github/workflows/release-please.yml +0 -18
- package/.github/workflows/stale.yml +0 -20
- package/.github/workflows/typedoc.yaml +0 -47
- package/.release-please-manifest.json +0 -3
- package/.vscode/extensions.json +0 -3
- package/.vscode/settings.json +0 -11
- package/biome.json +0 -98
- package/examples/join-and-log.js +0 -24
- package/release-please-config.json +0 -9
- package/src/adapter/adapter.ts +0 -189
- package/src/adapter/adapterDiscovery.ts +0 -666
- package/src/adapter/const.ts +0 -12
- package/src/adapter/deconz/adapter/deconzAdapter.ts +0 -877
- package/src/adapter/deconz/driver/constants.ts +0 -246
- package/src/adapter/deconz/driver/driver.ts +0 -1540
- package/src/adapter/deconz/driver/frame.ts +0 -11
- package/src/adapter/deconz/driver/frameParser.ts +0 -753
- package/src/adapter/deconz/driver/parser.ts +0 -45
- package/src/adapter/deconz/driver/writer.ts +0 -22
- package/src/adapter/deconz/types.d.ts +0 -13
- package/src/adapter/ember/adapter/emberAdapter.ts +0 -2265
- package/src/adapter/ember/adapter/endpoints.ts +0 -86
- package/src/adapter/ember/adapter/oneWaitress.ts +0 -324
- package/src/adapter/ember/adapter/tokensManager.ts +0 -782
- package/src/adapter/ember/consts.ts +0 -178
- package/src/adapter/ember/enums.ts +0 -1746
- package/src/adapter/ember/ezsp/buffalo.ts +0 -1392
- package/src/adapter/ember/ezsp/consts.ts +0 -148
- package/src/adapter/ember/ezsp/enums.ts +0 -1114
- package/src/adapter/ember/ezsp/ezsp.ts +0 -9061
- package/src/adapter/ember/ezspError.ts +0 -10
- package/src/adapter/ember/types.ts +0 -866
- package/src/adapter/ember/uart/ash.ts +0 -1960
- package/src/adapter/ember/uart/consts.ts +0 -109
- package/src/adapter/ember/uart/enums.ts +0 -192
- package/src/adapter/ember/uart/parser.ts +0 -48
- package/src/adapter/ember/uart/queues.ts +0 -247
- package/src/adapter/ember/uart/writer.ts +0 -53
- package/src/adapter/ember/utils/initters.ts +0 -58
- package/src/adapter/ember/utils/math.ts +0 -73
- package/src/adapter/events.ts +0 -21
- package/src/adapter/ezsp/adapter/backup.ts +0 -109
- package/src/adapter/ezsp/adapter/ezspAdapter.ts +0 -614
- package/src/adapter/ezsp/driver/commands.ts +0 -2497
- package/src/adapter/ezsp/driver/consts.ts +0 -11
- package/src/adapter/ezsp/driver/driver.ts +0 -1002
- package/src/adapter/ezsp/driver/ezsp.ts +0 -802
- package/src/adapter/ezsp/driver/frame.ts +0 -101
- package/src/adapter/ezsp/driver/index.ts +0 -4
- package/src/adapter/ezsp/driver/multicast.ts +0 -78
- package/src/adapter/ezsp/driver/parser.ts +0 -81
- package/src/adapter/ezsp/driver/types/basic.ts +0 -201
- package/src/adapter/ezsp/driver/types/index.ts +0 -239
- package/src/adapter/ezsp/driver/types/named.ts +0 -2330
- package/src/adapter/ezsp/driver/types/struct.ts +0 -844
- package/src/adapter/ezsp/driver/uart.ts +0 -460
- package/src/adapter/ezsp/driver/utils/crc16ccitt.ts +0 -44
- package/src/adapter/ezsp/driver/utils/index.ts +0 -32
- package/src/adapter/ezsp/driver/writer.ts +0 -64
- package/src/adapter/index.ts +0 -3
- package/src/adapter/serialPort.ts +0 -58
- package/src/adapter/socketPortUtils.ts +0 -16
- package/src/adapter/tstype.ts +0 -78
- package/src/adapter/z-stack/adapter/adapter-backup.ts +0 -519
- package/src/adapter/z-stack/adapter/adapter-nv-memory.ts +0 -457
- package/src/adapter/z-stack/adapter/endpoints.ts +0 -57
- package/src/adapter/z-stack/adapter/manager.ts +0 -543
- package/src/adapter/z-stack/adapter/tstype.ts +0 -6
- package/src/adapter/z-stack/adapter/zStackAdapter.ts +0 -1190
- package/src/adapter/z-stack/constants/af.ts +0 -27
- package/src/adapter/z-stack/constants/common.ts +0 -285
- package/src/adapter/z-stack/constants/dbg.ts +0 -23
- package/src/adapter/z-stack/constants/index.ts +0 -11
- package/src/adapter/z-stack/constants/mac.ts +0 -128
- package/src/adapter/z-stack/constants/sapi.ts +0 -25
- package/src/adapter/z-stack/constants/sys.ts +0 -72
- package/src/adapter/z-stack/constants/util.ts +0 -82
- package/src/adapter/z-stack/constants/utils.ts +0 -14
- package/src/adapter/z-stack/constants/zdo.ts +0 -103
- package/src/adapter/z-stack/models/startup-options.ts +0 -13
- package/src/adapter/z-stack/structs/entries/address-manager-entry.ts +0 -44
- package/src/adapter/z-stack/structs/entries/address-manager-table.ts +0 -19
- package/src/adapter/z-stack/structs/entries/aps-link-key-data-entry.ts +0 -12
- package/src/adapter/z-stack/structs/entries/aps-link-key-data-table.ts +0 -21
- package/src/adapter/z-stack/structs/entries/aps-tc-link-key-entry.ts +0 -19
- package/src/adapter/z-stack/structs/entries/aps-tc-link-key-table.ts +0 -21
- package/src/adapter/z-stack/structs/entries/channel-list.ts +0 -8
- package/src/adapter/z-stack/structs/entries/has-configured.ts +0 -16
- package/src/adapter/z-stack/structs/entries/index.ts +0 -16
- package/src/adapter/z-stack/structs/entries/nib.ts +0 -66
- package/src/adapter/z-stack/structs/entries/nwk-key-descriptor.ts +0 -15
- package/src/adapter/z-stack/structs/entries/nwk-key.ts +0 -13
- package/src/adapter/z-stack/structs/entries/nwk-pan-id.ts +0 -8
- package/src/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-entry.ts +0 -20
- package/src/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-table.ts +0 -19
- package/src/adapter/z-stack/structs/entries/security-manager-entry.ts +0 -33
- package/src/adapter/z-stack/structs/entries/security-manager-table.ts +0 -22
- package/src/adapter/z-stack/structs/index.ts +0 -4
- package/src/adapter/z-stack/structs/serializable-memory-object.ts +0 -14
- package/src/adapter/z-stack/structs/struct.ts +0 -367
- package/src/adapter/z-stack/structs/table.ts +0 -198
- package/src/adapter/z-stack/unpi/constants.ts +0 -33
- package/src/adapter/z-stack/unpi/frame.ts +0 -62
- package/src/adapter/z-stack/unpi/index.ts +0 -4
- package/src/adapter/z-stack/unpi/parser.ts +0 -56
- package/src/adapter/z-stack/unpi/writer.ts +0 -21
- package/src/adapter/z-stack/utils/channel-list.ts +0 -40
- package/src/adapter/z-stack/utils/index.ts +0 -2
- package/src/adapter/z-stack/utils/network-options.ts +0 -26
- package/src/adapter/z-stack/znp/buffaloZnp.ts +0 -175
- package/src/adapter/z-stack/znp/definition.ts +0 -2713
- package/src/adapter/z-stack/znp/index.ts +0 -2
- package/src/adapter/z-stack/znp/parameterType.ts +0 -22
- package/src/adapter/z-stack/znp/tstype.ts +0 -44
- package/src/adapter/z-stack/znp/utils.ts +0 -10
- package/src/adapter/z-stack/znp/znp.ts +0 -342
- package/src/adapter/z-stack/znp/zpiObject.ts +0 -148
- package/src/adapter/zboss/adapter/zbossAdapter.ts +0 -526
- package/src/adapter/zboss/commands.ts +0 -1184
- package/src/adapter/zboss/consts.ts +0 -9
- package/src/adapter/zboss/driver.ts +0 -422
- package/src/adapter/zboss/enums.ts +0 -360
- package/src/adapter/zboss/frame.ts +0 -227
- package/src/adapter/zboss/reader.ts +0 -65
- package/src/adapter/zboss/types.ts +0 -0
- package/src/adapter/zboss/uart.ts +0 -428
- package/src/adapter/zboss/utils.ts +0 -58
- package/src/adapter/zboss/writer.ts +0 -49
- package/src/adapter/zigate/adapter/patchZdoBuffaloBE.ts +0 -27
- package/src/adapter/zigate/adapter/zigateAdapter.ts +0 -618
- package/src/adapter/zigate/driver/LICENSE +0 -17
- package/src/adapter/zigate/driver/buffaloZiGate.ts +0 -212
- package/src/adapter/zigate/driver/commandType.ts +0 -418
- package/src/adapter/zigate/driver/constants.ts +0 -150
- package/src/adapter/zigate/driver/frame.ts +0 -197
- package/src/adapter/zigate/driver/messageType.ts +0 -287
- package/src/adapter/zigate/driver/parameterType.ts +0 -32
- package/src/adapter/zigate/driver/ziGateObject.ts +0 -146
- package/src/adapter/zigate/driver/zigate.ts +0 -423
- package/src/adapter/zoh/adapter/utils.ts +0 -27
- package/src/adapter/zoh/adapter/zohAdapter.ts +0 -838
- package/src/buffalo/buffalo.ts +0 -342
- package/src/buffalo/index.ts +0 -1
- package/src/controller/controller.ts +0 -1022
- package/src/controller/database.ts +0 -124
- package/src/controller/events.ts +0 -52
- package/src/controller/greenPower.ts +0 -603
- package/src/controller/helpers/index.ts +0 -1
- package/src/controller/helpers/installCodes.ts +0 -107
- package/src/controller/helpers/request.ts +0 -96
- package/src/controller/helpers/requestQueue.ts +0 -125
- package/src/controller/helpers/zclFrameConverter.ts +0 -47
- package/src/controller/helpers/zclTransactionSequenceNumber.ts +0 -19
- package/src/controller/index.ts +0 -6
- package/src/controller/model/device.ts +0 -1248
- package/src/controller/model/endpoint.ts +0 -1105
- package/src/controller/model/entity.ts +0 -23
- package/src/controller/model/group.ts +0 -424
- package/src/controller/model/index.ts +0 -5
- package/src/controller/model/zigbeeEntity.ts +0 -30
- package/src/controller/touchlink.ts +0 -189
- package/src/controller/tstype.ts +0 -274
- package/src/index.ts +0 -12
- package/src/models/backup-storage-legacy.ts +0 -48
- package/src/models/backup-storage-unified.ts +0 -47
- package/src/models/backup.ts +0 -37
- package/src/models/index.ts +0 -5
- package/src/models/network-options.ts +0 -11
- package/src/utils/backup.ts +0 -152
- package/src/utils/index.ts +0 -5
- package/src/utils/logger.ts +0 -20
- package/src/utils/patchBigIntSerialization.ts +0 -8
- package/src/utils/queue.ts +0 -76
- package/src/utils/types.d.ts +0 -3
- package/src/utils/utils.ts +0 -19
- package/src/utils/wait.ts +0 -5
- package/src/utils/waitress.ts +0 -96
- package/src/zspec/consts.ts +0 -84
- package/src/zspec/enums.ts +0 -22
- package/src/zspec/index.ts +0 -3
- package/src/zspec/tstypes.ts +0 -18
- package/src/zspec/utils.ts +0 -247
- package/src/zspec/zcl/buffaloZcl.ts +0 -1220
- package/src/zspec/zcl/definition/cluster.ts +0 -5915
- package/src/zspec/zcl/definition/clusters-typegen.ts +0 -588
- package/src/zspec/zcl/definition/clusters-types.ts +0 -7331
- package/src/zspec/zcl/definition/consts.ts +0 -24
- package/src/zspec/zcl/definition/enums.ts +0 -203
- package/src/zspec/zcl/definition/foundation.ts +0 -329
- package/src/zspec/zcl/definition/manufacturerCode.ts +0 -729
- package/src/zspec/zcl/definition/status.ts +0 -69
- package/src/zspec/zcl/definition/tstype.ts +0 -377
- package/src/zspec/zcl/index.ts +0 -11
- package/src/zspec/zcl/utils.ts +0 -321
- package/src/zspec/zcl/zclFrame.ts +0 -356
- package/src/zspec/zcl/zclHeader.ts +0 -102
- package/src/zspec/zcl/zclStatusError.ts +0 -10
- package/src/zspec/zdo/buffaloZdo.ts +0 -2336
- package/src/zspec/zdo/definition/clusters.ts +0 -722
- package/src/zspec/zdo/definition/consts.ts +0 -16
- package/src/zspec/zdo/definition/enums.ts +0 -99
- package/src/zspec/zdo/definition/status.ts +0 -105
- package/src/zspec/zdo/definition/tstypes.ts +0 -1062
- package/src/zspec/zdo/index.ts +0 -7
- package/src/zspec/zdo/utils.ts +0 -76
- package/src/zspec/zdo/zdoStatusError.ts +0 -10
- package/test/adapter/adapter.test.ts +0 -1062
- package/test/adapter/ember/ash.test.ts +0 -337
- package/test/adapter/ember/consts.ts +0 -131
- package/test/adapter/ember/emberAdapter.test.ts +0 -3449
- package/test/adapter/ember/ezsp.test.ts +0 -385
- package/test/adapter/ember/ezspBuffalo.test.ts +0 -93
- package/test/adapter/ember/ezspError.test.ts +0 -12
- package/test/adapter/ember/math.test.ts +0 -206
- package/test/adapter/ezsp/frame.test.ts +0 -30
- package/test/adapter/ezsp/uart.test.ts +0 -181
- package/test/adapter/z-stack/adapter.test.ts +0 -3984
- package/test/adapter/z-stack/constants.test.ts +0 -33
- package/test/adapter/z-stack/structs.test.ts +0 -115
- package/test/adapter/z-stack/unpi.test.ts +0 -213
- package/test/adapter/z-stack/znp.test.ts +0 -1284
- package/test/adapter/zboss/fixZdoResponse.test.ts +0 -179
- package/test/adapter/zigate/patchZdoBuffaloBE.test.ts +0 -81
- package/test/adapter/zigate/zdo.test.ts +0 -187
- package/test/adapter/zoh/utils.test.ts +0 -36
- package/test/adapter/zoh/zohAdapter.test.ts +0 -1307
- package/test/buffalo.test.ts +0 -431
- package/test/controller.bench.ts +0 -193
- package/test/controller.test.ts +0 -8702
- package/test/greenpower.test.ts +0 -1408
- package/test/mockAdapters.ts +0 -65
- package/test/mockDevices.ts +0 -598
- package/test/requests.bench.ts +0 -206
- package/test/testUtils.ts +0 -20
- package/test/tsconfig.json +0 -9
- package/test/utils/math.ts +0 -19
- package/test/utils.test.ts +0 -279
- package/test/vitest.config.mts +0 -27
- package/test/zcl.test.ts +0 -2831
- package/test/zspec/utils.test.ts +0 -68
- package/test/zspec/zcl/buffalo.test.ts +0 -1374
- package/test/zspec/zcl/frame.test.ts +0 -960
- package/test/zspec/zcl/utils.test.ts +0 -273
- package/test/zspec/zdo/buffalo.test.ts +0 -1850
- package/test/zspec/zdo/utils.test.ts +0 -241
- package/tsconfig.json +0 -24
|
@@ -1,603 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert";
|
|
2
|
-
import {createCipheriv} from "node:crypto";
|
|
3
|
-
import {EventEmitter} from "node:events";
|
|
4
|
-
|
|
5
|
-
import {aes128CcmStar} from "zigbee-on-host/dist/zigbee/zigbee";
|
|
6
|
-
|
|
7
|
-
import type {Adapter, Events as AdapterEvents} from "../adapter";
|
|
8
|
-
import {logger} from "../utils/logger";
|
|
9
|
-
import {COORDINATOR_ADDRESS, GP_ENDPOINT, GP_GROUP_ID, INTEROPERABILITY_LINK_KEY} from "../zspec/consts";
|
|
10
|
-
import {BroadcastAddress} from "../zspec/enums";
|
|
11
|
-
import * as Zcl from "../zspec/zcl";
|
|
12
|
-
import type {GpdChannelConfiguration, GpdCommissioningReply} from "../zspec/zcl/definition/tstype";
|
|
13
|
-
import zclTransactionSequenceNumber from "./helpers/zclTransactionSequenceNumber";
|
|
14
|
-
import {Device} from "./model";
|
|
15
|
-
import type {GreenPowerDeviceJoinedPayload} from "./tstype";
|
|
16
|
-
|
|
17
|
-
const NS = "zh:controller:greenpower";
|
|
18
|
-
|
|
19
|
-
const enum ZigbeeNWKGPAppId {
|
|
20
|
-
Default = 0x00,
|
|
21
|
-
Lped = 0x01,
|
|
22
|
-
Zgp = 0x02,
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const enum ZigbeeNWKGPSecurityLevel {
|
|
26
|
-
/** No Security */
|
|
27
|
-
No = 0x00,
|
|
28
|
-
/** Reserved? */
|
|
29
|
-
OneLsb = 0x01,
|
|
30
|
-
/** 4 Byte Frame Counter and 4 Byte MIC */
|
|
31
|
-
Full = 0x02,
|
|
32
|
-
/** 4 Byte Frame Counter and 4 Byte MIC with encryption */
|
|
33
|
-
FullEncr = 0x03,
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const enum ZigbeeNWKGPSecurityKeyType {
|
|
37
|
-
NoKey = 0x00,
|
|
38
|
-
ZbNwkKey = 0x01,
|
|
39
|
-
GpdGroupKey = 0x02,
|
|
40
|
-
NwkKeyDerivedGpdKeyGroupKey = 0x03,
|
|
41
|
-
PreconfiguredIndividualGpdKey = 0x04,
|
|
42
|
-
DerivedIndividualGpdKey = 0x07,
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const enum GPCommunicationMode {
|
|
46
|
-
FullUnicast = 0,
|
|
47
|
-
GroupcastToDgroupId = 1,
|
|
48
|
-
GroupcastToPrecommissionedGroupId = 2,
|
|
49
|
-
LightweightUnicast = 3,
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
type PairingOptions = {
|
|
53
|
-
appId: ZigbeeNWKGPAppId;
|
|
54
|
-
addSink: boolean;
|
|
55
|
-
removeGpd: boolean;
|
|
56
|
-
communicationMode: GPCommunicationMode;
|
|
57
|
-
gpdFixed: boolean;
|
|
58
|
-
gpdMacSeqNumCapabilities: boolean;
|
|
59
|
-
securityLevel: ZigbeeNWKGPSecurityLevel;
|
|
60
|
-
securityKeyType: ZigbeeNWKGPSecurityKeyType;
|
|
61
|
-
gpdSecurityFrameCounterPresent: boolean;
|
|
62
|
-
gpdSecurityKeyPresent: boolean;
|
|
63
|
-
assignedAliasPresent: boolean;
|
|
64
|
-
groupcastRadiusPresent: boolean;
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
type CommissioningModeOptions = {
|
|
68
|
-
action: number;
|
|
69
|
-
commissioningWindowPresent: boolean;
|
|
70
|
-
/** Bits: 0: On first Pairing success | 1: On GP Proxy Commissioning Mode (exit) */
|
|
71
|
-
exitMode: number;
|
|
72
|
-
/** should always be always false in current spec (1.1.2) */
|
|
73
|
-
channelPresent: boolean;
|
|
74
|
-
unicastCommunication: boolean;
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
/** @see Zcl.Clusters.greenPower.commandsResponse.pairing */
|
|
78
|
-
type PairingPayload = {
|
|
79
|
-
options: number;
|
|
80
|
-
srcID?: number;
|
|
81
|
-
gpdIEEEAddr?: string;
|
|
82
|
-
gpdEndpoint?: number;
|
|
83
|
-
sinkIEEEAddr?: string;
|
|
84
|
-
sinkNwkAddr?: number;
|
|
85
|
-
sinkGroupID?: number;
|
|
86
|
-
deviceID?: number;
|
|
87
|
-
frameCounter?: number;
|
|
88
|
-
gpdKey?: Buffer;
|
|
89
|
-
assignedAlias?: number;
|
|
90
|
-
groupcastRadius?: number;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
/** @see Zcl.Clusters.greenPower.commandsResponse.response */
|
|
94
|
-
type ResponsePayload<T extends GpdCommissioningReply | GpdChannelConfiguration> = {
|
|
95
|
-
options: number;
|
|
96
|
-
tempMaster: number;
|
|
97
|
-
tempMasterTx: number;
|
|
98
|
-
srcID?: number;
|
|
99
|
-
gpdIEEEAddr?: string;
|
|
100
|
-
gpdEndpoint?: number;
|
|
101
|
-
gpdCmd: number;
|
|
102
|
-
gpdPayload: T;
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
interface GreenPowerEventMap {
|
|
106
|
-
deviceJoined: [payload: GreenPowerDeviceJoinedPayload];
|
|
107
|
-
deviceLeave: [sourceID: number];
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export class GreenPower extends EventEmitter<GreenPowerEventMap> {
|
|
111
|
-
private adapter: Adapter;
|
|
112
|
-
|
|
113
|
-
public constructor(adapter: Adapter) {
|
|
114
|
-
super();
|
|
115
|
-
this.adapter = adapter;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
public static sourceIdToIeeeAddress(sourceId: number): string {
|
|
119
|
-
return `0x${sourceId.toString(16).padStart(16, "0")}`;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
private encryptSecurityKey(sourceID: number, securityKey: Buffer): Buffer {
|
|
123
|
-
const nonce = Buffer.alloc(13);
|
|
124
|
-
|
|
125
|
-
nonce.writeUInt32LE(sourceID, 0);
|
|
126
|
-
nonce.writeUInt32LE(sourceID, 4);
|
|
127
|
-
nonce.writeUInt32LE(sourceID, 8);
|
|
128
|
-
nonce.writeUInt8(0x05, 12);
|
|
129
|
-
|
|
130
|
-
const cipher = createCipheriv("aes-128-ccm", Buffer.from(INTEROPERABILITY_LINK_KEY), nonce, {authTagLength: 16});
|
|
131
|
-
const encrypted = cipher.update(securityKey);
|
|
132
|
-
|
|
133
|
-
return Buffer.concat([encrypted, cipher.final()]);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
private decryptPayload(sourceID: number, frameCounter: number, securityKey: Buffer, payload: Buffer): Buffer {
|
|
137
|
-
const nonce = Buffer.alloc(13);
|
|
138
|
-
|
|
139
|
-
nonce.writeUInt32LE(sourceID, 0);
|
|
140
|
-
nonce.writeUInt32LE(sourceID, 4);
|
|
141
|
-
nonce.writeUInt32LE(frameCounter, 8);
|
|
142
|
-
nonce.writeUInt8(0x05, 12);
|
|
143
|
-
|
|
144
|
-
const [, decryptedPayload] = aes128CcmStar(4, securityKey, nonce, payload);
|
|
145
|
-
|
|
146
|
-
return decryptedPayload;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
public static encodePairingOptions(options: PairingOptions): number {
|
|
150
|
-
return (
|
|
151
|
-
(options.appId & 0x7) |
|
|
152
|
-
(((options.addSink ? 1 : 0) << 3) & 0x8) |
|
|
153
|
-
(((options.removeGpd ? 1 : 0) << 4) & 0x10) |
|
|
154
|
-
((options.communicationMode << 5) & 0x60) |
|
|
155
|
-
(((options.gpdFixed ? 1 : 0) << 7) & 0x80) |
|
|
156
|
-
(((options.gpdMacSeqNumCapabilities ? 1 : 0) << 8) & 0x100) |
|
|
157
|
-
((options.securityLevel << 9) & 0x600) |
|
|
158
|
-
((options.securityKeyType << 11) & 0x3800) |
|
|
159
|
-
(((options.gpdSecurityFrameCounterPresent ? 1 : 0) << 14) & 0x4000) |
|
|
160
|
-
(((options.gpdSecurityKeyPresent ? 1 : 0) << 15) & 0x8000) |
|
|
161
|
-
(((options.assignedAliasPresent ? 1 : 0) << 16) & 0x10000) |
|
|
162
|
-
(((options.groupcastRadiusPresent ? 1 : 0) << 17) & 0x20000)
|
|
163
|
-
// bits 18..23 reserved
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
public static decodePairingOptions(byte: number): PairingOptions {
|
|
168
|
-
return {
|
|
169
|
-
appId: byte & 0x7,
|
|
170
|
-
addSink: Boolean((byte & 0x8) >> 3),
|
|
171
|
-
removeGpd: Boolean((byte & 0x10) >> 4),
|
|
172
|
-
communicationMode: (byte & 0x60) >> 5,
|
|
173
|
-
gpdFixed: Boolean((byte & 0x80) >> 7),
|
|
174
|
-
gpdMacSeqNumCapabilities: Boolean((byte & 0x100) >> 8),
|
|
175
|
-
securityLevel: (byte & 0x600) >> 9,
|
|
176
|
-
securityKeyType: (byte & 0x3800) >> 11,
|
|
177
|
-
gpdSecurityFrameCounterPresent: Boolean((byte & 0x4000) >> 14),
|
|
178
|
-
gpdSecurityKeyPresent: Boolean((byte & 0x8000) >> 15),
|
|
179
|
-
assignedAliasPresent: Boolean((byte & 0x10000) >> 16),
|
|
180
|
-
groupcastRadiusPresent: Boolean((byte & 0x20000) >> 17),
|
|
181
|
-
// bits 18..23 reserved
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/** see 14-0563-19 A.3.3.5.2 */
|
|
186
|
-
private async sendPairingCommand(
|
|
187
|
-
options: PairingOptions,
|
|
188
|
-
payload: PairingPayload,
|
|
189
|
-
gppNwkAddr: number | undefined,
|
|
190
|
-
): Promise<AdapterEvents.ZclPayload | undefined> {
|
|
191
|
-
payload.options = GreenPower.encodePairingOptions(options);
|
|
192
|
-
logger.debug(
|
|
193
|
-
`[PAIRING] srcID=${payload.srcID} gpp=${gppNwkAddr ?? "NO"} options=${payload.options} (addSink=${options.addSink} commMode=${options.communicationMode})`,
|
|
194
|
-
NS,
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
// Set sink address based on communication mode
|
|
198
|
-
switch (options.communicationMode) {
|
|
199
|
-
case GPCommunicationMode.GroupcastToPrecommissionedGroupId:
|
|
200
|
-
case GPCommunicationMode.GroupcastToDgroupId: {
|
|
201
|
-
payload.sinkGroupID = GP_GROUP_ID;
|
|
202
|
-
break;
|
|
203
|
-
}
|
|
204
|
-
/* v8 ignore next */
|
|
205
|
-
case GPCommunicationMode.FullUnicast:
|
|
206
|
-
case GPCommunicationMode.LightweightUnicast: {
|
|
207
|
-
payload.sinkIEEEAddr = await this.adapter.getCoordinatorIEEE();
|
|
208
|
-
payload.sinkNwkAddr = COORDINATOR_ADDRESS;
|
|
209
|
-
break;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
const replyFrame = Zcl.Frame.create(
|
|
214
|
-
Zcl.FrameType.SPECIFIC,
|
|
215
|
-
Zcl.Direction.SERVER_TO_CLIENT,
|
|
216
|
-
true,
|
|
217
|
-
undefined,
|
|
218
|
-
zclTransactionSequenceNumber.next(),
|
|
219
|
-
"pairing",
|
|
220
|
-
Zcl.Clusters.greenPower.ID,
|
|
221
|
-
payload,
|
|
222
|
-
{},
|
|
223
|
-
);
|
|
224
|
-
|
|
225
|
-
if (options.communicationMode !== GPCommunicationMode.LightweightUnicast) {
|
|
226
|
-
await this.adapter.sendZclFrameToAll(GP_ENDPOINT, replyFrame, GP_ENDPOINT, BroadcastAddress.RX_ON_WHEN_IDLE);
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
const device = Device.byNetworkAddress(gppNwkAddr ?? /* v8 ignore next */ COORDINATOR_ADDRESS);
|
|
231
|
-
assert(device, "Failed to find green power proxy device");
|
|
232
|
-
|
|
233
|
-
return await this.adapter.sendZclFrameToEndpoint(
|
|
234
|
-
device.ieeeAddr,
|
|
235
|
-
device.networkAddress,
|
|
236
|
-
GP_ENDPOINT,
|
|
237
|
-
replyFrame,
|
|
238
|
-
10000,
|
|
239
|
-
false,
|
|
240
|
-
false,
|
|
241
|
-
GP_ENDPOINT,
|
|
242
|
-
);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
public async processCommand(dataPayload: AdapterEvents.ZclPayload, frame: Zcl.Frame, securityKey?: Buffer): Promise<Zcl.Frame> {
|
|
246
|
-
try {
|
|
247
|
-
// notification: A.3.3.4.1
|
|
248
|
-
// commissioningNotification: A.3.3.4.3
|
|
249
|
-
const isCommissioningNotification = frame.header.commandIdentifier === Zcl.Clusters.greenPower.commands.commissioningNotification.ID;
|
|
250
|
-
const securityLevel = isCommissioningNotification ? (frame.payload.options >> 4) & 0x3 : (frame.payload.options >> 6) & 0x3;
|
|
251
|
-
|
|
252
|
-
if (
|
|
253
|
-
securityLevel === ZigbeeNWKGPSecurityLevel.FullEncr &&
|
|
254
|
-
(!isCommissioningNotification || ((frame.payload.options >> 9) & 0x1) === 1) /* security processing failed */
|
|
255
|
-
) {
|
|
256
|
-
if (!securityKey) {
|
|
257
|
-
logger.error(
|
|
258
|
-
`[FULLENCR] srcID=${frame.payload.srcID} gpp=${frame.payload.gppNwkAddr ?? "NO"} commandIdentifier=${frame.header.commandIdentifier} Unknown security key`,
|
|
259
|
-
NS,
|
|
260
|
-
);
|
|
261
|
-
return frame;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
const oldHeader = dataPayload.data.subarray(0, 15);
|
|
265
|
-
let dataEndOffset = dataPayload.data.byteLength;
|
|
266
|
-
|
|
267
|
-
if (isCommissioningNotification) {
|
|
268
|
-
const hasMic = frame.payload.options & 0x200;
|
|
269
|
-
const hasGppData = frame.payload.options & 0x800;
|
|
270
|
-
|
|
271
|
-
if (hasGppData) {
|
|
272
|
-
dataEndOffset -= 3;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
if (hasMic) {
|
|
276
|
-
dataEndOffset -= 4;
|
|
277
|
-
}
|
|
278
|
-
} else {
|
|
279
|
-
const hasGppData = frame.payload.options & 0x4000;
|
|
280
|
-
|
|
281
|
-
if (hasGppData) {
|
|
282
|
-
dataEndOffset -= 3;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
const hashedKey = this.encryptSecurityKey(frame.payload.srcID, securityKey);
|
|
287
|
-
// 4 bytes appended for MIC placeholder (just needs the bytes present for decrypt)
|
|
288
|
-
const payload = Buffer.from([frame.payload.commandID, ...dataPayload.data.subarray(15, dataEndOffset), 0, 0, 0, 0]);
|
|
289
|
-
const decrypted = this.decryptPayload(frame.payload.srcID, frame.payload.frameCounter, hashedKey, payload);
|
|
290
|
-
const newHeader = Buffer.alloc(15);
|
|
291
|
-
newHeader.set(oldHeader, 0);
|
|
292
|
-
// flip necessary bits in options before re-parsing
|
|
293
|
-
// - "securityLevel" to ZigbeeNWKGPSecurityLevel.NO (for ease) and "securityProcessingFailed" to 0
|
|
294
|
-
// - "securityLevel" to ZigbeeNWKGPSecurityLevel.NO (for ease)
|
|
295
|
-
newHeader.writeUInt16LE(isCommissioningNotification ? frame.payload.options & ~0x30 & ~0x200 : frame.payload.options & ~0xc0, 3);
|
|
296
|
-
newHeader.writeUInt8(decrypted[0], oldHeader.byteLength - 2); // commandID
|
|
297
|
-
newHeader.writeUInt8(decrypted.byteLength - 1, oldHeader.byteLength - 1); // payloadSize
|
|
298
|
-
|
|
299
|
-
// re-parse with decrypted data
|
|
300
|
-
frame = Zcl.Frame.fromBuffer(
|
|
301
|
-
dataPayload.clusterID,
|
|
302
|
-
dataPayload.header,
|
|
303
|
-
Buffer.concat([newHeader, decrypted.subarray(1), dataPayload.data.subarray(dataEndOffset)]),
|
|
304
|
-
{},
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
let logStr: string;
|
|
309
|
-
|
|
310
|
-
/* v8 ignore start */
|
|
311
|
-
if (frame.payload.gppGpdLink !== undefined) {
|
|
312
|
-
const rssi = frame.payload.gppGpdLink & 0x3f;
|
|
313
|
-
const linkQuality = (frame.payload.gppGpdLink >> 6) & 0x3;
|
|
314
|
-
let linkQualityStr: string | undefined;
|
|
315
|
-
|
|
316
|
-
switch (linkQuality) {
|
|
317
|
-
case 0b00:
|
|
318
|
-
linkQualityStr = "Poor";
|
|
319
|
-
break;
|
|
320
|
-
case 0b01:
|
|
321
|
-
linkQualityStr = "Moderate";
|
|
322
|
-
break;
|
|
323
|
-
case 0b10:
|
|
324
|
-
linkQualityStr = "High";
|
|
325
|
-
break;
|
|
326
|
-
case 0b11:
|
|
327
|
-
linkQualityStr = "Excellent";
|
|
328
|
-
break;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
logStr = `srcID=${frame.payload.srcID} gpp=${frame.payload.gppNwkAddr} rssi=${rssi} linkQuality=${linkQualityStr}`;
|
|
332
|
-
} else {
|
|
333
|
-
logStr = `srcID=${frame.payload.srcID} gpp=NO`;
|
|
334
|
-
}
|
|
335
|
-
/* v8 ignore stop */
|
|
336
|
-
|
|
337
|
-
switch (frame.payload.commandID) {
|
|
338
|
-
case 0xe0: {
|
|
339
|
-
logger.info(`[COMMISSIONING] ${logStr}`, NS);
|
|
340
|
-
|
|
341
|
-
/* v8 ignore start */
|
|
342
|
-
if (frame.payload.options & 0x200) {
|
|
343
|
-
logger.warning(`[COMMISSIONING] ${logStr} Security processing marked as failed`, NS);
|
|
344
|
-
}
|
|
345
|
-
/* v8 ignore stop */
|
|
346
|
-
|
|
347
|
-
const rxOnCap = frame.payload.commandFrame.options & 0x2;
|
|
348
|
-
const gpdMacSeqNumCapabilities = Boolean(frame.payload.commandFrame.options & 0x1);
|
|
349
|
-
const gpdFixed = Boolean(frame.payload.commandFrame.options & 0x40);
|
|
350
|
-
|
|
351
|
-
if (rxOnCap) {
|
|
352
|
-
// RX capable GPD needs GP Commissioning Reply
|
|
353
|
-
logger.debug(`[COMMISSIONING] ${logStr} GPD has receiving capabilities in operational mode (RxOnCapability)`, NS);
|
|
354
|
-
// NOTE: currently encryption is disabled for RX capable GPDs
|
|
355
|
-
|
|
356
|
-
const networkParameters = await this.adapter.getNetworkParameters();
|
|
357
|
-
// Commissioning reply
|
|
358
|
-
const payloadResponse: ResponsePayload<GpdCommissioningReply> = {
|
|
359
|
-
options: 0,
|
|
360
|
-
tempMaster: frame.payload.gppNwkAddr ?? /* v8 ignore next */ COORDINATOR_ADDRESS,
|
|
361
|
-
tempMasterTx: networkParameters.channel - 11,
|
|
362
|
-
srcID: frame.payload.srcID,
|
|
363
|
-
gpdCmd: 0xf0,
|
|
364
|
-
gpdPayload: {
|
|
365
|
-
commandID: 0xf0,
|
|
366
|
-
options: 0b00000000, // Disable encryption
|
|
367
|
-
// panID: number,
|
|
368
|
-
// securityKey: frame.payload.commandFrame.securityKey,
|
|
369
|
-
// keyMic: frame.payload.commandFrame.keyMic,
|
|
370
|
-
// frameCounter: number,
|
|
371
|
-
},
|
|
372
|
-
};
|
|
373
|
-
|
|
374
|
-
const replyFrame = Zcl.Frame.create(
|
|
375
|
-
Zcl.FrameType.SPECIFIC,
|
|
376
|
-
Zcl.Direction.SERVER_TO_CLIENT,
|
|
377
|
-
true,
|
|
378
|
-
undefined,
|
|
379
|
-
zclTransactionSequenceNumber.next(),
|
|
380
|
-
"response",
|
|
381
|
-
Zcl.Clusters.greenPower.ID,
|
|
382
|
-
payloadResponse,
|
|
383
|
-
{},
|
|
384
|
-
);
|
|
385
|
-
|
|
386
|
-
await this.adapter.sendZclFrameToAll(GP_ENDPOINT, replyFrame, GP_ENDPOINT, BroadcastAddress.RX_ON_WHEN_IDLE);
|
|
387
|
-
|
|
388
|
-
await this.sendPairingCommand(
|
|
389
|
-
{
|
|
390
|
-
appId: ZigbeeNWKGPAppId.Default,
|
|
391
|
-
addSink: true,
|
|
392
|
-
removeGpd: false,
|
|
393
|
-
communicationMode: GPCommunicationMode.GroupcastToDgroupId,
|
|
394
|
-
gpdFixed,
|
|
395
|
-
gpdMacSeqNumCapabilities,
|
|
396
|
-
securityLevel: ZigbeeNWKGPSecurityLevel.No,
|
|
397
|
-
securityKeyType: ZigbeeNWKGPSecurityKeyType.NoKey,
|
|
398
|
-
gpdSecurityFrameCounterPresent: false,
|
|
399
|
-
gpdSecurityKeyPresent: false,
|
|
400
|
-
assignedAliasPresent: false,
|
|
401
|
-
groupcastRadiusPresent: false,
|
|
402
|
-
},
|
|
403
|
-
{
|
|
404
|
-
options: 0, // set from first param in `sendPairingCommand`
|
|
405
|
-
srcID: frame.payload.srcID,
|
|
406
|
-
deviceID: frame.payload.commandFrame.deviceID,
|
|
407
|
-
},
|
|
408
|
-
frame.payload.gppNwkAddr,
|
|
409
|
-
);
|
|
410
|
-
} else {
|
|
411
|
-
const gpdKey = this.encryptSecurityKey(frame.payload.srcID, frame.payload.commandFrame.securityKey);
|
|
412
|
-
|
|
413
|
-
await this.sendPairingCommand(
|
|
414
|
-
{
|
|
415
|
-
appId: ZigbeeNWKGPAppId.Default,
|
|
416
|
-
addSink: true,
|
|
417
|
-
removeGpd: false,
|
|
418
|
-
// keep communication mode matching incoming tx mode
|
|
419
|
-
communicationMode: dataPayload.wasBroadcast
|
|
420
|
-
? GPCommunicationMode.GroupcastToPrecommissionedGroupId
|
|
421
|
-
: GPCommunicationMode.LightweightUnicast,
|
|
422
|
-
gpdFixed,
|
|
423
|
-
gpdMacSeqNumCapabilities,
|
|
424
|
-
securityLevel: ZigbeeNWKGPSecurityLevel.Full,
|
|
425
|
-
securityKeyType: ZigbeeNWKGPSecurityKeyType.PreconfiguredIndividualGpdKey,
|
|
426
|
-
gpdSecurityFrameCounterPresent: true,
|
|
427
|
-
gpdSecurityKeyPresent: true,
|
|
428
|
-
assignedAliasPresent: false,
|
|
429
|
-
groupcastRadiusPresent: false,
|
|
430
|
-
},
|
|
431
|
-
{
|
|
432
|
-
options: 0, // set from first param in `sendPairingCommand`
|
|
433
|
-
srcID: frame.payload.srcID,
|
|
434
|
-
deviceID: frame.payload.commandFrame.deviceID,
|
|
435
|
-
frameCounter: frame.payload.commandFrame.outgoingCounter,
|
|
436
|
-
gpdKey,
|
|
437
|
-
},
|
|
438
|
-
frame.payload.gppNwkAddr,
|
|
439
|
-
);
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
this.emit("deviceJoined", {
|
|
443
|
-
sourceID: frame.payload.srcID,
|
|
444
|
-
deviceID: frame.payload.commandFrame.deviceID,
|
|
445
|
-
// XXX: this has the potential to create conflicting network addresses
|
|
446
|
-
networkAddress: frame.payload.srcID & 0xffff,
|
|
447
|
-
securityKey: frame.payload.commandFrame.securityKey,
|
|
448
|
-
});
|
|
449
|
-
|
|
450
|
-
break;
|
|
451
|
-
}
|
|
452
|
-
case 0xe1: {
|
|
453
|
-
logger.debug(`[DECOMMISSIONING] ${logStr}`, NS);
|
|
454
|
-
|
|
455
|
-
await this.sendPairingCommand(
|
|
456
|
-
{
|
|
457
|
-
appId: ZigbeeNWKGPAppId.Default,
|
|
458
|
-
addSink: false,
|
|
459
|
-
removeGpd: true,
|
|
460
|
-
communicationMode: GPCommunicationMode.GroupcastToDgroupId,
|
|
461
|
-
gpdFixed: false,
|
|
462
|
-
gpdMacSeqNumCapabilities: false,
|
|
463
|
-
securityLevel: ZigbeeNWKGPSecurityLevel.No,
|
|
464
|
-
securityKeyType: ZigbeeNWKGPSecurityKeyType.NoKey,
|
|
465
|
-
gpdSecurityFrameCounterPresent: false,
|
|
466
|
-
gpdSecurityKeyPresent: false,
|
|
467
|
-
assignedAliasPresent: false,
|
|
468
|
-
groupcastRadiusPresent: false,
|
|
469
|
-
},
|
|
470
|
-
{
|
|
471
|
-
options: 0, // set from first param in `sendPairingCommand`
|
|
472
|
-
srcID: frame.payload.srcID,
|
|
473
|
-
},
|
|
474
|
-
frame.payload.gppNwkAddr,
|
|
475
|
-
);
|
|
476
|
-
|
|
477
|
-
this.emit("deviceLeave", frame.payload.srcID);
|
|
478
|
-
|
|
479
|
-
break;
|
|
480
|
-
}
|
|
481
|
-
/* v8 ignore start */
|
|
482
|
-
case 0xe2: {
|
|
483
|
-
logger.debug(`[SUCCESS] ${logStr}`, NS);
|
|
484
|
-
break;
|
|
485
|
-
}
|
|
486
|
-
/* v8 ignore stop */
|
|
487
|
-
case 0xe3: {
|
|
488
|
-
logger.debug(`[CHANNEL_REQUEST] ${logStr}`, NS);
|
|
489
|
-
const networkParameters = await this.adapter.getNetworkParameters();
|
|
490
|
-
// Channel notification
|
|
491
|
-
const payload: ResponsePayload<GpdChannelConfiguration> = {
|
|
492
|
-
options: 0,
|
|
493
|
-
tempMaster: frame.payload.gppNwkAddr ?? /* v8 ignore next */ COORDINATOR_ADDRESS,
|
|
494
|
-
tempMasterTx: frame.payload.commandFrame.nextChannel,
|
|
495
|
-
srcID: frame.payload.srcID,
|
|
496
|
-
gpdCmd: 0xf3,
|
|
497
|
-
gpdPayload: {
|
|
498
|
-
commandID: 0xf3,
|
|
499
|
-
operationalChannel: networkParameters.channel - 11,
|
|
500
|
-
// If EITHER the sink is a GP Basic sink OR the sink is a GP Advanced sink,
|
|
501
|
-
// but all of the candidate TempMasters are GP Basic proxies (as indicated by the BidirectionalCommunicationCapability
|
|
502
|
-
// sub-field of the Options field of the received GP Commissioning Notification set to 0b0),
|
|
503
|
-
// the sink SHALL set the Basic sub-field of the Channel field to 0b1.
|
|
504
|
-
basic: true,
|
|
505
|
-
},
|
|
506
|
-
};
|
|
507
|
-
|
|
508
|
-
const replyFrame = Zcl.Frame.create(
|
|
509
|
-
Zcl.FrameType.SPECIFIC,
|
|
510
|
-
Zcl.Direction.SERVER_TO_CLIENT,
|
|
511
|
-
true,
|
|
512
|
-
undefined,
|
|
513
|
-
zclTransactionSequenceNumber.next(),
|
|
514
|
-
"response",
|
|
515
|
-
Zcl.Clusters.greenPower.ID,
|
|
516
|
-
payload,
|
|
517
|
-
{},
|
|
518
|
-
);
|
|
519
|
-
|
|
520
|
-
await this.adapter.sendZclFrameToAll(GP_ENDPOINT, replyFrame, GP_ENDPOINT, BroadcastAddress.RX_ON_WHEN_IDLE);
|
|
521
|
-
break;
|
|
522
|
-
}
|
|
523
|
-
/* v8 ignore start */
|
|
524
|
-
case 0xe4: {
|
|
525
|
-
logger.debug(`[APP_DESCRIPTION] ${logStr}`, NS);
|
|
526
|
-
break;
|
|
527
|
-
}
|
|
528
|
-
case 0xa1: {
|
|
529
|
-
// GP Manufacturer-specific Attribute Reporting
|
|
530
|
-
break;
|
|
531
|
-
}
|
|
532
|
-
/* v8 ignore stop */
|
|
533
|
-
default: {
|
|
534
|
-
// NOTE: this is spammy because it logs everything that is handed back to Controller without special processing here
|
|
535
|
-
logger.debug(`[UNHANDLED_CMD/PASSTHROUGH] command=0x${frame.payload.commandID.toString(16)} ${logStr}`, NS);
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
/* v8 ignore start */
|
|
539
|
-
} catch (error) {
|
|
540
|
-
// biome-ignore lint/style/noNonNullAssertion: ignored using `--suppress`
|
|
541
|
-
logger.error((error as Error).stack!, NS);
|
|
542
|
-
}
|
|
543
|
-
/* v8 ignore stop */
|
|
544
|
-
|
|
545
|
-
return frame;
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
public static encodeCommissioningModeOptions(options: CommissioningModeOptions): number {
|
|
549
|
-
return (
|
|
550
|
-
(options.action & 0x1) |
|
|
551
|
-
(((options.commissioningWindowPresent ? 1 : 0) << 1) & 0x2) |
|
|
552
|
-
((options.exitMode << 2) & 0x0c) |
|
|
553
|
-
(((options.channelPresent ? 1 : 0) << 4) & 0x10) |
|
|
554
|
-
(((options.unicastCommunication ? 1 : 0) << 5) & 0x20)
|
|
555
|
-
);
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
public static decodeCommissioningModeOptions(byte: number): CommissioningModeOptions {
|
|
559
|
-
return {
|
|
560
|
-
action: byte & 0x1,
|
|
561
|
-
commissioningWindowPresent: Boolean((byte & 0x2) >> 1),
|
|
562
|
-
exitMode: (byte & 0x0c) >> 2,
|
|
563
|
-
channelPresent: Boolean((byte & 0x10) >> 4),
|
|
564
|
-
unicastCommunication: Boolean((byte & 0x20) >> 5),
|
|
565
|
-
};
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
public async permitJoin(time: number, networkAddress?: number): Promise<void> {
|
|
569
|
-
const payload = {
|
|
570
|
-
options: GreenPower.encodeCommissioningModeOptions({
|
|
571
|
-
action: time > 0 ? 1 : 0,
|
|
572
|
-
commissioningWindowPresent: true,
|
|
573
|
-
exitMode: 0b10,
|
|
574
|
-
channelPresent: false,
|
|
575
|
-
unicastCommunication: networkAddress !== undefined,
|
|
576
|
-
}),
|
|
577
|
-
commisioningWindow: time,
|
|
578
|
-
};
|
|
579
|
-
|
|
580
|
-
const frame = Zcl.Frame.create(
|
|
581
|
-
Zcl.FrameType.SPECIFIC,
|
|
582
|
-
Zcl.Direction.SERVER_TO_CLIENT,
|
|
583
|
-
true, // avoid receiving many responses, especially from the nodes not supporting this functionality
|
|
584
|
-
undefined,
|
|
585
|
-
zclTransactionSequenceNumber.next(),
|
|
586
|
-
"commisioningMode",
|
|
587
|
-
Zcl.Clusters.greenPower.ID,
|
|
588
|
-
payload,
|
|
589
|
-
{},
|
|
590
|
-
);
|
|
591
|
-
|
|
592
|
-
if (networkAddress === undefined) {
|
|
593
|
-
await this.adapter.sendZclFrameToAll(GP_ENDPOINT, frame, GP_ENDPOINT, BroadcastAddress.RX_ON_WHEN_IDLE);
|
|
594
|
-
} else {
|
|
595
|
-
const device = Device.byNetworkAddress(networkAddress);
|
|
596
|
-
assert(device, "Failed to find device to permit GP join on");
|
|
597
|
-
|
|
598
|
-
await this.adapter.sendZclFrameToEndpoint(device.ieeeAddr, networkAddress, GP_ENDPOINT, frame, 10000, false, false, GP_ENDPOINT);
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
export default GreenPower;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * as ZclFrameConverter from "./zclFrameConverter";
|