@matter/protocol 0.15.0-alpha.0-20250625-4a4b1be1b → 0.15.0-alpha.0-20250626-fc3a84ce9

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.
Files changed (117) hide show
  1. package/dist/cjs/cluster/client/ClusterClient.d.ts.map +1 -1
  2. package/dist/cjs/cluster/client/ClusterClient.js +7 -1
  3. package/dist/cjs/cluster/client/ClusterClient.js.map +1 -1
  4. package/dist/cjs/cluster/client/ClusterClientTypes.d.ts +10 -0
  5. package/dist/cjs/cluster/client/ClusterClientTypes.d.ts.map +1 -1
  6. package/dist/cjs/interaction/InteractionClient.d.ts +8 -1
  7. package/dist/cjs/interaction/InteractionClient.d.ts.map +1 -1
  8. package/dist/cjs/interaction/InteractionClient.js +15 -10
  9. package/dist/cjs/interaction/InteractionClient.js.map +1 -1
  10. package/dist/cjs/interaction/InteractionMessenger.d.ts +0 -1
  11. package/dist/cjs/interaction/InteractionMessenger.d.ts.map +1 -1
  12. package/dist/cjs/interaction/InteractionMessenger.js +0 -3
  13. package/dist/cjs/interaction/InteractionMessenger.js.map +1 -1
  14. package/dist/cjs/interaction/SubscriptionClient.d.ts +1 -1
  15. package/dist/cjs/interaction/SubscriptionClient.d.ts.map +1 -1
  16. package/dist/cjs/interaction/SubscriptionClient.js +1 -1
  17. package/dist/cjs/peer/ControllerCommissioner.d.ts +3 -2
  18. package/dist/cjs/peer/ControllerCommissioner.d.ts.map +1 -1
  19. package/dist/cjs/peer/ControllerCommissioner.js +6 -5
  20. package/dist/cjs/peer/ControllerCommissioner.js.map +1 -1
  21. package/dist/cjs/peer/ControllerCommissioningFlow.d.ts.map +1 -1
  22. package/dist/cjs/peer/ControllerCommissioningFlow.js +81 -52
  23. package/dist/cjs/peer/ControllerCommissioningFlow.js.map +1 -1
  24. package/dist/cjs/peer/PeerSet.d.ts +4 -3
  25. package/dist/cjs/peer/PeerSet.d.ts.map +1 -1
  26. package/dist/cjs/peer/PeerSet.js +9 -8
  27. package/dist/cjs/peer/PeerSet.js.map +1 -1
  28. package/dist/cjs/protocol/ChannelManager.d.ts +2 -2
  29. package/dist/cjs/protocol/ChannelManager.d.ts.map +1 -1
  30. package/dist/cjs/protocol/ChannelManager.js +4 -4
  31. package/dist/cjs/protocol/ChannelManager.js.map +1 -1
  32. package/dist/cjs/protocol/ExchangeManager.d.ts +5 -24
  33. package/dist/cjs/protocol/ExchangeManager.d.ts.map +1 -1
  34. package/dist/cjs/protocol/ExchangeManager.js +12 -55
  35. package/dist/cjs/protocol/ExchangeManager.js.map +1 -1
  36. package/dist/cjs/protocol/ExchangeProvider.d.ts +10 -6
  37. package/dist/cjs/protocol/ExchangeProvider.d.ts.map +1 -1
  38. package/dist/cjs/protocol/ExchangeProvider.js +12 -1
  39. package/dist/cjs/protocol/ExchangeProvider.js.map +1 -1
  40. package/dist/cjs/protocol/MessageChannel.d.ts +52 -0
  41. package/dist/cjs/protocol/MessageChannel.d.ts.map +1 -0
  42. package/dist/cjs/protocol/MessageChannel.js +130 -0
  43. package/dist/cjs/protocol/MessageChannel.js.map +6 -0
  44. package/dist/cjs/protocol/MessageExchange.d.ts +5 -5
  45. package/dist/cjs/protocol/MessageExchange.d.ts.map +1 -1
  46. package/dist/cjs/protocol/MessageExchange.js +34 -78
  47. package/dist/cjs/protocol/MessageExchange.js.map +1 -1
  48. package/dist/cjs/protocol/index.d.ts +1 -0
  49. package/dist/cjs/protocol/index.d.ts.map +1 -1
  50. package/dist/cjs/protocol/index.js +1 -0
  51. package/dist/cjs/protocol/index.js.map +1 -1
  52. package/dist/esm/cluster/client/ClusterClient.d.ts.map +1 -1
  53. package/dist/esm/cluster/client/ClusterClient.js +7 -1
  54. package/dist/esm/cluster/client/ClusterClient.js.map +1 -1
  55. package/dist/esm/cluster/client/ClusterClientTypes.d.ts +10 -0
  56. package/dist/esm/cluster/client/ClusterClientTypes.d.ts.map +1 -1
  57. package/dist/esm/interaction/InteractionClient.d.ts +8 -1
  58. package/dist/esm/interaction/InteractionClient.d.ts.map +1 -1
  59. package/dist/esm/interaction/InteractionClient.js +15 -10
  60. package/dist/esm/interaction/InteractionClient.js.map +1 -1
  61. package/dist/esm/interaction/InteractionMessenger.d.ts +0 -1
  62. package/dist/esm/interaction/InteractionMessenger.d.ts.map +1 -1
  63. package/dist/esm/interaction/InteractionMessenger.js +0 -3
  64. package/dist/esm/interaction/InteractionMessenger.js.map +1 -1
  65. package/dist/esm/interaction/SubscriptionClient.d.ts +1 -1
  66. package/dist/esm/interaction/SubscriptionClient.d.ts.map +1 -1
  67. package/dist/esm/interaction/SubscriptionClient.js +1 -1
  68. package/dist/esm/peer/ControllerCommissioner.d.ts +3 -2
  69. package/dist/esm/peer/ControllerCommissioner.d.ts.map +1 -1
  70. package/dist/esm/peer/ControllerCommissioner.js +4 -3
  71. package/dist/esm/peer/ControllerCommissioner.js.map +1 -1
  72. package/dist/esm/peer/ControllerCommissioningFlow.d.ts.map +1 -1
  73. package/dist/esm/peer/ControllerCommissioningFlow.js +81 -52
  74. package/dist/esm/peer/ControllerCommissioningFlow.js.map +1 -1
  75. package/dist/esm/peer/PeerSet.d.ts +4 -3
  76. package/dist/esm/peer/PeerSet.d.ts.map +1 -1
  77. package/dist/esm/peer/PeerSet.js +5 -4
  78. package/dist/esm/peer/PeerSet.js.map +1 -1
  79. package/dist/esm/protocol/ChannelManager.d.ts +2 -2
  80. package/dist/esm/protocol/ChannelManager.d.ts.map +1 -1
  81. package/dist/esm/protocol/ChannelManager.js +2 -2
  82. package/dist/esm/protocol/ChannelManager.js.map +1 -1
  83. package/dist/esm/protocol/ExchangeManager.d.ts +5 -24
  84. package/dist/esm/protocol/ExchangeManager.d.ts.map +1 -1
  85. package/dist/esm/protocol/ExchangeManager.js +13 -56
  86. package/dist/esm/protocol/ExchangeManager.js.map +1 -1
  87. package/dist/esm/protocol/ExchangeProvider.d.ts +10 -6
  88. package/dist/esm/protocol/ExchangeProvider.d.ts.map +1 -1
  89. package/dist/esm/protocol/ExchangeProvider.js +12 -1
  90. package/dist/esm/protocol/ExchangeProvider.js.map +1 -1
  91. package/dist/esm/protocol/MessageChannel.d.ts +52 -0
  92. package/dist/esm/protocol/MessageChannel.d.ts.map +1 -0
  93. package/dist/esm/protocol/MessageChannel.js +110 -0
  94. package/dist/esm/protocol/MessageChannel.js.map +6 -0
  95. package/dist/esm/protocol/MessageExchange.d.ts +5 -5
  96. package/dist/esm/protocol/MessageExchange.d.ts.map +1 -1
  97. package/dist/esm/protocol/MessageExchange.js +39 -83
  98. package/dist/esm/protocol/MessageExchange.js.map +1 -1
  99. package/dist/esm/protocol/index.d.ts +1 -0
  100. package/dist/esm/protocol/index.d.ts.map +1 -1
  101. package/dist/esm/protocol/index.js +1 -0
  102. package/dist/esm/protocol/index.js.map +1 -1
  103. package/package.json +6 -6
  104. package/src/cluster/client/ClusterClient.ts +8 -1
  105. package/src/cluster/client/ClusterClientTypes.ts +12 -0
  106. package/src/interaction/InteractionClient.ts +29 -16
  107. package/src/interaction/InteractionMessenger.ts +0 -4
  108. package/src/interaction/SubscriptionClient.ts +2 -2
  109. package/src/peer/ControllerCommissioner.ts +4 -3
  110. package/src/peer/ControllerCommissioningFlow.ts +96 -57
  111. package/src/peer/PeerSet.ts +5 -4
  112. package/src/protocol/ChannelManager.ts +3 -3
  113. package/src/protocol/ExchangeManager.ts +18 -67
  114. package/src/protocol/ExchangeProvider.ts +20 -6
  115. package/src/protocol/MessageChannel.ts +163 -0
  116. package/src/protocol/MessageExchange.ts +40 -119
  117. package/src/protocol/index.ts +1 -0
