@matter/protocol 0.15.0-alpha.0-20250624-e8c89f458 → 0.15.0-alpha.0-20250625-c7634df96
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/cluster/client/ClusterClient.d.ts.map +1 -1
- package/dist/cjs/cluster/client/ClusterClient.js +7 -1
- package/dist/cjs/cluster/client/ClusterClient.js.map +1 -1
- package/dist/cjs/cluster/client/ClusterClientTypes.d.ts +10 -0
- package/dist/cjs/cluster/client/ClusterClientTypes.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionClient.d.ts +8 -1
- package/dist/cjs/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionClient.js +15 -10
- package/dist/cjs/interaction/InteractionClient.js.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.d.ts +0 -1
- package/dist/cjs/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.js +0 -3
- package/dist/cjs/interaction/InteractionMessenger.js.map +1 -1
- package/dist/cjs/interaction/SubscriptionClient.d.ts +1 -1
- package/dist/cjs/interaction/SubscriptionClient.d.ts.map +1 -1
- package/dist/cjs/interaction/SubscriptionClient.js +1 -1
- package/dist/cjs/peer/ControllerCommissioner.d.ts +3 -2
- package/dist/cjs/peer/ControllerCommissioner.d.ts.map +1 -1
- package/dist/cjs/peer/ControllerCommissioner.js +6 -5
- package/dist/cjs/peer/ControllerCommissioner.js.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.d.ts.map +1 -1
- package/dist/cjs/peer/ControllerCommissioningFlow.js +81 -52
- package/dist/cjs/peer/ControllerCommissioningFlow.js.map +1 -1
- package/dist/cjs/peer/PeerSet.d.ts +4 -3
- package/dist/cjs/peer/PeerSet.d.ts.map +1 -1
- package/dist/cjs/peer/PeerSet.js +10 -9
- package/dist/cjs/peer/PeerSet.js.map +1 -1
- package/dist/cjs/protocol/ChannelManager.d.ts +2 -2
- package/dist/cjs/protocol/ChannelManager.d.ts.map +1 -1
- package/dist/cjs/protocol/ChannelManager.js +4 -4
- package/dist/cjs/protocol/ChannelManager.js.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.d.ts +5 -24
- package/dist/cjs/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.js +12 -55
- package/dist/cjs/protocol/ExchangeManager.js.map +1 -1
- package/dist/cjs/protocol/ExchangeProvider.d.ts +10 -6
- package/dist/cjs/protocol/ExchangeProvider.d.ts.map +1 -1
- package/dist/cjs/protocol/ExchangeProvider.js +12 -1
- package/dist/cjs/protocol/ExchangeProvider.js.map +1 -1
- package/dist/cjs/protocol/MessageChannel.d.ts +52 -0
- package/dist/cjs/protocol/MessageChannel.d.ts.map +1 -0
- package/dist/cjs/protocol/MessageChannel.js +130 -0
- package/dist/cjs/protocol/MessageChannel.js.map +6 -0
- package/dist/cjs/protocol/MessageExchange.d.ts +5 -5
- package/dist/cjs/protocol/MessageExchange.d.ts.map +1 -1
- package/dist/cjs/protocol/MessageExchange.js +34 -78
- package/dist/cjs/protocol/MessageExchange.js.map +1 -1
- package/dist/cjs/protocol/ProtocolStatusMessage.d.ts +20 -0
- package/dist/cjs/protocol/ProtocolStatusMessage.d.ts.map +1 -0
- package/dist/cjs/protocol/ProtocolStatusMessage.js +61 -0
- package/dist/cjs/protocol/ProtocolStatusMessage.js.map +6 -0
- package/dist/cjs/protocol/index.d.ts +2 -0
- package/dist/cjs/protocol/index.d.ts.map +1 -1
- package/dist/cjs/protocol/index.js +2 -0
- package/dist/cjs/protocol/index.js.map +1 -1
- package/dist/cjs/securechannel/SecureChannelMessenger.d.ts +4 -5
- package/dist/cjs/securechannel/SecureChannelMessenger.d.ts.map +1 -1
- package/dist/cjs/securechannel/SecureChannelMessenger.js +7 -8
- package/dist/cjs/securechannel/SecureChannelMessenger.js.map +1 -1
- package/dist/cjs/securechannel/SecureChannelProtocol.js +2 -2
- package/dist/cjs/securechannel/SecureChannelProtocol.js.map +1 -1
- package/dist/cjs/securechannel/SecureChannelStatusMessageSchema.d.ts +4 -15
- package/dist/cjs/securechannel/SecureChannelStatusMessageSchema.d.ts.map +1 -1
- package/dist/cjs/securechannel/SecureChannelStatusMessageSchema.js +3 -21
- package/dist/cjs/securechannel/SecureChannelStatusMessageSchema.js.map +1 -1
- package/dist/cjs/session/case/CaseClient.d.ts.map +1 -1
- package/dist/cjs/session/case/CaseClient.js +1 -1
- package/dist/cjs/session/case/CaseClient.js.map +1 -1
- package/dist/cjs/session/case/CaseServer.js +2 -2
- package/dist/cjs/session/case/CaseServer.js.map +1 -1
- package/dist/cjs/session/pase/PaseClient.js +2 -2
- package/dist/cjs/session/pase/PaseClient.js.map +1 -1
- package/dist/cjs/session/pase/PaseServer.js +1 -1
- package/dist/cjs/session/pase/PaseServer.js.map +1 -1
- package/dist/esm/cluster/client/ClusterClient.d.ts.map +1 -1
- package/dist/esm/cluster/client/ClusterClient.js +7 -1
- package/dist/esm/cluster/client/ClusterClient.js.map +1 -1
- package/dist/esm/cluster/client/ClusterClientTypes.d.ts +10 -0
- package/dist/esm/cluster/client/ClusterClientTypes.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionClient.d.ts +8 -1
- package/dist/esm/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionClient.js +15 -10
- package/dist/esm/interaction/InteractionClient.js.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.d.ts +0 -1
- package/dist/esm/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.js +0 -3
- package/dist/esm/interaction/InteractionMessenger.js.map +1 -1
- package/dist/esm/interaction/SubscriptionClient.d.ts +1 -1
- package/dist/esm/interaction/SubscriptionClient.d.ts.map +1 -1
- package/dist/esm/interaction/SubscriptionClient.js +1 -1
- package/dist/esm/peer/ControllerCommissioner.d.ts +3 -2
- 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.map +1 -1
- package/dist/esm/peer/ControllerCommissioningFlow.js +81 -52
- package/dist/esm/peer/ControllerCommissioningFlow.js.map +1 -1
- package/dist/esm/peer/PeerSet.d.ts +4 -3
- package/dist/esm/peer/PeerSet.d.ts.map +1 -1
- package/dist/esm/peer/PeerSet.js +7 -6
- package/dist/esm/peer/PeerSet.js.map +1 -1
- package/dist/esm/protocol/ChannelManager.d.ts +2 -2
- package/dist/esm/protocol/ChannelManager.d.ts.map +1 -1
- package/dist/esm/protocol/ChannelManager.js +2 -2
- package/dist/esm/protocol/ChannelManager.js.map +1 -1
- package/dist/esm/protocol/ExchangeManager.d.ts +5 -24
- package/dist/esm/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/esm/protocol/ExchangeManager.js +13 -56
- package/dist/esm/protocol/ExchangeManager.js.map +1 -1
- package/dist/esm/protocol/ExchangeProvider.d.ts +10 -6
- package/dist/esm/protocol/ExchangeProvider.d.ts.map +1 -1
- package/dist/esm/protocol/ExchangeProvider.js +12 -1
- package/dist/esm/protocol/ExchangeProvider.js.map +1 -1
- package/dist/esm/protocol/MessageChannel.d.ts +52 -0
- package/dist/esm/protocol/MessageChannel.d.ts.map +1 -0
- package/dist/esm/protocol/MessageChannel.js +110 -0
- package/dist/esm/protocol/MessageChannel.js.map +6 -0
- package/dist/esm/protocol/MessageExchange.d.ts +5 -5
- package/dist/esm/protocol/MessageExchange.d.ts.map +1 -1
- package/dist/esm/protocol/MessageExchange.js +39 -83
- package/dist/esm/protocol/MessageExchange.js.map +1 -1
- package/dist/esm/protocol/ProtocolStatusMessage.d.ts +20 -0
- package/dist/esm/protocol/ProtocolStatusMessage.d.ts.map +1 -0
- package/dist/esm/protocol/ProtocolStatusMessage.js +41 -0
- package/dist/esm/protocol/ProtocolStatusMessage.js.map +6 -0
- package/dist/esm/protocol/index.d.ts +2 -0
- package/dist/esm/protocol/index.d.ts.map +1 -1
- package/dist/esm/protocol/index.js +2 -0
- package/dist/esm/protocol/index.js.map +1 -1
- package/dist/esm/securechannel/SecureChannelMessenger.d.ts +4 -5
- package/dist/esm/securechannel/SecureChannelMessenger.d.ts.map +1 -1
- package/dist/esm/securechannel/SecureChannelMessenger.js +8 -14
- package/dist/esm/securechannel/SecureChannelMessenger.js.map +1 -1
- package/dist/esm/securechannel/SecureChannelProtocol.js +3 -3
- package/dist/esm/securechannel/SecureChannelProtocol.js.map +1 -1
- package/dist/esm/securechannel/SecureChannelStatusMessageSchema.d.ts +4 -15
- package/dist/esm/securechannel/SecureChannelStatusMessageSchema.d.ts.map +1 -1
- package/dist/esm/securechannel/SecureChannelStatusMessageSchema.js +4 -22
- package/dist/esm/securechannel/SecureChannelStatusMessageSchema.js.map +1 -1
- package/dist/esm/session/case/CaseClient.d.ts.map +1 -1
- package/dist/esm/session/case/CaseClient.js +2 -2
- package/dist/esm/session/case/CaseClient.js.map +1 -1
- package/dist/esm/session/case/CaseServer.js +3 -3
- package/dist/esm/session/case/CaseServer.js.map +1 -1
- package/dist/esm/session/pase/PaseClient.js +3 -3
- package/dist/esm/session/pase/PaseClient.js.map +1 -1
- package/dist/esm/session/pase/PaseServer.js +2 -2
- package/dist/esm/session/pase/PaseServer.js.map +1 -1
- package/package.json +6 -6
- package/src/cluster/client/ClusterClient.ts +8 -1
- package/src/cluster/client/ClusterClientTypes.ts +12 -0
- package/src/interaction/InteractionClient.ts +29 -16
- package/src/interaction/InteractionMessenger.ts +0 -4
- package/src/interaction/SubscriptionClient.ts +2 -2
- package/src/peer/ControllerCommissioner.ts +4 -3
- package/src/peer/ControllerCommissioningFlow.ts +96 -57
- package/src/peer/PeerSet.ts +7 -6
- package/src/protocol/ChannelManager.ts +3 -3
- package/src/protocol/ExchangeManager.ts +18 -67
- package/src/protocol/ExchangeProvider.ts +20 -6
- package/src/protocol/MessageChannel.ts +163 -0
- package/src/protocol/MessageExchange.ts +40 -119
- package/src/protocol/ProtocolStatusMessage.ts +51 -0
- package/src/protocol/index.ts +2 -0
- package/src/securechannel/SecureChannelMessenger.ts +11 -18
- package/src/securechannel/SecureChannelProtocol.ts +3 -3
- package/src/securechannel/SecureChannelStatusMessageSchema.ts +5 -31
- package/src/session/case/CaseClient.ts +2 -2
- package/src/session/case/CaseServer.ts +3 -3
- package/src/session/pase/PaseClient.ts +3 -3
- package/src/session/pase/PaseServer.ts +2 -2
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { Message, MessageCodec, PacketHeader, SessionType } from "#codec/MessageCodec.js";
|
|
7
8
|
import {
|
|
8
9
|
AsyncObservable,
|
|
10
|
+
createPromise,
|
|
9
11
|
CRYPTO_AEAD_MIC_LENGTH_BYTES,
|
|
10
12
|
DataReadQueue,
|
|
11
13
|
Diagnostic,
|
|
@@ -16,9 +18,16 @@ import {
|
|
|
16
18
|
NoResponseTimeoutError,
|
|
17
19
|
Time,
|
|
18
20
|
Timer,
|
|
19
|
-
createPromise,
|
|
20
21
|
} from "#general";
|
|
21
|
-
import {
|
|
22
|
+
import { MessageChannel, MRP } from "#protocol/MessageChannel.js";
|
|
23
|
+
import { SecureChannelProtocol } from "#securechannel/SecureChannelProtocol.js";
|
|
24
|
+
import { GroupSession } from "#session/GroupSession.js";
|
|
25
|
+
import {
|
|
26
|
+
SESSION_ACTIVE_INTERVAL_MS,
|
|
27
|
+
SESSION_ACTIVE_THRESHOLD_MS,
|
|
28
|
+
SESSION_IDLE_INTERVAL_MS,
|
|
29
|
+
SessionParameters,
|
|
30
|
+
} from "#session/Session.js";
|
|
22
31
|
import {
|
|
23
32
|
GroupId,
|
|
24
33
|
NodeId,
|
|
@@ -27,15 +36,7 @@ import {
|
|
|
27
36
|
StatusCode,
|
|
28
37
|
StatusResponseError,
|
|
29
38
|
} from "#types";
|
|
30
|
-
import {
|
|
31
|
-
import { SecureChannelProtocol } from "../securechannel/SecureChannelProtocol.js";
|
|
32
|
-
import {
|
|
33
|
-
SESSION_ACTIVE_INTERVAL_MS,
|
|
34
|
-
SESSION_ACTIVE_THRESHOLD_MS,
|
|
35
|
-
SESSION_IDLE_INTERVAL_MS,
|
|
36
|
-
SessionParameters,
|
|
37
|
-
} from "../session/Session.js";
|
|
38
|
-
import { ChannelNotConnectedError, MessageChannel } from "./ExchangeManager.js";
|
|
39
|
+
import { ChannelNotConnectedError } from "./ExchangeManager.js";
|
|
39
40
|
|
|
40
41
|
const logger = Logger.get("MessageExchange");
|
|
41
42
|
|
|
@@ -86,27 +87,6 @@ export type ExchangeSendOptions = {
|
|
|
86
87
|
logContext?: ExchangeLogContext;
|
|
87
88
|
};
|
|
88
89
|
|
|
89
|
-
/**
|
|
90
|
-
* The maximum number of transmission attempts for a given reliable message. The sender MAY choose this value as it
|
|
91
|
-
* sees fit.
|
|
92
|
-
*/
|
|
93
|
-
const MRP_MAX_TRANSMISSIONS = 5;
|
|
94
|
-
|
|
95
|
-
/** The base number for the exponential backoff equation. */
|
|
96
|
-
const MRP_BACKOFF_BASE = 1.6;
|
|
97
|
-
|
|
98
|
-
/** The scaler for random jitter in the backoff equation. */
|
|
99
|
-
const MRP_BACKOFF_JITTER = 0.25;
|
|
100
|
-
|
|
101
|
-
/** The scaler margin increase to backoff over the peer sleepy interval. */
|
|
102
|
-
const MRP_BACKOFF_MARGIN = 1.1;
|
|
103
|
-
|
|
104
|
-
/** The number of retransmissions before transitioning from linear to exponential backoff. */
|
|
105
|
-
const MRP_BACKOFF_THRESHOLD = 1;
|
|
106
|
-
|
|
107
|
-
/** @see {@link MatterSpecification.v12.Core}, section 4.11.8 */
|
|
108
|
-
const MRP_STANDALONE_ACK_TIMEOUT_MS = 200;
|
|
109
|
-
|
|
110
90
|
/**
|
|
111
91
|
* Default expected processing time for a messages in milliseconds. The value is derived from kExpectedIMProcessingTime
|
|
112
92
|
* from chip implementation. This is basically the default used with different names, also kExpectedLowProcessingTime or
|
|
@@ -114,12 +94,6 @@ const MRP_STANDALONE_ACK_TIMEOUT_MS = 200;
|
|
|
114
94
|
*/
|
|
115
95
|
export const DEFAULT_EXPECTED_PROCESSING_TIME_MS = 2_000;
|
|
116
96
|
|
|
117
|
-
/**
|
|
118
|
-
* The buffer time in milliseconds to add to the peer response time to also consider network delays and other factors.
|
|
119
|
-
* TODO: This is a pure guess and should be adjusted in the future.
|
|
120
|
-
*/
|
|
121
|
-
const PEER_RESPONSE_TIME_BUFFER_MS = 5_000;
|
|
122
|
-
|
|
123
97
|
/**
|
|
124
98
|
* Message size overhead of a Matter message:
|
|
125
99
|
* 26 (Matter Message Header) + 12 (Matter Payload Header) taken from https://github.com/project-chip/connectedhomeip/blob/2d97cda23024e72f36216900ca667bf1a0d9499f/src/system/SystemConfig.h#L327
|
|
@@ -173,10 +147,9 @@ export class MessageExchange {
|
|
|
173
147
|
readonly #activeIntervalMs: number;
|
|
174
148
|
readonly #idleIntervalMs: number;
|
|
175
149
|
readonly #activeThresholdMs: number;
|
|
176
|
-
readonly #maxTransmissions: number;
|
|
177
150
|
readonly #messagesQueue = new DataReadQueue<Message>();
|
|
178
151
|
#receivedMessageToAck: Message | undefined;
|
|
179
|
-
#receivedMessageAckTimer = Time.getTimer("Ack receipt timeout",
|
|
152
|
+
#receivedMessageAckTimer = Time.getTimer("Ack receipt timeout", MRP.STANDALONE_ACK_TIMEOUT_MS, () => {
|
|
180
153
|
if (this.#receivedMessageToAck !== undefined) {
|
|
181
154
|
const messageToAck = this.#receivedMessageToAck;
|
|
182
155
|
this.#receivedMessageToAck = undefined;
|
|
@@ -203,7 +176,6 @@ export class MessageExchange {
|
|
|
203
176
|
readonly #protocolId: number;
|
|
204
177
|
readonly #closed = AsyncObservable<[]>();
|
|
205
178
|
readonly #closing = AsyncObservable<[]>();
|
|
206
|
-
readonly #useMRP: boolean;
|
|
207
179
|
|
|
208
180
|
constructor(
|
|
209
181
|
readonly context: MessageExchangeContext,
|
|
@@ -227,10 +199,7 @@ export class MessageExchange {
|
|
|
227
199
|
this.#activeIntervalMs = activeIntervalMs ?? SESSION_ACTIVE_INTERVAL_MS;
|
|
228
200
|
this.#idleIntervalMs = idleIntervalMs ?? SESSION_IDLE_INTERVAL_MS;
|
|
229
201
|
this.#activeThresholdMs = activeThresholdMs ?? SESSION_ACTIVE_THRESHOLD_MS;
|
|
230
|
-
this.#maxTransmissions = MRP_MAX_TRANSMISSIONS;
|
|
231
202
|
|
|
232
|
-
// When the session is supporting MRP and the channel is not reliable, use MRP handling
|
|
233
|
-
this.#useMRP = session.supportsMRP && !channel.isReliable;
|
|
234
203
|
this.#used = !isInitiator; // If we are the initiator then exchange was not used yet, so track it
|
|
235
204
|
|
|
236
205
|
logger.debug(
|
|
@@ -244,9 +213,9 @@ export class MessageExchange {
|
|
|
244
213
|
SAT: this.#activeThresholdMs,
|
|
245
214
|
SAI: this.#activeIntervalMs,
|
|
246
215
|
SII: this.#idleIntervalMs,
|
|
247
|
-
maxTrans:
|
|
216
|
+
maxTrans: MRP.MAX_TRANSMISSIONS,
|
|
248
217
|
exchangeFlags: Diagnostic.asFlags({
|
|
249
|
-
MRP: this
|
|
218
|
+
MRP: this.channel.usesMrp,
|
|
250
219
|
I: this.isInitiator,
|
|
251
220
|
}),
|
|
252
221
|
}),
|
|
@@ -297,7 +266,7 @@ export class MessageExchange {
|
|
|
297
266
|
packetHeader: { messageId },
|
|
298
267
|
payloadHeader: { requiresAck },
|
|
299
268
|
} = message;
|
|
300
|
-
if (!requiresAck || !this
|
|
269
|
+
if (!requiresAck || !this.channel.usesMrp) return;
|
|
301
270
|
|
|
302
271
|
await this.send(SecureMessageType.StandaloneAck, new Uint8Array(0), { includeAcknowledgeMessageId: messageId });
|
|
303
272
|
}
|
|
@@ -306,7 +275,7 @@ export class MessageExchange {
|
|
|
306
275
|
logger.debug("Message «", MessageCodec.messageDiagnostics(message, { duplicate }));
|
|
307
276
|
|
|
308
277
|
// Adjust the incoming message when ack was required, but this exchange does not use it to skip all relevant logic
|
|
309
|
-
if (message.payloadHeader.requiresAck && !this
|
|
278
|
+
if (message.payloadHeader.requiresAck && !this.channel.usesMrp) {
|
|
310
279
|
logger.debug("Ignoring ack-required flag because MRP is not used for this exchange");
|
|
311
280
|
message.payloadHeader.requiresAck = false;
|
|
312
281
|
}
|
|
@@ -384,7 +353,7 @@ export class MessageExchange {
|
|
|
384
353
|
}
|
|
385
354
|
|
|
386
355
|
async send(messageType: number, payload: Uint8Array, options?: ExchangeSendOptions) {
|
|
387
|
-
if (options?.requiresAck && !this
|
|
356
|
+
if (options?.requiresAck && !this.channel.usesMrp) {
|
|
388
357
|
options.requiresAck = false;
|
|
389
358
|
}
|
|
390
359
|
|
|
@@ -396,11 +365,11 @@ export class MessageExchange {
|
|
|
396
365
|
includeAcknowledgeMessageId,
|
|
397
366
|
logContext,
|
|
398
367
|
} = options ?? {};
|
|
399
|
-
if (!this
|
|
368
|
+
if (!this.channel.usesMrp && includeAcknowledgeMessageId !== undefined) {
|
|
400
369
|
throw new InternalError("Cannot include an acknowledge message ID when MRP is not used");
|
|
401
370
|
}
|
|
402
371
|
if (messageType === SecureMessageType.StandaloneAck) {
|
|
403
|
-
if (!this
|
|
372
|
+
if (!this.channel.usesMrp) {
|
|
404
373
|
return;
|
|
405
374
|
}
|
|
406
375
|
if (requiresAck) {
|
|
@@ -414,7 +383,7 @@ export class MessageExchange {
|
|
|
414
383
|
this.session.notifyActivity(false);
|
|
415
384
|
|
|
416
385
|
let ackedMessageId = includeAcknowledgeMessageId;
|
|
417
|
-
if (ackedMessageId === undefined && this
|
|
386
|
+
if (ackedMessageId === undefined && this.channel.usesMrp) {
|
|
418
387
|
ackedMessageId = this.#receivedMessageToAck?.packetHeader.messageId;
|
|
419
388
|
if (ackedMessageId !== undefined) {
|
|
420
389
|
this.#receivedMessageAckTimer.stop();
|
|
@@ -465,7 +434,7 @@ export class MessageExchange {
|
|
|
465
434
|
messageType === SecureMessageType.StandaloneAck ? SECURE_CHANNEL_PROTOCOL_ID : this.#protocolId,
|
|
466
435
|
messageType,
|
|
467
436
|
isInitiatorMessage: this.isInitiator,
|
|
468
|
-
requiresAck: requiresAck ?? (this
|
|
437
|
+
requiresAck: requiresAck ?? (this.channel.usesMrp && messageType !== SecureMessageType.StandaloneAck),
|
|
469
438
|
ackedMessageId,
|
|
470
439
|
hasSecuredExtension: false,
|
|
471
440
|
},
|
|
@@ -473,11 +442,11 @@ export class MessageExchange {
|
|
|
473
442
|
};
|
|
474
443
|
|
|
475
444
|
let ackPromise: Promise<Message> | undefined;
|
|
476
|
-
if (this
|
|
445
|
+
if (this.channel.usesMrp && message.payloadHeader.requiresAck && !disableMrpLogic) {
|
|
477
446
|
this.#sentMessageToAck = message;
|
|
478
447
|
this.#retransmissionTimer = Time.getTimer(
|
|
479
448
|
`Message retransmission ${message.packetHeader.messageId}`,
|
|
480
|
-
this
|
|
449
|
+
this.channel.getMrpResubmissionBackOffTime(0),
|
|
481
450
|
() => this.#retransmitMessage(message, expectedProcessingTimeMs),
|
|
482
451
|
);
|
|
483
452
|
const { promise, resolver, rejecter } = createPromise<Message>();
|
|
@@ -512,81 +481,33 @@ export class MessageExchange {
|
|
|
512
481
|
} else if (this.#messagesQueue.size > 0) {
|
|
513
482
|
timeout = 0; // If we have messages in the queue, we can return them immediately
|
|
514
483
|
} else {
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
break;
|
|
520
|
-
case "udp":
|
|
521
|
-
// UDP normally uses MRP, if not we have Group communication which normally have no responses
|
|
522
|
-
if (!this.#useMRP) {
|
|
523
|
-
throw new MatterFlowError(
|
|
524
|
-
"No response expected for this message exchange because UDP and no MRP.",
|
|
525
|
-
);
|
|
526
|
-
}
|
|
527
|
-
const { expectedProcessingTimeMs } = options ?? {};
|
|
528
|
-
timeout = this.calculateMaximumPeerResponseTime(expectedProcessingTimeMs);
|
|
529
|
-
break;
|
|
530
|
-
case "ble":
|
|
531
|
-
// chip sdk uses BTP_ACK_TIMEOUT_MS which is wrong in my eyes, so we use static 30s as like TCP here
|
|
532
|
-
timeout = 30_000;
|
|
533
|
-
break;
|
|
534
|
-
default:
|
|
535
|
-
throw new MatterFlowError(
|
|
536
|
-
`Can not calculate expected timeout for unknown channel type: ${this.channel.type}`,
|
|
537
|
-
);
|
|
538
|
-
}
|
|
539
|
-
timeout += PEER_RESPONSE_TIME_BUFFER_MS;
|
|
484
|
+
timeout = this.channel.calculateMaximumPeerResponseTimeMs(
|
|
485
|
+
this.context.localSessionParameters,
|
|
486
|
+
options?.expectedProcessingTimeMs,
|
|
487
|
+
);
|
|
540
488
|
}
|
|
541
489
|
return this.#messagesQueue.read(timeout);
|
|
542
490
|
}
|
|
543
491
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
* side of the exchange.
|
|
549
|
-
*
|
|
550
|
-
* @see {@link MatterSpecification.v10.Core}, section 4.11.2.1
|
|
551
|
-
*/
|
|
552
|
-
#getResubmissionBackOffTime(retransmissionCount: number, sessionParameters?: SessionParameters) {
|
|
553
|
-
const { activeIntervalMs, idleIntervalMs } = sessionParameters ?? {
|
|
554
|
-
activeIntervalMs: this.#activeIntervalMs,
|
|
555
|
-
idleIntervalMs: this.#idleIntervalMs,
|
|
556
|
-
};
|
|
557
|
-
const baseInterval =
|
|
558
|
-
sessionParameters !== undefined || this.session.isPeerActive() ? activeIntervalMs : idleIntervalMs;
|
|
559
|
-
return Math.floor(
|
|
560
|
-
MRP_BACKOFF_MARGIN *
|
|
561
|
-
baseInterval *
|
|
562
|
-
Math.pow(MRP_BACKOFF_BASE, Math.max(0, retransmissionCount - MRP_BACKOFF_THRESHOLD)) *
|
|
563
|
-
(1 + (sessionParameters !== undefined ? 1 : Math.random()) * MRP_BACKOFF_JITTER),
|
|
492
|
+
calculateMaximumPeerResponseTimeMs(expectedProcessingTimeMs = DEFAULT_EXPECTED_PROCESSING_TIME_MS) {
|
|
493
|
+
return this.channel.calculateMaximumPeerResponseTimeMs(
|
|
494
|
+
this.context.localSessionParameters,
|
|
495
|
+
expectedProcessingTimeMs,
|
|
564
496
|
);
|
|
565
497
|
}
|
|
566
498
|
|
|
567
|
-
calculateMaximumPeerResponseTime(expectedProcessingTimeMs = DEFAULT_EXPECTED_PROCESSING_TIME_MS) {
|
|
568
|
-
// We use the expected processing time and deduct the time we already waited since last resubmission
|
|
569
|
-
let finalWaitTime = expectedProcessingTimeMs;
|
|
570
|
-
|
|
571
|
-
// and then add the time the other side needs for a full resubmission cycle under the assumption we are active
|
|
572
|
-
for (let i = 0; i < this.#maxTransmissions; i++) {
|
|
573
|
-
finalWaitTime += this.#getResubmissionBackOffTime(i, this.context.localSessionParameters);
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
// TODO: Also add any network latency buffer, for now lets consider it's included in the processing time already
|
|
577
|
-
return finalWaitTime;
|
|
578
|
-
}
|
|
579
|
-
|
|
580
499
|
#retransmitMessage(message: Message, expectedProcessingTimeMs?: number) {
|
|
581
500
|
this.#retransmissionCounter++;
|
|
582
|
-
if (this.#retransmissionCounter >=
|
|
501
|
+
if (this.#retransmissionCounter >= MRP.MAX_TRANSMISSIONS) {
|
|
583
502
|
// Ok all 4 resubmissions are done, but we need to wait a bit longer because of processing time and
|
|
584
503
|
// the resubmissions from the other side
|
|
585
504
|
if (expectedProcessingTimeMs !== undefined) {
|
|
586
505
|
// We already have waited after the last message was sent, so deduct this time from the final wait time
|
|
587
506
|
const finalWaitTime =
|
|
588
|
-
this.
|
|
589
|
-
|
|
507
|
+
this.channel.calculateMaximumPeerResponseTimeMs(
|
|
508
|
+
this.context.localSessionParameters,
|
|
509
|
+
expectedProcessingTimeMs,
|
|
510
|
+
) - (this.#retransmissionTimer?.intervalMs ?? 0);
|
|
590
511
|
if (finalWaitTime > 0) {
|
|
591
512
|
this.#retransmissionCounter--; // We will not resubmit the message again
|
|
592
513
|
logger.debug(
|
|
@@ -620,7 +541,7 @@ export class MessageExchange {
|
|
|
620
541
|
if (this.#retransmissionCounter === 1) {
|
|
621
542
|
this.context.resubmissionStarted();
|
|
622
543
|
}
|
|
623
|
-
const resubmissionBackoffTime = this
|
|
544
|
+
const resubmissionBackoffTime = this.channel.getMrpResubmissionBackOffTime(this.#retransmissionCounter);
|
|
624
545
|
logger.debug(
|
|
625
546
|
`Resubmit message ${message.packetHeader.messageId} (retransmission attempt ${this.#retransmissionCounter}, backoff time ${resubmissionBackoffTime}ms))`,
|
|
626
547
|
);
|
|
@@ -742,8 +663,8 @@ export class MessageExchange {
|
|
|
742
663
|
// We might wait a bit longer then needed but because this is mainly a failsafe mechanism it is acceptable.
|
|
743
664
|
// in normal case this timer is cancelled before it triggers when all retries are done.
|
|
744
665
|
let maxResubmissionTime = 0;
|
|
745
|
-
for (let i = this.#retransmissionCounter; i <=
|
|
746
|
-
maxResubmissionTime += this
|
|
666
|
+
for (let i = this.#retransmissionCounter; i <= MRP.MAX_TRANSMISSIONS; i++) {
|
|
667
|
+
maxResubmissionTime += this.channel.getMrpResubmissionBackOffTime(i);
|
|
747
668
|
}
|
|
748
669
|
this.#closeTimer = Time.getTimer(
|
|
749
670
|
`Message exchange cleanup ${this.session.name} / ${this.#exchangeId}`,
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { DataReader, DataWriter, Endian } from "#general";
|
|
8
|
+
import { GeneralStatusCode, Schema } from "#types";
|
|
9
|
+
|
|
10
|
+
export type ProtocolStatusMessage<T> = {
|
|
11
|
+
generalStatus: GeneralStatusCode;
|
|
12
|
+
protocolId: number;
|
|
13
|
+
protocolStatus: T;
|
|
14
|
+
protocolData?: Uint8Array;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export abstract class ProtocolStatusMessageSchema<T extends ProtocolStatusMessage<any>> extends Schema<T, Uint8Array> {
|
|
18
|
+
#protocolId: number;
|
|
19
|
+
#protocolSpecificDataAllowed: boolean;
|
|
20
|
+
|
|
21
|
+
constructor(protocolId: number, protocolSpecificDataAllowed = true) {
|
|
22
|
+
super();
|
|
23
|
+
this.#protocolId = protocolId;
|
|
24
|
+
this.#protocolSpecificDataAllowed = protocolSpecificDataAllowed;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
override encode(message: Omit<T, "protocolId">): Uint8Array {
|
|
28
|
+
return super.encode({ ...message, protocolId: this.#protocolId } as T);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
encodeInternal({ generalStatus, protocolStatus, protocolId, protocolData }: T) {
|
|
32
|
+
const writer = new DataWriter(Endian.Little);
|
|
33
|
+
writer.writeUInt16(generalStatus);
|
|
34
|
+
writer.writeUInt32(protocolId);
|
|
35
|
+
writer.writeUInt16(protocolStatus);
|
|
36
|
+
if (this.#protocolSpecificDataAllowed && protocolData !== undefined && protocolData.length > 0) {
|
|
37
|
+
writer.writeByteArray(protocolData);
|
|
38
|
+
}
|
|
39
|
+
return writer.toByteArray();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
decodeInternal(bytes: Uint8Array) {
|
|
43
|
+
const reader = new DataReader(bytes, Endian.Little);
|
|
44
|
+
const generalStatus = reader.readUInt16();
|
|
45
|
+
const protocolId = reader.readUInt32();
|
|
46
|
+
const protocolStatus = reader.readUInt16();
|
|
47
|
+
const remainingBytes = reader.remainingBytesCount > 0 ? reader.remainingBytes : undefined;
|
|
48
|
+
|
|
49
|
+
return { generalStatus, protocolId, protocolStatus, remainingBytes } as unknown as T;
|
|
50
|
+
}
|
|
51
|
+
}
|
package/src/protocol/index.ts
CHANGED
|
@@ -9,7 +9,9 @@ export * from "./DeviceAdvertiser.js";
|
|
|
9
9
|
export * from "./DeviceCommissioner.js";
|
|
10
10
|
export * from "./ExchangeManager.js";
|
|
11
11
|
export * from "./ExchangeProvider.js";
|
|
12
|
+
export * from "./MessageChannel.js";
|
|
12
13
|
export * from "./MessageCounter.js";
|
|
13
14
|
export * from "./MessageExchange.js";
|
|
14
15
|
export * from "./MessageReceptionState.js";
|
|
15
16
|
export * from "./ProtocolHandler.js";
|
|
17
|
+
export * from "./ProtocolStatusMessage.js";
|
|
@@ -5,13 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { Diagnostic, MatterError, UnexpectedDataError } from "#general";
|
|
8
|
-
import {
|
|
9
|
-
GeneralStatusCode,
|
|
10
|
-
ProtocolStatusCode,
|
|
11
|
-
SECURE_CHANNEL_PROTOCOL_ID,
|
|
12
|
-
SecureMessageType,
|
|
13
|
-
TlvSchema,
|
|
14
|
-
} from "#types";
|
|
8
|
+
import { GeneralStatusCode, SecureChannelStatusCode, SecureMessageType, TlvSchema } from "#types";
|
|
15
9
|
import { Message } from "../codec/MessageCodec.js";
|
|
16
10
|
import { ExchangeSendOptions, MessageExchange } from "../protocol/MessageExchange.js";
|
|
17
11
|
import { TlvSecureChannelStatusMessage } from "./SecureChannelStatusMessageSchema.js";
|
|
@@ -21,10 +15,10 @@ export class ChannelStatusResponseError extends MatterError {
|
|
|
21
15
|
public constructor(
|
|
22
16
|
message: string,
|
|
23
17
|
public readonly generalStatusCode: GeneralStatusCode,
|
|
24
|
-
public readonly protocolStatusCode:
|
|
18
|
+
public readonly protocolStatusCode: SecureChannelStatusCode,
|
|
25
19
|
) {
|
|
26
20
|
super(
|
|
27
|
-
`(${GeneralStatusCode[generalStatusCode]} (${generalStatusCode}) / ${
|
|
21
|
+
`(${GeneralStatusCode[generalStatusCode]} (${generalStatusCode}) / ${SecureChannelStatusCode[protocolStatusCode]} (${protocolStatusCode})) ${message}`,
|
|
28
22
|
);
|
|
29
23
|
}
|
|
30
24
|
}
|
|
@@ -125,16 +119,16 @@ export class SecureChannelMessenger {
|
|
|
125
119
|
return payload;
|
|
126
120
|
}
|
|
127
121
|
|
|
128
|
-
sendError(code:
|
|
129
|
-
return this
|
|
122
|
+
sendError(code: SecureChannelStatusCode) {
|
|
123
|
+
return this.#sendStatusReport(GeneralStatusCode.Failure, code);
|
|
130
124
|
}
|
|
131
125
|
|
|
132
126
|
sendSuccess() {
|
|
133
|
-
return this
|
|
127
|
+
return this.#sendStatusReport(GeneralStatusCode.Success, SecureChannelStatusCode.Success);
|
|
134
128
|
}
|
|
135
129
|
|
|
136
130
|
sendCloseSession() {
|
|
137
|
-
return this
|
|
131
|
+
return this.#sendStatusReport(GeneralStatusCode.Success, SecureChannelStatusCode.CloseSession, false);
|
|
138
132
|
}
|
|
139
133
|
|
|
140
134
|
getChannelName() {
|
|
@@ -145,23 +139,22 @@ export class SecureChannelMessenger {
|
|
|
145
139
|
await this.exchange.close();
|
|
146
140
|
}
|
|
147
141
|
|
|
148
|
-
|
|
142
|
+
async #sendStatusReport(
|
|
149
143
|
generalStatus: GeneralStatusCode,
|
|
150
|
-
protocolStatus:
|
|
144
|
+
protocolStatus: SecureChannelStatusCode,
|
|
151
145
|
requiresAck?: boolean,
|
|
152
146
|
) {
|
|
153
147
|
await this.exchange.send(
|
|
154
148
|
SecureMessageType.StatusReport,
|
|
155
149
|
TlvSecureChannelStatusMessage.encode({
|
|
156
150
|
generalStatus,
|
|
157
|
-
protocolId: SECURE_CHANNEL_PROTOCOL_ID,
|
|
158
151
|
protocolStatus,
|
|
159
152
|
}),
|
|
160
153
|
{
|
|
161
154
|
requiresAck,
|
|
162
155
|
logContext: {
|
|
163
156
|
generalStatus: GeneralStatusCode[generalStatus] ?? Diagnostic.hex(generalStatus),
|
|
164
|
-
protocolStatus:
|
|
157
|
+
protocolStatus: SecureChannelStatusCode[protocolStatus] ?? Diagnostic.hex(protocolStatus),
|
|
165
158
|
},
|
|
166
159
|
},
|
|
167
160
|
);
|
|
@@ -182,7 +175,7 @@ export class SecureChannelMessenger {
|
|
|
182
175
|
protocolStatus,
|
|
183
176
|
);
|
|
184
177
|
}
|
|
185
|
-
if (protocolStatus !==
|
|
178
|
+
if (protocolStatus !== SecureChannelStatusCode.Success) {
|
|
186
179
|
throw new ChannelStatusResponseError(
|
|
187
180
|
`Received general success status, but protocol status is not Success${logHint ? ` (${logHint})` : ""}`,
|
|
188
181
|
generalStatus,
|
|
@@ -10,8 +10,8 @@ import { ExchangeManager } from "#protocol/ExchangeManager.js";
|
|
|
10
10
|
import { SessionManager } from "#session/SessionManager.js";
|
|
11
11
|
import {
|
|
12
12
|
GeneralStatusCode,
|
|
13
|
-
ProtocolStatusCode,
|
|
14
13
|
SECURE_CHANNEL_PROTOCOL_ID,
|
|
14
|
+
SecureChannelStatusCode,
|
|
15
15
|
SecureMessageType,
|
|
16
16
|
StatusCode,
|
|
17
17
|
StatusResponseError,
|
|
@@ -70,7 +70,7 @@ export class StatusReportOnlySecureChannelProtocol implements ProtocolHandler {
|
|
|
70
70
|
protocolStatus,
|
|
71
71
|
);
|
|
72
72
|
}
|
|
73
|
-
if (protocolStatus !==
|
|
73
|
+
if (protocolStatus !== SecureChannelStatusCode.CloseSession) {
|
|
74
74
|
throw new ChannelStatusResponseError(
|
|
75
75
|
`Received general success status, but protocol status is not CloseSession`,
|
|
76
76
|
generalStatus,
|
|
@@ -131,7 +131,7 @@ export class SecureChannelProtocol extends StatusReportOnlySecureChannelProtocol
|
|
|
131
131
|
// Cleaner to return an error (ok for chip-tool as it seems)?
|
|
132
132
|
// Formally we should not respond at all which leads to retries and such
|
|
133
133
|
const messenger = new SecureChannelMessenger(exchange);
|
|
134
|
-
await messenger.sendError(
|
|
134
|
+
await messenger.sendError(SecureChannelStatusCode.InvalidParam);
|
|
135
135
|
await messenger.close(); // also closes exchange
|
|
136
136
|
return;
|
|
137
137
|
}
|
|
@@ -4,37 +4,11 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { ProtocolStatusMessage, ProtocolStatusMessageSchema } from "#protocol/ProtocolStatusMessage.js";
|
|
8
|
+
import { SECURE_CHANNEL_PROTOCOL_ID, SecureChannelStatusCode } from "#types";
|
|
9
9
|
|
|
10
|
-
export type
|
|
11
|
-
generalStatus: GeneralStatusCode;
|
|
12
|
-
protocolId: number;
|
|
13
|
-
protocolStatus: ProtocolStatusCode;
|
|
14
|
-
protocolData?: Uint8Array;
|
|
15
|
-
};
|
|
10
|
+
export type SecureChannelStatusMessage = ProtocolStatusMessage<SecureChannelStatusCode>;
|
|
16
11
|
|
|
17
|
-
export class SecureChannelStatusMessageSchema extends
|
|
18
|
-
encodeInternal({ generalStatus, protocolId, protocolStatus, protocolData }: StatusMessage) {
|
|
19
|
-
const writer = new DataWriter(Endian.Little);
|
|
20
|
-
writer.writeUInt16(generalStatus);
|
|
21
|
-
writer.writeUInt32(protocolId);
|
|
22
|
-
writer.writeUInt16(protocolStatus);
|
|
23
|
-
if (protocolData !== undefined && protocolData.length > 0) {
|
|
24
|
-
writer.writeByteArray(protocolData);
|
|
25
|
-
}
|
|
26
|
-
return writer.toByteArray();
|
|
27
|
-
}
|
|
12
|
+
export class SecureChannelStatusMessageSchema extends ProtocolStatusMessageSchema<SecureChannelStatusMessage> {}
|
|
28
13
|
|
|
29
|
-
|
|
30
|
-
const reader = new DataReader(bytes, Endian.Little);
|
|
31
|
-
const generalStatus = reader.readUInt16();
|
|
32
|
-
const protocolId = reader.readUInt32();
|
|
33
|
-
const protocolStatus = reader.readUInt16();
|
|
34
|
-
const remainingBytes = reader.remainingBytesCount > 0 ? reader.remainingBytes : undefined;
|
|
35
|
-
|
|
36
|
-
return { generalStatus, protocolId, protocolStatus, remainingBytes };
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export const TlvSecureChannelStatusMessage = new SecureChannelStatusMessageSchema();
|
|
14
|
+
export const TlvSecureChannelStatusMessage = new SecureChannelStatusMessageSchema(SECURE_CHANNEL_PROTOCOL_ID);
|
|
@@ -8,7 +8,7 @@ import { Icac, Noc } from "#certificate/index.js";
|
|
|
8
8
|
import { Bytes, Logger, PublicKey, UnexpectedDataError } from "#general";
|
|
9
9
|
import { ChannelStatusResponseError } from "#securechannel/index.js";
|
|
10
10
|
import { SessionManager } from "#session/SessionManager.js";
|
|
11
|
-
import { NodeId,
|
|
11
|
+
import { NodeId, SecureChannelStatusCode } from "#types";
|
|
12
12
|
import { Fabric } from "../../fabric/Fabric.js";
|
|
13
13
|
import { MessageExchange } from "../../protocol/MessageExchange.js";
|
|
14
14
|
import {
|
|
@@ -42,7 +42,7 @@ export class CaseClient {
|
|
|
42
42
|
return await this.#doPair(messenger, exchange, fabric, peerNodeId);
|
|
43
43
|
} catch (error) {
|
|
44
44
|
if (!(error instanceof ChannelStatusResponseError)) {
|
|
45
|
-
await messenger.sendError(
|
|
45
|
+
await messenger.sendError(SecureChannelStatusCode.InvalidParam);
|
|
46
46
|
}
|
|
47
47
|
throw error;
|
|
48
48
|
}
|
|
@@ -8,7 +8,7 @@ import { Noc } from "#certificate/index.js";
|
|
|
8
8
|
import { Bytes, Crypto, CryptoDecryptError, Logger, PublicKey, UnexpectedDataError } from "#general";
|
|
9
9
|
import { TlvSessionParameters } from "#session/pase/PaseMessages.js";
|
|
10
10
|
import { ResumptionRecord, SessionManager } from "#session/SessionManager.js";
|
|
11
|
-
import { NodeId,
|
|
11
|
+
import { NodeId, SECURE_CHANNEL_PROTOCOL_ID, SecureChannelStatusCode, TypeFromSchema } from "#types";
|
|
12
12
|
import { FabricManager, FabricNotFoundError } from "../../fabric/FabricManager.js";
|
|
13
13
|
import { MessageExchange } from "../../protocol/MessageExchange.js";
|
|
14
14
|
import { ProtocolHandler } from "../../protocol/ProtocolHandler.js";
|
|
@@ -51,11 +51,11 @@ export class CaseServer implements ProtocolHandler {
|
|
|
51
51
|
logger.error("An error occurred during the commissioning", error);
|
|
52
52
|
|
|
53
53
|
if (error instanceof FabricNotFoundError) {
|
|
54
|
-
await messenger.sendError(
|
|
54
|
+
await messenger.sendError(SecureChannelStatusCode.NoSharedTrustRoots);
|
|
55
55
|
}
|
|
56
56
|
// If we received a ChannelStatusResponseError we do not need to send one back, so just cancel pairing
|
|
57
57
|
else if (!(error instanceof ChannelStatusResponseError)) {
|
|
58
|
-
await messenger.sendError(
|
|
58
|
+
await messenger.sendError(SecureChannelStatusCode.InvalidParam);
|
|
59
59
|
}
|
|
60
60
|
} finally {
|
|
61
61
|
// Destroy the unsecure session used to establish the secure Case session
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import { Bytes, Crypto, ec, Logger, PbkdfParameters, Spake2p, UnexpectedDataError } from "#general";
|
|
8
8
|
import { SessionManager } from "#session/SessionManager.js";
|
|
9
|
-
import { CommissioningOptions, NodeId,
|
|
9
|
+
import { CommissioningOptions, NodeId, SecureChannelStatusCode } from "#types";
|
|
10
10
|
import { MessageExchange } from "../../protocol/MessageExchange.js";
|
|
11
11
|
import { SessionParameters } from "../Session.js";
|
|
12
12
|
import { DEFAULT_PASSCODE_ID, PaseClientMessenger, SPAKE_CONTEXT } from "./PaseMessenger.js";
|
|
@@ -70,7 +70,7 @@ export class PaseClient {
|
|
|
70
70
|
if (pbkdfParameters === undefined) {
|
|
71
71
|
// Sending this error is not defined in the specs and should normally never happen, but better inform device
|
|
72
72
|
// that we cancel the pairing
|
|
73
|
-
await messenger.sendError(
|
|
73
|
+
await messenger.sendError(SecureChannelStatusCode.InvalidParam);
|
|
74
74
|
throw new UnexpectedDataError("Missing requested PbkdfParameters in the response. Commissioning failed.");
|
|
75
75
|
}
|
|
76
76
|
|
|
@@ -94,7 +94,7 @@ export class PaseClient {
|
|
|
94
94
|
const { y: Y, verifier } = await messenger.readPasePake2();
|
|
95
95
|
const { Ke, hAY, hBX } = await spake2p.computeSecretAndVerifiersFromY(w1, X, Y);
|
|
96
96
|
if (!Bytes.areEqual(verifier, hBX)) {
|
|
97
|
-
await messenger.sendError(
|
|
97
|
+
await messenger.sendError(SecureChannelStatusCode.InvalidParam);
|
|
98
98
|
throw new UnexpectedDataError(
|
|
99
99
|
"Received incorrect key confirmation from the receiver. Commissioning failed.",
|
|
100
100
|
);
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
UnexpectedDataError,
|
|
18
18
|
} from "#general";
|
|
19
19
|
import { SessionManager } from "#session/SessionManager.js";
|
|
20
|
-
import { NodeId,
|
|
20
|
+
import { NodeId, SECURE_CHANNEL_PROTOCOL_ID, SecureChannelStatusCode } from "#types";
|
|
21
21
|
import { MessageExchange } from "../../protocol/MessageExchange.js";
|
|
22
22
|
import { ProtocolHandler } from "../../protocol/ProtocolHandler.js";
|
|
23
23
|
import { ChannelStatusResponseError } from "../../securechannel/SecureChannelMessenger.js";
|
|
@@ -186,7 +186,7 @@ export class PaseServer implements ProtocolHandler {
|
|
|
186
186
|
this.#pairingTimer = undefined;
|
|
187
187
|
|
|
188
188
|
if (sendError) {
|
|
189
|
-
await messenger.sendError(
|
|
189
|
+
await messenger.sendError(SecureChannelStatusCode.InvalidParam);
|
|
190
190
|
}
|
|
191
191
|
await messenger.close();
|
|
192
192
|
}
|