@matter/protocol 0.14.0-alpha.0-20250531-7ed2d6da8 → 0.14.0-alpha.0-20250601-939a65f46
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/peer/ControllerCommissioner.d.ts.map +1 -1
- package/dist/cjs/peer/ControllerCommissioner.js +2 -2
- package/dist/cjs/peer/ControllerCommissioner.js.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.d.ts +34 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.d.ts.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.js +81 -27
- package/dist/cjs/peer/ControllerCommissioningFlow.js.map +1 -1
- package/dist/cjs/peer/ControllerDiscovery.d.ts.map +1 -1
- package/dist/cjs/peer/ControllerDiscovery.js +3 -3
- package/dist/cjs/peer/ControllerDiscovery.js.map +1 -1
- package/dist/cjs/peer/PeerSet.d.ts.map +1 -1
- package/dist/cjs/peer/PeerSet.js +39 -26
- package/dist/cjs/peer/PeerSet.js.map +1 -1
- package/dist/cjs/securechannel/SecureChannelMessenger.d.ts.map +1 -1
- package/dist/cjs/securechannel/SecureChannelMessenger.js +3 -1
- package/dist/cjs/securechannel/SecureChannelMessenger.js.map +1 -1
- package/dist/cjs/session/SessionManager.d.ts +10 -2
- package/dist/cjs/session/SessionManager.d.ts.map +1 -1
- package/dist/cjs/session/SessionManager.js +24 -8
- package/dist/cjs/session/SessionManager.js.map +1 -1
- package/dist/cjs/session/case/CaseClient.d.ts.map +1 -1
- package/dist/cjs/session/case/CaseClient.js.map +1 -1
- package/dist/cjs/session/case/CaseMessenger.js +1 -1
- package/dist/cjs/session/case/CaseMessenger.js.map +1 -1
- package/dist/esm/peer/ControllerCommissioner.d.ts.map +1 -1
- package/dist/esm/peer/ControllerCommissioner.js +4 -3
- package/dist/esm/peer/ControllerCommissioner.js.map +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.d.ts +34 -1
- package/dist/esm/peer/ControllerCommissioningFlow.d.ts.map +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.js +81 -27
- package/dist/esm/peer/ControllerCommissioningFlow.js.map +1 -1
- package/dist/esm/peer/ControllerDiscovery.d.ts.map +1 -1
- package/dist/esm/peer/ControllerDiscovery.js +3 -3
- package/dist/esm/peer/ControllerDiscovery.js.map +1 -1
- package/dist/esm/peer/PeerSet.d.ts.map +1 -1
- package/dist/esm/peer/PeerSet.js +40 -27
- package/dist/esm/peer/PeerSet.js.map +1 -1
- package/dist/esm/securechannel/SecureChannelMessenger.d.ts.map +1 -1
- package/dist/esm/securechannel/SecureChannelMessenger.js +3 -1
- package/dist/esm/securechannel/SecureChannelMessenger.js.map +1 -1
- package/dist/esm/session/SessionManager.d.ts +10 -2
- package/dist/esm/session/SessionManager.d.ts.map +1 -1
- package/dist/esm/session/SessionManager.js +24 -8
- package/dist/esm/session/SessionManager.js.map +1 -1
- package/dist/esm/session/case/CaseClient.d.ts.map +1 -1
- package/dist/esm/session/case/CaseClient.js.map +1 -1
- package/dist/esm/session/case/CaseMessenger.js +1 -1
- package/dist/esm/session/case/CaseMessenger.js.map +1 -1
- package/package.json +6 -6
- package/src/peer/ControllerCommissioner.ts +3 -2
- package/src/peer/ControllerCommissioningFlow.ts +87 -38
- package/src/peer/ControllerDiscovery.ts +3 -3
- package/src/peer/PeerSet.ts +56 -30
- package/src/securechannel/SecureChannelMessenger.ts +3 -1
- package/src/session/SessionManager.ts +24 -7
- package/src/session/case/CaseClient.ts +1 -0
- package/src/session/case/CaseMessenger.ts +1 -1
package/src/peer/PeerSet.ts
CHANGED
|
@@ -31,13 +31,14 @@ import {
|
|
|
31
31
|
import { SubscriptionClient } from "#interaction/SubscriptionClient.js";
|
|
32
32
|
import { MdnsScanner } from "#mdns/MdnsScanner.js";
|
|
33
33
|
import { PeerAddress, PeerAddressMap } from "#peer/PeerAddress.js";
|
|
34
|
+
import { ChannelStatusResponseError } from "#securechannel/index.js";
|
|
34
35
|
import { CaseClient, SecureSession, Session } from "#session/index.js";
|
|
35
36
|
import { SessionManager } from "#session/SessionManager.js";
|
|
36
|
-
import { SECURE_CHANNEL_PROTOCOL_ID } from "#types";
|
|
37
|
+
import { NodeId, ProtocolStatusCode, SECURE_CHANNEL_PROTOCOL_ID } from "#types";
|
|
37
38
|
import { ChannelManager } from "../protocol/ChannelManager.js";
|
|
38
39
|
import { ChannelNotConnectedError, ExchangeManager, MessageChannel } from "../protocol/ExchangeManager.js";
|
|
39
40
|
import { DedicatedChannelExchangeProvider, ReconnectableExchangeProvider } from "../protocol/ExchangeProvider.js";
|
|
40
|
-
import { RetransmissionLimitReachedError } from "../protocol/MessageExchange.js";
|
|
41
|
+
import { MessageExchange, RetransmissionLimitReachedError } from "../protocol/MessageExchange.js";
|
|
41
42
|
import { ControllerDiscovery, DiscoveryError, PairRetransmissionLimitReachedError } from "./ControllerDiscovery.js";
|
|
42
43
|
import { InteractionQueue } from "./InteractionQueue.js";
|
|
43
44
|
import { OperationalPeer } from "./OperationalPeer.js";
|
|
@@ -654,42 +655,67 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
654
655
|
},
|
|
655
656
|
isInitiator: true,
|
|
656
657
|
});
|
|
657
|
-
|
|
658
|
-
let operationalSecureSession;
|
|
658
|
+
|
|
659
659
|
try {
|
|
660
|
-
const
|
|
661
|
-
|
|
662
|
-
|
|
660
|
+
const operationalSecureSession = await this.#doCasePair(
|
|
661
|
+
new MessageChannel(operationalChannel, unsecureSession),
|
|
662
|
+
address,
|
|
663
|
+
expectedProcessingTimeMs,
|
|
663
664
|
);
|
|
664
665
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
expectedProcessingTimeMs,
|
|
671
|
-
);
|
|
672
|
-
operationalSecureSession = session;
|
|
673
|
-
|
|
674
|
-
if (!resumed) {
|
|
675
|
-
// When the session was not resumed then most likely the device firmware got updated, so we clear the cache
|
|
676
|
-
this.#nodeCachedData.delete(address);
|
|
677
|
-
}
|
|
678
|
-
} catch (e) {
|
|
679
|
-
await exchange.close();
|
|
680
|
-
throw e;
|
|
681
|
-
}
|
|
682
|
-
} catch (e) {
|
|
683
|
-
NoResponseTimeoutError.accept(e);
|
|
666
|
+
const channel = new MessageChannel(operationalChannel, operationalSecureSession);
|
|
667
|
+
await this.#channels.setChannel(address, channel);
|
|
668
|
+
return channel;
|
|
669
|
+
} catch (error) {
|
|
670
|
+
NoResponseTimeoutError.accept(error);
|
|
684
671
|
|
|
685
672
|
// Convert error
|
|
686
|
-
throw new PairRetransmissionLimitReachedError(
|
|
673
|
+
throw new PairRetransmissionLimitReachedError(error.message);
|
|
687
674
|
} finally {
|
|
688
675
|
await unsecureSession.destroy();
|
|
689
676
|
}
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
async #doCasePair(
|
|
680
|
+
unsecureMessageChannel: MessageChannel,
|
|
681
|
+
address: PeerAddress,
|
|
682
|
+
expectedProcessingTimeMs?: number,
|
|
683
|
+
): Promise<SecureSession> {
|
|
684
|
+
const fabric = this.#sessions.fabricFor(address);
|
|
685
|
+
let exchange: MessageExchange | undefined;
|
|
686
|
+
try {
|
|
687
|
+
exchange = this.#exchanges.initiateExchangeWithChannel(unsecureMessageChannel, SECURE_CHANNEL_PROTOCOL_ID);
|
|
688
|
+
|
|
689
|
+
const { session, resumed } = await this.#caseClient.pair(
|
|
690
|
+
exchange,
|
|
691
|
+
fabric,
|
|
692
|
+
address.nodeId,
|
|
693
|
+
expectedProcessingTimeMs,
|
|
694
|
+
);
|
|
695
|
+
|
|
696
|
+
if (!resumed) {
|
|
697
|
+
// When the session was not resumed then most likely the device firmware got updated, so we clear the cache
|
|
698
|
+
this.#nodeCachedData.delete(address);
|
|
699
|
+
}
|
|
700
|
+
return session;
|
|
701
|
+
} catch (error) {
|
|
702
|
+
await exchange?.close();
|
|
703
|
+
|
|
704
|
+
if (
|
|
705
|
+
error instanceof ChannelStatusResponseError &&
|
|
706
|
+
error.protocolStatusCode === ProtocolStatusCode.NoSharedTrustRoots
|
|
707
|
+
) {
|
|
708
|
+
// It seems the stored resumption record is outdated; we need to retry pairing without resumption
|
|
709
|
+
if (await this.#sessions.deleteResumptionRecord(fabric.addressOf(address.nodeId))) {
|
|
710
|
+
logger.info(
|
|
711
|
+
`Case client: Resumption record seems outdated for Fabric ${NodeId.toHexString(fabric.nodeId)} (index ${fabric.fabricIndex}) and PeerNode ${NodeId.toHexString(address.nodeId)}. Retrying pairing without resumption...`,
|
|
712
|
+
);
|
|
713
|
+
// An endless loop should not happen here, as the resumption record is deleted in the next step
|
|
714
|
+
return await this.#doCasePair(unsecureMessageChannel, address, expectedProcessingTimeMs);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
throw error;
|
|
718
|
+
}
|
|
693
719
|
}
|
|
694
720
|
|
|
695
721
|
/**
|
|
@@ -23,7 +23,9 @@ export class ChannelStatusResponseError extends MatterError {
|
|
|
23
23
|
public readonly generalStatusCode: GeneralStatusCode,
|
|
24
24
|
public readonly protocolStatusCode: ProtocolStatusCode,
|
|
25
25
|
) {
|
|
26
|
-
super(
|
|
26
|
+
super(
|
|
27
|
+
`(${GeneralStatusCode[generalStatusCode]} (${generalStatusCode}) / ${ProtocolStatusCode[protocolStatusCode]} (${protocolStatusCode})) ${message}`,
|
|
28
|
+
);
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
31
|
|
|
@@ -135,9 +135,9 @@ export class SessionManager {
|
|
|
135
135
|
this.#sessionParameters = { ...DEFAULT_SESSION_PARAMETERS, ...context.parameters };
|
|
136
136
|
|
|
137
137
|
// When fabric is removed, also remove the resumption record
|
|
138
|
-
this.#observers.on(context.fabrics.events.deleted, async fabric =>
|
|
139
|
-
this.deleteResumptionRecordsForFabric(fabric)
|
|
140
|
-
);
|
|
138
|
+
this.#observers.on(context.fabrics.events.deleted, async fabric => {
|
|
139
|
+
await this.deleteResumptionRecordsForFabric(fabric);
|
|
140
|
+
});
|
|
141
141
|
|
|
142
142
|
this.#construction = Construction(this, () => this.#initialize());
|
|
143
143
|
}
|
|
@@ -308,23 +308,40 @@ export class SessionManager {
|
|
|
308
308
|
return session;
|
|
309
309
|
}
|
|
310
310
|
|
|
311
|
+
/**
|
|
312
|
+
* Deletes a resumption record for a given address. Returns true if the record was deleted, false if it did not
|
|
313
|
+
* exist.
|
|
314
|
+
*/
|
|
311
315
|
async deleteResumptionRecord(address: PeerAddress) {
|
|
312
316
|
await this.#construction;
|
|
313
317
|
|
|
314
|
-
this.#resumptionRecords.delete(address);
|
|
315
|
-
|
|
318
|
+
const result = this.#resumptionRecords.delete(address);
|
|
319
|
+
if (result) {
|
|
320
|
+
await this.#storeResumptionRecords();
|
|
321
|
+
}
|
|
322
|
+
return result;
|
|
316
323
|
}
|
|
317
324
|
|
|
325
|
+
/**
|
|
326
|
+
* Deletes all resumption records for a given fabric. Returns true if any records were deleted, false if none
|
|
327
|
+
* existed.
|
|
328
|
+
*/
|
|
318
329
|
async deleteResumptionRecordsForFabric(fabric: Fabric) {
|
|
319
330
|
await this.#construction;
|
|
320
331
|
|
|
332
|
+
let deletedCount = 0;
|
|
321
333
|
for (const address of this.#resumptionRecords.keys()) {
|
|
322
334
|
if (address.fabricIndex === fabric.fabricIndex) {
|
|
323
|
-
this.#resumptionRecords.delete(address)
|
|
335
|
+
if (this.#resumptionRecords.delete(address)) {
|
|
336
|
+
deletedCount++;
|
|
337
|
+
}
|
|
324
338
|
}
|
|
325
339
|
}
|
|
326
340
|
|
|
327
|
-
|
|
341
|
+
if (deletedCount > 0) {
|
|
342
|
+
await this.#storeResumptionRecords();
|
|
343
|
+
}
|
|
344
|
+
return deletedCount > 0;
|
|
328
345
|
}
|
|
329
346
|
|
|
330
347
|
findOldestInactiveSession() {
|
|
@@ -37,6 +37,7 @@ export class CaseClient {
|
|
|
37
37
|
|
|
38
38
|
async pair(exchange: MessageExchange, fabric: Fabric, peerNodeId: NodeId, expectedProcessingTimeMs?: number) {
|
|
39
39
|
const messenger = new CaseClientMessenger(exchange, expectedProcessingTimeMs);
|
|
40
|
+
|
|
40
41
|
try {
|
|
41
42
|
return await this.#doPair(messenger, exchange, fabric, peerNodeId);
|
|
42
43
|
} catch (error) {
|
|
@@ -46,7 +46,7 @@ export class CaseClientMessenger extends SecureChannelMessenger {
|
|
|
46
46
|
return { sigma2Resume: TlvCaseSigma2Resume.decode(payload) };
|
|
47
47
|
default:
|
|
48
48
|
throw new MatterFlowError(
|
|
49
|
-
`Received unexpected message type while expecting CASE Sigma2: ${messageType}, expected: ${SecureMessageType.Sigma2} or ${SecureMessageType.Sigma2Resume}`,
|
|
49
|
+
`Received unexpected message type while expecting CASE Sigma2(Resume): ${messageType}, expected: ${SecureMessageType.Sigma2} or ${SecureMessageType.Sigma2Resume}`,
|
|
50
50
|
);
|
|
51
51
|
}
|
|
52
52
|
}
|