@matter/protocol 0.16.0-alpha.0-20251104-8c3166ea3 → 0.16.0-alpha.0-20251107-6bcb5baf4
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/dist/cjs/action/client/ClientInteraction.d.ts +1 -0
- package/dist/cjs/action/client/ClientInteraction.d.ts.map +1 -1
- package/dist/cjs/action/client/ClientInteraction.js +3 -0
- package/dist/cjs/action/client/ClientInteraction.js.map +1 -1
- package/dist/cjs/action/client/subscription/ClientSubscriptionHandler.js +2 -4
- package/dist/cjs/action/client/subscription/ClientSubscriptionHandler.js.map +1 -1
- package/dist/cjs/advertisement/PairingHintBitmap.d.ts +2 -2
- package/dist/cjs/advertisement/PairingHintBitmap.js +1 -1
- package/dist/cjs/advertisement/PairingHintBitmap.js.map +1 -1
- package/dist/cjs/advertisement/mdns/CommissionableMdnsAdvertisement.d.ts.map +1 -1
- package/dist/cjs/advertisement/mdns/CommissionableMdnsAdvertisement.js +22 -4
- package/dist/cjs/advertisement/mdns/CommissionableMdnsAdvertisement.js.map +1 -1
- package/dist/cjs/certificate/index.d.ts +1 -0
- package/dist/cjs/certificate/index.d.ts.map +1 -1
- package/dist/cjs/certificate/index.js +1 -0
- package/dist/cjs/certificate/index.js.map +1 -1
- package/dist/cjs/certificate/kinds/Icac.d.ts +2 -0
- package/dist/cjs/certificate/kinds/Icac.d.ts.map +1 -1
- package/dist/cjs/certificate/kinds/Icac.js +9 -0
- package/dist/cjs/certificate/kinds/Icac.js.map +1 -1
- package/dist/cjs/certificate/kinds/Noc.d.ts +2 -0
- package/dist/cjs/certificate/kinds/Noc.d.ts.map +1 -1
- package/dist/cjs/certificate/kinds/Noc.js +9 -0
- package/dist/cjs/certificate/kinds/Noc.js.map +1 -1
- package/dist/cjs/certificate/kinds/OperationalBase.d.ts +6 -1
- package/dist/cjs/certificate/kinds/OperationalBase.d.ts.map +1 -1
- package/dist/cjs/certificate/kinds/OperationalBase.js +14 -0
- package/dist/cjs/certificate/kinds/OperationalBase.js.map +1 -1
- package/dist/cjs/certificate/kinds/Rcac.d.ts +2 -0
- package/dist/cjs/certificate/kinds/Rcac.d.ts.map +1 -1
- package/dist/cjs/certificate/kinds/Rcac.js +9 -0
- package/dist/cjs/certificate/kinds/Rcac.js.map +1 -1
- package/dist/cjs/certificate/kinds/Vvsc.d.ts +29 -0
- package/dist/cjs/certificate/kinds/Vvsc.d.ts.map +1 -0
- package/dist/cjs/certificate/kinds/Vvsc.js +79 -0
- package/dist/cjs/certificate/kinds/Vvsc.js.map +6 -0
- package/dist/cjs/certificate/kinds/X509Base.d.ts +10 -3
- package/dist/cjs/certificate/kinds/X509Base.d.ts.map +1 -1
- package/dist/cjs/certificate/kinds/X509Base.js +304 -13
- package/dist/cjs/certificate/kinds/X509Base.js.map +2 -2
- package/dist/cjs/certificate/kinds/definitions/asn.d.ts +15 -0
- package/dist/cjs/certificate/kinds/definitions/asn.d.ts.map +1 -1
- package/dist/cjs/certificate/kinds/definitions/asn.js +33 -21
- package/dist/cjs/certificate/kinds/definitions/asn.js.map +2 -2
- package/dist/cjs/certificate/kinds/definitions/operational.d.ts +121 -12
- package/dist/cjs/certificate/kinds/definitions/operational.d.ts.map +1 -1
- package/dist/cjs/certificate/kinds/definitions/operational.js +8 -2
- package/dist/cjs/certificate/kinds/definitions/operational.js.map +1 -1
- package/dist/cjs/certificate/kinds/index.d.ts +1 -0
- package/dist/cjs/certificate/kinds/index.d.ts.map +1 -1
- package/dist/cjs/certificate/kinds/index.js +1 -0
- package/dist/cjs/certificate/kinds/index.js.map +1 -1
- package/dist/cjs/fabric/Fabric.d.ts +6 -1
- package/dist/cjs/fabric/Fabric.d.ts.map +1 -1
- package/dist/cjs/fabric/Fabric.js +53 -2
- package/dist/cjs/fabric/Fabric.js.map +1 -1
- package/dist/cjs/fabric/FabricManager.d.ts.map +1 -1
- package/dist/cjs/fabric/FabricManager.js +24 -9
- package/dist/cjs/fabric/FabricManager.js.map +1 -1
- package/dist/cjs/mdns/MdnsConsts.d.ts +1 -1
- package/dist/cjs/mdns/MdnsConsts.d.ts.map +1 -1
- package/dist/cjs/mdns/MdnsConsts.js +1 -1
- package/dist/cjs/peer/PhysicalDeviceProperties.d.ts +11 -7
- package/dist/cjs/peer/PhysicalDeviceProperties.d.ts.map +1 -1
- package/dist/cjs/peer/PhysicalDeviceProperties.js +34 -25
- package/dist/cjs/peer/PhysicalDeviceProperties.js.map +1 -1
- package/dist/cjs/protocol/DeviceAdvertiser.d.ts.map +1 -1
- package/dist/cjs/protocol/DeviceAdvertiser.js +17 -0
- package/dist/cjs/protocol/DeviceAdvertiser.js.map +1 -1
- package/dist/esm/action/client/ClientInteraction.d.ts +1 -0
- package/dist/esm/action/client/ClientInteraction.d.ts.map +1 -1
- package/dist/esm/action/client/ClientInteraction.js +3 -0
- package/dist/esm/action/client/ClientInteraction.js.map +1 -1
- package/dist/esm/action/client/subscription/ClientSubscriptionHandler.js +2 -4
- package/dist/esm/action/client/subscription/ClientSubscriptionHandler.js.map +1 -1
- package/dist/esm/advertisement/PairingHintBitmap.d.ts +2 -2
- package/dist/esm/advertisement/PairingHintBitmap.js +1 -1
- package/dist/esm/advertisement/PairingHintBitmap.js.map +1 -1
- package/dist/esm/advertisement/mdns/CommissionableMdnsAdvertisement.d.ts.map +1 -1
- package/dist/esm/advertisement/mdns/CommissionableMdnsAdvertisement.js +22 -4
- package/dist/esm/advertisement/mdns/CommissionableMdnsAdvertisement.js.map +1 -1
- package/dist/esm/certificate/index.d.ts +1 -0
- package/dist/esm/certificate/index.d.ts.map +1 -1
- package/dist/esm/certificate/index.js +1 -0
- package/dist/esm/certificate/index.js.map +1 -1
- package/dist/esm/certificate/kinds/Icac.d.ts +2 -0
- package/dist/esm/certificate/kinds/Icac.d.ts.map +1 -1
- package/dist/esm/certificate/kinds/Icac.js +9 -0
- package/dist/esm/certificate/kinds/Icac.js.map +1 -1
- package/dist/esm/certificate/kinds/Noc.d.ts +2 -0
- package/dist/esm/certificate/kinds/Noc.d.ts.map +1 -1
- package/dist/esm/certificate/kinds/Noc.js +9 -0
- package/dist/esm/certificate/kinds/Noc.js.map +1 -1
- package/dist/esm/certificate/kinds/OperationalBase.d.ts +6 -1
- package/dist/esm/certificate/kinds/OperationalBase.d.ts.map +1 -1
- package/dist/esm/certificate/kinds/OperationalBase.js +16 -2
- package/dist/esm/certificate/kinds/OperationalBase.js.map +1 -1
- package/dist/esm/certificate/kinds/Rcac.d.ts +2 -0
- package/dist/esm/certificate/kinds/Rcac.d.ts.map +1 -1
- package/dist/esm/certificate/kinds/Rcac.js +9 -0
- package/dist/esm/certificate/kinds/Rcac.js.map +1 -1
- package/dist/esm/certificate/kinds/Vvsc.d.ts +29 -0
- package/dist/esm/certificate/kinds/Vvsc.d.ts.map +1 -0
- package/dist/esm/certificate/kinds/Vvsc.js +59 -0
- package/dist/esm/certificate/kinds/Vvsc.js.map +6 -0
- package/dist/esm/certificate/kinds/X509Base.d.ts +10 -3
- package/dist/esm/certificate/kinds/X509Base.d.ts.map +1 -1
- package/dist/esm/certificate/kinds/X509Base.js +308 -14
- package/dist/esm/certificate/kinds/X509Base.js.map +2 -2
- package/dist/esm/certificate/kinds/definitions/asn.d.ts +15 -0
- package/dist/esm/certificate/kinds/definitions/asn.d.ts.map +1 -1
- package/dist/esm/certificate/kinds/definitions/asn.js +33 -21
- package/dist/esm/certificate/kinds/definitions/asn.js.map +1 -1
- package/dist/esm/certificate/kinds/definitions/operational.d.ts +121 -12
- package/dist/esm/certificate/kinds/definitions/operational.d.ts.map +1 -1
- package/dist/esm/certificate/kinds/definitions/operational.js +8 -2
- package/dist/esm/certificate/kinds/definitions/operational.js.map +1 -1
- package/dist/esm/certificate/kinds/index.d.ts +1 -0
- package/dist/esm/certificate/kinds/index.d.ts.map +1 -1
- package/dist/esm/certificate/kinds/index.js +1 -0
- package/dist/esm/certificate/kinds/index.js.map +1 -1
- package/dist/esm/fabric/Fabric.d.ts +6 -1
- package/dist/esm/fabric/Fabric.d.ts.map +1 -1
- package/dist/esm/fabric/Fabric.js +54 -3
- package/dist/esm/fabric/Fabric.js.map +1 -1
- package/dist/esm/fabric/FabricManager.d.ts.map +1 -1
- package/dist/esm/fabric/FabricManager.js +25 -9
- package/dist/esm/fabric/FabricManager.js.map +1 -1
- package/dist/esm/mdns/MdnsConsts.d.ts +1 -1
- package/dist/esm/mdns/MdnsConsts.d.ts.map +1 -1
- package/dist/esm/mdns/MdnsConsts.js +1 -1
- package/dist/esm/peer/PhysicalDeviceProperties.d.ts +11 -7
- package/dist/esm/peer/PhysicalDeviceProperties.d.ts.map +1 -1
- package/dist/esm/peer/PhysicalDeviceProperties.js +35 -26
- package/dist/esm/peer/PhysicalDeviceProperties.js.map +1 -1
- package/dist/esm/protocol/DeviceAdvertiser.d.ts.map +1 -1
- package/dist/esm/protocol/DeviceAdvertiser.js +17 -0
- package/dist/esm/protocol/DeviceAdvertiser.js.map +1 -1
- package/package.json +6 -6
- package/src/action/client/ClientInteraction.ts +5 -1
- package/src/action/client/subscription/ClientSubscriptionHandler.ts +2 -4
- package/src/advertisement/PairingHintBitmap.ts +1 -1
- package/src/advertisement/mdns/CommissionableMdnsAdvertisement.ts +23 -6
- package/src/certificate/index.ts +1 -0
- package/src/certificate/kinds/Icac.ts +12 -0
- package/src/certificate/kinds/Noc.ts +12 -0
- package/src/certificate/kinds/OperationalBase.ts +18 -3
- package/src/certificate/kinds/Rcac.ts +12 -0
- package/src/certificate/kinds/Vvsc.ts +72 -0
- package/src/certificate/kinds/X509Base.ts +426 -7
- package/src/certificate/kinds/definitions/asn.ts +50 -24
- package/src/certificate/kinds/definitions/operational.ts +10 -2
- package/src/certificate/kinds/index.ts +1 -0
- package/src/fabric/Fabric.ts +66 -3
- package/src/fabric/FabricManager.ts +32 -9
- package/src/mdns/MdnsConsts.ts +1 -1
- package/src/peer/PhysicalDeviceProperties.ts +52 -35
- package/src/protocol/DeviceAdvertiser.ts +30 -0
package/src/fabric/Fabric.ts
CHANGED
|
@@ -29,7 +29,7 @@ import { FabricGroups, GROUP_SECURITY_INFO } from "#groups/FabricGroups.js";
|
|
|
29
29
|
import { FabricAccessControl } from "#interaction/FabricAccessControl.js";
|
|
30
30
|
import { PeerAddress } from "#peer/PeerAddress.js";
|
|
31
31
|
import { Session } from "#session/Session.js";
|
|
32
|
-
import { CaseAuthenticatedTag, FabricId, FabricIndex, GroupId, NodeId, VendorId } from "#types";
|
|
32
|
+
import { CaseAuthenticatedTag, FabricId, FabricIndex, GroupId, NodeId, StatusResponse, VendorId } from "#types";
|
|
33
33
|
|
|
34
34
|
const logger = Logger.get("Fabric");
|
|
35
35
|
|
|
@@ -54,7 +54,7 @@ export class Fabric {
|
|
|
54
54
|
readonly rootNodeId: NodeId;
|
|
55
55
|
readonly operationalId: Bytes;
|
|
56
56
|
readonly rootPublicKey: Bytes;
|
|
57
|
-
|
|
57
|
+
#rootVendorId: VendorId;
|
|
58
58
|
readonly rootCert: Bytes;
|
|
59
59
|
readonly identityProtectionKey: Bytes;
|
|
60
60
|
readonly operationalIdentityProtectionKey: Bytes;
|
|
@@ -64,6 +64,8 @@ export class Fabric {
|
|
|
64
64
|
readonly #sessions = new Set<Session>();
|
|
65
65
|
readonly #groups: FabricGroups;
|
|
66
66
|
readonly #accessControl: FabricAccessControl;
|
|
67
|
+
#vidVerificationStatement?: Bytes;
|
|
68
|
+
#vvsc?: Bytes;
|
|
67
69
|
#label: string;
|
|
68
70
|
#removeCallbacks = new Array<() => MaybePromise<void>>();
|
|
69
71
|
#persistCallback: ((isUpdate?: boolean) => MaybePromise<void>) | undefined;
|
|
@@ -77,12 +79,14 @@ export class Fabric {
|
|
|
77
79
|
this.rootNodeId = config.rootNodeId;
|
|
78
80
|
this.operationalId = config.operationalId;
|
|
79
81
|
this.rootPublicKey = config.rootPublicKey;
|
|
80
|
-
this
|
|
82
|
+
this.#rootVendorId = config.rootVendorId;
|
|
81
83
|
this.rootCert = config.rootCert;
|
|
82
84
|
this.identityProtectionKey = config.identityProtectionKey;
|
|
83
85
|
this.operationalIdentityProtectionKey = config.operationalIdentityProtectionKey;
|
|
84
86
|
this.intermediateCACert = config.intermediateCACert;
|
|
85
87
|
this.operationalCert = config.operationalCert;
|
|
88
|
+
this.#vidVerificationStatement = config.vidVerificationStatement;
|
|
89
|
+
this.#vvsc = config.vvsc;
|
|
86
90
|
this.#label = config.label;
|
|
87
91
|
this.#keyPair = PrivateKey(config.keyPair);
|
|
88
92
|
this.#accessControl = new FabricAccessControl(this);
|
|
@@ -108,6 +112,7 @@ export class Fabric {
|
|
|
108
112
|
operationalIdentityProtectionKey: this.operationalIdentityProtectionKey,
|
|
109
113
|
intermediateCACert: this.intermediateCACert,
|
|
110
114
|
operationalCert: this.operationalCert,
|
|
115
|
+
vidVerificationStatement: this.vidVerificationStatement,
|
|
111
116
|
label: this.#label,
|
|
112
117
|
};
|
|
113
118
|
}
|
|
@@ -127,6 +132,56 @@ export class Fabric {
|
|
|
127
132
|
await this.persist();
|
|
128
133
|
}
|
|
129
134
|
|
|
135
|
+
get vidVerificationStatement() {
|
|
136
|
+
return this.#vidVerificationStatement;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async updateVendorVerificationData(
|
|
140
|
+
vendorId: VendorId | undefined,
|
|
141
|
+
vidVerificationStatement: Bytes | undefined,
|
|
142
|
+
vvsc: Bytes | undefined,
|
|
143
|
+
) {
|
|
144
|
+
if (vvsc !== undefined && this.intermediateCACert !== undefined) {
|
|
145
|
+
throw new StatusResponse.InvalidCommandError("A VVSC is only allowed without an ICAC.");
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (vidVerificationStatement !== undefined) {
|
|
149
|
+
if (vidVerificationStatement.byteLength === 0) {
|
|
150
|
+
this.#vidVerificationStatement = undefined;
|
|
151
|
+
} else if (vidVerificationStatement.byteLength === 85) {
|
|
152
|
+
// VERIFICATION_STATEMENT_SIZE
|
|
153
|
+
this.#vidVerificationStatement = vidVerificationStatement;
|
|
154
|
+
} else {
|
|
155
|
+
throw new StatusResponse.ConstraintErrorError("VID Verification Statement must be 0 or 85 bytes long.");
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (vendorId !== undefined) {
|
|
159
|
+
this.#rootVendorId = vendorId;
|
|
160
|
+
}
|
|
161
|
+
if (vvsc !== undefined) {
|
|
162
|
+
if (vvsc.byteLength === 0) {
|
|
163
|
+
this.#vvsc = undefined;
|
|
164
|
+
} else {
|
|
165
|
+
this.#vvsc = vvsc;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
logger.info(
|
|
169
|
+
"Updated Vendor Verification Data for Fabric",
|
|
170
|
+
this.#rootVendorId,
|
|
171
|
+
this.#vidVerificationStatement,
|
|
172
|
+
this.#vvsc,
|
|
173
|
+
);
|
|
174
|
+
await this.persist();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
get vvsc() {
|
|
178
|
+
return this.#vvsc;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
get rootVendorId() {
|
|
182
|
+
return this.#rootVendorId;
|
|
183
|
+
}
|
|
184
|
+
|
|
130
185
|
set storage(storage: StorageContext) {
|
|
131
186
|
this.#storage = storage;
|
|
132
187
|
this.#groups.storage = storage;
|
|
@@ -282,6 +337,8 @@ export class FabricBuilder {
|
|
|
282
337
|
#rootNodeId?: NodeId;
|
|
283
338
|
#rootPublicKey?: Bytes;
|
|
284
339
|
#identityProtectionKey?: Bytes;
|
|
340
|
+
#vidVerificationStatement?: Bytes;
|
|
341
|
+
#vvsc?: Bytes;
|
|
285
342
|
#fabricIndex?: FabricIndex;
|
|
286
343
|
#label = "";
|
|
287
344
|
|
|
@@ -387,6 +444,8 @@ export class FabricBuilder {
|
|
|
387
444
|
this.#identityProtectionKey = fabric.identityProtectionKey;
|
|
388
445
|
this.#rootCert = fabric.rootCert;
|
|
389
446
|
this.#rootPublicKey = fabric.rootPublicKey;
|
|
447
|
+
this.#vidVerificationStatement = fabric.vidVerificationStatement;
|
|
448
|
+
this.#vvsc = fabric.vvsc;
|
|
390
449
|
this.#label = fabric.label;
|
|
391
450
|
}
|
|
392
451
|
|
|
@@ -447,6 +506,8 @@ export class FabricBuilder {
|
|
|
447
506
|
),
|
|
448
507
|
intermediateCACert: this.#intermediateCACert,
|
|
449
508
|
operationalCert: this.#operationalCert,
|
|
509
|
+
vidVerificationStatement: this.#vidVerificationStatement,
|
|
510
|
+
vvsc: this.#vvsc,
|
|
450
511
|
label: this.#label,
|
|
451
512
|
});
|
|
452
513
|
}
|
|
@@ -464,6 +525,8 @@ export namespace Fabric {
|
|
|
464
525
|
rootVendorId: VendorId;
|
|
465
526
|
rootCert: Bytes;
|
|
466
527
|
identityProtectionKey: Bytes;
|
|
528
|
+
vidVerificationStatement?: Bytes;
|
|
529
|
+
vvsc?: Bytes;
|
|
467
530
|
operationalIdentityProtectionKey: Bytes;
|
|
468
531
|
intermediateCACert: Bytes | undefined;
|
|
469
532
|
operationalCert: Bytes;
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
Environmental,
|
|
13
13
|
ImplementationError,
|
|
14
14
|
Key,
|
|
15
|
+
Logger,
|
|
15
16
|
MatterError,
|
|
16
17
|
MatterFlowError,
|
|
17
18
|
MaybePromise,
|
|
@@ -23,6 +24,8 @@ import { PeerAddress } from "#peer/PeerAddress.js";
|
|
|
23
24
|
import { FabricIndex } from "#types";
|
|
24
25
|
import { Fabric } from "./Fabric.js";
|
|
25
26
|
|
|
27
|
+
const logger = Logger.get("FabricManager");
|
|
28
|
+
|
|
26
29
|
/** Specific Error for when a fabric is not found. */
|
|
27
30
|
export class FabricNotFoundError extends MatterError {}
|
|
28
31
|
export class FabricTableFullError extends MatterError {}
|
|
@@ -63,7 +66,7 @@ export class FabricManager {
|
|
|
63
66
|
|
|
64
67
|
const fabrics = await this.#storage.get<Fabric.Config[]>("fabrics", []);
|
|
65
68
|
for (const fabricConfig of fabrics) {
|
|
66
|
-
this.#
|
|
69
|
+
this.#addNewFabric(new Fabric(crypto, fabricConfig));
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
this.#nextFabricIndex = await this.#storage.get("nextFabricIndex", this.#nextFabricIndex);
|
|
@@ -156,18 +159,34 @@ export class FabricManager {
|
|
|
156
159
|
|
|
157
160
|
addFabric(fabric: Fabric) {
|
|
158
161
|
this.#construction.assert();
|
|
159
|
-
this.#
|
|
162
|
+
this.#addNewFabric(fabric);
|
|
160
163
|
}
|
|
161
164
|
|
|
162
|
-
#
|
|
165
|
+
#addNewFabric(fabric: Fabric) {
|
|
163
166
|
const { fabricIndex } = fabric;
|
|
164
167
|
if (this.#fabrics.has(fabricIndex)) {
|
|
165
168
|
throw new MatterFlowError(`Fabric with index ${fabricIndex} already exists.`);
|
|
166
169
|
}
|
|
170
|
+
|
|
171
|
+
this.#addOrUpdateFabricEntry(fabric);
|
|
172
|
+
|
|
173
|
+
if (this.#initializationDone) {
|
|
174
|
+
this.#events.added.emit(fabric);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Insert Fabric into the manager without emitting events */
|
|
179
|
+
#addOrUpdateFabricEntry(fabric: Fabric) {
|
|
180
|
+
const { fabricIndex } = fabric;
|
|
167
181
|
this.#fabrics.set(fabricIndex, fabric);
|
|
168
182
|
fabric.addRemoveCallback(async () => this.removeFabric(fabricIndex));
|
|
169
183
|
fabric.persistCallback = (isUpdate = true) => {
|
|
170
184
|
if (!this.#storage) {
|
|
185
|
+
if (isUpdate) {
|
|
186
|
+
logger.warn(
|
|
187
|
+
"Fabric can not be persisted because FabricManager has no storage but it is a fabric update.",
|
|
188
|
+
);
|
|
189
|
+
}
|
|
171
190
|
return;
|
|
172
191
|
}
|
|
173
192
|
const persistResult = this.persistFabrics();
|
|
@@ -177,12 +196,9 @@ export class FabricManager {
|
|
|
177
196
|
}
|
|
178
197
|
});
|
|
179
198
|
};
|
|
180
|
-
if (this.#storage !== undefined) {
|
|
199
|
+
if (this.#storage !== undefined && fabric.storage === undefined) {
|
|
181
200
|
fabric.storage = this.#storage.createContext(`fabric-${fabricIndex}`);
|
|
182
201
|
}
|
|
183
|
-
if (this.#initializationDone) {
|
|
184
|
-
this.#events.added.emit(fabric);
|
|
185
|
-
}
|
|
186
202
|
}
|
|
187
203
|
|
|
188
204
|
async removeFabric(fabricIndex: FabricIndex) {
|
|
@@ -259,12 +275,19 @@ export class FabricManager {
|
|
|
259
275
|
await this.#construction;
|
|
260
276
|
|
|
261
277
|
const { fabricIndex } = fabric;
|
|
262
|
-
|
|
278
|
+
const existingFabric = this.#fabrics.get(fabricIndex);
|
|
279
|
+
if (existingFabric === undefined) {
|
|
263
280
|
throw new FabricNotFoundError(
|
|
264
281
|
`Fabric with index ${fabricIndex} cannot be updated because it does not exist.`,
|
|
265
282
|
);
|
|
266
283
|
}
|
|
267
|
-
|
|
284
|
+
if (existingFabric === fabric) {
|
|
285
|
+
// Nothing changed, so it is a restore without any change
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
this.#addOrUpdateFabricEntry(fabric);
|
|
290
|
+
|
|
268
291
|
if (this.#storage) {
|
|
269
292
|
await this.persistFabrics();
|
|
270
293
|
}
|
package/src/mdns/MdnsConsts.ts
CHANGED
|
@@ -23,7 +23,7 @@ export const DEFAULT_PAIRING_HINT = {
|
|
|
23
23
|
|
|
24
24
|
export const PAIRING_HINTS_REQUIRING_INSTRUCTION = Array<keyof typeof PairingHintBitmap>(
|
|
25
25
|
"customInstruction",
|
|
26
|
-
"
|
|
26
|
+
"pressResetButtonForNumberOfSeconds",
|
|
27
27
|
"pressResetButtonUntilLightBlinks",
|
|
28
28
|
"pressResetButtonForNumberOfSecondsWithApplicationOfPower",
|
|
29
29
|
"pressResetButtonUntilLightBlinksWithApplicationOfPower",
|
|
@@ -4,77 +4,94 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { Logger } from "#general";
|
|
7
|
+
import { Duration, Instant, Logger, Minutes, Seconds } from "#general";
|
|
8
8
|
|
|
9
9
|
const logger = Logger.get("PhysicalDeviceProperties");
|
|
10
10
|
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
11
|
+
const DEFAULT_SUBSCRIPTION_FLOOR_DEFAULT = Seconds(1);
|
|
12
|
+
const DEFAULT_SUBSCRIPTION_FLOOR_ICD = Instant;
|
|
13
|
+
const DEFAULT_SUBSCRIPTION_CEILING_WIFI = Minutes(1);
|
|
14
|
+
const DEFAULT_SUBSCRIPTION_CEILING_THREAD = Minutes(1);
|
|
15
|
+
const DEFAULT_SUBSCRIPTION_CEILING_THREAD_SLEEPY = Minutes(3);
|
|
16
|
+
const DEFAULT_SUBSCRIPTION_CEILING_BATTERY_POWERED = Minutes(10);
|
|
17
17
|
|
|
18
18
|
export interface PhysicalDeviceProperties {
|
|
19
19
|
threadConnected: boolean;
|
|
20
20
|
wifiConnected: boolean;
|
|
21
21
|
ethernetConnected: boolean;
|
|
22
22
|
rootEndpointServerList: number[];
|
|
23
|
+
isMainsPowered: boolean;
|
|
23
24
|
isBatteryPowered: boolean;
|
|
24
25
|
isIntermittentlyConnected: boolean;
|
|
25
26
|
isThreadSleepyEndDevice: boolean;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
export namespace PhysicalDeviceProperties {
|
|
29
|
-
export function
|
|
30
|
+
export function subscriptionIntervalBoundsFor(options?: {
|
|
30
31
|
properties?: PhysicalDeviceProperties;
|
|
31
32
|
description?: string;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const { properties } = options ?? {};
|
|
33
|
+
request?: Partial<PhysicalDeviceProperties.IntervalBounds>;
|
|
34
|
+
}): PhysicalDeviceProperties.IntervalBounds {
|
|
35
|
+
const { properties, request } = options ?? {};
|
|
36
36
|
|
|
37
|
-
let {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
let { description } = options ?? {};
|
|
38
|
+
|
|
39
|
+
let minIntervalFloor, maxIntervalCeiling;
|
|
40
|
+
if (request) {
|
|
41
|
+
({ minIntervalFloor, maxIntervalCeiling } = request);
|
|
42
|
+
}
|
|
42
43
|
|
|
43
44
|
if (description === undefined) {
|
|
44
45
|
description = "Node";
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
const {
|
|
48
|
-
|
|
48
|
+
const {
|
|
49
|
+
isMainsPowered,
|
|
50
|
+
isBatteryPowered,
|
|
51
|
+
isIntermittentlyConnected,
|
|
52
|
+
threadConnected,
|
|
53
|
+
isThreadSleepyEndDevice,
|
|
54
|
+
} = properties ?? {};
|
|
49
55
|
|
|
50
56
|
if (isIntermittentlyConnected) {
|
|
51
|
-
if (
|
|
57
|
+
if (minIntervalFloor !== undefined && minIntervalFloor !== DEFAULT_SUBSCRIPTION_FLOOR_ICD) {
|
|
52
58
|
logger.info(
|
|
53
|
-
`${description}: Overwriting minIntervalFloorSeconds for intermittently connected device to ${
|
|
59
|
+
`${description}: Overwriting minIntervalFloorSeconds for intermittently connected device to ${Duration.format(DEFAULT_SUBSCRIPTION_FLOOR_ICD)}`,
|
|
54
60
|
);
|
|
55
|
-
|
|
61
|
+
minIntervalFloor = DEFAULT_SUBSCRIPTION_FLOOR_ICD;
|
|
56
62
|
}
|
|
57
63
|
}
|
|
64
|
+
if (minIntervalFloor === undefined) {
|
|
65
|
+
minIntervalFloor = DEFAULT_SUBSCRIPTION_FLOOR_DEFAULT;
|
|
66
|
+
}
|
|
58
67
|
|
|
59
|
-
const defaultCeiling =
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
const defaultCeiling =
|
|
69
|
+
isBatteryPowered && !isMainsPowered
|
|
70
|
+
? DEFAULT_SUBSCRIPTION_CEILING_BATTERY_POWERED
|
|
71
|
+
: isThreadSleepyEndDevice
|
|
72
|
+
? DEFAULT_SUBSCRIPTION_CEILING_THREAD_SLEEPY
|
|
73
|
+
: threadConnected
|
|
74
|
+
? DEFAULT_SUBSCRIPTION_CEILING_THREAD
|
|
75
|
+
: DEFAULT_SUBSCRIPTION_CEILING_WIFI;
|
|
76
|
+
if (maxIntervalCeiling === undefined) {
|
|
77
|
+
maxIntervalCeiling = defaultCeiling;
|
|
68
78
|
}
|
|
69
|
-
if (
|
|
79
|
+
if (maxIntervalCeiling < defaultCeiling) {
|
|
70
80
|
logger.debug(
|
|
71
|
-
`${description}: maxIntervalCeilingSeconds ideally is ${defaultCeiling}s instead of ${
|
|
81
|
+
`${description}: maxIntervalCeilingSeconds ideally is ${defaultCeiling}s instead of ${maxIntervalCeiling}s due to device type`,
|
|
72
82
|
);
|
|
73
83
|
}
|
|
74
84
|
|
|
75
85
|
return {
|
|
76
|
-
|
|
77
|
-
|
|
86
|
+
minIntervalFloor,
|
|
87
|
+
maxIntervalCeiling,
|
|
78
88
|
};
|
|
79
89
|
}
|
|
80
90
|
}
|
|
91
|
+
|
|
92
|
+
export namespace PhysicalDeviceProperties {
|
|
93
|
+
export interface IntervalBounds {
|
|
94
|
+
minIntervalFloor: Duration;
|
|
95
|
+
maxIntervalCeiling: Duration;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -47,6 +47,36 @@ export class DeviceAdvertiser {
|
|
|
47
47
|
this.#advertiseFabric(fabric, "startup");
|
|
48
48
|
});
|
|
49
49
|
|
|
50
|
+
// When a fabric is updated we might need to adjust announcements
|
|
51
|
+
this.#observers.on(fabrics.events.updated, async fabric => {
|
|
52
|
+
if (!this.#isOperational) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Look for update for this fabricIndex because other Ids might have changed and object is different
|
|
57
|
+
const fabricIndexAdvertisements = this.#advertisements(
|
|
58
|
+
ad => ad.isOperational() && ad.description.fabric.fabricIndex === fabric.fabricIndex,
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
// If the announcement relevant IDs are unchanged, do nothing
|
|
62
|
+
if (
|
|
63
|
+
fabricIndexAdvertisements.every(
|
|
64
|
+
ad =>
|
|
65
|
+
ad.isOperational() &&
|
|
66
|
+
ad.description.fabric.operationalId === fabric.operationalId &&
|
|
67
|
+
ad.description.fabric.nodeId === fabric.nodeId,
|
|
68
|
+
)
|
|
69
|
+
) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
for (const ad of fabricIndexAdvertisements) {
|
|
74
|
+
await ad.close();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
this.#advertiseFabric(fabric, "startup");
|
|
78
|
+
});
|
|
79
|
+
|
|
50
80
|
// When a fabric is deleted, cancel any active advertisement
|
|
51
81
|
this.#observers.on(fabrics.events.deleted, fabric => {
|
|
52
82
|
Advertisement.cancelAll(this.#advertisements(ad => ad.isOperational() && ad.description.fabric === fabric));
|