@@ -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 { GroupSession } from "#session/index.js";
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 { Message, MessageCodec, PacketHeader, SessionType } from "../codec/MessageCodec.js";
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", MRP_STANDALONE_ACK_TIMEOUT_MS, () => {
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: this.#maxTransmissions,
216
+ maxTrans: MRP.MAX_TRANSMISSIONS,
248
217
  exchangeFlags: Diagnostic.asFlags({
249
- MRP: this.#useMRP,
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.#useMRP) return;
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.#useMRP) {
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.#useMRP) {
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.#useMRP && includeAcknowledgeMessageId !== undefined) {
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.#useMRP) {
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.#useMRP) {
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.#useMRP && messageType !== SecureMessageType.StandaloneAck),
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.#useMRP && message.payloadHeader.requiresAck && !disableMrpLogic) {
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.#getResubmissionBackOffTime(0),
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
- switch (this.channel.type) {
516
- case "tcp":
517
- // TCP uses 30s timeout according to chip sdk implementation, so do the same
518
- timeout = 30_000;
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
- * Calculates the backoff time for a resubmission based on the current retransmission count.
546
- * If no session parameters are provided, the parameters of the current session are used.
547
- * If session parameters are provided, the method can be used to calculate the maximum backoff time for the other
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 >= this.#maxTransmissions) {
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.calculateMaximumPeerResponseTime(expectedProcessingTimeMs) -
589
- (this.#retransmissionTimer?.intervalMs ?? 0);
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.#getResubmissionBackOffTime(this.#retransmissionCounter);
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 <= this.#maxTransmissions; i++) {
746
- maxResubmissionTime += this.#getResubmissionBackOffTime(i);
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}`,
@@ -9,6 +9,7 @@ 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";