@matter/protocol 0.13.0-alpha.0-20250311-3eb0af5f2 → 0.13.0-alpha.0-20250322-f085fa576
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/certificate/CertificateAuthority.d.ts +1 -0
- package/dist/cjs/certificate/CertificateAuthority.d.ts.map +1 -1
- package/dist/cjs/certificate/CertificateAuthority.js.map +1 -1
- package/dist/cjs/cluster/client/ClusterClient.d.ts.map +1 -1
- package/dist/cjs/cluster/client/ClusterClient.js +3 -0
- package/dist/cjs/cluster/client/ClusterClient.js.map +1 -1
- package/dist/cjs/common/FailsafeContext.js +1 -1
- package/dist/cjs/common/FailsafeContext.js.map +1 -1
- package/dist/cjs/interaction/AttributeDataDecoder.d.ts +21 -4
- package/dist/cjs/interaction/AttributeDataDecoder.d.ts.map +1 -1
- package/dist/cjs/interaction/AttributeDataDecoder.js +40 -1
- package/dist/cjs/interaction/AttributeDataDecoder.js.map +1 -1
- package/dist/cjs/interaction/DecodedDataReport.d.ts +4 -2
- package/dist/cjs/interaction/DecodedDataReport.d.ts.map +1 -1
- package/dist/cjs/interaction/DecodedDataReport.js +6 -2
- package/dist/cjs/interaction/DecodedDataReport.js.map +1 -1
- package/dist/cjs/interaction/EventDataDecoder.d.ts +15 -3
- package/dist/cjs/interaction/EventDataDecoder.d.ts.map +1 -1
- package/dist/cjs/interaction/EventDataDecoder.js +39 -2
- package/dist/cjs/interaction/EventDataDecoder.js.map +1 -1
- package/dist/cjs/interaction/InteractionClient.d.ts +44 -4
- package/dist/cjs/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionClient.js +65 -12
- package/dist/cjs/interaction/InteractionClient.js.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.js +5 -2
- package/dist/cjs/interaction/InteractionMessenger.js.map +1 -1
- package/dist/cjs/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionServer.js +2 -2
- package/dist/cjs/interaction/InteractionServer.js.map +1 -1
- package/dist/cjs/peer/ControllerCommissioner.d.ts +15 -3
- package/dist/cjs/peer/ControllerCommissioner.d.ts.map +1 -1
- package/dist/cjs/peer/ControllerCommissioner.js +17 -6
- package/dist/cjs/peer/ControllerCommissioner.js.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.d.ts +47 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.d.ts.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.js +133 -133
- package/dist/cjs/peer/ControllerCommissioningFlow.js.map +1 -1
- package/dist/cjs/peer/PeerSet.d.ts +2 -2
- package/dist/cjs/peer/PeerSet.d.ts.map +1 -1
- package/dist/cjs/peer/PeerSet.js +6 -1
- package/dist/cjs/peer/PeerSet.js.map +1 -1
- package/dist/cjs/protocol/ChannelManager.d.ts.map +1 -1
- package/dist/cjs/protocol/ChannelManager.js +11 -4
- package/dist/cjs/protocol/ChannelManager.js.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.js +0 -1
- package/dist/cjs/protocol/ExchangeManager.js.map +1 -1
- package/dist/esm/certificate/CertificateAuthority.d.ts +1 -0
- package/dist/esm/certificate/CertificateAuthority.d.ts.map +1 -1
- package/dist/esm/certificate/CertificateAuthority.js.map +1 -1
- package/dist/esm/cluster/client/ClusterClient.d.ts.map +1 -1
- package/dist/esm/cluster/client/ClusterClient.js +3 -0
- package/dist/esm/cluster/client/ClusterClient.js.map +1 -1
- package/dist/esm/common/FailsafeContext.js +1 -1
- package/dist/esm/common/FailsafeContext.js.map +1 -1
- package/dist/esm/interaction/AttributeDataDecoder.d.ts +21 -4
- package/dist/esm/interaction/AttributeDataDecoder.d.ts.map +1 -1
- package/dist/esm/interaction/AttributeDataDecoder.js +40 -1
- package/dist/esm/interaction/AttributeDataDecoder.js.map +1 -1
- package/dist/esm/interaction/DecodedDataReport.d.ts +4 -2
- package/dist/esm/interaction/DecodedDataReport.d.ts.map +1 -1
- package/dist/esm/interaction/DecodedDataReport.js +12 -4
- package/dist/esm/interaction/DecodedDataReport.js.map +1 -1
- package/dist/esm/interaction/EventDataDecoder.d.ts +15 -3
- package/dist/esm/interaction/EventDataDecoder.d.ts.map +1 -1
- package/dist/esm/interaction/EventDataDecoder.js +39 -2
- package/dist/esm/interaction/EventDataDecoder.js.map +1 -1
- package/dist/esm/interaction/InteractionClient.d.ts +44 -4
- package/dist/esm/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionClient.js +67 -12
- package/dist/esm/interaction/InteractionClient.js.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.js +6 -2
- package/dist/esm/interaction/InteractionMessenger.js.map +1 -1
- package/dist/esm/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionServer.js +12 -3
- package/dist/esm/interaction/InteractionServer.js.map +1 -1
- package/dist/esm/peer/ControllerCommissioner.d.ts +15 -3
- package/dist/esm/peer/ControllerCommissioner.d.ts.map +1 -1
- package/dist/esm/peer/ControllerCommissioner.js +17 -6
- package/dist/esm/peer/ControllerCommissioner.js.map +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.d.ts +47 -1
- package/dist/esm/peer/ControllerCommissioningFlow.d.ts.map +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.js +133 -133
- package/dist/esm/peer/ControllerCommissioningFlow.js.map +1 -1
- package/dist/esm/peer/PeerSet.d.ts +2 -2
- package/dist/esm/peer/PeerSet.d.ts.map +1 -1
- package/dist/esm/peer/PeerSet.js +7 -2
- package/dist/esm/peer/PeerSet.js.map +1 -1
- package/dist/esm/protocol/ChannelManager.d.ts.map +1 -1
- package/dist/esm/protocol/ChannelManager.js +11 -4
- package/dist/esm/protocol/ChannelManager.js.map +1 -1
- package/dist/esm/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/esm/protocol/ExchangeManager.js +0 -1
- package/dist/esm/protocol/ExchangeManager.js.map +1 -1
- package/package.json +6 -6
- package/src/certificate/CertificateAuthority.ts +1 -0
- package/src/cluster/client/ClusterClient.ts +3 -0
- package/src/common/FailsafeContext.ts +1 -1
- package/src/interaction/AttributeDataDecoder.ts +66 -6
- package/src/interaction/DecodedDataReport.ts +24 -5
- package/src/interaction/EventDataDecoder.ts +57 -5
- package/src/interaction/InteractionClient.ts +105 -12
- package/src/interaction/InteractionMessenger.ts +6 -2
- package/src/interaction/InteractionServer.ts +14 -4
- package/src/peer/ControllerCommissioner.ts +30 -6
- package/src/peer/ControllerCommissioningFlow.ts +144 -140
- package/src/peer/PeerSet.ts +7 -2
- package/src/protocol/ChannelManager.ts +11 -4
- package/src/protocol/ExchangeManager.ts +0 -1
|
@@ -142,22 +142,22 @@ const DEFAULT_FAILSAFE_TIME_MS = 60_000; // 60 seconds
|
|
|
142
142
|
* Class to abstract the Device commission flow in a step wise way as defined in Specs. The specs are not 100%
|
|
143
143
|
*/
|
|
144
144
|
export class ControllerCommissioningFlow {
|
|
145
|
-
|
|
146
|
-
readonly
|
|
147
|
-
readonly
|
|
148
|
-
readonly
|
|
145
|
+
protected interactionClient: InteractionClient;
|
|
146
|
+
protected readonly ca: CertificateAuthority;
|
|
147
|
+
protected readonly fabric: Fabric;
|
|
148
|
+
protected readonly transitionToCase: (
|
|
149
149
|
peerAddress: PeerAddress,
|
|
150
150
|
supportsConcurrentConnections: boolean,
|
|
151
151
|
) => Promise<InteractionClient | undefined>;
|
|
152
|
-
readonly
|
|
153
|
-
readonly
|
|
154
|
-
readonly
|
|
152
|
+
protected readonly commissioningOptions: ControllerCommissioningFlowOptions;
|
|
153
|
+
protected readonly commissioningSteps = new Array<CommissioningStep>();
|
|
154
|
+
protected readonly commissioningStepResults = new Map<string, CommissioningStepResult>();
|
|
155
155
|
readonly #clusterClients = new Map<ClusterId, ClusterClientObj>();
|
|
156
156
|
#commissioningStartedTime: number | undefined;
|
|
157
157
|
#commissioningExpiryTime: number | undefined;
|
|
158
158
|
#lastFailSafeTime: number | undefined;
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
protected lastBreadcrumb = 1;
|
|
160
|
+
protected collectedCommissioningData: CollectedCommissioningData = {};
|
|
161
161
|
#failSafeTimeMs = DEFAULT_FAILSAFE_TIME_MS;
|
|
162
162
|
|
|
163
163
|
constructor(
|
|
@@ -179,11 +179,11 @@ export class ControllerCommissioningFlow {
|
|
|
179
179
|
supportsConcurrentConnections: boolean,
|
|
180
180
|
) => Promise<InteractionClient | undefined>,
|
|
181
181
|
) {
|
|
182
|
-
this
|
|
183
|
-
this
|
|
184
|
-
this
|
|
185
|
-
this
|
|
186
|
-
this
|
|
182
|
+
this.interactionClient = interactionClient;
|
|
183
|
+
this.ca = ca;
|
|
184
|
+
this.fabric = fabric;
|
|
185
|
+
this.transitionToCase = transitionToCase;
|
|
186
|
+
this.commissioningOptions = commissioningOptions;
|
|
187
187
|
logger.debug(`Commissioning options: ${Logger.toJSON(commissioningOptions)}`);
|
|
188
188
|
this.#initializeCommissioningSteps();
|
|
189
189
|
}
|
|
@@ -198,7 +198,7 @@ export class ControllerCommissioningFlow {
|
|
|
198
198
|
this.#sortSteps();
|
|
199
199
|
|
|
200
200
|
let failSafeTimerReArmedAfterPreviousStep = false;
|
|
201
|
-
for (const step of this
|
|
201
|
+
for (const step of this.commissioningSteps) {
|
|
202
202
|
logger.info(`Executing commissioning step ${step.stepNumber}.${step.subStepNumber}: ${step.name}`);
|
|
203
203
|
try {
|
|
204
204
|
if (step.reArmFailsafe && !failSafeTimerReArmedAfterPreviousStep) {
|
|
@@ -294,7 +294,7 @@ export class ControllerCommissioningFlow {
|
|
|
294
294
|
logger.debug(
|
|
295
295
|
`Creating new cluster client for cluster ${cluster.name} (endpoint ${endpointId}, isFeatureSpecific ${isFeatureSpecific})`,
|
|
296
296
|
);
|
|
297
|
-
const client = ClusterClient(cluster, endpointId, this
|
|
297
|
+
const client = ClusterClient(cluster, endpointId, this.interactionClient);
|
|
298
298
|
this.#clusterClients.set(cluster.id, client);
|
|
299
299
|
return client;
|
|
300
300
|
}
|
|
@@ -304,7 +304,7 @@ export class ControllerCommissioningFlow {
|
|
|
304
304
|
* @see {@link MatterSpecification.v13.Core} § 5.5
|
|
305
305
|
*/
|
|
306
306
|
#initializeCommissioningSteps() {
|
|
307
|
-
this
|
|
307
|
+
this.commissioningSteps.push({
|
|
308
308
|
stepNumber: 0, // Preparation
|
|
309
309
|
subStepNumber: 1,
|
|
310
310
|
name: "GetInitialData",
|
|
@@ -316,21 +316,21 @@ export class ControllerCommissioningFlow {
|
|
|
316
316
|
// TODO Step 3-5: Commissioner handles/prepares for T&C Ack, if supported
|
|
317
317
|
// Step 6: is the PASE session establishment which is done before this starts here
|
|
318
318
|
|
|
319
|
-
this
|
|
319
|
+
this.commissioningSteps.push({
|
|
320
320
|
stepNumber: 7,
|
|
321
321
|
subStepNumber: 1,
|
|
322
322
|
name: "GeneralCommissioning.ArmFailsafe",
|
|
323
323
|
stepLogic: () => this.#armFailsafe(),
|
|
324
324
|
});
|
|
325
325
|
|
|
326
|
-
this
|
|
326
|
+
this.commissioningSteps.push({
|
|
327
327
|
stepNumber: 8,
|
|
328
328
|
subStepNumber: 1,
|
|
329
329
|
name: "GeneralCommissioning.ConfigureRegulatoryInformation",
|
|
330
330
|
stepLogic: () => this.#configureRegulatoryInformation(),
|
|
331
331
|
});
|
|
332
332
|
|
|
333
|
-
this
|
|
333
|
+
this.commissioningSteps.push({
|
|
334
334
|
stepNumber: 8,
|
|
335
335
|
subStepNumber: 2,
|
|
336
336
|
name: "TimeSynchronization.SynchronizeTime",
|
|
@@ -339,14 +339,14 @@ export class ControllerCommissioningFlow {
|
|
|
339
339
|
|
|
340
340
|
// TODO Step 9: If device and Controller supports T&C Feature then User consent is handled
|
|
341
341
|
|
|
342
|
-
this
|
|
342
|
+
this.commissioningSteps.push({
|
|
343
343
|
stepNumber: 10,
|
|
344
344
|
subStepNumber: 1,
|
|
345
345
|
name: "OperationalCredentials.DeviceAttestation",
|
|
346
346
|
stepLogic: () => this.#deviceAttestation(),
|
|
347
347
|
});
|
|
348
348
|
|
|
349
|
-
this
|
|
349
|
+
this.commissioningSteps.push({
|
|
350
350
|
stepNumber: 11, // includes 11-13
|
|
351
351
|
subStepNumber: 1,
|
|
352
352
|
name: "OperationalCredentials.Certificates",
|
|
@@ -355,7 +355,7 @@ export class ControllerCommissioningFlow {
|
|
|
355
355
|
|
|
356
356
|
// TODO Step 14: TimeSynchronization.SetTrustedTimeSource if supported
|
|
357
357
|
|
|
358
|
-
this
|
|
358
|
+
this.commissioningSteps.push({
|
|
359
359
|
stepNumber: 15,
|
|
360
360
|
subStepNumber: 1,
|
|
361
361
|
name: "AccessControl",
|
|
@@ -363,15 +363,15 @@ export class ControllerCommissioningFlow {
|
|
|
363
363
|
});
|
|
364
364
|
|
|
365
365
|
// Care about Network commissioning only when we are on BLE, because else we are already on IP network
|
|
366
|
-
if (this
|
|
367
|
-
this
|
|
366
|
+
if (this.interactionClient.channelType === ChannelType.BLE) {
|
|
367
|
+
this.commissioningSteps.push({
|
|
368
368
|
stepNumber: 16,
|
|
369
369
|
subStepNumber: 1,
|
|
370
370
|
name: "NetworkCommissioning.Validate",
|
|
371
371
|
stepLogic: () => this.#validateNetwork(),
|
|
372
372
|
});
|
|
373
|
-
if (this
|
|
374
|
-
this
|
|
373
|
+
if (this.commissioningOptions.wifiNetwork !== undefined) {
|
|
374
|
+
this.commissioningSteps.push({
|
|
375
375
|
stepNumber: 16, // includes step 17
|
|
376
376
|
subStepNumber: 2,
|
|
377
377
|
name: "NetworkCommissioning.Wifi",
|
|
@@ -379,8 +379,8 @@ export class ControllerCommissioningFlow {
|
|
|
379
379
|
stepLogic: () => this.#configureNetworkWifi(),
|
|
380
380
|
});
|
|
381
381
|
}
|
|
382
|
-
if (this
|
|
383
|
-
this
|
|
382
|
+
if (this.commissioningOptions.threadNetwork !== undefined) {
|
|
383
|
+
this.commissioningSteps.push({
|
|
384
384
|
stepNumber: 16, // includes step 17
|
|
385
385
|
subStepNumber: 3,
|
|
386
386
|
name: "NetworkCommissioning.Thread",
|
|
@@ -390,11 +390,11 @@ export class ControllerCommissioningFlow {
|
|
|
390
390
|
}
|
|
391
391
|
} else {
|
|
392
392
|
logger.info(
|
|
393
|
-
`Skipping NetworkCommissioning steps because the device is already on IP network (${this
|
|
393
|
+
`Skipping NetworkCommissioning steps because the device is already on IP network (${this.interactionClient.channelType})`,
|
|
394
394
|
);
|
|
395
395
|
}
|
|
396
396
|
|
|
397
|
-
this
|
|
397
|
+
this.commissioningSteps.push({
|
|
398
398
|
stepNumber: 18, // includes step 19 (CASE connection)
|
|
399
399
|
subStepNumber: 1,
|
|
400
400
|
name: "Reconnect",
|
|
@@ -402,14 +402,14 @@ export class ControllerCommissioningFlow {
|
|
|
402
402
|
stepLogic: () => this.#reconnectWithDevice(),
|
|
403
403
|
});
|
|
404
404
|
|
|
405
|
-
this
|
|
405
|
+
this.commissioningSteps.push({
|
|
406
406
|
stepNumber: 20,
|
|
407
407
|
subStepNumber: 1,
|
|
408
408
|
name: "GeneralCommissioning.Complete",
|
|
409
409
|
stepLogic: () => this.#completeCommissioning(),
|
|
410
410
|
});
|
|
411
411
|
|
|
412
|
-
this
|
|
412
|
+
this.commissioningSteps.push({
|
|
413
413
|
stepNumber: 99, // Should be allowed in Step 13, but Tasmota is not supporting this
|
|
414
414
|
subStepNumber: 1,
|
|
415
415
|
name: "OperationalCredentials.UpdateFabricLabel",
|
|
@@ -418,18 +418,18 @@ export class ControllerCommissioningFlow {
|
|
|
418
418
|
}
|
|
419
419
|
|
|
420
420
|
#sortSteps() {
|
|
421
|
-
this
|
|
421
|
+
this.commissioningSteps.sort((a, b) => {
|
|
422
422
|
if (a.stepNumber !== b.stepNumber) return a.stepNumber - b.stepNumber;
|
|
423
423
|
return a.subStepNumber - b.subStepNumber;
|
|
424
424
|
});
|
|
425
425
|
}
|
|
426
426
|
|
|
427
427
|
#setCommissioningStepResult(step: CommissioningStep, result: CommissioningStepResult) {
|
|
428
|
-
this
|
|
428
|
+
this.commissioningStepResults.set(`${step.stepNumber}-${step.subStepNumber}`, result);
|
|
429
429
|
}
|
|
430
430
|
|
|
431
431
|
getCommissioningStepResult(stepNumber: number, subStepNumber: number) {
|
|
432
|
-
return this
|
|
432
|
+
return this.commissioningStepResults.get(`${stepNumber}-${subStepNumber}`);
|
|
433
433
|
}
|
|
434
434
|
|
|
435
435
|
/** Helper method to check for errorCode/debugTest responses and throw error on failure */
|
|
@@ -472,10 +472,10 @@ export class ControllerCommissioningFlow {
|
|
|
472
472
|
*/
|
|
473
473
|
async #getInitialData() {
|
|
474
474
|
const descriptorClient = this.#getClusterClient(Descriptor.Cluster);
|
|
475
|
-
this
|
|
476
|
-
this
|
|
475
|
+
this.collectedCommissioningData.rootPartsList = await descriptorClient.getPartsListAttribute();
|
|
476
|
+
this.collectedCommissioningData.rootServerList = await descriptorClient.getServerListAttribute();
|
|
477
477
|
|
|
478
|
-
const networkData = await this
|
|
478
|
+
const networkData = await this.interactionClient.getMultipleAttributes({
|
|
479
479
|
attributes: [
|
|
480
480
|
{
|
|
481
481
|
clusterId: NetworkCommissioning.Complete.id,
|
|
@@ -505,16 +505,16 @@ export class ControllerCommissioningFlow {
|
|
|
505
505
|
networkStatus.push({ endpointId, value });
|
|
506
506
|
}
|
|
507
507
|
}
|
|
508
|
-
this
|
|
509
|
-
this
|
|
508
|
+
this.collectedCommissioningData.networkFeatures = networkFeatures;
|
|
509
|
+
this.collectedCommissioningData.networkStatus = networkStatus;
|
|
510
510
|
|
|
511
511
|
const basicInfoClient = this.#getClusterClient(BasicInformation.Cluster);
|
|
512
|
-
this
|
|
513
|
-
this
|
|
514
|
-
this
|
|
512
|
+
this.collectedCommissioningData.vendorId = await basicInfoClient.getVendorIdAttribute();
|
|
513
|
+
this.collectedCommissioningData.productId = await basicInfoClient.getProductIdAttribute();
|
|
514
|
+
this.collectedCommissioningData.productName = await basicInfoClient.getProductNameAttribute();
|
|
515
515
|
|
|
516
516
|
const generalCommissioningClient = this.#getClusterClient(GeneralCommissioning.Cluster);
|
|
517
|
-
this
|
|
517
|
+
this.collectedCommissioningData.supportsConcurrentConnection =
|
|
518
518
|
await generalCommissioningClient.getSupportsConcurrentConnectionAttribute();
|
|
519
519
|
|
|
520
520
|
/*
|
|
@@ -529,7 +529,7 @@ export class ControllerCommissioningFlow {
|
|
|
529
529
|
|
|
530
530
|
return {
|
|
531
531
|
code: CommissioningStepResultCode.Success,
|
|
532
|
-
breadcrumb: this
|
|
532
|
+
breadcrumb: this.lastBreadcrumb,
|
|
533
533
|
};
|
|
534
534
|
}
|
|
535
535
|
|
|
@@ -544,9 +544,9 @@ export class ControllerCommissioningFlow {
|
|
|
544
544
|
*/
|
|
545
545
|
async #armFailsafe() {
|
|
546
546
|
const client = this.#getClusterClient(GeneralCommissioning.Cluster);
|
|
547
|
-
if (this
|
|
547
|
+
if (this.collectedCommissioningData.basicCommissioningInfo === undefined) {
|
|
548
548
|
const basicCommissioningInfo = await client.getBasicCommissioningInfoAttribute();
|
|
549
|
-
this
|
|
549
|
+
this.collectedCommissioningData.basicCommissioningInfo = basicCommissioningInfo;
|
|
550
550
|
this.#failSafeTimeMs = basicCommissioningInfo.failSafeExpiryLengthSeconds * 1000;
|
|
551
551
|
this.#commissioningStartedTime = Time.nowMs();
|
|
552
552
|
this.#commissioningExpiryTime =
|
|
@@ -555,15 +555,15 @@ export class ControllerCommissioningFlow {
|
|
|
555
555
|
this.#ensureGeneralCommissioningSuccess(
|
|
556
556
|
"armFailSafe",
|
|
557
557
|
await client.armFailSafe({
|
|
558
|
-
breadcrumb: this
|
|
558
|
+
breadcrumb: this.lastBreadcrumb,
|
|
559
559
|
expiryLengthSeconds:
|
|
560
|
-
this
|
|
560
|
+
this.collectedCommissioningData.basicCommissioningInfo?.failSafeExpiryLengthSeconds,
|
|
561
561
|
}),
|
|
562
562
|
);
|
|
563
563
|
this.#lastFailSafeTime = Time.nowMs();
|
|
564
564
|
return {
|
|
565
565
|
code: CommissioningStepResultCode.Success,
|
|
566
|
-
breadcrumb: this
|
|
566
|
+
breadcrumb: this.lastBreadcrumb,
|
|
567
567
|
};
|
|
568
568
|
}
|
|
569
569
|
|
|
@@ -572,7 +572,7 @@ export class ControllerCommissioningFlow {
|
|
|
572
572
|
try {
|
|
573
573
|
const client = this.#getClusterClient(GeneralCommissioning.Cluster);
|
|
574
574
|
await client.armFailSafe({
|
|
575
|
-
breadcrumb: this
|
|
575
|
+
breadcrumb: this.lastBreadcrumb,
|
|
576
576
|
expiryLengthSeconds: 0,
|
|
577
577
|
});
|
|
578
578
|
this.#lastFailSafeTime = undefined; // No failsafe active anymore
|
|
@@ -589,11 +589,11 @@ export class ControllerCommissioningFlow {
|
|
|
589
589
|
* Commissionee using the SetRegulatoryConfig command.
|
|
590
590
|
*/
|
|
591
591
|
async #configureRegulatoryInformation() {
|
|
592
|
-
if (this
|
|
592
|
+
if (this.collectedCommissioningData.networkFeatures === undefined) {
|
|
593
593
|
throw new CommissioningError("No network features collected. This should never happen.");
|
|
594
594
|
}
|
|
595
595
|
// Read the infos for all Network Commissioning clusters
|
|
596
|
-
const hasRadioNetwork = this
|
|
596
|
+
const hasRadioNetwork = this.collectedCommissioningData.networkFeatures.some(
|
|
597
597
|
({ value: { wiFiNetworkInterface, threadNetworkInterface } }) =>
|
|
598
598
|
wiFiNetworkInterface || threadNetworkInterface,
|
|
599
599
|
);
|
|
@@ -602,7 +602,7 @@ export class ControllerCommissioningFlow {
|
|
|
602
602
|
const client = this.#getClusterClient(GeneralCommissioning.Cluster);
|
|
603
603
|
let locationCapability = await client.getLocationCapabilityAttribute();
|
|
604
604
|
if (locationCapability === GeneralCommissioning.RegulatoryLocationType.IndoorOutdoor) {
|
|
605
|
-
locationCapability = this
|
|
605
|
+
locationCapability = this.commissioningOptions.regulatoryLocation;
|
|
606
606
|
} else {
|
|
607
607
|
logger.debug(
|
|
608
608
|
`Device does not support a configurable regulatory location type. Location is set to "${
|
|
@@ -610,10 +610,10 @@ export class ControllerCommissioningFlow {
|
|
|
610
610
|
}"`,
|
|
611
611
|
);
|
|
612
612
|
}
|
|
613
|
-
let countryCode = this
|
|
613
|
+
let countryCode = this.commissioningOptions.regulatoryCountryCode;
|
|
614
614
|
const regulatoryResult = await client.setRegulatoryConfig(
|
|
615
615
|
{
|
|
616
|
-
breadcrumb: this
|
|
616
|
+
breadcrumb: this.lastBreadcrumb++,
|
|
617
617
|
newRegulatoryConfig: locationCapability,
|
|
618
618
|
countryCode,
|
|
619
619
|
},
|
|
@@ -631,7 +631,7 @@ export class ControllerCommissioningFlow {
|
|
|
631
631
|
"setRegulatoryConfig",
|
|
632
632
|
await client.setRegulatoryConfig(
|
|
633
633
|
{
|
|
634
|
-
breadcrumb: this
|
|
634
|
+
breadcrumb: this.lastBreadcrumb,
|
|
635
635
|
newRegulatoryConfig: locationCapability,
|
|
636
636
|
countryCode,
|
|
637
637
|
},
|
|
@@ -643,12 +643,12 @@ export class ControllerCommissioningFlow {
|
|
|
643
643
|
}
|
|
644
644
|
return {
|
|
645
645
|
code: CommissioningStepResultCode.Success,
|
|
646
|
-
breadcrumb: this
|
|
646
|
+
breadcrumb: this.lastBreadcrumb,
|
|
647
647
|
};
|
|
648
648
|
}
|
|
649
649
|
return {
|
|
650
650
|
code: CommissioningStepResultCode.Skipped,
|
|
651
|
-
breadcrumb: this
|
|
651
|
+
breadcrumb: this.lastBreadcrumb,
|
|
652
652
|
};
|
|
653
653
|
}
|
|
654
654
|
|
|
@@ -663,8 +663,8 @@ export class ControllerCommissioningFlow {
|
|
|
663
663
|
*/
|
|
664
664
|
async #synchronizeTime() {
|
|
665
665
|
if (
|
|
666
|
-
this
|
|
667
|
-
this
|
|
666
|
+
this.collectedCommissioningData.rootServerList !== undefined &&
|
|
667
|
+
this.collectedCommissioningData.rootServerList.find(
|
|
668
668
|
clusterId => clusterId === TimeSynchronizationCluster.id,
|
|
669
669
|
)
|
|
670
670
|
) {
|
|
@@ -673,7 +673,7 @@ export class ControllerCommissioningFlow {
|
|
|
673
673
|
}
|
|
674
674
|
return {
|
|
675
675
|
code: CommissioningStepResultCode.Skipped,
|
|
676
|
-
breadcrumb: this
|
|
676
|
+
breadcrumb: this.lastBreadcrumb,
|
|
677
677
|
};
|
|
678
678
|
}
|
|
679
679
|
|
|
@@ -717,7 +717,7 @@ export class ControllerCommissioningFlow {
|
|
|
717
717
|
}
|
|
718
718
|
return {
|
|
719
719
|
code: CommissioningStepResultCode.Success,
|
|
720
|
-
breadcrumb: this
|
|
720
|
+
breadcrumb: this.lastBreadcrumb,
|
|
721
721
|
};
|
|
722
722
|
|
|
723
723
|
// TODO consider Distributed Compliance Ledger Info about Commissioning Flow
|
|
@@ -756,23 +756,23 @@ export class ControllerCommissioningFlow {
|
|
|
756
756
|
|
|
757
757
|
await operationalCredentialsClusterClient.addTrustedRootCertificate(
|
|
758
758
|
{
|
|
759
|
-
rootCaCertificate: this
|
|
759
|
+
rootCaCertificate: this.ca.rootCert,
|
|
760
760
|
},
|
|
761
761
|
{ useExtendedFailSafeMessageResponseTimeout: true },
|
|
762
762
|
);
|
|
763
|
-
const peerOperationalCert = this
|
|
763
|
+
const peerOperationalCert = this.ca.generateNoc(
|
|
764
764
|
operationalPublicKey,
|
|
765
|
-
this
|
|
766
|
-
this
|
|
765
|
+
this.fabric.fabricId,
|
|
766
|
+
this.interactionClient.address.nodeId,
|
|
767
767
|
);
|
|
768
768
|
|
|
769
769
|
const addNocResponse = await operationalCredentialsClusterClient.addNoc(
|
|
770
770
|
{
|
|
771
771
|
nocValue: peerOperationalCert,
|
|
772
772
|
icacValue: new Uint8Array(0),
|
|
773
|
-
ipkValue: this
|
|
774
|
-
adminVendorId: this
|
|
775
|
-
caseAdminSubject: this
|
|
773
|
+
ipkValue: this.fabric.identityProtectionKey,
|
|
774
|
+
adminVendorId: this.fabric.rootVendorId,
|
|
775
|
+
caseAdminSubject: this.fabric.rootNodeId,
|
|
776
776
|
},
|
|
777
777
|
{ useExtendedFailSafeMessageResponseTimeout: true },
|
|
778
778
|
);
|
|
@@ -780,11 +780,11 @@ export class ControllerCommissioningFlow {
|
|
|
780
780
|
this.#ensureOperationalCredentialsSuccess("addNoc", addNocResponse);
|
|
781
781
|
|
|
782
782
|
const { fabricIndex } = addNocResponse;
|
|
783
|
-
this
|
|
783
|
+
this.collectedCommissioningData.fabricIndex = fabricIndex;
|
|
784
784
|
|
|
785
785
|
return {
|
|
786
786
|
code: CommissioningStepResultCode.Success,
|
|
787
|
-
breadcrumb: this
|
|
787
|
+
breadcrumb: this.lastBreadcrumb,
|
|
788
788
|
};
|
|
789
789
|
}
|
|
790
790
|
|
|
@@ -796,12 +796,12 @@ export class ControllerCommissioningFlow {
|
|
|
796
796
|
* the commissioning process.
|
|
797
797
|
*/
|
|
798
798
|
async #updateFabricLabel() {
|
|
799
|
-
const { fabricIndex } = this
|
|
799
|
+
const { fabricIndex } = this.collectedCommissioningData;
|
|
800
800
|
if (fabricIndex === undefined) {
|
|
801
801
|
logger.error("No fabric index available after addNoc. This should never happen.");
|
|
802
802
|
return {
|
|
803
803
|
code: CommissioningStepResultCode.Failure,
|
|
804
|
-
breadcrumb: this
|
|
804
|
+
breadcrumb: this.lastBreadcrumb,
|
|
805
805
|
};
|
|
806
806
|
}
|
|
807
807
|
const operationalCredentialCluster = this.#getClusterClient(OperationalCredentials.Cluster);
|
|
@@ -809,7 +809,7 @@ export class ControllerCommissioningFlow {
|
|
|
809
809
|
this.#ensureOperationalCredentialsSuccess(
|
|
810
810
|
"updateFabricLabel",
|
|
811
811
|
await operationalCredentialCluster.updateFabricLabel({
|
|
812
|
-
label: this
|
|
812
|
+
label: this.fabric.label,
|
|
813
813
|
fabricIndex,
|
|
814
814
|
}),
|
|
815
815
|
);
|
|
@@ -820,7 +820,7 @@ export class ControllerCommissioningFlow {
|
|
|
820
820
|
|
|
821
821
|
return {
|
|
822
822
|
code: CommissioningStepResultCode.Success,
|
|
823
|
-
breadcrumb: this
|
|
823
|
+
breadcrumb: this.lastBreadcrumb,
|
|
824
824
|
};
|
|
825
825
|
}
|
|
826
826
|
|
|
@@ -836,7 +836,7 @@ export class ControllerCommissioningFlow {
|
|
|
836
836
|
|
|
837
837
|
return {
|
|
838
838
|
code: CommissioningStepResultCode.Skipped,
|
|
839
|
-
breadcrumb: this
|
|
839
|
+
breadcrumb: this.lastBreadcrumb,
|
|
840
840
|
};
|
|
841
841
|
}
|
|
842
842
|
|
|
@@ -855,24 +855,28 @@ export class ControllerCommissioningFlow {
|
|
|
855
855
|
*/
|
|
856
856
|
async #validateNetwork() {
|
|
857
857
|
if (
|
|
858
|
-
this
|
|
859
|
-
this
|
|
858
|
+
this.collectedCommissioningData.networkFeatures === undefined ||
|
|
859
|
+
this.collectedCommissioningData.networkStatus === undefined
|
|
860
860
|
) {
|
|
861
861
|
throw new CommissioningError("No network features or status collected. This should never happen.");
|
|
862
862
|
}
|
|
863
863
|
if (
|
|
864
|
-
this
|
|
865
|
-
|
|
864
|
+
(this.commissioningOptions.wifiNetwork === undefined ||
|
|
865
|
+
!this.commissioningOptions.wifiNetwork.wifiSsid ||
|
|
866
|
+
!this.commissioningOptions.wifiNetwork.wifiCredentials) &&
|
|
867
|
+
(this.commissioningOptions.threadNetwork === undefined ||
|
|
868
|
+
!this.commissioningOptions.threadNetwork.networkName ||
|
|
869
|
+
!this.commissioningOptions.threadNetwork.operationalDataset)
|
|
866
870
|
) {
|
|
867
871
|
// Check if we have no networkCommissioning cluster or an Ethernet one
|
|
868
872
|
const anyEthernetInterface =
|
|
869
|
-
this
|
|
870
|
-
this
|
|
873
|
+
this.collectedCommissioningData.networkFeatures.length === 0 ||
|
|
874
|
+
this.collectedCommissioningData.networkFeatures.some(
|
|
871
875
|
({ value: { ethernetNetworkInterface } }) => ethernetNetworkInterface === true,
|
|
872
876
|
);
|
|
873
877
|
const anyInterfaceConnected =
|
|
874
|
-
this
|
|
875
|
-
this
|
|
878
|
+
this.collectedCommissioningData.networkStatus.length === 0 ||
|
|
879
|
+
this.collectedCommissioningData.networkStatus.some(({ value }) =>
|
|
876
880
|
value.some(({ connected }) => connected),
|
|
877
881
|
);
|
|
878
882
|
if (!anyEthernetInterface && !anyInterfaceConnected) {
|
|
@@ -884,26 +888,26 @@ export class ControllerCommissioningFlow {
|
|
|
884
888
|
|
|
885
889
|
return {
|
|
886
890
|
code: CommissioningStepResultCode.Success,
|
|
887
|
-
breadcrumb: this
|
|
891
|
+
breadcrumb: this.lastBreadcrumb,
|
|
888
892
|
};
|
|
889
893
|
}
|
|
890
894
|
|
|
891
895
|
async #configureNetworkWifi() {
|
|
892
|
-
if (this
|
|
896
|
+
if (this.commissioningOptions.wifiNetwork === undefined) {
|
|
893
897
|
logger.debug("WiFi network is not configured");
|
|
894
898
|
return {
|
|
895
899
|
code: CommissioningStepResultCode.Skipped,
|
|
896
|
-
breadcrumb: this
|
|
900
|
+
breadcrumb: this.lastBreadcrumb,
|
|
897
901
|
};
|
|
898
902
|
}
|
|
899
903
|
if (
|
|
900
|
-
this
|
|
901
|
-
this
|
|
904
|
+
this.collectedCommissioningData.networkFeatures !== undefined &&
|
|
905
|
+
this.collectedCommissioningData.networkStatus !== undefined
|
|
902
906
|
) {
|
|
903
|
-
const rootNetworkFeatures = this
|
|
907
|
+
const rootNetworkFeatures = this.collectedCommissioningData.networkFeatures.find(
|
|
904
908
|
({ endpointId }) => endpointId === 0,
|
|
905
909
|
)?.value;
|
|
906
|
-
const rootNetworkStatus = this
|
|
910
|
+
const rootNetworkStatus = this.collectedCommissioningData.networkStatus.find(
|
|
907
911
|
({ endpointId }) => endpointId === 0,
|
|
908
912
|
)?.value;
|
|
909
913
|
|
|
@@ -915,15 +919,15 @@ export class ControllerCommissioningFlow {
|
|
|
915
919
|
logger.debug("Commissionee does not support any WiFi network interface");
|
|
916
920
|
return {
|
|
917
921
|
code: CommissioningStepResultCode.Skipped,
|
|
918
|
-
breadcrumb: this
|
|
922
|
+
breadcrumb: this.lastBreadcrumb,
|
|
919
923
|
};
|
|
920
924
|
}
|
|
921
925
|
if (rootNetworkStatus !== undefined && rootNetworkStatus.length > 0 && rootNetworkStatus[0].connected) {
|
|
922
926
|
logger.debug("Commissionee is already connected to the WiFi network");
|
|
923
|
-
this
|
|
927
|
+
this.collectedCommissioningData.successfullyConnectedToNetwork = true;
|
|
924
928
|
return {
|
|
925
929
|
code: CommissioningStepResultCode.Skipped,
|
|
926
|
-
breadcrumb: this
|
|
930
|
+
breadcrumb: this.lastBreadcrumb,
|
|
927
931
|
};
|
|
928
932
|
}
|
|
929
933
|
}
|
|
@@ -934,13 +938,13 @@ export class ControllerCommissioningFlow {
|
|
|
934
938
|
EndpointNumber(0),
|
|
935
939
|
true,
|
|
936
940
|
);
|
|
937
|
-
const ssid = Bytes.fromString(this
|
|
938
|
-
const credentials = Bytes.fromString(this
|
|
941
|
+
const ssid = Bytes.fromString(this.commissioningOptions.wifiNetwork.wifiSsid);
|
|
942
|
+
const credentials = Bytes.fromString(this.commissioningOptions.wifiNetwork.wifiCredentials);
|
|
939
943
|
|
|
940
944
|
const { networkingStatus, wiFiScanResults, debugText } = await networkCommissioningClusterClient.scanNetworks(
|
|
941
945
|
{
|
|
942
946
|
ssid,
|
|
943
|
-
breadcrumb: this
|
|
947
|
+
breadcrumb: this.lastBreadcrumb++,
|
|
944
948
|
},
|
|
945
949
|
{ useExtendedFailSafeMessageResponseTimeout: true },
|
|
946
950
|
);
|
|
@@ -949,7 +953,7 @@ export class ControllerCommissioningFlow {
|
|
|
949
953
|
}
|
|
950
954
|
if (wiFiScanResults === undefined || wiFiScanResults.length === 0) {
|
|
951
955
|
throw new CommissioningError(
|
|
952
|
-
`Commissionee did not return any WiFi networks for the requested SSID ${this
|
|
956
|
+
`Commissionee did not return any WiFi networks for the requested SSID ${this.commissioningOptions.wifiNetwork.wifiSsid}`,
|
|
953
957
|
);
|
|
954
958
|
}
|
|
955
959
|
|
|
@@ -961,7 +965,7 @@ export class ControllerCommissioningFlow {
|
|
|
961
965
|
{
|
|
962
966
|
ssid,
|
|
963
967
|
credentials,
|
|
964
|
-
breadcrumb: this
|
|
968
|
+
breadcrumb: this.lastBreadcrumb++,
|
|
965
969
|
},
|
|
966
970
|
{ useExtendedFailSafeMessageResponseTimeout: true },
|
|
967
971
|
);
|
|
@@ -972,7 +976,7 @@ export class ControllerCommissioningFlow {
|
|
|
972
976
|
throw new CommissioningError(`Commissionee did not return network index`);
|
|
973
977
|
}
|
|
974
978
|
logger.debug(
|
|
975
|
-
`Commissionee added WiFi network ${this
|
|
979
|
+
`Commissionee added WiFi network ${this.commissioningOptions.wifiNetwork.wifiSsid} with network index ${networkIndex}`,
|
|
976
980
|
);
|
|
977
981
|
|
|
978
982
|
const updatedNetworks = await networkCommissioningClusterClient.getNetworksAttribute();
|
|
@@ -981,22 +985,22 @@ export class ControllerCommissioningFlow {
|
|
|
981
985
|
}
|
|
982
986
|
const { networkId, connected } = updatedNetworks[networkIndex];
|
|
983
987
|
if (connected) {
|
|
984
|
-
this
|
|
988
|
+
this.collectedCommissioningData.successfullyConnectedToNetwork = true;
|
|
985
989
|
logger.debug(
|
|
986
990
|
`Commissionee is already connected to WiFi network ${
|
|
987
|
-
this
|
|
991
|
+
this.commissioningOptions.wifiNetwork.wifiSsid
|
|
988
992
|
} (networkId ${Bytes.toHex(networkId)})`,
|
|
989
993
|
);
|
|
990
994
|
return {
|
|
991
995
|
code: CommissioningStepResultCode.Success,
|
|
992
|
-
breadcrumb: this
|
|
996
|
+
breadcrumb: this.lastBreadcrumb,
|
|
993
997
|
};
|
|
994
998
|
}
|
|
995
999
|
|
|
996
1000
|
const connectResult = await networkCommissioningClusterClient.connectNetwork(
|
|
997
1001
|
{
|
|
998
1002
|
networkId: networkId,
|
|
999
|
-
breadcrumb: this
|
|
1003
|
+
breadcrumb: this.lastBreadcrumb++,
|
|
1000
1004
|
},
|
|
1001
1005
|
{ useExtendedFailSafeMessageResponseTimeout: true },
|
|
1002
1006
|
);
|
|
@@ -1004,42 +1008,42 @@ export class ControllerCommissioningFlow {
|
|
|
1004
1008
|
if (connectResult.networkingStatus !== NetworkCommissioning.NetworkCommissioningStatus.Success) {
|
|
1005
1009
|
throw new CommissioningError(`Commissionee failed to connect to WiFi network: ${connectResult.debugText}`);
|
|
1006
1010
|
}
|
|
1007
|
-
this
|
|
1011
|
+
this.collectedCommissioningData.successfullyConnectedToNetwork = true;
|
|
1008
1012
|
logger.debug(
|
|
1009
1013
|
`Commissionee successfully connected to WiFi network ${
|
|
1010
|
-
this
|
|
1014
|
+
this.commissioningOptions.wifiNetwork.wifiSsid
|
|
1011
1015
|
} (networkId ${Bytes.toHex(networkId)})`,
|
|
1012
1016
|
);
|
|
1013
1017
|
|
|
1014
1018
|
return {
|
|
1015
1019
|
code: CommissioningStepResultCode.Success,
|
|
1016
|
-
breadcrumb: this
|
|
1020
|
+
breadcrumb: this.lastBreadcrumb,
|
|
1017
1021
|
};
|
|
1018
1022
|
}
|
|
1019
1023
|
|
|
1020
1024
|
async #configureNetworkThread() {
|
|
1021
|
-
if (this
|
|
1022
|
-
logger.
|
|
1025
|
+
if (this.collectedCommissioningData.successfullyConnectedToNetwork) {
|
|
1026
|
+
logger.info("Node is already connected to a network. Skipping Thread configuration.");
|
|
1023
1027
|
return {
|
|
1024
1028
|
code: CommissioningStepResultCode.Skipped,
|
|
1025
|
-
breadcrumb: this
|
|
1029
|
+
breadcrumb: this.lastBreadcrumb,
|
|
1026
1030
|
};
|
|
1027
1031
|
}
|
|
1028
|
-
if (this
|
|
1032
|
+
if (this.commissioningOptions.threadNetwork === undefined) {
|
|
1029
1033
|
logger.debug("Thread network is not configured");
|
|
1030
1034
|
return {
|
|
1031
1035
|
code: CommissioningStepResultCode.Skipped,
|
|
1032
|
-
breadcrumb: this
|
|
1036
|
+
breadcrumb: this.lastBreadcrumb,
|
|
1033
1037
|
};
|
|
1034
1038
|
}
|
|
1035
1039
|
if (
|
|
1036
|
-
this
|
|
1037
|
-
this
|
|
1040
|
+
this.collectedCommissioningData.networkFeatures !== undefined &&
|
|
1041
|
+
this.collectedCommissioningData.networkStatus !== undefined
|
|
1038
1042
|
) {
|
|
1039
|
-
const rootNetworkFeatures = this
|
|
1043
|
+
const rootNetworkFeatures = this.collectedCommissioningData.networkFeatures.find(
|
|
1040
1044
|
({ endpointId }) => endpointId === 0,
|
|
1041
1045
|
)?.value;
|
|
1042
|
-
const rootNetworkStatus = this
|
|
1046
|
+
const rootNetworkStatus = this.collectedCommissioningData.networkStatus.find(
|
|
1043
1047
|
({ endpointId }) => endpointId === 0,
|
|
1044
1048
|
)?.value;
|
|
1045
1049
|
|
|
@@ -1051,14 +1055,14 @@ export class ControllerCommissioningFlow {
|
|
|
1051
1055
|
logger.debug("Commissionee does not support any Thread network interface");
|
|
1052
1056
|
return {
|
|
1053
1057
|
code: CommissioningStepResultCode.Skipped,
|
|
1054
|
-
breadcrumb: this
|
|
1058
|
+
breadcrumb: this.lastBreadcrumb,
|
|
1055
1059
|
};
|
|
1056
1060
|
}
|
|
1057
1061
|
if (rootNetworkStatus !== undefined && rootNetworkStatus.length > 0 && rootNetworkStatus[0].connected) {
|
|
1058
1062
|
logger.debug("Commissionee is already connected to the Thread network");
|
|
1059
1063
|
return {
|
|
1060
1064
|
code: CommissioningStepResultCode.Skipped,
|
|
1061
|
-
breadcrumb: this
|
|
1065
|
+
breadcrumb: this.lastBreadcrumb,
|
|
1062
1066
|
};
|
|
1063
1067
|
}
|
|
1064
1068
|
}
|
|
@@ -1071,7 +1075,7 @@ export class ControllerCommissioningFlow {
|
|
|
1071
1075
|
);
|
|
1072
1076
|
|
|
1073
1077
|
const { networkingStatus, threadScanResults, debugText } = await networkCommissioningClusterClient.scanNetworks(
|
|
1074
|
-
{ breadcrumb: this
|
|
1078
|
+
{ breadcrumb: this.lastBreadcrumb++ },
|
|
1075
1079
|
{ useExtendedFailSafeMessageResponseTimeout: true },
|
|
1076
1080
|
);
|
|
1077
1081
|
if (networkingStatus !== NetworkCommissioning.NetworkCommissioningStatus.Success) {
|
|
@@ -1079,22 +1083,22 @@ export class ControllerCommissioningFlow {
|
|
|
1079
1083
|
}
|
|
1080
1084
|
if (threadScanResults === undefined || threadScanResults.length === 0) {
|
|
1081
1085
|
throw new CommissioningError(
|
|
1082
|
-
`Commissionee did not return any Thread networks for the requested Network ${this
|
|
1086
|
+
`Commissionee did not return any Thread networks for the requested Network ${this.commissioningOptions.threadNetwork.networkName}`,
|
|
1083
1087
|
);
|
|
1084
1088
|
}
|
|
1085
1089
|
const wantedNetworkFound = threadScanResults.find(
|
|
1086
|
-
({ networkName }) => networkName === this
|
|
1090
|
+
({ networkName }) => networkName === this.commissioningOptions.threadNetwork?.networkName,
|
|
1087
1091
|
);
|
|
1088
1092
|
if (wantedNetworkFound === undefined) {
|
|
1089
1093
|
throw new CommissioningError(
|
|
1090
1094
|
`Commissionee did not return the requested Network ${
|
|
1091
|
-
this
|
|
1095
|
+
this.commissioningOptions.threadNetwork.networkName
|
|
1092
1096
|
}: ${Logger.toJSON(threadScanResults)}`,
|
|
1093
1097
|
);
|
|
1094
1098
|
}
|
|
1095
1099
|
logger.debug(
|
|
1096
1100
|
`Commissionee found wanted Thread network ${
|
|
1097
|
-
this
|
|
1101
|
+
this.commissioningOptions.threadNetwork.networkName
|
|
1098
1102
|
}: ${Logger.toJSON(wantedNetworkFound)}`,
|
|
1099
1103
|
);
|
|
1100
1104
|
|
|
@@ -1104,8 +1108,8 @@ export class ControllerCommissioningFlow {
|
|
|
1104
1108
|
networkIndex,
|
|
1105
1109
|
} = await networkCommissioningClusterClient.addOrUpdateThreadNetwork(
|
|
1106
1110
|
{
|
|
1107
|
-
operationalDataset: Bytes.fromHex(this
|
|
1108
|
-
breadcrumb: this
|
|
1111
|
+
operationalDataset: Bytes.fromHex(this.commissioningOptions.threadNetwork.operationalDataset),
|
|
1112
|
+
breadcrumb: this.lastBreadcrumb++,
|
|
1109
1113
|
},
|
|
1110
1114
|
{ useExtendedFailSafeMessageResponseTimeout: true },
|
|
1111
1115
|
);
|
|
@@ -1116,7 +1120,7 @@ export class ControllerCommissioningFlow {
|
|
|
1116
1120
|
throw new CommissioningError(`Commissionee did not return network index`);
|
|
1117
1121
|
}
|
|
1118
1122
|
logger.debug(
|
|
1119
|
-
`Commissionee added Thread network ${this
|
|
1123
|
+
`Commissionee added Thread network ${this.commissioningOptions.threadNetwork.networkName} with network index ${networkIndex}`,
|
|
1120
1124
|
);
|
|
1121
1125
|
|
|
1122
1126
|
const updatedNetworks = await networkCommissioningClusterClient.getNetworksAttribute();
|
|
@@ -1127,19 +1131,19 @@ export class ControllerCommissioningFlow {
|
|
|
1127
1131
|
if (connected) {
|
|
1128
1132
|
logger.debug(
|
|
1129
1133
|
`Commissionee is already connected to Thread network ${
|
|
1130
|
-
this
|
|
1134
|
+
this.commissioningOptions.threadNetwork.networkName
|
|
1131
1135
|
} (networkId ${Bytes.toHex(networkId)})`,
|
|
1132
1136
|
);
|
|
1133
1137
|
return {
|
|
1134
1138
|
code: CommissioningStepResultCode.Success,
|
|
1135
|
-
breadcrumb: this
|
|
1139
|
+
breadcrumb: this.lastBreadcrumb,
|
|
1136
1140
|
};
|
|
1137
1141
|
}
|
|
1138
1142
|
|
|
1139
1143
|
const connectResult = await networkCommissioningClusterClient.connectNetwork(
|
|
1140
1144
|
{
|
|
1141
1145
|
networkId: networkId,
|
|
1142
|
-
breadcrumb: this
|
|
1146
|
+
breadcrumb: this.lastBreadcrumb++,
|
|
1143
1147
|
},
|
|
1144
1148
|
{ useExtendedFailSafeMessageResponseTimeout: true },
|
|
1145
1149
|
);
|
|
@@ -1151,13 +1155,13 @@ export class ControllerCommissioningFlow {
|
|
|
1151
1155
|
}
|
|
1152
1156
|
logger.debug(
|
|
1153
1157
|
`Commissionee successfully connected to Thread network ${
|
|
1154
|
-
this
|
|
1158
|
+
this.commissioningOptions.threadNetwork.networkName
|
|
1155
1159
|
} (networkId ${Bytes.toHex(networkId)})`,
|
|
1156
1160
|
);
|
|
1157
1161
|
|
|
1158
1162
|
return {
|
|
1159
1163
|
code: CommissioningStepResultCode.Success,
|
|
1160
|
-
breadcrumb: this
|
|
1164
|
+
breadcrumb: this.lastBreadcrumb,
|
|
1161
1165
|
};
|
|
1162
1166
|
}
|
|
1163
1167
|
|
|
@@ -1170,7 +1174,7 @@ export class ControllerCommissioningFlow {
|
|
|
1170
1174
|
* (CASE)”) session with the Commissionee over the operational network.
|
|
1171
1175
|
*/
|
|
1172
1176
|
async #reconnectWithDevice() {
|
|
1173
|
-
const isConcurrentFlow = this
|
|
1177
|
+
const isConcurrentFlow = this.collectedCommissioningData.supportsConcurrentConnection !== false;
|
|
1174
1178
|
|
|
1175
1179
|
logger.debug(`Reconnecting with device with ${isConcurrentFlow ? "concurrent" : "non-concurrent"} flow ...`);
|
|
1176
1180
|
|
|
@@ -1201,8 +1205,8 @@ export class ControllerCommissioningFlow {
|
|
|
1201
1205
|
reArmFailsafeInterval.start();
|
|
1202
1206
|
}
|
|
1203
1207
|
|
|
1204
|
-
const transitionResult = await this
|
|
1205
|
-
this
|
|
1208
|
+
const transitionResult = await this.transitionToCase(
|
|
1209
|
+
this.interactionClient.address,
|
|
1206
1210
|
// Assume concurrent connections are supported if not know (which should not be the case when we came here)
|
|
1207
1211
|
isConcurrentFlow,
|
|
1208
1212
|
);
|
|
@@ -1213,18 +1217,18 @@ export class ControllerCommissioningFlow {
|
|
|
1213
1217
|
logger.debug("CASE commissioning handled externally, terminating commissioning flow");
|
|
1214
1218
|
return {
|
|
1215
1219
|
code: CommissioningStepResultCode.Stop,
|
|
1216
|
-
breadcrumb: this
|
|
1220
|
+
breadcrumb: this.lastBreadcrumb,
|
|
1217
1221
|
};
|
|
1218
1222
|
}
|
|
1219
1223
|
|
|
1220
|
-
this
|
|
1224
|
+
this.interactionClient = transitionResult;
|
|
1221
1225
|
this.#clusterClients.clear();
|
|
1222
1226
|
|
|
1223
1227
|
logger.debug("Successfully reconnected with device ...");
|
|
1224
1228
|
|
|
1225
1229
|
return {
|
|
1226
1230
|
code: CommissioningStepResultCode.Success,
|
|
1227
|
-
breadcrumb: this
|
|
1231
|
+
breadcrumb: this.lastBreadcrumb,
|
|
1228
1232
|
};
|
|
1229
1233
|
}
|
|
1230
1234
|
|
|
@@ -1247,7 +1251,7 @@ export class ControllerCommissioningFlow {
|
|
|
1247
1251
|
|
|
1248
1252
|
return {
|
|
1249
1253
|
code: CommissioningStepResultCode.Success,
|
|
1250
|
-
breadcrumb: this
|
|
1254
|
+
breadcrumb: this.lastBreadcrumb,
|
|
1251
1255
|
};
|
|
1252
1256
|
}
|
|
1253
1257
|
}
|