@matter/protocol 0.12.4-alpha.0-20250217-b0bba5179 → 0.12.4-alpha.0-20250224-e0964a795
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/action/client/ClientInteraction.d.ts +38 -0
- package/dist/cjs/action/client/ClientInteraction.d.ts.map +1 -0
- package/dist/cjs/action/client/ClientInteraction.js +91 -0
- package/dist/cjs/action/client/ClientInteraction.js.map +6 -0
- package/dist/cjs/action/client/index.d.ts +7 -0
- package/dist/cjs/action/client/index.d.ts.map +1 -0
- package/dist/cjs/action/client/index.js +24 -0
- package/dist/cjs/action/client/index.js.map +6 -0
- package/dist/cjs/action/index.d.ts +1 -0
- package/dist/cjs/action/index.d.ts.map +1 -1
- package/dist/cjs/action/index.js +1 -0
- package/dist/cjs/action/index.js.map +1 -1
- package/dist/cjs/interaction/DecodedDataReport.d.ts +15 -0
- package/dist/cjs/interaction/DecodedDataReport.d.ts.map +1 -0
- package/dist/cjs/interaction/DecodedDataReport.js +42 -0
- package/dist/cjs/interaction/DecodedDataReport.js.map +6 -0
- package/dist/cjs/interaction/InteractionClient.d.ts +13 -23
- package/dist/cjs/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionClient.js +99 -127
- package/dist/cjs/interaction/InteractionClient.js.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.d.ts +94 -1
- package/dist/cjs/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.js +56 -37
- package/dist/cjs/interaction/InteractionMessenger.js.map +1 -1
- package/dist/cjs/interaction/InteractionServer.d.ts +4 -2
- package/dist/cjs/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionServer.js +12 -4
- package/dist/cjs/interaction/InteractionServer.js.map +1 -1
- package/dist/cjs/interaction/SubscriptionClient.d.ts +38 -0
- package/dist/cjs/interaction/SubscriptionClient.d.ts.map +1 -0
- package/dist/cjs/interaction/SubscriptionClient.js +98 -0
- package/dist/cjs/interaction/SubscriptionClient.js.map +6 -0
- package/dist/cjs/interaction/index.d.ts +1 -0
- package/dist/cjs/interaction/index.d.ts.map +1 -1
- package/dist/cjs/interaction/index.js +1 -0
- package/dist/cjs/interaction/index.js.map +1 -1
- package/dist/cjs/peer/ControllerCommissioner.d.ts +2 -2
- package/dist/cjs/peer/ControllerCommissioner.d.ts.map +1 -1
- package/dist/cjs/peer/ControllerCommissioner.js +4 -3
- package/dist/cjs/peer/ControllerCommissioner.js.map +1 -1
- package/dist/cjs/peer/InteractionQueue.d.ts +11 -0
- package/dist/cjs/peer/InteractionQueue.d.ts.map +1 -0
- package/dist/cjs/peer/InteractionQueue.js +42 -0
- package/dist/cjs/peer/InteractionQueue.js.map +6 -0
- package/dist/cjs/peer/PeerAddressStore.d.ts +1 -1
- package/dist/cjs/peer/PeerAddressStore.d.ts.map +1 -1
- package/dist/cjs/peer/PeerSet.d.ts +16 -7
- package/dist/cjs/peer/PeerSet.d.ts.map +1 -1
- package/dist/cjs/peer/PeerSet.js +58 -61
- package/dist/cjs/peer/PeerSet.js.map +1 -1
- package/dist/cjs/peer/PhysicalDeviceProperties.d.ts +26 -0
- package/dist/cjs/peer/PhysicalDeviceProperties.d.ts.map +1 -0
- package/dist/cjs/peer/PhysicalDeviceProperties.js +74 -0
- package/dist/cjs/peer/PhysicalDeviceProperties.js.map +6 -0
- package/dist/cjs/peer/index.d.ts +1 -0
- package/dist/cjs/peer/index.d.ts.map +1 -1
- package/dist/cjs/peer/index.js +1 -0
- package/dist/cjs/peer/index.js.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.d.ts +1 -0
- package/dist/cjs/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.js +18 -11
- package/dist/cjs/protocol/ExchangeManager.js.map +1 -1
- package/dist/cjs/protocol/ExchangeProvider.d.ts +13 -1
- package/dist/cjs/protocol/ExchangeProvider.d.ts.map +1 -1
- package/dist/cjs/protocol/ExchangeProvider.js +2 -0
- package/dist/cjs/protocol/ExchangeProvider.js.map +1 -1
- package/dist/cjs/protocol/ProtocolHandler.d.ts +1 -1
- package/dist/cjs/protocol/ProtocolHandler.d.ts.map +1 -1
- package/dist/cjs/securechannel/SecureChannelProtocol.d.ts +1 -1
- package/dist/cjs/securechannel/SecureChannelProtocol.d.ts.map +1 -1
- package/dist/cjs/securechannel/SecureChannelProtocol.js +1 -3
- package/dist/cjs/securechannel/SecureChannelProtocol.js.map +1 -1
- package/dist/cjs/session/InsecureSession.d.ts.map +1 -1
- package/dist/cjs/session/InsecureSession.js +1 -0
- package/dist/cjs/session/InsecureSession.js.map +1 -1
- package/dist/cjs/session/SecureSession.d.ts.map +1 -1
- package/dist/cjs/session/SecureSession.js +4 -0
- package/dist/cjs/session/SecureSession.js.map +1 -1
- package/dist/cjs/session/Session.d.ts +3 -1
- package/dist/cjs/session/Session.d.ts.map +1 -1
- package/dist/cjs/session/Session.js +5 -1
- package/dist/cjs/session/Session.js.map +1 -1
- package/dist/cjs/session/SessionManager.d.ts.map +1 -1
- package/dist/cjs/session/SessionManager.js +1 -0
- 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 +22 -15
- package/dist/cjs/session/case/CaseClient.js.map +1 -1
- package/dist/cjs/session/case/CaseServer.d.ts +1 -1
- package/dist/cjs/session/case/CaseServer.d.ts.map +1 -1
- package/dist/cjs/session/case/CaseServer.js +2 -4
- package/dist/cjs/session/case/CaseServer.js.map +1 -1
- package/dist/cjs/session/pase/PaseServer.d.ts +2 -3
- package/dist/cjs/session/pase/PaseServer.d.ts.map +1 -1
- package/dist/cjs/session/pase/PaseServer.js +12 -14
- package/dist/cjs/session/pase/PaseServer.js.map +1 -1
- package/dist/esm/action/client/ClientInteraction.d.ts +38 -0
- package/dist/esm/action/client/ClientInteraction.d.ts.map +1 -0
- package/dist/esm/action/client/ClientInteraction.js +71 -0
- package/dist/esm/action/client/ClientInteraction.js.map +6 -0
- package/dist/esm/action/client/index.d.ts +7 -0
- package/dist/esm/action/client/index.d.ts.map +1 -0
- package/dist/esm/action/client/index.js +7 -0
- package/dist/esm/action/client/index.js.map +6 -0
- package/dist/esm/action/index.d.ts +1 -0
- package/dist/esm/action/index.d.ts.map +1 -1
- package/dist/esm/action/index.js +1 -0
- package/dist/esm/action/index.js.map +1 -1
- package/dist/esm/interaction/DecodedDataReport.d.ts +15 -0
- package/dist/esm/interaction/DecodedDataReport.d.ts.map +1 -0
- package/dist/esm/interaction/DecodedDataReport.js +22 -0
- package/dist/esm/interaction/DecodedDataReport.js.map +6 -0
- package/dist/esm/interaction/InteractionClient.d.ts +13 -23
- package/dist/esm/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionClient.js +101 -134
- package/dist/esm/interaction/InteractionClient.js.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.d.ts +94 -1
- package/dist/esm/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.js +56 -37
- package/dist/esm/interaction/InteractionMessenger.js.map +1 -1
- package/dist/esm/interaction/InteractionServer.d.ts +4 -2
- package/dist/esm/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionServer.js +12 -4
- package/dist/esm/interaction/InteractionServer.js.map +1 -1
- package/dist/esm/interaction/SubscriptionClient.d.ts +38 -0
- package/dist/esm/interaction/SubscriptionClient.d.ts.map +1 -0
- package/dist/esm/interaction/SubscriptionClient.js +78 -0
- package/dist/esm/interaction/SubscriptionClient.js.map +6 -0
- package/dist/esm/interaction/index.d.ts +1 -0
- package/dist/esm/interaction/index.d.ts.map +1 -1
- package/dist/esm/interaction/index.js +1 -0
- package/dist/esm/interaction/index.js.map +1 -1
- package/dist/esm/peer/ControllerCommissioner.d.ts +2 -2
- package/dist/esm/peer/ControllerCommissioner.d.ts.map +1 -1
- package/dist/esm/peer/ControllerCommissioner.js +6 -5
- package/dist/esm/peer/ControllerCommissioner.js.map +1 -1
- package/dist/esm/peer/InteractionQueue.d.ts +11 -0
- package/dist/esm/peer/InteractionQueue.d.ts.map +1 -0
- package/dist/esm/peer/InteractionQueue.js +22 -0
- package/dist/esm/peer/InteractionQueue.js.map +6 -0
- package/dist/esm/peer/PeerAddressStore.d.ts +1 -1
- package/dist/esm/peer/PeerAddressStore.d.ts.map +1 -1
- package/dist/esm/peer/PeerSet.d.ts +16 -7
- package/dist/esm/peer/PeerSet.d.ts.map +1 -1
- package/dist/esm/peer/PeerSet.js +59 -62
- package/dist/esm/peer/PeerSet.js.map +1 -1
- package/dist/esm/peer/PhysicalDeviceProperties.d.ts +26 -0
- package/dist/esm/peer/PhysicalDeviceProperties.d.ts.map +1 -0
- package/dist/esm/peer/PhysicalDeviceProperties.js +54 -0
- package/dist/esm/peer/PhysicalDeviceProperties.js.map +6 -0
- package/dist/esm/peer/index.d.ts +1 -0
- package/dist/esm/peer/index.d.ts.map +1 -1
- package/dist/esm/peer/index.js +1 -0
- package/dist/esm/peer/index.js.map +1 -1
- package/dist/esm/protocol/ExchangeManager.d.ts +1 -0
- package/dist/esm/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/esm/protocol/ExchangeManager.js +18 -11
- package/dist/esm/protocol/ExchangeManager.js.map +1 -1
- package/dist/esm/protocol/ExchangeProvider.d.ts +13 -1
- package/dist/esm/protocol/ExchangeProvider.d.ts.map +1 -1
- package/dist/esm/protocol/ExchangeProvider.js +2 -0
- package/dist/esm/protocol/ExchangeProvider.js.map +1 -1
- package/dist/esm/protocol/ProtocolHandler.d.ts +1 -1
- package/dist/esm/protocol/ProtocolHandler.d.ts.map +1 -1
- package/dist/esm/securechannel/SecureChannelProtocol.d.ts +1 -1
- package/dist/esm/securechannel/SecureChannelProtocol.d.ts.map +1 -1
- package/dist/esm/securechannel/SecureChannelProtocol.js +1 -3
- package/dist/esm/securechannel/SecureChannelProtocol.js.map +1 -1
- package/dist/esm/session/InsecureSession.d.ts.map +1 -1
- package/dist/esm/session/InsecureSession.js +1 -0
- package/dist/esm/session/InsecureSession.js.map +1 -1
- package/dist/esm/session/SecureSession.d.ts.map +1 -1
- package/dist/esm/session/SecureSession.js +4 -0
- package/dist/esm/session/SecureSession.js.map +1 -1
- package/dist/esm/session/Session.d.ts +3 -1
- package/dist/esm/session/Session.d.ts.map +1 -1
- package/dist/esm/session/Session.js +6 -2
- package/dist/esm/session/Session.js.map +1 -1
- package/dist/esm/session/SessionManager.d.ts.map +1 -1
- package/dist/esm/session/SessionManager.js +1 -0
- 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 +22 -15
- package/dist/esm/session/case/CaseClient.js.map +1 -1
- package/dist/esm/session/case/CaseServer.d.ts +1 -1
- package/dist/esm/session/case/CaseServer.d.ts.map +1 -1
- package/dist/esm/session/case/CaseServer.js +2 -4
- package/dist/esm/session/case/CaseServer.js.map +1 -1
- package/dist/esm/session/pase/PaseServer.d.ts +2 -3
- package/dist/esm/session/pase/PaseServer.d.ts.map +1 -1
- package/dist/esm/session/pase/PaseServer.js +12 -14
- package/dist/esm/session/pase/PaseServer.js.map +1 -1
- package/package.json +6 -6
- package/src/action/client/ClientInteraction.ts +110 -0
- package/src/action/client/index.ts +7 -0
- package/src/action/index.ts +1 -0
- package/src/interaction/DecodedDataReport.ts +29 -0
- package/src/interaction/InteractionClient.ts +112 -164
- package/src/interaction/InteractionMessenger.ts +63 -43
- package/src/interaction/InteractionServer.ts +18 -5
- package/src/interaction/SubscriptionClient.ts +107 -0
- package/src/interaction/index.ts +1 -0
- package/src/peer/ControllerCommissioner.ts +7 -6
- package/src/peer/InteractionQueue.ts +22 -0
- package/src/peer/PeerAddressStore.ts +1 -1
- package/src/peer/PeerSet.ts +69 -76
- package/src/peer/PhysicalDeviceProperties.ts +80 -0
- package/src/peer/index.ts +1 -0
- package/src/protocol/ExchangeManager.ts +19 -11
- package/src/protocol/ExchangeProvider.ts +14 -1
- package/src/protocol/ProtocolHandler.ts +1 -1
- package/src/securechannel/SecureChannelProtocol.ts +1 -3
- package/src/session/InsecureSession.ts +1 -0
- package/src/session/SecureSession.ts +4 -0
- package/src/session/Session.ts +7 -2
- package/src/session/SessionManager.ts +1 -0
- package/src/session/case/CaseClient.ts +18 -12
- package/src/session/case/CaseServer.ts +3 -5
- package/src/session/pase/PaseServer.ts +13 -15
|
@@ -227,9 +227,11 @@ export interface InteractionContext {
|
|
|
227
227
|
* Translates interactions from the Matter protocol to matter.js APIs.
|
|
228
228
|
*/
|
|
229
229
|
export class InteractionServer implements ProtocolHandler, InteractionRecipient {
|
|
230
|
+
readonly id = INTERACTION_PROTOCOL_ID;
|
|
230
231
|
#context: InteractionContext;
|
|
231
232
|
#nextSubscriptionId = Crypto.getRandomUInt32();
|
|
232
233
|
#isClosing = false;
|
|
234
|
+
#clientHandler?: ProtocolHandler;
|
|
233
235
|
readonly #subscriptionConfig: ServerSubscriptionConfig;
|
|
234
236
|
readonly #maxPathsPerInvoke;
|
|
235
237
|
|
|
@@ -244,10 +246,6 @@ export class InteractionServer implements ProtocolHandler, InteractionRecipient
|
|
|
244
246
|
});
|
|
245
247
|
}
|
|
246
248
|
|
|
247
|
-
getId() {
|
|
248
|
-
return INTERACTION_PROTOCOL_ID;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
249
|
protected get isClosing() {
|
|
252
250
|
return this.#isClosing;
|
|
253
251
|
}
|
|
@@ -256,13 +254,28 @@ export class InteractionServer implements ProtocolHandler, InteractionRecipient
|
|
|
256
254
|
return this.#maxPathsPerInvoke;
|
|
257
255
|
}
|
|
258
256
|
|
|
259
|
-
async onNewExchange(exchange: MessageExchange) {
|
|
257
|
+
async onNewExchange(exchange: MessageExchange, message: Message) {
|
|
260
258
|
// Note - changes here must be copied to TransactionalInteractionServer as it does not call super() to avoid
|
|
261
259
|
// the stack frame
|
|
262
260
|
if (this.#isClosing) return; // We are closing, ignore anything newly incoming
|
|
261
|
+
|
|
262
|
+
// An incoming data report as the first message is not a valid server operation. We instead delegate to a
|
|
263
|
+
// client implementation if available
|
|
264
|
+
if (message.payloadHeader.messageType === MessageType.SubscribeRequest && this.#clientHandler) {
|
|
265
|
+
return this.#clientHandler.onNewExchange(exchange, message);
|
|
266
|
+
}
|
|
267
|
+
|
|
263
268
|
await new InteractionServerMessenger(exchange).handleRequest(this);
|
|
264
269
|
}
|
|
265
270
|
|
|
271
|
+
get clientHandler(): ProtocolHandler | undefined {
|
|
272
|
+
return this.#clientHandler;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
set clientHandler(clientHandler: ProtocolHandler) {
|
|
276
|
+
this.#clientHandler = clientHandler;
|
|
277
|
+
}
|
|
278
|
+
|
|
266
279
|
async #collectEventDataForRead(
|
|
267
280
|
{ eventRequests, eventFilters, isFabricFiltered }: ReadRequest,
|
|
268
281
|
exchange: MessageExchange,
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { MessageExchange } from "#protocol/MessageExchange.js";
|
|
8
|
+
import { ProtocolHandler } from "#protocol/ProtocolHandler.js";
|
|
9
|
+
import { Environment, Environmental, Logger, MaybePromise, Time, Timer } from "@matter/general";
|
|
10
|
+
import { INTERACTION_PROTOCOL_ID } from "@matter/types";
|
|
11
|
+
import { DataReport, IncomingInteractionClientMessenger } from "./InteractionMessenger.js";
|
|
12
|
+
|
|
13
|
+
const logger = Logger.get("SubscriptionClient");
|
|
14
|
+
|
|
15
|
+
export interface RegisteredSubscription {
|
|
16
|
+
id: number;
|
|
17
|
+
maximumPeerResponseTime: number;
|
|
18
|
+
maxIntervalS: number;
|
|
19
|
+
onData: (dataReport: DataReport) => MaybePromise<void>;
|
|
20
|
+
onTimeout?: () => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A simple protocol handler that handles exchanges starting with data reports.
|
|
25
|
+
*
|
|
26
|
+
* Incoming data reports must match to a subscription registered with {@link add} or the exchange is invalid.
|
|
27
|
+
*/
|
|
28
|
+
export class SubscriptionClient implements ProtocolHandler {
|
|
29
|
+
readonly #listeners = new Map<number, (dataReport: DataReport) => MaybePromise<void>>();
|
|
30
|
+
readonly #timeouts = new Map<number, Timer>();
|
|
31
|
+
|
|
32
|
+
constructor() {}
|
|
33
|
+
|
|
34
|
+
static [Environmental.create](env: Environment) {
|
|
35
|
+
const client = new SubscriptionClient();
|
|
36
|
+
env.set(SubscriptionClient, client);
|
|
37
|
+
return client;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
readonly id = INTERACTION_PROTOCOL_ID;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Register a subscription.
|
|
44
|
+
*/
|
|
45
|
+
add(subscription: RegisteredSubscription) {
|
|
46
|
+
const { id, onData, onTimeout } = subscription;
|
|
47
|
+
|
|
48
|
+
this.#listeners.set(id, onData);
|
|
49
|
+
if (onTimeout) {
|
|
50
|
+
let timer = this.#timeouts.get(id);
|
|
51
|
+
if (timer !== undefined) {
|
|
52
|
+
timer.stop();
|
|
53
|
+
this.#timeouts.delete(id);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const maxIntervalMs = subscription.maxIntervalS * 1000 + subscription.maximumPeerResponseTime;
|
|
57
|
+
|
|
58
|
+
timer = Time.getTimer("Subscription timeout", maxIntervalMs, () => {
|
|
59
|
+
logger.info(`Subscription ${id} timed out after ${maxIntervalMs}ms`);
|
|
60
|
+
this.delete(id);
|
|
61
|
+
onTimeout();
|
|
62
|
+
}).start();
|
|
63
|
+
|
|
64
|
+
this.#timeouts.set(id, timer);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Unregister a subscription.
|
|
70
|
+
*/
|
|
71
|
+
delete(id: number) {
|
|
72
|
+
this.#listeners.delete(id);
|
|
73
|
+
const timer = this.#timeouts.get(id);
|
|
74
|
+
if (timer !== undefined) {
|
|
75
|
+
timer.stop();
|
|
76
|
+
this.#timeouts.delete(id);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async onNewExchange(exchange: MessageExchange) {
|
|
81
|
+
const messenger = new IncomingInteractionClientMessenger(exchange);
|
|
82
|
+
|
|
83
|
+
let dataReport: DataReport;
|
|
84
|
+
try {
|
|
85
|
+
// TODO Adjust this to getting packages as callback when received to handle error cases and checks outside
|
|
86
|
+
dataReport = await messenger.readAggregateDataReport([...this.#listeners.keys()]);
|
|
87
|
+
} finally {
|
|
88
|
+
messenger.close().catch(error => logger.info("Error closing client messenger", error));
|
|
89
|
+
}
|
|
90
|
+
const subscriptionId = dataReport.subscriptionId as number; // this is checked in the messenger already because we hand over allowed list
|
|
91
|
+
|
|
92
|
+
const listener = this.#listeners.get(subscriptionId);
|
|
93
|
+
const timer = this.#timeouts.get(subscriptionId);
|
|
94
|
+
|
|
95
|
+
if (timer !== undefined) {
|
|
96
|
+
timer.stop().start(); // Restart timer because we received data
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
await listener?.(dataReport);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async close() {
|
|
103
|
+
this.#listeners.clear();
|
|
104
|
+
this.#timeouts.forEach(timer => timer.stop());
|
|
105
|
+
this.#timeouts.clear();
|
|
106
|
+
}
|
|
107
|
+
}
|
package/src/interaction/index.ts
CHANGED
|
@@ -27,11 +27,11 @@ import { ChannelStatusResponseError } from "#securechannel/index.js";
|
|
|
27
27
|
import { PaseClient } from "#session/index.js";
|
|
28
28
|
import { SessionManager } from "#session/SessionManager.js";
|
|
29
29
|
import { DiscoveryCapabilitiesBitmap, NodeId, SECURE_CHANNEL_PROTOCOL_ID, TypeFromPartialBitSchema } from "#types";
|
|
30
|
-
import { InteractionClient } from "../interaction/InteractionClient.js";
|
|
30
|
+
import { InteractionClient, InteractionClientProvider } from "../interaction/InteractionClient.js";
|
|
31
31
|
import { ExchangeManager, MessageChannel } from "../protocol/ExchangeManager.js";
|
|
32
32
|
import { DedicatedChannelExchangeProvider } from "../protocol/ExchangeProvider.js";
|
|
33
33
|
import { PeerAddress } from "./PeerAddress.js";
|
|
34
|
-
import { NodeDiscoveryType
|
|
34
|
+
import { NodeDiscoveryType } from "./PeerSet.js";
|
|
35
35
|
|
|
36
36
|
const logger = Logger.get("PeerCommissioner");
|
|
37
37
|
|
|
@@ -108,7 +108,7 @@ export interface DiscoveryAndCommissioningOptions extends CommissioningOptions {
|
|
|
108
108
|
* Interfaces {@link ControllerCommissioner} with other components.
|
|
109
109
|
*/
|
|
110
110
|
export interface ControllerCommissionerContext {
|
|
111
|
-
|
|
111
|
+
clients: InteractionClientProvider;
|
|
112
112
|
scanners: ScannerSet;
|
|
113
113
|
netInterfaces: NetInterfaceSet;
|
|
114
114
|
sessions: SessionManager;
|
|
@@ -130,7 +130,7 @@ export class ControllerCommissioner {
|
|
|
130
130
|
|
|
131
131
|
static [Environmental.create](env: Environment) {
|
|
132
132
|
const instance = new ControllerCommissioner({
|
|
133
|
-
|
|
133
|
+
clients: env.get(InteractionClientProvider),
|
|
134
134
|
scanners: env.get(ScannerSet),
|
|
135
135
|
netInterfaces: env.get(NetInterfaceSet),
|
|
136
136
|
sessions: env.get(SessionManager),
|
|
@@ -385,6 +385,7 @@ export class ControllerCommissioner {
|
|
|
385
385
|
// Use the created secure session to do the commissioning
|
|
386
386
|
new InteractionClient(
|
|
387
387
|
new DedicatedChannelExchangeProvider(this.#context.exchanges, paseSecureMessageChannel),
|
|
388
|
+
this.#context.clients.peers.subscriptionClient,
|
|
388
389
|
address,
|
|
389
390
|
),
|
|
390
391
|
this.#context.ca,
|
|
@@ -406,7 +407,7 @@ export class ControllerCommissioner {
|
|
|
406
407
|
}
|
|
407
408
|
|
|
408
409
|
// Look for the device broadcast over MDNS and do CASE pairing
|
|
409
|
-
return await this.#context.
|
|
410
|
+
return await this.#context.clients.connect(
|
|
410
411
|
address,
|
|
411
412
|
{
|
|
412
413
|
discoveryType: NodeDiscoveryType.TimedDiscovery,
|
|
@@ -422,7 +423,7 @@ export class ControllerCommissioner {
|
|
|
422
423
|
await commissioningManager.executeCommissioning();
|
|
423
424
|
} catch (error) {
|
|
424
425
|
// We might have added data for an operational address that we need to cleanup
|
|
425
|
-
await this.#context.peers.delete(address);
|
|
426
|
+
await this.#context.clients.peers.delete(address);
|
|
426
427
|
throw error;
|
|
427
428
|
} finally {
|
|
428
429
|
if (!paseSecureMessageChannel.closed) {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Environment, Environmental, PromiseQueue } from "@matter/general";
|
|
8
|
+
|
|
9
|
+
const CONCURRENT_QUEUED_INTERACTIONS = 4;
|
|
10
|
+
const INTERACTION_QUEUE_DELAY_MS = 100;
|
|
11
|
+
|
|
12
|
+
export class InteractionQueue extends PromiseQueue {
|
|
13
|
+
constructor() {
|
|
14
|
+
super(CONCURRENT_QUEUED_INTERACTIONS, INTERACTION_QUEUE_DELAY_MS);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static [Environmental.create](env: Environment) {
|
|
18
|
+
const instance = new InteractionQueue();
|
|
19
|
+
env.set(InteractionQueue, instance);
|
|
20
|
+
return instance;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -18,7 +18,7 @@ export abstract class PeerAddressStore {
|
|
|
18
18
|
abstract loadPeers(): MaybePromise<Iterable<OperationalPeer>>;
|
|
19
19
|
abstract updatePeer(peer: OperationalPeer): MaybePromise<void>;
|
|
20
20
|
abstract deletePeer(address: PeerAddress): MaybePromise<void>;
|
|
21
|
-
abstract createNodeStore(address: PeerAddress):
|
|
21
|
+
abstract createNodeStore(address: PeerAddress): MaybePromise<PeerDataStore | undefined>;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export abstract class PeerDataStore {
|
package/src/peer/PeerSet.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { DiscoveryData, ScannerSet } from "#common/Scanner.js";
|
|
8
8
|
import {
|
|
9
9
|
anyPromise,
|
|
10
|
+
AsyncObservable,
|
|
10
11
|
BasicSet,
|
|
11
12
|
ChannelType,
|
|
12
13
|
Construction,
|
|
@@ -22,13 +23,12 @@ import {
|
|
|
22
23
|
NetInterfaceSet,
|
|
23
24
|
NoResponseTimeoutError,
|
|
24
25
|
ObservableSet,
|
|
25
|
-
PromiseQueue,
|
|
26
26
|
ServerAddressIp,
|
|
27
27
|
serverAddressToString,
|
|
28
28
|
Time,
|
|
29
29
|
Timer,
|
|
30
30
|
} from "#general";
|
|
31
|
-
import {
|
|
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
34
|
import { CaseClient, SecureSession, Session } from "#session/index.js";
|
|
@@ -39,6 +39,7 @@ import { ChannelNotConnectedError, ExchangeManager, MessageChannel } from "../pr
|
|
|
39
39
|
import { ReconnectableExchangeProvider } from "../protocol/ExchangeProvider.js";
|
|
40
40
|
import { RetransmissionLimitReachedError } from "../protocol/MessageExchange.js";
|
|
41
41
|
import { ControllerDiscovery, DiscoveryError, PairRetransmissionLimitReachedError } from "./ControllerDiscovery.js";
|
|
42
|
+
import { InteractionQueue } from "./InteractionQueue.js";
|
|
42
43
|
import { OperationalPeer } from "./OperationalPeer.js";
|
|
43
44
|
import { PeerAddressStore, PeerDataStore } from "./PeerAddressStore.js";
|
|
44
45
|
|
|
@@ -47,9 +48,6 @@ const logger = Logger.get("PeerSet");
|
|
|
47
48
|
const RECONNECTION_POLLING_INTERVAL_MS = 600_000; // 10 minutes
|
|
48
49
|
const RETRANSMISSION_DISCOVERY_TIMEOUT_S = 5;
|
|
49
50
|
|
|
50
|
-
const CONCURRENT_QUEUED_INTERACTIONS = 4;
|
|
51
|
-
const INTERACTION_QUEUE_DELAY_MS = 100;
|
|
52
|
-
|
|
53
51
|
/**
|
|
54
52
|
* Types of discovery that may be performed when connecting operationally.
|
|
55
53
|
*/
|
|
@@ -93,6 +91,7 @@ export interface PeerSetContext {
|
|
|
93
91
|
sessions: SessionManager;
|
|
94
92
|
channels: ChannelManager;
|
|
95
93
|
exchanges: ExchangeManager;
|
|
94
|
+
subscriptionClient: SubscriptionClient;
|
|
96
95
|
scanners: ScannerSet;
|
|
97
96
|
netInterfaces: NetInterfaceSet;
|
|
98
97
|
store: PeerAddressStore;
|
|
@@ -105,6 +104,7 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
105
104
|
readonly #sessions: SessionManager;
|
|
106
105
|
readonly #channels: ChannelManager;
|
|
107
106
|
readonly #exchanges: ExchangeManager;
|
|
107
|
+
readonly #subscriptionClient: SubscriptionClient;
|
|
108
108
|
readonly #scanners: ScannerSet;
|
|
109
109
|
readonly #netInterfaces: NetInterfaceSet;
|
|
110
110
|
readonly #caseClient: CaseClient;
|
|
@@ -117,16 +117,17 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
117
117
|
}>();
|
|
118
118
|
readonly #construction: Construction<PeerSet>;
|
|
119
119
|
readonly #store: PeerAddressStore;
|
|
120
|
-
readonly #interactionQueue = new
|
|
120
|
+
readonly #interactionQueue = new InteractionQueue();
|
|
121
121
|
readonly #nodeCachedData = new PeerAddressMap<PeerDataStore>(); // Temporarily until we store it in new API
|
|
122
|
-
readonly #
|
|
122
|
+
readonly #disconnected = AsyncObservable<[address: PeerAddress]>();
|
|
123
123
|
|
|
124
124
|
constructor(context: PeerSetContext) {
|
|
125
|
-
const { sessions, channels, exchanges, scanners, netInterfaces, store } = context;
|
|
125
|
+
const { sessions, channels, exchanges, subscriptionClient, scanners, netInterfaces, store } = context;
|
|
126
126
|
|
|
127
127
|
this.#sessions = sessions;
|
|
128
128
|
this.#channels = channels;
|
|
129
129
|
this.#exchanges = exchanges;
|
|
130
|
+
this.#subscriptionClient = subscriptionClient;
|
|
130
131
|
this.#scanners = scanners;
|
|
131
132
|
this.#netInterfaces = netInterfaces;
|
|
132
133
|
this.#store = store;
|
|
@@ -165,6 +166,10 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
165
166
|
return this.#peers.deleted;
|
|
166
167
|
}
|
|
167
168
|
|
|
169
|
+
get disconnected() {
|
|
170
|
+
return this.#disconnected;
|
|
171
|
+
}
|
|
172
|
+
|
|
168
173
|
has(item: PeerAddress | OperationalPeer) {
|
|
169
174
|
if ("address" in item) {
|
|
170
175
|
return this.#peers.has(item);
|
|
@@ -201,6 +206,7 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
201
206
|
sessions: env.get(SessionManager),
|
|
202
207
|
channels: env.get(ChannelManager),
|
|
203
208
|
exchanges: env.get(ExchangeManager),
|
|
209
|
+
subscriptionClient: env.get(SubscriptionClient),
|
|
204
210
|
scanners: env.get(ScannerSet),
|
|
205
211
|
netInterfaces: env.get(NetInterfaceSet),
|
|
206
212
|
store: env.get(PeerAddressStore),
|
|
@@ -213,20 +219,18 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
213
219
|
return this.#peers;
|
|
214
220
|
}
|
|
215
221
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
async connect(
|
|
220
|
-
address: PeerAddress,
|
|
221
|
-
discoveryOptions: DiscoveryOptions,
|
|
222
|
-
allowUnknownPeer = false,
|
|
223
|
-
): Promise<InteractionClient> {
|
|
224
|
-
await this.#ensureConnection(address, discoveryOptions, allowUnknownPeer);
|
|
222
|
+
get subscriptionClient() {
|
|
223
|
+
return this.#subscriptionClient;
|
|
224
|
+
}
|
|
225
225
|
|
|
226
|
-
|
|
226
|
+
get interactionQueue() {
|
|
227
|
+
return this.#interactionQueue;
|
|
227
228
|
}
|
|
228
229
|
|
|
229
|
-
|
|
230
|
+
/**
|
|
231
|
+
* Ensure there is a channel to the designated peer.
|
|
232
|
+
*/
|
|
233
|
+
async ensureConnection(address: PeerAddress, discoveryOptions: DiscoveryOptions, allowUnknownPeer = false) {
|
|
230
234
|
if (!this.#peersByAddress.has(address) && !allowUnknownPeer) {
|
|
231
235
|
throw new UnknownNodeError(`Cannot connect to unknown device ${PeerAddress(address)}`);
|
|
232
236
|
}
|
|
@@ -256,62 +260,44 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
256
260
|
}
|
|
257
261
|
}
|
|
258
262
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
const nodeStore = this.get(address)?.dataStore;
|
|
266
|
-
await nodeStore?.construction; // Lazy initialize the data if not already done
|
|
267
|
-
|
|
263
|
+
/**
|
|
264
|
+
* Obtain an exchange provider for the designated peer.
|
|
265
|
+
*/
|
|
266
|
+
async exchangeProviderFor(address: PeerAddress, discoveryOptions?: DiscoveryOptions) {
|
|
268
267
|
let initiallyConnected = this.#channels.hasChannel(address);
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
268
|
+
return new ReconnectableExchangeProvider(this.#exchanges, this.#channels, address, async () => {
|
|
269
|
+
if (!initiallyConnected && !this.#channels.hasChannel(address)) {
|
|
270
|
+
// We got an uninitialized node, so do the first connection as usual
|
|
271
|
+
await this.ensureConnection(address, { discoveryType: NodeDiscoveryType.None });
|
|
272
|
+
initiallyConnected = true; // We only do this connection once, rest is handled in following code
|
|
273
|
+
if (this.#channels.hasChannel(address)) {
|
|
274
|
+
return;
|
|
278
275
|
}
|
|
276
|
+
}
|
|
279
277
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
285
|
-
await this.#channels.removeAllNodeChannels(address);
|
|
278
|
+
if (!this.#channels.hasChannel(address)) {
|
|
279
|
+
throw new RetransmissionLimitReachedError(`Device ${PeerAddress(address)} is currently not reachable.`);
|
|
280
|
+
}
|
|
281
|
+
await this.#channels.removeAllNodeChannels(address);
|
|
286
282
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
) {
|
|
306
|
-
throw new RetransmissionLimitReachedError(`${PeerAddress(address)} is not reachable.`);
|
|
307
|
-
}
|
|
308
|
-
}),
|
|
309
|
-
address,
|
|
310
|
-
this.#interactionQueue,
|
|
311
|
-
nodeStore,
|
|
312
|
-
);
|
|
313
|
-
this.#clients.set(address, client);
|
|
314
|
-
return client;
|
|
283
|
+
// Enrich discoveryData with data from the node store when not provided
|
|
284
|
+
const { discoveryData } = discoveryOptions ?? {
|
|
285
|
+
discoveryData: this.#peersByAddress.get(address)?.discoveryData,
|
|
286
|
+
};
|
|
287
|
+
// Try to use first result for one last try before we need to reconnect
|
|
288
|
+
const operationalAddress = this.#knownOperationalAddressFor(address, true);
|
|
289
|
+
if (operationalAddress === undefined) {
|
|
290
|
+
logger.info(
|
|
291
|
+
`Re-discovering device failed (no address found), remove all sessions for ${PeerAddress(address)}`,
|
|
292
|
+
);
|
|
293
|
+
// We remove all sessions, this also informs the PairedNode class
|
|
294
|
+
await this.#sessions.removeAllSessionsForNode(address);
|
|
295
|
+
throw new RetransmissionLimitReachedError(`No operational address found for ${PeerAddress(address)}`);
|
|
296
|
+
}
|
|
297
|
+
if ((await this.#reconnectKnownAddress(address, operationalAddress, discoveryData, 2_000)) === undefined) {
|
|
298
|
+
throw new RetransmissionLimitReachedError(`${PeerAddress(address)} is not reachable.`);
|
|
299
|
+
}
|
|
300
|
+
});
|
|
315
301
|
}
|
|
316
302
|
|
|
317
303
|
/**
|
|
@@ -327,10 +313,15 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
327
313
|
/**
|
|
328
314
|
* Terminate any active peer connection.
|
|
329
315
|
*/
|
|
330
|
-
async disconnect(
|
|
331
|
-
this
|
|
316
|
+
async disconnect(peer: PeerAddress | OperationalPeer, sendSessionClose = true) {
|
|
317
|
+
const address = this.get(peer)?.address;
|
|
318
|
+
if (address === undefined) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
|
|
332
322
|
await this.#sessions.removeAllSessionsForNode(address, sendSessionClose);
|
|
333
323
|
await this.#channels.removeAllNodeChannels(address);
|
|
324
|
+
await this.#disconnected.emit(address);
|
|
334
325
|
}
|
|
335
326
|
|
|
336
327
|
/**
|
|
@@ -348,7 +339,6 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
348
339
|
await this.#store.deletePeer(address);
|
|
349
340
|
await this.disconnect(address, false);
|
|
350
341
|
await this.#sessions.deleteResumptionRecord(address);
|
|
351
|
-
this.#clients.delete(address);
|
|
352
342
|
}
|
|
353
343
|
|
|
354
344
|
async close() {
|
|
@@ -358,8 +348,11 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
358
348
|
// This ends discovery without triggering promises
|
|
359
349
|
mdnsScanner?.cancelOperationalDeviceDiscovery(this.#sessions.fabricFor(address), address.nodeId, false);
|
|
360
350
|
}
|
|
361
|
-
|
|
362
|
-
this.#
|
|
351
|
+
|
|
352
|
+
for (const { address } of this.#peers) {
|
|
353
|
+
await this.disconnect(address, false);
|
|
354
|
+
}
|
|
355
|
+
|
|
363
356
|
this.#interactionQueue.close();
|
|
364
357
|
this.#runningPeerReconnections.forEach(({ rejecter }) =>
|
|
365
358
|
rejecter(new ChannelNotConnectedError("PeerSet closed")),
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Logger } from "#general";
|
|
8
|
+
|
|
9
|
+
const logger = Logger.get("PhysicalDeviceProperties");
|
|
10
|
+
|
|
11
|
+
const DEFAULT_SUBSCRIPTION_FLOOR_DEFAULT_S = 1;
|
|
12
|
+
const DEFAULT_SUBSCRIPTION_FLOOR_ICD_S = 0;
|
|
13
|
+
const DEFAULT_SUBSCRIPTION_CEILING_WIFI_S = 60;
|
|
14
|
+
const DEFAULT_SUBSCRIPTION_CEILING_THREAD_S = 60;
|
|
15
|
+
const DEFAULT_SUBSCRIPTION_CEILING_THREAD_SLEEPY_S = 180;
|
|
16
|
+
const DEFAULT_SUBSCRIPTION_CEILING_BATTERY_POWERED_S = 600;
|
|
17
|
+
|
|
18
|
+
export interface PhysicalDeviceProperties {
|
|
19
|
+
threadConnected: boolean;
|
|
20
|
+
wifiConnected: boolean;
|
|
21
|
+
ethernetConnected: boolean;
|
|
22
|
+
rootEndpointServerList: number[];
|
|
23
|
+
isBatteryPowered: boolean;
|
|
24
|
+
isIntermittentlyConnected: boolean;
|
|
25
|
+
isThreadSleepyEndDevice: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export namespace PhysicalDeviceProperties {
|
|
29
|
+
export function determineSubscriptionParameters(options?: {
|
|
30
|
+
properties?: PhysicalDeviceProperties;
|
|
31
|
+
description?: string;
|
|
32
|
+
subscribeMinIntervalFloorSeconds?: number;
|
|
33
|
+
subscribeMaxIntervalCeilingSeconds?: number;
|
|
34
|
+
}) {
|
|
35
|
+
const { properties } = options ?? {};
|
|
36
|
+
|
|
37
|
+
let {
|
|
38
|
+
description,
|
|
39
|
+
subscribeMinIntervalFloorSeconds: minIntervalFloorSeconds,
|
|
40
|
+
subscribeMaxIntervalCeilingSeconds: maxIntervalCeilingSeconds,
|
|
41
|
+
} = options ?? {};
|
|
42
|
+
|
|
43
|
+
if (description === undefined) {
|
|
44
|
+
description = "Node";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const { isBatteryPowered, isIntermittentlyConnected, threadConnected, isThreadSleepyEndDevice } =
|
|
48
|
+
properties ?? {};
|
|
49
|
+
|
|
50
|
+
if (isIntermittentlyConnected) {
|
|
51
|
+
if (minIntervalFloorSeconds !== undefined && minIntervalFloorSeconds !== DEFAULT_SUBSCRIPTION_FLOOR_ICD_S) {
|
|
52
|
+
logger.info(
|
|
53
|
+
`${description}: Overwriting minIntervalFloorSeconds for intermittently connected device to ${DEFAULT_SUBSCRIPTION_FLOOR_ICD_S}`,
|
|
54
|
+
);
|
|
55
|
+
minIntervalFloorSeconds = DEFAULT_SUBSCRIPTION_FLOOR_ICD_S;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const defaultCeiling = isBatteryPowered
|
|
60
|
+
? DEFAULT_SUBSCRIPTION_CEILING_BATTERY_POWERED_S
|
|
61
|
+
: isThreadSleepyEndDevice
|
|
62
|
+
? DEFAULT_SUBSCRIPTION_CEILING_THREAD_SLEEPY_S
|
|
63
|
+
: threadConnected
|
|
64
|
+
? DEFAULT_SUBSCRIPTION_CEILING_THREAD_S
|
|
65
|
+
: DEFAULT_SUBSCRIPTION_CEILING_WIFI_S;
|
|
66
|
+
if (maxIntervalCeilingSeconds === undefined) {
|
|
67
|
+
maxIntervalCeilingSeconds = defaultCeiling;
|
|
68
|
+
}
|
|
69
|
+
if (maxIntervalCeilingSeconds < defaultCeiling) {
|
|
70
|
+
logger.debug(
|
|
71
|
+
`${description}: maxIntervalCeilingSeconds ideally is ${defaultCeiling}s instead of ${maxIntervalCeilingSeconds}s due to device type`,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
minIntervalFloorSeconds: minIntervalFloorSeconds ?? DEFAULT_SUBSCRIPTION_FLOOR_DEFAULT_S,
|
|
77
|
+
maxIntervalCeilingSeconds,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
package/src/peer/index.ts
CHANGED