@matter/protocol 0.13.1-alpha.0-20250515-a4c61c546 → 0.13.1-alpha.0-20250517-99a1e848a
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/Interactable.d.ts +5 -1
- package/dist/cjs/action/Interactable.d.ts.map +1 -1
- package/dist/cjs/action/client/ClientInteraction.d.ts +3 -4
- package/dist/cjs/action/client/ClientInteraction.d.ts.map +1 -1
- package/dist/cjs/action/client/ClientInteraction.js +28 -16
- package/dist/cjs/action/client/ClientInteraction.js.map +1 -1
- package/dist/cjs/action/protocols.d.ts +7 -2
- package/dist/cjs/action/protocols.d.ts.map +1 -1
- package/dist/cjs/action/request/Write.d.ts +43 -2
- package/dist/cjs/action/request/Write.d.ts.map +1 -1
- package/dist/cjs/action/request/Write.js +74 -0
- package/dist/cjs/action/request/Write.js.map +2 -2
- package/dist/cjs/action/response/InvokeResult.d.ts +1 -2
- package/dist/cjs/action/response/InvokeResult.d.ts.map +1 -1
- package/dist/cjs/action/response/ReadResult.d.ts +5 -14
- package/dist/cjs/action/response/ReadResult.d.ts.map +1 -1
- package/dist/cjs/action/response/WriteResult.d.ts +19 -5
- package/dist/cjs/action/response/WriteResult.d.ts.map +1 -1
- package/dist/cjs/action/server/AccessControl.js +4 -4
- package/dist/cjs/action/server/AccessControl.js.map +1 -1
- package/dist/cjs/action/server/{AttributeResponse.d.ts → AttributeReadResponse.d.ts} +4 -4
- package/dist/cjs/action/server/AttributeReadResponse.d.ts.map +1 -0
- package/dist/cjs/action/server/{AttributeResponse.js → AttributeReadResponse.js} +12 -12
- package/dist/cjs/action/server/{AttributeResponse.js.map → AttributeReadResponse.js.map} +2 -2
- package/dist/cjs/action/server/AttributeSubscriptionResponse.d.ts +4 -4
- package/dist/cjs/action/server/AttributeSubscriptionResponse.d.ts.map +1 -1
- package/dist/cjs/action/server/AttributeSubscriptionResponse.js +2 -2
- package/dist/cjs/action/server/AttributeSubscriptionResponse.js.map +1 -1
- package/dist/cjs/action/server/AttributeWriteResponse.d.ts +28 -0
- package/dist/cjs/action/server/AttributeWriteResponse.d.ts.map +1 -0
- package/dist/cjs/action/server/AttributeWriteResponse.js +349 -0
- package/dist/cjs/action/server/AttributeWriteResponse.js.map +6 -0
- package/dist/cjs/action/server/DataResponse.d.ts +4 -3
- package/dist/cjs/action/server/DataResponse.d.ts.map +1 -1
- package/dist/cjs/action/server/DataResponse.js +1 -1
- package/dist/cjs/action/server/DataResponse.js.map +1 -1
- package/dist/cjs/action/server/{EventResponse.d.ts → EventReadResponse.d.ts} +4 -4
- package/dist/cjs/action/server/EventReadResponse.d.ts.map +1 -0
- package/dist/cjs/action/server/{EventResponse.js → EventReadResponse.js} +8 -8
- package/dist/cjs/action/server/EventReadResponse.js.map +6 -0
- package/dist/cjs/action/server/ServerInteraction.d.ts +3 -4
- package/dist/cjs/action/server/ServerInteraction.d.ts.map +1 -1
- package/dist/cjs/action/server/ServerInteraction.js +12 -10
- package/dist/cjs/action/server/ServerInteraction.js.map +1 -1
- package/dist/cjs/action/server/index.d.ts +3 -2
- package/dist/cjs/action/server/index.d.ts.map +1 -1
- package/dist/cjs/action/server/index.js +3 -2
- package/dist/cjs/action/server/index.js.map +1 -1
- package/dist/cjs/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionClient.js +12 -1
- package/dist/cjs/interaction/InteractionClient.js.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.js +8 -3
- package/dist/cjs/interaction/InteractionMessenger.js.map +1 -1
- package/dist/esm/action/Interactable.d.ts +5 -1
- package/dist/esm/action/Interactable.d.ts.map +1 -1
- package/dist/esm/action/client/ClientInteraction.d.ts +3 -4
- package/dist/esm/action/client/ClientInteraction.d.ts.map +1 -1
- package/dist/esm/action/client/ClientInteraction.js +29 -17
- package/dist/esm/action/client/ClientInteraction.js.map +1 -1
- package/dist/esm/action/protocols.d.ts +7 -2
- package/dist/esm/action/protocols.d.ts.map +1 -1
- package/dist/esm/action/request/Write.d.ts +43 -2
- package/dist/esm/action/request/Write.d.ts.map +1 -1
- package/dist/esm/action/request/Write.js +70 -0
- package/dist/esm/action/request/Write.js.map +2 -2
- package/dist/esm/action/response/InvokeResult.d.ts +1 -2
- package/dist/esm/action/response/InvokeResult.d.ts.map +1 -1
- package/dist/esm/action/response/ReadResult.d.ts +5 -14
- package/dist/esm/action/response/ReadResult.d.ts.map +1 -1
- package/dist/esm/action/response/WriteResult.d.ts +19 -5
- package/dist/esm/action/response/WriteResult.d.ts.map +1 -1
- package/dist/esm/action/server/AccessControl.js +4 -4
- package/dist/esm/action/server/AccessControl.js.map +1 -1
- package/dist/esm/action/server/{AttributeResponse.d.ts → AttributeReadResponse.d.ts} +4 -4
- package/dist/esm/action/server/AttributeReadResponse.d.ts.map +1 -0
- package/dist/esm/action/server/{AttributeResponse.js → AttributeReadResponse.js} +9 -9
- package/dist/esm/action/server/{AttributeResponse.js.map → AttributeReadResponse.js.map} +2 -2
- package/dist/esm/action/server/AttributeSubscriptionResponse.d.ts +4 -4
- package/dist/esm/action/server/AttributeSubscriptionResponse.d.ts.map +1 -1
- package/dist/esm/action/server/AttributeSubscriptionResponse.js +2 -2
- package/dist/esm/action/server/AttributeSubscriptionResponse.js.map +1 -1
- package/dist/esm/action/server/AttributeWriteResponse.d.ts +28 -0
- package/dist/esm/action/server/AttributeWriteResponse.d.ts.map +1 -0
- package/dist/esm/action/server/AttributeWriteResponse.js +335 -0
- package/dist/esm/action/server/AttributeWriteResponse.js.map +6 -0
- package/dist/esm/action/server/DataResponse.d.ts +4 -3
- package/dist/esm/action/server/DataResponse.d.ts.map +1 -1
- package/dist/esm/action/server/DataResponse.js +1 -1
- package/dist/esm/action/server/DataResponse.js.map +1 -1
- package/dist/esm/action/server/{EventResponse.d.ts → EventReadResponse.d.ts} +4 -4
- package/dist/esm/action/server/EventReadResponse.d.ts.map +1 -0
- package/dist/esm/action/server/{EventResponse.js → EventReadResponse.js} +5 -5
- package/dist/esm/action/server/EventReadResponse.js.map +6 -0
- package/dist/esm/action/server/ServerInteraction.d.ts +3 -4
- package/dist/esm/action/server/ServerInteraction.d.ts.map +1 -1
- package/dist/esm/action/server/ServerInteraction.js +12 -10
- package/dist/esm/action/server/ServerInteraction.js.map +1 -1
- package/dist/esm/action/server/index.d.ts +3 -2
- package/dist/esm/action/server/index.d.ts.map +1 -1
- package/dist/esm/action/server/index.js +3 -2
- package/dist/esm/action/server/index.js.map +1 -1
- package/dist/esm/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionClient.js +12 -1
- package/dist/esm/interaction/InteractionClient.js.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.js +8 -3
- package/dist/esm/interaction/InteractionMessenger.js.map +1 -1
- package/package.json +6 -6
- package/src/action/Interactable.ts +6 -1
- package/src/action/client/ClientInteraction.ts +31 -23
- package/src/action/protocols.ts +8 -2
- package/src/action/request/Write.ts +127 -4
- package/src/action/response/InvokeResult.ts +1 -2
- package/src/action/response/ReadResult.ts +5 -22
- package/src/action/response/WriteResult.ts +21 -5
- package/src/action/server/AccessControl.ts +4 -4
- package/src/action/server/{AttributeResponse.ts → AttributeReadResponse.ts} +14 -13
- package/src/action/server/AttributeSubscriptionResponse.ts +5 -5
- package/src/action/server/AttributeWriteResponse.ts +437 -0
- package/src/action/server/DataResponse.ts +5 -4
- package/src/action/server/{EventResponse.ts → EventReadResponse.ts} +6 -5
- package/src/action/server/ServerInteraction.ts +16 -14
- package/src/action/server/index.ts +3 -2
- package/src/interaction/InteractionClient.ts +20 -1
- package/src/interaction/InteractionMessenger.ts +8 -3
- package/dist/cjs/action/server/AttributeResponse.d.ts.map +0 -1
- package/dist/cjs/action/server/EventResponse.d.ts.map +0 -1
- package/dist/cjs/action/server/EventResponse.js.map +0 -6
- package/dist/esm/action/server/AttributeResponse.d.ts.map +0 -1
- package/dist/esm/action/server/EventResponse.d.ts.map +0 -1
- package/dist/esm/action/server/EventResponse.js.map +0 -6
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { Interactable } from "#action/Interactable.js";
|
|
7
|
+
import { Interactable, InteractionSession } from "#action/Interactable.js";
|
|
8
8
|
import { Invoke } from "#action/request/Invoke.js";
|
|
9
9
|
import { Read } from "#action/request/Read.js";
|
|
10
10
|
import { Subscribe } from "#action/request/Subscribe.js";
|
|
@@ -13,13 +13,11 @@ import { InvokeResult } from "#action/response/InvokeResult.js";
|
|
|
13
13
|
import { ReadResult } from "#action/response/ReadResult.js";
|
|
14
14
|
import { SubscribeResult } from "#action/response/SubscribeResult.js";
|
|
15
15
|
import { WriteResult } from "#action/response/WriteResult.js";
|
|
16
|
-
import {
|
|
17
|
-
import { CancelablePromise, Environment, Environmental, NotImplementedError, PromiseQueue } from "#general";
|
|
16
|
+
import { Environment, Environmental, NotImplementedError, PromiseQueue } from "#general";
|
|
18
17
|
import { InteractionClientMessenger } from "#interaction/InteractionMessenger.js";
|
|
19
18
|
import { SubscriptionClient } from "#interaction/SubscriptionClient.js";
|
|
20
19
|
import { InteractionQueue } from "#peer/InteractionQueue.js";
|
|
21
20
|
import { ExchangeProvider } from "#protocol/ExchangeProvider.js";
|
|
22
|
-
import { WriteResponse } from "#types";
|
|
23
21
|
|
|
24
22
|
export interface ClientInteractableContext {
|
|
25
23
|
exchanges: ExchangeProvider;
|
|
@@ -30,7 +28,7 @@ export interface ClientInteractableContext {
|
|
|
30
28
|
/**
|
|
31
29
|
* This is a WIP and currently largely a stub.
|
|
32
30
|
*/
|
|
33
|
-
export class ClientInteraction<SessionT extends
|
|
31
|
+
export class ClientInteraction<SessionT extends InteractionSession = InteractionSession>
|
|
34
32
|
implements Interactable<SessionT>
|
|
35
33
|
{
|
|
36
34
|
readonly #exchanges: ExchangeProvider;
|
|
@@ -66,28 +64,38 @@ export class ClientInteraction<SessionT extends AccessControl.Session = AccessCo
|
|
|
66
64
|
throw new NotImplementedError();
|
|
67
65
|
}
|
|
68
66
|
|
|
69
|
-
write<T extends Write>(request: T, _session?: SessionT) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
67
|
+
async write<T extends Write>(request: T, _session?: SessionT): WriteResult<T> {
|
|
68
|
+
const messenger = await InteractionClientMessenger.create(this.#exchanges);
|
|
69
|
+
const response = await messenger.sendWriteCommand(request);
|
|
70
|
+
if (request.suppressResponse) {
|
|
71
|
+
return undefined as Awaited<WriteResult<T>>;
|
|
72
|
+
}
|
|
73
|
+
if (!response || !response.writeResponses?.length) {
|
|
74
|
+
return new Array<WriteResult.AttributeStatus>() as Awaited<WriteResult<T>>;
|
|
75
|
+
} else {
|
|
76
|
+
return response.writeResponses.map(
|
|
77
|
+
({
|
|
78
|
+
path: { nodeId, endpointId, clusterId, attributeId, listIndex },
|
|
79
|
+
status: { status, clusterStatus },
|
|
80
|
+
}) => ({
|
|
81
|
+
kind: "attr-status",
|
|
82
|
+
path: {
|
|
83
|
+
nodeId,
|
|
84
|
+
endpointId: endpointId!,
|
|
85
|
+
clusterId: clusterId!,
|
|
86
|
+
attributeId: attributeId!,
|
|
87
|
+
listIndex,
|
|
88
|
+
},
|
|
89
|
+
status: status!,
|
|
90
|
+
clusterStatus,
|
|
91
|
+
}),
|
|
92
|
+
) as Awaited<WriteResult<T>>;
|
|
93
|
+
}
|
|
86
94
|
}
|
|
87
95
|
|
|
88
96
|
invoke<T extends Invoke>(request: Invoke, _session?: SessionT): InvokeResult<T> {
|
|
89
97
|
if (request.suppressResponse) {
|
|
90
|
-
return new
|
|
98
|
+
return new Promise<void>((resolve, reject) => {
|
|
91
99
|
InteractionClientMessenger.create(this.#exchanges)
|
|
92
100
|
.then(messenger =>
|
|
93
101
|
messenger
|
package/src/action/protocols.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { InteractionSession } from "#action/Interactable.js";
|
|
7
8
|
import { OccurrenceManager } from "#events/OccurrenceManager.js";
|
|
8
9
|
import { MaybePromise, Observable } from "#general";
|
|
9
10
|
import { DataModelPath, MatterModel } from "#model";
|
|
@@ -106,12 +107,17 @@ export interface ClusterProtocol {
|
|
|
106
107
|
stateChanged: Observable<[changes: AttributeId[], version: number], MaybePromise>;
|
|
107
108
|
|
|
108
109
|
/**
|
|
109
|
-
*
|
|
110
|
+
* Read-only state of the cluster
|
|
111
|
+
*/
|
|
112
|
+
readState(session: InteractionSession): Val.ProtocolStruct;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Writeable record of attribute values, keyed by attribute ID.
|
|
110
116
|
*
|
|
111
117
|
* Note that current protocol implementations do not filter data within this responsibility based on the
|
|
112
118
|
* session. So doing is the responsibility of the node implementation.
|
|
113
119
|
*/
|
|
114
|
-
|
|
120
|
+
openForWrite(session: InteractionSession): Promise<Val.ProtocolStruct>;
|
|
115
121
|
}
|
|
116
122
|
|
|
117
123
|
/**
|
|
@@ -4,10 +4,133 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { FALLBACK_INTERACTIONMODEL_REVISION } from "#session/Session.js";
|
|
8
|
+
import { AttributeData, ClusterType, WriteRequest } from "#types";
|
|
9
|
+
import { MalformedRequestError } from "./MalformedRequestError.js";
|
|
10
|
+
import { Specifier } from "./Specifier.js";
|
|
8
11
|
|
|
9
|
-
export interface Write extends WriteRequest {
|
|
10
|
-
|
|
12
|
+
export interface Write extends WriteRequest {}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Formulate a write-request using Matter numeric IDs.
|
|
16
|
+
*/
|
|
17
|
+
export function Write(options: Write.Options): Write;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Formulate a write-request with extended options and name-based IDs.
|
|
21
|
+
*/
|
|
22
|
+
export function Write(options: Write.Options, ...data: Write.Attribute[]): Write;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Formulate a write-request with name-based IDs.
|
|
26
|
+
*/
|
|
27
|
+
export function Write(...data: Write.Attribute[]): Write;
|
|
28
|
+
|
|
29
|
+
export function Write(optionsOrData: Write.Options | Write.Attribute, ...data: Write.Attribute[]): Write {
|
|
30
|
+
let options;
|
|
31
|
+
if ("kind" in optionsOrData) {
|
|
32
|
+
data = [optionsOrData, ...data];
|
|
33
|
+
options = {};
|
|
34
|
+
} else {
|
|
35
|
+
options = optionsOrData;
|
|
36
|
+
}
|
|
37
|
+
const { writes: writeRequests = [] } = options;
|
|
38
|
+
|
|
39
|
+
const result: Write = {
|
|
40
|
+
timedRequest: !!options.timed || !!options.timeout,
|
|
41
|
+
writeRequests,
|
|
42
|
+
interactionModelRevision: options.interactionModelRevision ?? FALLBACK_INTERACTIONMODEL_REVISION,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
for (const entry of data) {
|
|
46
|
+
reifyData(entry);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!writeRequests.length) {
|
|
50
|
+
throw new MalformedRequestError(`Write action contains no attributes to write`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return result;
|
|
54
|
+
|
|
55
|
+
function reifyData(data: Write.Attribute) {
|
|
56
|
+
const cluster = Specifier.clusterOf(data);
|
|
57
|
+
|
|
58
|
+
if (cluster === undefined) {
|
|
59
|
+
throw new MalformedRequestError(`Write action must specify a cluster`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let { attributes } = data;
|
|
63
|
+
if (attributes === undefined) {
|
|
64
|
+
throw new MalformedRequestError(`Write action must specify an attribute`);
|
|
65
|
+
}
|
|
66
|
+
if (!Array.isArray(attributes)) {
|
|
67
|
+
attributes = [attributes];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const { endpoint, value, version: dataVersion } = data;
|
|
71
|
+
|
|
72
|
+
// Configure base AttributePath
|
|
73
|
+
const prototype: Omit<AttributeData, "data"> = {
|
|
74
|
+
path: {
|
|
75
|
+
endpointId: endpoint !== undefined ? Specifier.endpointIdOf(data) : undefined,
|
|
76
|
+
clusterId: cluster.id,
|
|
77
|
+
attributeId: undefined,
|
|
78
|
+
},
|
|
79
|
+
dataVersion,
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
for (const specifier of attributes) {
|
|
83
|
+
const attribute = Specifier.attributeFor(cluster, specifier);
|
|
84
|
+
writeRequests.push({
|
|
85
|
+
...prototype,
|
|
86
|
+
path: {
|
|
87
|
+
...prototype.path,
|
|
88
|
+
attributeId: attribute.id,
|
|
89
|
+
},
|
|
90
|
+
data: attribute.schema.encodeTlv(value, { forWriteInteraction: true }),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
11
94
|
}
|
|
12
95
|
|
|
13
|
-
|
|
96
|
+
export namespace Write {
|
|
97
|
+
export interface Options {
|
|
98
|
+
writes?: AttributeData[];
|
|
99
|
+
timed?: boolean;
|
|
100
|
+
timeout?: number;
|
|
101
|
+
interactionModelRevision?: number;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Selects attributes to Write. Limits fields to legal permutations per the Matter specification.
|
|
106
|
+
*/
|
|
107
|
+
export type Attribute<C extends Specifier.Cluster = Specifier.Cluster> = (
|
|
108
|
+
| Attribute.Concrete<C>
|
|
109
|
+
| Attribute.WildcardEndpoint<C>
|
|
110
|
+
) & {
|
|
111
|
+
kind: "attribute";
|
|
112
|
+
value: any;
|
|
113
|
+
version?: number;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export function Attribute<const C extends ClusterType>(data: Omit<Attribute<C>, "kind">): Attribute<C> {
|
|
117
|
+
return {
|
|
118
|
+
kind: "attribute",
|
|
119
|
+
...data,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export namespace Attribute {
|
|
124
|
+
export interface Concrete<C extends Specifier.Cluster> {
|
|
125
|
+
endpoint: Specifier.Endpoint;
|
|
126
|
+
cluster: C;
|
|
127
|
+
attributes: Specifier.Attribute<Specifier.ClusterFor<C>> | Specifier.Attribute<Specifier.ClusterFor<C>>[];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export interface WildcardEndpoint<C extends Specifier.Cluster> {
|
|
131
|
+
endpoint?: undefined;
|
|
132
|
+
cluster: C;
|
|
133
|
+
attributes: Specifier.Attribute<Specifier.ClusterFor<C>> | Specifier.Attribute<Specifier.ClusterFor<C>>[];
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -6,10 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
import type { Invoke } from "#action/request/Invoke.js";
|
|
8
8
|
import type { CommandData } from "#types";
|
|
9
|
-
import { CancelablePromise } from "@matter/general";
|
|
10
9
|
|
|
11
10
|
export type InvokeResult<T extends Invoke> = T extends { suppressResponse: true }
|
|
12
|
-
?
|
|
11
|
+
? Promise<void>
|
|
13
12
|
: AsyncIterable<InvokeResult.Chunk>;
|
|
14
13
|
|
|
15
14
|
export namespace InvokeResult {
|
|
@@ -33,13 +33,7 @@ export interface ReadResult<Chunk = ReadResult.Chunk> extends AsyncIterable<Read
|
|
|
33
33
|
export namespace ReadResult {
|
|
34
34
|
export type Chunk = Iterable<Report>;
|
|
35
35
|
|
|
36
|
-
export type Report =
|
|
37
|
-
| AttributeValue
|
|
38
|
-
| GlobalAttributeStatus
|
|
39
|
-
| ClusterAttributeStatus
|
|
40
|
-
| EventValue
|
|
41
|
-
| GlobalEventStatus
|
|
42
|
-
| ClusterEventStatus;
|
|
36
|
+
export type Report = AttributeValue | AttributeStatus | EventValue | EventStatus;
|
|
43
37
|
|
|
44
38
|
export interface ConcreteAttributePath extends AttributePath {
|
|
45
39
|
nodeId?: NodeId;
|
|
@@ -56,17 +50,11 @@ export namespace ReadResult {
|
|
|
56
50
|
tlv: TlvSchema<unknown>;
|
|
57
51
|
}
|
|
58
52
|
|
|
59
|
-
export interface
|
|
53
|
+
export interface AttributeStatus {
|
|
60
54
|
kind: "attr-status";
|
|
61
55
|
path: ConcreteAttributePath;
|
|
62
56
|
status: StatusCode;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
export interface ClusterAttributeStatus {
|
|
66
|
-
kind: "attr-cluster-status";
|
|
67
|
-
path: ConcreteAttributePath;
|
|
68
|
-
status: number;
|
|
69
|
-
clusterStatus: number;
|
|
57
|
+
clusterStatus?: number;
|
|
70
58
|
}
|
|
71
59
|
|
|
72
60
|
export interface ConcreteEventPath extends EventPath {
|
|
@@ -86,15 +74,10 @@ export namespace ReadResult {
|
|
|
86
74
|
tlv: TlvSchema<unknown>;
|
|
87
75
|
}
|
|
88
76
|
|
|
89
|
-
export interface
|
|
77
|
+
export interface EventStatus {
|
|
90
78
|
kind: "event-status";
|
|
91
79
|
path: ConcreteEventPath;
|
|
92
80
|
status: Status;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
export interface ClusterEventStatus {
|
|
96
|
-
kind: "event-cluster-status";
|
|
97
|
-
path: ConcreteEventPath;
|
|
98
|
-
clusterStatus: number;
|
|
81
|
+
clusterStatus?: number;
|
|
99
82
|
}
|
|
100
83
|
}
|
|
@@ -4,10 +4,26 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import
|
|
8
|
-
import type {
|
|
9
|
-
import type { WriteResponse } from "#types";
|
|
7
|
+
import { Write } from "#action/request/Write.js";
|
|
8
|
+
import type { AttributeId, AttributePath, ClusterId, EndpointNumber, NodeId, StatusCode } from "#types";
|
|
10
9
|
|
|
11
|
-
export type WriteResult<T extends Write> =
|
|
12
|
-
T extends { suppressResponse: true } ? void :
|
|
10
|
+
export type WriteResult<T extends Write> = Promise<
|
|
11
|
+
T extends { suppressResponse: true } ? void : WriteResult.AttributeStatus[]
|
|
13
12
|
>;
|
|
13
|
+
|
|
14
|
+
export namespace WriteResult {
|
|
15
|
+
export interface ConcreteAttributePath extends AttributePath {
|
|
16
|
+
nodeId?: NodeId;
|
|
17
|
+
endpointId: EndpointNumber;
|
|
18
|
+
clusterId: ClusterId;
|
|
19
|
+
attributeId: AttributeId;
|
|
20
|
+
listIndex?: number | null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface AttributeStatus {
|
|
24
|
+
kind: "attr-status";
|
|
25
|
+
path: ConcreteAttributePath;
|
|
26
|
+
status: StatusCode;
|
|
27
|
+
clusterStatus?: number;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -286,7 +286,7 @@ function dataEnforcerFor(schema: Schema): AccessControl {
|
|
|
286
286
|
);
|
|
287
287
|
}
|
|
288
288
|
|
|
289
|
-
if (location?.owningFabric && location.owningFabric !== session.fabric) {
|
|
289
|
+
if (location?.owningFabric !== undefined && location.owningFabric !== session.fabric) {
|
|
290
290
|
throw new ReadError(
|
|
291
291
|
location,
|
|
292
292
|
"Permission denied: Owning/accessing fabric mismatch",
|
|
@@ -307,7 +307,7 @@ function dataEnforcerFor(schema: Schema): AccessControl {
|
|
|
307
307
|
return false;
|
|
308
308
|
}
|
|
309
309
|
|
|
310
|
-
if (location?.owningFabric && location.owningFabric !== session.fabric) {
|
|
310
|
+
if (location?.owningFabric !== undefined && location.owningFabric !== session.fabric) {
|
|
311
311
|
return false;
|
|
312
312
|
}
|
|
313
313
|
|
|
@@ -323,7 +323,7 @@ function dataEnforcerFor(schema: Schema): AccessControl {
|
|
|
323
323
|
throw new WriteError(location, "Permission denied: No accessing fabric", StatusCode.UnsupportedAccess);
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
-
if (location?.owningFabric && location.owningFabric !== session.fabric) {
|
|
326
|
+
if (location?.owningFabric !== undefined && location.owningFabric !== session.fabric) {
|
|
327
327
|
throw new WriteError(location, "Permission denied: Owning/accessing fabric mismatch");
|
|
328
328
|
}
|
|
329
329
|
|
|
@@ -339,7 +339,7 @@ function dataEnforcerFor(schema: Schema): AccessControl {
|
|
|
339
339
|
return false;
|
|
340
340
|
}
|
|
341
341
|
|
|
342
|
-
if (location?.owningFabric && location.owningFabric !== session.fabric) {
|
|
342
|
+
if (location?.owningFabric !== undefined && location.owningFabric !== session.fabric) {
|
|
343
343
|
return false;
|
|
344
344
|
}
|
|
345
345
|
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { InteractionSession } from "#action/index.js";
|
|
7
8
|
import { AttributeTypeProtocol, ClusterProtocol, EndpointProtocol, NodeProtocol } from "#action/protocols.js";
|
|
8
9
|
import { Read } from "#action/request/Read.js";
|
|
9
10
|
import { ReadResult } from "#action/response/ReadResult.js";
|
|
@@ -24,7 +25,7 @@ import {
|
|
|
24
25
|
} from "#types";
|
|
25
26
|
import { StatusCode } from "@matter/types";
|
|
26
27
|
|
|
27
|
-
const logger = Logger.get("
|
|
28
|
+
const logger = Logger.get("AttributeReadResponse");
|
|
28
29
|
|
|
29
30
|
export const GlobalAttrIds = new Set(Object.values(GlobalAttributes({})).map(attr => attr.id));
|
|
30
31
|
|
|
@@ -33,14 +34,14 @@ export const GlobalAttrIds = new Set(Object.values(GlobalAttributes({})).map(att
|
|
|
33
34
|
*
|
|
34
35
|
* TODO - profile; ensure nested functions are properly JITed and/or inlined
|
|
35
36
|
*/
|
|
36
|
-
export class
|
|
37
|
-
SessionT extends
|
|
37
|
+
export class AttributeReadResponse<
|
|
38
|
+
SessionT extends InteractionSession = InteractionSession,
|
|
38
39
|
> extends DataResponse<SessionT> {
|
|
39
40
|
#versions?: Record<EndpointNumber, Record<ClusterId, number>>;
|
|
40
41
|
|
|
41
42
|
// Each input AttributePathIB that does not have an error installs a producer. Producers run after validation and
|
|
42
43
|
// generate actual attribute data
|
|
43
|
-
#dataProducers?: Array<(this:
|
|
44
|
+
#dataProducers?: Array<(this: AttributeReadResponse) => Iterable<ReadResult.Chunk>>;
|
|
44
45
|
|
|
45
46
|
// The initial "chunk" may be a list of errors. As producers execute it is a set of records associated with the
|
|
46
47
|
// most recently touched endpoint. When the endpoint changes the previous chunk emits
|
|
@@ -124,7 +125,7 @@ export class AttributeResponse<
|
|
|
124
125
|
get counts() {
|
|
125
126
|
return {
|
|
126
127
|
status: this.#statusCount,
|
|
127
|
-
|
|
128
|
+
success: this.#valueCount,
|
|
128
129
|
existent: this.#valueCount + this.#filteredCount,
|
|
129
130
|
};
|
|
130
131
|
}
|
|
@@ -149,7 +150,7 @@ export class AttributeResponse<
|
|
|
149
150
|
const wpf = wildcardPathFlags ? WildcardPathFlagsCodec.encode(wildcardPathFlags) : 0;
|
|
150
151
|
|
|
151
152
|
if (endpointId === undefined) {
|
|
152
|
-
this.#addProducer(function* (this:
|
|
153
|
+
this.#addProducer(function* (this: AttributeReadResponse) {
|
|
153
154
|
this.#wildcardPathFlags = wpf;
|
|
154
155
|
for (const endpoint of this.node) {
|
|
155
156
|
yield* this.readEndpointForWildcard(endpoint, path);
|
|
@@ -160,7 +161,7 @@ export class AttributeResponse<
|
|
|
160
161
|
|
|
161
162
|
const endpoint = this.node[endpointId];
|
|
162
163
|
if (endpoint) {
|
|
163
|
-
this.#addProducer(function (this:
|
|
164
|
+
this.#addProducer(function (this: AttributeReadResponse) {
|
|
164
165
|
this.#wildcardPathFlags = wpf;
|
|
165
166
|
return this.readEndpointForWildcard(endpoint, path);
|
|
166
167
|
});
|
|
@@ -263,12 +264,12 @@ export class AttributeResponse<
|
|
|
263
264
|
}
|
|
264
265
|
this.#currentEndpoint = endpoint;
|
|
265
266
|
this.#currentCluster = cluster;
|
|
266
|
-
this.#currentState = cluster.
|
|
267
|
+
this.#currentState = cluster.readState(this.session);
|
|
267
268
|
} else if (this.#currentCluster !== cluster) {
|
|
268
269
|
this.#currentCluster = cluster;
|
|
269
|
-
this.#currentState = cluster.
|
|
270
|
+
this.#currentState = cluster.readState(this.session);
|
|
270
271
|
} else if (this.#currentState === undefined) {
|
|
271
|
-
this.#currentState = cluster.
|
|
272
|
+
this.#currentState = cluster.readState(this.session);
|
|
272
273
|
}
|
|
273
274
|
|
|
274
275
|
const value = this.#currentState[attributeId];
|
|
@@ -386,7 +387,7 @@ export class AttributeResponse<
|
|
|
386
387
|
}
|
|
387
388
|
|
|
388
389
|
if (this.#currentState === undefined) {
|
|
389
|
-
this.#currentState = this.#guardedCurrentCluster.
|
|
390
|
+
this.#currentState = this.#guardedCurrentCluster.readState(this.session);
|
|
390
391
|
}
|
|
391
392
|
const value = this.#currentState[attribute.id];
|
|
392
393
|
if (value === undefined) {
|
|
@@ -411,7 +412,7 @@ export class AttributeResponse<
|
|
|
411
412
|
/**
|
|
412
413
|
* Add a function that produces data. These functions are run after validation of input paths.
|
|
413
414
|
*/
|
|
414
|
-
#addProducer(producer: (this:
|
|
415
|
+
#addProducer(producer: (this: AttributeReadResponse) => Iterable<ReadResult.Chunk>) {
|
|
415
416
|
if (this.#dataProducers) {
|
|
416
417
|
this.#dataProducers.push(producer);
|
|
417
418
|
} else {
|
|
@@ -435,7 +436,7 @@ export class AttributeResponse<
|
|
|
435
436
|
() => `Error reading attribute ${this.node.inspectPath(path)}: Status=${StatusCode[status]}(${status})`,
|
|
436
437
|
);
|
|
437
438
|
|
|
438
|
-
const report: ReadResult.
|
|
439
|
+
const report: ReadResult.AttributeStatus = {
|
|
439
440
|
kind: "attr-status",
|
|
440
441
|
path,
|
|
441
442
|
status,
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
* Copyright 2022-2025 Project CHIP Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
import { InteractionSession } from "#action/index.js";
|
|
6
7
|
import { AttributeTypeProtocol, ClusterProtocol, EndpointProtocol, NodeProtocol } from "#action/protocols.js";
|
|
7
8
|
import { ReadResult } from "#action/response/ReadResult.js";
|
|
8
9
|
import { InternalError } from "#general";
|
|
9
10
|
import { AttributeId, AttributePath, ClusterId, EndpointNumber } from "#types";
|
|
10
|
-
import {
|
|
11
|
-
import { AttributeResponse } from "./AttributeResponse.js";
|
|
11
|
+
import { AttributeReadResponse } from "./AttributeReadResponse.js";
|
|
12
12
|
|
|
13
13
|
type ClusterFilter = {
|
|
14
14
|
[clusterId: ClusterId]: Set<AttributeId>;
|
|
@@ -18,12 +18,12 @@ export type AttributeResponseFilter = {
|
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* AttributeSubscriptionResponse is a specialized version of
|
|
21
|
+
* AttributeSubscriptionResponse is a specialized version of AttributeReadResponse that processes a read/subscribe request
|
|
22
22
|
* with a filter applied to the attributes. Only the attributes that match the filter will be processed.
|
|
23
23
|
*/
|
|
24
24
|
export class AttributeSubscriptionResponse<
|
|
25
|
-
SessionT extends
|
|
26
|
-
> extends
|
|
25
|
+
SessionT extends InteractionSession = InteractionSession,
|
|
26
|
+
> extends AttributeReadResponse<SessionT> {
|
|
27
27
|
#filter: AttributeResponseFilter;
|
|
28
28
|
#currentEndpointFilter?: ClusterFilter;
|
|
29
29
|
#currentClusterFilter?: Set<number>;
|