@matter/protocol 0.12.4-alpha.0-20250223-1e0341a1a → 0.12.4-alpha.0-20250224-46934b522
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 +17 -23
- package/dist/cjs/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionClient.js +100 -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 +22 -3
- package/dist/cjs/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionServer.js +129 -45
- package/dist/cjs/interaction/InteractionServer.js.map +1 -1
- package/dist/cjs/interaction/ServerSubscription.d.ts +8 -16
- package/dist/cjs/interaction/ServerSubscription.d.ts.map +1 -1
- package/dist/cjs/interaction/ServerSubscription.js +78 -55
- package/dist/cjs/interaction/ServerSubscription.js.map +1 -1
- package/dist/cjs/interaction/Subscription.d.ts +7 -1
- package/dist/cjs/interaction/Subscription.d.ts.map +1 -1
- package/dist/cjs/interaction/Subscription.js +25 -2
- package/dist/cjs/interaction/Subscription.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 +7 -7
- 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/PeerAddress.d.ts +5 -0
- package/dist/cjs/peer/PeerAddress.d.ts.map +1 -1
- package/dist/cjs/peer/PeerAddress.js +13 -1
- package/dist/cjs/peer/PeerAddress.js.map +1 -1
- 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 +20 -7
- package/dist/cjs/peer/PeerSet.d.ts.map +1 -1
- package/dist/cjs/peer/PeerSet.js +74 -67
- 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 +6 -3
- 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/SecureChannelMessenger.d.ts +1 -0
- package/dist/cjs/securechannel/SecureChannelMessenger.d.ts.map +1 -1
- package/dist/cjs/securechannel/SecureChannelMessenger.js +3 -0
- package/dist/cjs/securechannel/SecureChannelMessenger.js.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/SecureSession.d.ts +1 -1
- package/dist/cjs/session/SecureSession.d.ts.map +1 -1
- package/dist/cjs/session/SecureSession.js +3 -2
- package/dist/cjs/session/SecureSession.js.map +1 -1
- package/dist/cjs/session/Session.d.ts +1 -0
- package/dist/cjs/session/Session.d.ts.map +1 -1
- package/dist/cjs/session/Session.js +1 -0
- package/dist/cjs/session/Session.js.map +1 -1
- package/dist/cjs/session/SessionManager.d.ts +2 -2
- package/dist/cjs/session/SessionManager.d.ts.map +1 -1
- package/dist/cjs/session/SessionManager.js +6 -9
- package/dist/cjs/session/SessionManager.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 +1 -3
- 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 +17 -23
- package/dist/esm/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionClient.js +102 -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 +22 -3
- package/dist/esm/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionServer.js +130 -46
- package/dist/esm/interaction/InteractionServer.js.map +1 -1
- package/dist/esm/interaction/ServerSubscription.d.ts +8 -16
- package/dist/esm/interaction/ServerSubscription.d.ts.map +1 -1
- package/dist/esm/interaction/ServerSubscription.js +78 -55
- package/dist/esm/interaction/ServerSubscription.js.map +1 -1
- package/dist/esm/interaction/Subscription.d.ts +7 -1
- package/dist/esm/interaction/Subscription.d.ts.map +1 -1
- package/dist/esm/interaction/Subscription.js +26 -3
- package/dist/esm/interaction/Subscription.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 +9 -9
- 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/PeerAddress.d.ts +5 -0
- package/dist/esm/peer/PeerAddress.d.ts.map +1 -1
- package/dist/esm/peer/PeerAddress.js +13 -1
- package/dist/esm/peer/PeerAddress.js.map +1 -1
- 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 +20 -7
- package/dist/esm/peer/PeerSet.d.ts.map +1 -1
- package/dist/esm/peer/PeerSet.js +75 -68
- 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 +6 -3
- 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/SecureChannelMessenger.d.ts +1 -0
- package/dist/esm/securechannel/SecureChannelMessenger.d.ts.map +1 -1
- package/dist/esm/securechannel/SecureChannelMessenger.js +3 -0
- package/dist/esm/securechannel/SecureChannelMessenger.js.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/SecureSession.d.ts +1 -1
- package/dist/esm/session/SecureSession.d.ts.map +1 -1
- package/dist/esm/session/SecureSession.js +3 -2
- package/dist/esm/session/SecureSession.js.map +1 -1
- package/dist/esm/session/Session.d.ts +1 -0
- package/dist/esm/session/Session.d.ts.map +1 -1
- package/dist/esm/session/Session.js +1 -0
- package/dist/esm/session/Session.js.map +1 -1
- package/dist/esm/session/SessionManager.d.ts +2 -2
- package/dist/esm/session/SessionManager.d.ts.map +1 -1
- package/dist/esm/session/SessionManager.js +7 -10
- package/dist/esm/session/SessionManager.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 +1 -3
- 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 +118 -165
- package/src/interaction/InteractionMessenger.ts +63 -43
- package/src/interaction/InteractionServer.ts +176 -50
- package/src/interaction/ServerSubscription.ts +87 -63
- package/src/interaction/Subscription.ts +34 -6
- package/src/interaction/SubscriptionClient.ts +107 -0
- package/src/interaction/index.ts +1 -0
- package/src/peer/ControllerCommissioner.ts +10 -10
- package/src/peer/InteractionQueue.ts +22 -0
- package/src/peer/PeerAddress.ts +14 -0
- package/src/peer/PeerAddressStore.ts +1 -1
- package/src/peer/PeerSet.ts +98 -83
- package/src/peer/PhysicalDeviceProperties.ts +80 -0
- package/src/peer/index.ts +1 -0
- package/src/protocol/ExchangeManager.ts +7 -3
- package/src/protocol/ExchangeProvider.ts +14 -1
- package/src/protocol/ProtocolHandler.ts +1 -1
- package/src/securechannel/SecureChannelMessenger.ts +4 -0
- package/src/securechannel/SecureChannelProtocol.ts +1 -3
- package/src/session/SecureSession.ts +3 -2
- package/src/session/Session.ts +1 -0
- package/src/session/SessionManager.ts +6 -9
- package/src/session/case/CaseServer.ts +2 -4
- package/src/session/pase/PaseServer.ts +13 -15
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Interactable } from "#action/Interactable.js";
|
|
8
|
+
import { Invoke } from "#action/request/Invoke.js";
|
|
9
|
+
import { Read } from "#action/request/Read.js";
|
|
10
|
+
import { Subscribe } from "#action/request/Subscribe.js";
|
|
11
|
+
import { Write } from "#action/request/Write.js";
|
|
12
|
+
import { InvokeResult } from "#action/response/InvokeResult.js";
|
|
13
|
+
import { ReadResult } from "#action/response/ReadResult.js";
|
|
14
|
+
import { SubscribeResult } from "#action/response/SubscribeResult.js";
|
|
15
|
+
import { WriteResult } from "#action/response/WriteResult.js";
|
|
16
|
+
import { AccessControl } from "#action/server/AccessControl.js";
|
|
17
|
+
import { CancelablePromise, Environment, Environmental, NotImplementedError, PromiseQueue } from "#general";
|
|
18
|
+
import { InteractionClientMessenger } from "#interaction/InteractionMessenger.js";
|
|
19
|
+
import { SubscriptionClient } from "#interaction/SubscriptionClient.js";
|
|
20
|
+
import { InteractionQueue } from "#peer/InteractionQueue.js";
|
|
21
|
+
import { ExchangeProvider } from "#protocol/ExchangeProvider.js";
|
|
22
|
+
import { WriteResponse } from "#types";
|
|
23
|
+
|
|
24
|
+
export interface ClientInteractableContext {
|
|
25
|
+
exchanges: ExchangeProvider;
|
|
26
|
+
subscriptions: SubscriptionClient;
|
|
27
|
+
queue: PromiseQueue;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* This is a WIP and currently largely a stub.
|
|
32
|
+
*/
|
|
33
|
+
export class ClientInteraction<SessionT extends AccessControl.Session = AccessControl.Session>
|
|
34
|
+
implements Interactable<SessionT>
|
|
35
|
+
{
|
|
36
|
+
readonly #exchanges: ExchangeProvider;
|
|
37
|
+
readonly #subscriptions: SubscriptionClient;
|
|
38
|
+
readonly #queue?: PromiseQueue;
|
|
39
|
+
|
|
40
|
+
constructor(context: ClientInteractableContext) {
|
|
41
|
+
this.#exchanges = context.exchanges;
|
|
42
|
+
this.#subscriptions = context.subscriptions;
|
|
43
|
+
this.#queue = context.queue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
get subscriptions() {
|
|
47
|
+
return this.#subscriptions;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get queue() {
|
|
51
|
+
return this.#queue;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static [Environmental.create](env: Environment) {
|
|
55
|
+
const instance = new ClientInteraction({
|
|
56
|
+
exchanges: env.get(ExchangeProvider),
|
|
57
|
+
subscriptions: env.get(SubscriptionClient),
|
|
58
|
+
queue: env.get(InteractionQueue),
|
|
59
|
+
});
|
|
60
|
+
env.set(ClientInteraction, instance);
|
|
61
|
+
return instance;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
read(_request: Read, _session?: SessionT): ReadResult {
|
|
65
|
+
// TODO
|
|
66
|
+
throw new NotImplementedError();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
write<T extends Write>(request: T, _session?: SessionT) {
|
|
70
|
+
return new CancelablePromise<void | WriteResponse>((resolve, reject) => {
|
|
71
|
+
InteractionClientMessenger.create(this.#exchanges).then(messenger => {
|
|
72
|
+
const send = messenger.sendWriteCommand(request);
|
|
73
|
+
|
|
74
|
+
let sendResolve;
|
|
75
|
+
if (request.suppressResponse) {
|
|
76
|
+
sendResolve = send.then(() => {
|
|
77
|
+
resolve();
|
|
78
|
+
});
|
|
79
|
+
} else {
|
|
80
|
+
sendResolve = send.then(resolve);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
sendResolve.catch(reject);
|
|
84
|
+
}, reject);
|
|
85
|
+
}) as WriteResult<T>;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
invoke<T extends Invoke>(request: Invoke, _session?: SessionT): InvokeResult<T> {
|
|
89
|
+
if (request.suppressResponse) {
|
|
90
|
+
return new CancelablePromise<void>((resolve, reject) => {
|
|
91
|
+
InteractionClientMessenger.create(this.#exchanges)
|
|
92
|
+
.then(messenger =>
|
|
93
|
+
messenger
|
|
94
|
+
.sendInvokeCommand(request)
|
|
95
|
+
.then(() => resolve())
|
|
96
|
+
.catch(reject),
|
|
97
|
+
)
|
|
98
|
+
.then(resolve, reject);
|
|
99
|
+
}) as InvokeResult<T>;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// TODO
|
|
103
|
+
throw new NotImplementedError();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
subscribe(_request: Subscribe, _session?: SessionT): SubscribeResult {
|
|
107
|
+
// TODO
|
|
108
|
+
throw new NotImplementedError();
|
|
109
|
+
}
|
|
110
|
+
}
|
package/src/action/index.ts
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { DataReport } from "#types";
|
|
8
|
+
import { DecodedAttributeReportValue, normalizeAndDecodeReadAttributeReport } from "./AttributeDataDecoder.js";
|
|
9
|
+
import { DecodedEventReportValue, normalizeAndDecodeReadEventReport } from "./EventDataDecoder.js";
|
|
10
|
+
|
|
11
|
+
export interface DecodedDataReport extends DataReport {
|
|
12
|
+
isNormalized: true;
|
|
13
|
+
attributeReports: DecodedAttributeReportValue<any>[];
|
|
14
|
+
eventReports: DecodedEventReportValue<any>[];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function DecodedDataReport(report: DataReport): DecodedDataReport {
|
|
18
|
+
if ((report as DecodedDataReport).isNormalized) {
|
|
19
|
+
return report as DecodedDataReport;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
...report,
|
|
24
|
+
isNormalized: true,
|
|
25
|
+
attributeReports:
|
|
26
|
+
report.attributeReports === undefined ? [] : normalizeAndDecodeReadAttributeReport(report.attributeReports),
|
|
27
|
+
eventReports: report.eventReports === undefined ? [] : normalizeAndDecodeReadEventReport(report.eventReports),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -5,20 +5,21 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
|
+
Environment,
|
|
9
|
+
Environmental,
|
|
8
10
|
ImplementationError,
|
|
9
|
-
InternalError,
|
|
10
11
|
Logger,
|
|
11
12
|
MatterFlowError,
|
|
12
|
-
MaybePromise,
|
|
13
13
|
PromiseQueue,
|
|
14
|
-
|
|
14
|
+
ServerAddressIp,
|
|
15
15
|
Timer,
|
|
16
16
|
UnexpectedDataError,
|
|
17
17
|
isDeepEqual,
|
|
18
18
|
} from "#general";
|
|
19
19
|
import { Specification } from "#model";
|
|
20
|
-
import { PeerAddress } from "#peer/PeerAddress.js";
|
|
20
|
+
import { PeerAddress, PeerAddressMap } from "#peer/PeerAddress.js";
|
|
21
21
|
import { PeerDataStore } from "#peer/PeerAddressStore.js";
|
|
22
|
+
import { DiscoveryOptions, PeerSet } from "#peer/PeerSet.js";
|
|
22
23
|
import {
|
|
23
24
|
ArraySchema,
|
|
24
25
|
Attribute,
|
|
@@ -30,7 +31,6 @@ import {
|
|
|
30
31
|
Event,
|
|
31
32
|
EventId,
|
|
32
33
|
EventNumber,
|
|
33
|
-
INTERACTION_PROTOCOL_ID,
|
|
34
34
|
NodeId,
|
|
35
35
|
RequestType,
|
|
36
36
|
ResponseType,
|
|
@@ -47,16 +47,11 @@ import {
|
|
|
47
47
|
resolveEventName,
|
|
48
48
|
} from "#types";
|
|
49
49
|
import { ExchangeProvider, ReconnectableExchangeProvider } from "../protocol/ExchangeProvider.js";
|
|
50
|
-
import {
|
|
51
|
-
import {
|
|
52
|
-
import {
|
|
53
|
-
import {
|
|
54
|
-
import {
|
|
55
|
-
DataReport,
|
|
56
|
-
IncomingInteractionClientMessenger,
|
|
57
|
-
InteractionClientMessenger,
|
|
58
|
-
ReadRequest,
|
|
59
|
-
} from "./InteractionMessenger.js";
|
|
50
|
+
import { DecodedAttributeReportValue } from "./AttributeDataDecoder.js";
|
|
51
|
+
import { DecodedDataReport } from "./DecodedDataReport.js";
|
|
52
|
+
import { DecodedEventData, DecodedEventReportValue } from "./EventDataDecoder.js";
|
|
53
|
+
import { DataReport, InteractionClientMessenger, ReadRequest } from "./InteractionMessenger.js";
|
|
54
|
+
import { RegisteredSubscription, SubscriptionClient } from "./SubscriptionClient.js";
|
|
60
55
|
|
|
61
56
|
const logger = Logger.get("InteractionClient");
|
|
62
57
|
|
|
@@ -74,102 +69,102 @@ export interface AttributeStatus {
|
|
|
74
69
|
status: StatusCode;
|
|
75
70
|
}
|
|
76
71
|
|
|
77
|
-
export class
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
constructor() {}
|
|
82
|
-
|
|
83
|
-
getId() {
|
|
84
|
-
return INTERACTION_PROTOCOL_ID;
|
|
85
|
-
}
|
|
72
|
+
export class InteractionClientProvider {
|
|
73
|
+
readonly #peers: PeerSet;
|
|
74
|
+
readonly #clients = new PeerAddressMap<InteractionClient>();
|
|
86
75
|
|
|
87
|
-
|
|
88
|
-
this
|
|
76
|
+
constructor(peers: PeerSet) {
|
|
77
|
+
this.#peers = peers;
|
|
78
|
+
this.#peers.deleted.on(peer => this.#onPeerLoss(peer.address));
|
|
79
|
+
this.#peers.disconnected.on(address => this.#onPeerLoss(address));
|
|
89
80
|
}
|
|
90
81
|
|
|
91
|
-
|
|
92
|
-
|
|
82
|
+
static [Environmental.create](env: Environment) {
|
|
83
|
+
const instance = new InteractionClientProvider(env.get(PeerSet));
|
|
84
|
+
env.set(InteractionClientProvider, instance);
|
|
85
|
+
return instance;
|
|
93
86
|
}
|
|
94
87
|
|
|
95
|
-
|
|
96
|
-
this
|
|
88
|
+
get peers() {
|
|
89
|
+
return this.#peers;
|
|
97
90
|
}
|
|
98
91
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
92
|
+
async connect(
|
|
93
|
+
address: PeerAddress,
|
|
94
|
+
options: {
|
|
95
|
+
discoveryOptions: DiscoveryOptions;
|
|
96
|
+
allowUnknownPeer?: boolean;
|
|
97
|
+
operationalAddress?: ServerAddressIp;
|
|
98
|
+
},
|
|
99
|
+
): Promise<InteractionClient> {
|
|
100
|
+
await this.#peers.ensureConnection(address, options);
|
|
101
|
+
|
|
102
|
+
const { discoveryOptions } = options;
|
|
103
|
+
return this.getInteractionClient(address, discoveryOptions);
|
|
102
104
|
}
|
|
103
105
|
|
|
104
|
-
async
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
try {
|
|
109
|
-
// TODO Adjust this to getting packages as callback when received to handle error cases and checks outside
|
|
110
|
-
dataReport = await messenger.readDataReports([...this.subscriptionListeners.keys()]);
|
|
111
|
-
} finally {
|
|
112
|
-
messenger.close().catch(error => logger.info("Error closing client messenger", error));
|
|
106
|
+
async getInteractionClient(address: PeerAddress, discoveryOptions: DiscoveryOptions) {
|
|
107
|
+
let client = this.#clients.get(address);
|
|
108
|
+
if (client !== undefined) {
|
|
109
|
+
return client;
|
|
113
110
|
}
|
|
114
|
-
const subscriptionId = dataReport.subscriptionId as number; // this is checked in the messenger already because we hand over allowed list
|
|
115
111
|
|
|
116
|
-
const
|
|
117
|
-
|
|
112
|
+
const nodeStore = this.#peers.get(address)?.dataStore;
|
|
113
|
+
await nodeStore?.construction; // Lazy initialize the data if not already done
|
|
118
114
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
115
|
+
const exchangeProvider = await this.#peers.exchangeProviderFor(address, discoveryOptions);
|
|
116
|
+
|
|
117
|
+
client = new InteractionClient(
|
|
118
|
+
exchangeProvider,
|
|
119
|
+
this.#peers.subscriptionClient,
|
|
120
|
+
address,
|
|
121
|
+
this.#peers.interactionQueue,
|
|
122
|
+
nodeStore,
|
|
123
|
+
);
|
|
124
|
+
this.#clients.set(address, client);
|
|
122
125
|
|
|
123
|
-
|
|
126
|
+
return client;
|
|
124
127
|
}
|
|
125
128
|
|
|
126
|
-
|
|
127
|
-
this.
|
|
128
|
-
|
|
129
|
-
|
|
129
|
+
#onPeerLoss(address: PeerAddress) {
|
|
130
|
+
const client = this.#clients.get(address);
|
|
131
|
+
if (client !== undefined) {
|
|
132
|
+
client.close();
|
|
133
|
+
this.#clients.delete(address);
|
|
134
|
+
}
|
|
130
135
|
}
|
|
131
136
|
}
|
|
132
137
|
|
|
133
138
|
export class InteractionClient {
|
|
139
|
+
readonly #exchangeProvider: ExchangeProvider;
|
|
134
140
|
readonly #nodeStore?: PeerDataStore;
|
|
135
141
|
readonly #ownSubscriptionIds = new Set<number>();
|
|
136
142
|
readonly #subscriptionClient: SubscriptionClient;
|
|
137
143
|
readonly #queue?: PromiseQueue;
|
|
138
144
|
|
|
139
145
|
constructor(
|
|
140
|
-
|
|
146
|
+
exchangeProvider: ExchangeProvider,
|
|
147
|
+
subscriptionClient: SubscriptionClient,
|
|
141
148
|
readonly address: PeerAddress,
|
|
142
149
|
queue?: PromiseQueue,
|
|
143
150
|
nodeStore?: PeerDataStore,
|
|
144
151
|
) {
|
|
152
|
+
this.#exchangeProvider = exchangeProvider;
|
|
145
153
|
this.#nodeStore = nodeStore;
|
|
154
|
+
this.#subscriptionClient = subscriptionClient;
|
|
146
155
|
this.#queue = queue;
|
|
147
|
-
|
|
148
|
-
const client = this.exchangeProvider.getProtocolHandler(INTERACTION_PROTOCOL_ID);
|
|
149
|
-
if (client === undefined || !(client instanceof SubscriptionClient)) {
|
|
150
|
-
throw new InternalError(
|
|
151
|
-
`Subscription protocol handler ${INTERACTION_PROTOCOL_ID} missing or unexpected type.`,
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
this.#subscriptionClient = client;
|
|
155
156
|
}
|
|
156
157
|
|
|
157
158
|
get channelUpdated() {
|
|
158
|
-
if (this
|
|
159
|
-
return this
|
|
159
|
+
if (this.#exchangeProvider instanceof ReconnectableExchangeProvider) {
|
|
160
|
+
return this.#exchangeProvider.channelUpdated;
|
|
160
161
|
}
|
|
161
162
|
throw new ImplementationError("ExchangeProvider does not support channelUpdated");
|
|
162
163
|
}
|
|
163
164
|
|
|
164
|
-
registerSubscriptionListener(subscriptionId: number, listener: (dataReport: DataReport) => MaybePromise<void>) {
|
|
165
|
-
this.#ownSubscriptionIds.add(subscriptionId);
|
|
166
|
-
this.#subscriptionClient.registerSubscriptionListener(subscriptionId, listener);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
165
|
removeSubscription(subscriptionId: number) {
|
|
170
166
|
this.#ownSubscriptionIds.delete(subscriptionId);
|
|
171
|
-
this.#subscriptionClient.
|
|
172
|
-
this.#subscriptionClient.removeSubscriptionUpdateTimer(subscriptionId);
|
|
167
|
+
this.#subscriptionClient.delete(subscriptionId);
|
|
173
168
|
}
|
|
174
169
|
|
|
175
170
|
async getAllAttributes(
|
|
@@ -259,10 +254,7 @@ export class InteractionClient {
|
|
|
259
254
|
isFabricFiltered?: boolean;
|
|
260
255
|
executeQueued?: boolean;
|
|
261
256
|
} = {},
|
|
262
|
-
): Promise<{
|
|
263
|
-
attributeReports: DecodedAttributeReportValue<any>[];
|
|
264
|
-
eventReports: DecodedEventReportValue<any>[];
|
|
265
|
-
}> {
|
|
257
|
+
): Promise<DecodedDataReport> {
|
|
266
258
|
const {
|
|
267
259
|
attributes: attributeRequests,
|
|
268
260
|
dataVersionFilters,
|
|
@@ -302,10 +294,7 @@ export class InteractionClient {
|
|
|
302
294
|
);
|
|
303
295
|
}
|
|
304
296
|
|
|
305
|
-
const result = await this.withMessenger
|
|
306
|
-
attributeReports: DecodedAttributeReportValue<any>[];
|
|
307
|
-
eventReports: DecodedEventReportValue<any>[];
|
|
308
|
-
}>(async messenger => {
|
|
297
|
+
const result = await this.withMessenger(async messenger => {
|
|
309
298
|
const { isFabricFiltered = true } = options;
|
|
310
299
|
return await this.processReadRequest(messenger, {
|
|
311
300
|
attributeRequests,
|
|
@@ -404,7 +393,7 @@ export class InteractionClient {
|
|
|
404
393
|
private async processReadRequest(
|
|
405
394
|
messenger: InteractionClientMessenger,
|
|
406
395
|
request: ReadRequest,
|
|
407
|
-
): Promise<
|
|
396
|
+
): Promise<DecodedDataReport> {
|
|
408
397
|
const { attributeRequests, eventRequests } = request;
|
|
409
398
|
logger.debug(
|
|
410
399
|
`Sending read request to ${messenger.getExchangeChannelName()} for attributes ${attributeRequests
|
|
@@ -415,10 +404,7 @@ export class InteractionClient {
|
|
|
415
404
|
const response = await messenger.sendReadRequest(request);
|
|
416
405
|
|
|
417
406
|
// Normalize and decode the response
|
|
418
|
-
const normalizedResult =
|
|
419
|
-
attributeReports: normalizeAndDecodeReadAttributeReport(response.attributeReports ?? []),
|
|
420
|
-
eventReports: normalizeAndDecodeReadEventReport(response.eventReports ?? []),
|
|
421
|
-
};
|
|
407
|
+
const normalizedResult = DecodedDataReport(response);
|
|
422
408
|
logger.debug(
|
|
423
409
|
`Received read response with attributes ${normalizedResult.attributeReports
|
|
424
410
|
.map(({ path, value }) => `${resolveAttributeName(path)} = ${Logger.toJSON(value)}`)
|
|
@@ -643,33 +629,39 @@ export class InteractionClient {
|
|
|
643
629
|
return;
|
|
644
630
|
}
|
|
645
631
|
|
|
646
|
-
const
|
|
632
|
+
const { attributeReports } = DecodedDataReport(dataReport);
|
|
647
633
|
|
|
648
|
-
if (
|
|
634
|
+
if (attributeReports.length === 0) {
|
|
649
635
|
throw new MatterFlowError("Subscription result reporting undefined/no value not specified");
|
|
650
636
|
}
|
|
651
|
-
if (
|
|
637
|
+
if (attributeReports.length > 1) {
|
|
652
638
|
throw new UnexpectedDataError("Unexpected response with more then one attribute");
|
|
653
639
|
}
|
|
654
|
-
const { value, version } =
|
|
640
|
+
const { value, version } = attributeReports[0];
|
|
655
641
|
if (value === undefined)
|
|
656
642
|
throw new MatterFlowError("Subscription result reporting undefined value not specified.");
|
|
657
643
|
|
|
658
|
-
await this.#nodeStore?.persistAttributes([
|
|
644
|
+
await this.#nodeStore?.persistAttributes([attributeReports[0]]);
|
|
659
645
|
|
|
660
646
|
listener?.(value, version);
|
|
661
647
|
};
|
|
662
648
|
|
|
663
|
-
this
|
|
664
|
-
|
|
665
|
-
|
|
649
|
+
await this.#registerSubscription(
|
|
650
|
+
{
|
|
651
|
+
id: subscriptionId,
|
|
666
652
|
maximumPeerResponseTime,
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
updateTimeoutHandler,
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
653
|
+
maxIntervalS: maxInterval,
|
|
654
|
+
onData: subscriptionListener,
|
|
655
|
+
onTimeout: updateTimeoutHandler,
|
|
656
|
+
},
|
|
657
|
+
report,
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
async #registerSubscription(subscription: RegisteredSubscription, initialReport: DataReport) {
|
|
662
|
+
this.#ownSubscriptionIds.add(subscription.id);
|
|
663
|
+
this.#subscriptionClient.add(subscription);
|
|
664
|
+
await subscription.onData(initialReport);
|
|
673
665
|
}
|
|
674
666
|
|
|
675
667
|
async subscribeEvent<T, E extends Event<T, any>>(options: {
|
|
@@ -736,30 +728,30 @@ export class InteractionClient {
|
|
|
736
728
|
return;
|
|
737
729
|
}
|
|
738
730
|
|
|
739
|
-
const
|
|
731
|
+
const { eventReports } = DecodedDataReport(dataReport);
|
|
740
732
|
|
|
741
|
-
if (
|
|
733
|
+
if (eventReports.length === 0) {
|
|
742
734
|
throw new MatterFlowError("Received empty subscription result value.");
|
|
743
735
|
}
|
|
744
|
-
if (
|
|
736
|
+
if (eventReports.length > 1) {
|
|
745
737
|
throw new UnexpectedDataError("Unexpected response with more then one attribute.");
|
|
746
738
|
}
|
|
747
|
-
const { events } =
|
|
739
|
+
const { events } = eventReports[0];
|
|
748
740
|
if (events === undefined)
|
|
749
741
|
throw new MatterFlowError("Subscription result reporting undefined value not specified.");
|
|
750
742
|
|
|
751
743
|
events.forEach(event => listener?.(event));
|
|
752
744
|
};
|
|
753
|
-
this
|
|
754
|
-
|
|
755
|
-
|
|
745
|
+
await this.#registerSubscription(
|
|
746
|
+
{
|
|
747
|
+
id: subscriptionId,
|
|
756
748
|
maximumPeerResponseTime,
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
updateTimeoutHandler,
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
749
|
+
maxIntervalS: maxInterval,
|
|
750
|
+
onData: subscriptionListener,
|
|
751
|
+
onTimeout: updateTimeoutHandler,
|
|
752
|
+
},
|
|
753
|
+
report,
|
|
754
|
+
);
|
|
763
755
|
}
|
|
764
756
|
|
|
765
757
|
async subscribeAllAttributesAndEvents(options: {
|
|
@@ -957,39 +949,21 @@ export class InteractionClient {
|
|
|
957
949
|
}
|
|
958
950
|
}
|
|
959
951
|
};
|
|
960
|
-
this.registerSubscriptionListener(subscriptionId, async dataReport => {
|
|
961
|
-
await subscriptionListener({
|
|
962
|
-
...dataReport,
|
|
963
|
-
attributeReports:
|
|
964
|
-
dataReport.attributeReports !== undefined
|
|
965
|
-
? normalizeAndDecodeReadAttributeReport(dataReport.attributeReports)
|
|
966
|
-
: undefined,
|
|
967
|
-
eventReports:
|
|
968
|
-
dataReport.eventReports !== undefined
|
|
969
|
-
? normalizeAndDecodeReadEventReport(dataReport.eventReports)
|
|
970
|
-
: undefined,
|
|
971
|
-
});
|
|
972
|
-
});
|
|
973
952
|
|
|
974
|
-
|
|
975
|
-
|
|
953
|
+
const seedReport = DecodedDataReport(report);
|
|
954
|
+
|
|
955
|
+
await this.#registerSubscription(
|
|
956
|
+
{
|
|
957
|
+
id: subscriptionId,
|
|
976
958
|
maximumPeerResponseTime,
|
|
977
|
-
|
|
978
|
-
maxInterval,
|
|
979
|
-
updateTimeoutHandler,
|
|
980
|
-
);
|
|
981
|
-
}
|
|
959
|
+
maxIntervalS: maxInterval,
|
|
982
960
|
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
report.eventReports !== undefined ? normalizeAndDecodeReadEventReport(report.eventReports) : undefined,
|
|
990
|
-
subscriptionId,
|
|
991
|
-
};
|
|
992
|
-
await subscriptionListener(seedReport);
|
|
961
|
+
onData: dataReport => subscriptionListener(DecodedDataReport(dataReport)),
|
|
962
|
+
|
|
963
|
+
onTimeout: updateTimeoutHandler,
|
|
964
|
+
},
|
|
965
|
+
seedReport,
|
|
966
|
+
);
|
|
993
967
|
|
|
994
968
|
if (dataVersionFilters !== undefined && dataVersionFilters.length > 0 && enrichCachedAttributeData) {
|
|
995
969
|
this.#enrichCachedAttributeData(seedReport.attributeReports ?? [], dataVersionFilters);
|
|
@@ -1164,7 +1138,7 @@ export class InteractionClient {
|
|
|
1164
1138
|
invoke: (messenger: InteractionClientMessenger) => Promise<T>,
|
|
1165
1139
|
executeQueued = false,
|
|
1166
1140
|
): Promise<T> {
|
|
1167
|
-
const messenger = await InteractionClientMessenger.create(this
|
|
1141
|
+
const messenger = await InteractionClientMessenger.create(this.#exchangeProvider);
|
|
1168
1142
|
let result: T;
|
|
1169
1143
|
try {
|
|
1170
1144
|
if (executeQueued) {
|
|
@@ -1181,27 +1155,6 @@ export class InteractionClient {
|
|
|
1181
1155
|
return result;
|
|
1182
1156
|
}
|
|
1183
1157
|
|
|
1184
|
-
private registerSubscriptionUpdateTimer(
|
|
1185
|
-
maximumPeerResponseTime: number,
|
|
1186
|
-
subscriptionId: number,
|
|
1187
|
-
maxIntervalS: number,
|
|
1188
|
-
updateTimeoutHandler: Timer.Callback,
|
|
1189
|
-
) {
|
|
1190
|
-
if (!this.#ownSubscriptionIds.has(subscriptionId)) {
|
|
1191
|
-
throw new MatterFlowError(
|
|
1192
|
-
`Cannot register update timer for subscription ${subscriptionId} because it is not owned by this client.`,
|
|
1193
|
-
);
|
|
1194
|
-
}
|
|
1195
|
-
const maxIntervalMs = maxIntervalS * 1000 + maximumPeerResponseTime;
|
|
1196
|
-
|
|
1197
|
-
const timer = Time.getTimer("Subscription timeout", maxIntervalMs, () => {
|
|
1198
|
-
logger.info(`Subscription ${subscriptionId} timed out after ${maxIntervalMs}ms ...`);
|
|
1199
|
-
this.removeSubscription(subscriptionId);
|
|
1200
|
-
updateTimeoutHandler();
|
|
1201
|
-
}).start();
|
|
1202
|
-
this.#subscriptionClient.registerSubscriptionUpdateTimer(subscriptionId, timer);
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
1158
|
removeAllSubscriptions() {
|
|
1206
1159
|
for (const subscriptionId of this.#ownSubscriptionIds) {
|
|
1207
1160
|
this.removeSubscription(subscriptionId);
|
|
@@ -1213,11 +1166,11 @@ export class InteractionClient {
|
|
|
1213
1166
|
}
|
|
1214
1167
|
|
|
1215
1168
|
get session() {
|
|
1216
|
-
return this
|
|
1169
|
+
return this.#exchangeProvider.session;
|
|
1217
1170
|
}
|
|
1218
1171
|
|
|
1219
1172
|
get channelType() {
|
|
1220
|
-
return this
|
|
1173
|
+
return this.#exchangeProvider.channelType;
|
|
1221
1174
|
}
|
|
1222
1175
|
|
|
1223
1176
|
/** Enrich cached data to get complete responses when data version filters were used. */
|