@project-chip/matter.js 0.9.1 → 0.9.2
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/model/models/AttributeModel.d.ts +1 -0
- package/dist/cjs/model/models/AttributeModel.d.ts.map +1 -1
- package/dist/cjs/model/models/AttributeModel.js +3 -1
- package/dist/cjs/model/models/AttributeModel.js.map +2 -2
- package/dist/cjs/node/server/TransactionalInteractionServer.d.ts.map +1 -1
- package/dist/cjs/node/server/TransactionalInteractionServer.js +15 -2
- package/dist/cjs/node/server/TransactionalInteractionServer.js.map +2 -2
- package/dist/cjs/protocol/ChannelManager.js +1 -1
- package/dist/cjs/protocol/ChannelManager.js.map +2 -2
- package/dist/cjs/protocol/interaction/InteractionServer.d.ts +6 -0
- package/dist/cjs/protocol/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/cjs/protocol/interaction/InteractionServer.js +75 -20
- package/dist/cjs/protocol/interaction/InteractionServer.js.map +2 -2
- package/dist/cjs/protocol/securechannel/SecureChannelProtocol.d.ts.map +1 -1
- package/dist/cjs/protocol/securechannel/SecureChannelProtocol.js +4 -2
- package/dist/cjs/protocol/securechannel/SecureChannelProtocol.js.map +2 -2
- package/dist/esm/model/models/AttributeModel.d.ts +1 -0
- package/dist/esm/model/models/AttributeModel.d.ts.map +1 -1
- package/dist/esm/model/models/AttributeModel.js +3 -1
- package/dist/esm/model/models/AttributeModel.js.map +2 -2
- package/dist/esm/node/server/TransactionalInteractionServer.d.ts.map +1 -1
- package/dist/esm/node/server/TransactionalInteractionServer.js +15 -2
- package/dist/esm/node/server/TransactionalInteractionServer.js.map +2 -2
- package/dist/esm/protocol/ChannelManager.js +1 -1
- package/dist/esm/protocol/ChannelManager.js.map +2 -2
- package/dist/esm/protocol/interaction/InteractionServer.d.ts +6 -0
- package/dist/esm/protocol/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/esm/protocol/interaction/InteractionServer.js +75 -20
- package/dist/esm/protocol/interaction/InteractionServer.js.map +2 -2
- package/dist/esm/protocol/securechannel/SecureChannelProtocol.d.ts.map +1 -1
- package/dist/esm/protocol/securechannel/SecureChannelProtocol.js +4 -2
- package/dist/esm/protocol/securechannel/SecureChannelProtocol.js.map +2 -2
- package/package.json +3 -3
- package/src/model/models/AttributeModel.ts +2 -0
- package/src/node/server/TransactionalInteractionServer.ts +21 -6
- package/src/protocol/ChannelManager.ts +1 -1
- package/src/protocol/interaction/InteractionServer.ts +87 -22
- package/src/protocol/securechannel/SecureChannelProtocol.ts +3 -1
|
@@ -7,6 +7,7 @@ import { Mei } from "../../datatype/ManufacturerExtensibleIdentifier.js";
|
|
|
7
7
|
import { ElementTag } from "../definitions/index.js";
|
|
8
8
|
import { AttributeElement } from "../elements/index.js";
|
|
9
9
|
import { PropertyModel } from "./PropertyModel.js";
|
|
10
|
+
export declare const GLOBAL_IDS: Set<number>;
|
|
10
11
|
export declare class AttributeModel extends PropertyModel implements AttributeElement {
|
|
11
12
|
tag: AttributeElement.Tag;
|
|
12
13
|
id: Mei;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AttributeModel.d.ts","sourceRoot":"","sources":["../../../../src/model/models/AttributeModel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,oDAAoD,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAW,MAAM,sBAAsB,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"AttributeModel.d.ts","sourceRoot":"","sources":["../../../../src/model/models/AttributeModel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,oDAAoD,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAW,MAAM,sBAAsB,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,eAAO,MAAM,UAAU,aAA4D,CAAC;AAQpF,qBAAa,cAAe,SAAQ,aAAc,YAAW,gBAAgB;IAChE,GAAG,EAAE,gBAAgB,CAAC,GAAG,CAAwB;IACjD,EAAE,EAAG,GAAG,CAAC;IAElB,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM;IAI1B,IAAa,iBAAiB,qBAI7B;IAED,IAAI,QAAQ,YAEX;IAED,IAAI,YAAY,YAEf;IAED,IAAI,KAAK,YAER;gBAEW,UAAU,EAAE,gBAAgB,CAAC,UAAU;IAQnD,MAAM,CAAC,GAAG,aAAwB;CACrC"}
|
|
@@ -18,7 +18,8 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var AttributeModel_exports = {};
|
|
20
20
|
__export(AttributeModel_exports, {
|
|
21
|
-
AttributeModel: () => AttributeModel
|
|
21
|
+
AttributeModel: () => AttributeModel,
|
|
22
|
+
GLOBAL_IDS: () => GLOBAL_IDS
|
|
22
23
|
});
|
|
23
24
|
module.exports = __toCommonJS(AttributeModel_exports);
|
|
24
25
|
var import_definitions = require("../definitions/index.js");
|
|
@@ -30,6 +31,7 @@ var import_PropertyModel = require("./PropertyModel.js");
|
|
|
30
31
|
* Copyright 2022-2024 Matter.js Authors
|
|
31
32
|
* SPDX-License-Identifier: Apache-2.0
|
|
32
33
|
*/
|
|
34
|
+
const GLOBAL_IDS = /* @__PURE__ */ new Set([65533, 65532, 65531, 65530, 65529, 65528]);
|
|
33
35
|
const globalIds = /* @__PURE__ */ new Set();
|
|
34
36
|
for (const element of Object.values(import_elements.Globals)) {
|
|
35
37
|
if (element.tag === import_definitions.ElementTag.Attribute) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/model/models/AttributeModel.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Mei } from \"../../datatype/ManufacturerExtensibleIdentifier.js\";\nimport { ElementTag } from \"../definitions/index.js\";\nimport { AttributeElement, Globals } from \"../elements/index.js\";\nimport { Model } from \"./Model.js\";\nimport { PropertyModel } from \"./PropertyModel.js\";\n\nconst globalIds = new Set<number>();\nfor (const element of Object.values(Globals)) {\n if (element.tag === ElementTag.Attribute) {\n globalIds.add(element.id);\n }\n}\n\nexport class AttributeModel extends PropertyModel implements AttributeElement {\n override tag: AttributeElement.Tag = AttributeElement.Tag;\n override id!: Mei;\n\n static isGlobal(id: number) {\n return globalIds.has(id);\n }\n\n override get isGlobalAttribute() {\n if (AttributeModel.isGlobal(this.id)) {\n return true;\n }\n }\n\n get writable() {\n return !this.fixed && this.effectiveAccess.writable;\n }\n\n get fabricScoped() {\n return !!this.effectiveAccess.fabric;\n }\n\n get fixed() {\n return !!this.effectiveQuality.fixed;\n }\n\n constructor(definition: AttributeElement.Properties) {\n super(definition);\n }\n\n static {\n Model.types[AttributeElement.Tag] = this;\n }\n\n static Tag = AttributeElement.Tag;\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,yBAA2B;AAC3B,sBAA0C;AAC1C,mBAAsB;AACtB,2BAA8B;AAV9B;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Mei } from \"../../datatype/ManufacturerExtensibleIdentifier.js\";\nimport { ElementTag } from \"../definitions/index.js\";\nimport { AttributeElement, Globals } from \"../elements/index.js\";\nimport { Model } from \"./Model.js\";\nimport { PropertyModel } from \"./PropertyModel.js\";\n\n// Full set of global IDs per core spec 1.3\nexport const GLOBAL_IDS = new Set([0xfffd, 0xfffc, 0xfffb, 0xfffa, 0xfff9, 0xfff8]);\nconst globalIds = new Set<number>();\nfor (const element of Object.values(Globals)) {\n if (element.tag === ElementTag.Attribute) {\n globalIds.add(element.id);\n }\n}\n\nexport class AttributeModel extends PropertyModel implements AttributeElement {\n override tag: AttributeElement.Tag = AttributeElement.Tag;\n override id!: Mei;\n\n static isGlobal(id: number) {\n return globalIds.has(id);\n }\n\n override get isGlobalAttribute() {\n if (AttributeModel.isGlobal(this.id)) {\n return true;\n }\n }\n\n get writable() {\n return !this.fixed && this.effectiveAccess.writable;\n }\n\n get fabricScoped() {\n return !!this.effectiveAccess.fabric;\n }\n\n get fixed() {\n return !!this.effectiveQuality.fixed;\n }\n\n constructor(definition: AttributeElement.Properties) {\n super(definition);\n }\n\n static {\n Model.types[AttributeElement.Tag] = this;\n }\n\n static Tag = AttributeElement.Tag;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,yBAA2B;AAC3B,sBAA0C;AAC1C,mBAAsB;AACtB,2BAA8B;AAV9B;AAAA;AAAA;AAAA;AAAA;AAaO,MAAM,aAAa,oBAAI,IAAI,CAAC,OAAQ,OAAQ,OAAQ,OAAQ,OAAQ,KAAM,CAAC;AAClF,MAAM,YAAY,oBAAI,IAAY;AAClC,WAAW,WAAW,OAAO,OAAO,uBAAO,GAAG;AAC1C,MAAI,QAAQ,QAAQ,8BAAW,WAAW;AACtC,cAAU,IAAI,QAAQ,EAAE;AAAA,EAC5B;AACJ;AAEO,MAAM,uBAAuB,mCAA0C;AAAA,EA0B1E,YAAY,YAAyC;AACjD,UAAM,UAAU;AA1BpB,SAAS,MAA4B,iCAAiB;AAAA,EA2BtD;AAAA,EAxBA,OAAO,SAAS,IAAY;AACxB,WAAO,UAAU,IAAI,EAAE;AAAA,EAC3B;AAAA,EAEA,IAAa,oBAAoB;AAC7B,QAAI,eAAe,SAAS,KAAK,EAAE,GAAG;AAClC,aAAO;AAAA,IACX;AAAA,EACJ;AAAA,EAEA,IAAI,WAAW;AACX,WAAO,CAAC,KAAK,SAAS,KAAK,gBAAgB;AAAA,EAC/C;AAAA,EAEA,IAAI,eAAe;AACf,WAAO,CAAC,CAAC,KAAK,gBAAgB;AAAA,EAClC;AAAA,EAEA,IAAI,QAAQ;AACR,WAAO,CAAC,CAAC,KAAK,iBAAiB;AAAA,EACnC;AAAA,EAMA,OAAO;AACH,uBAAM,MAAM,iCAAiB,GAAG,IAAI;AAAA,EACxC;AAAA,EAEA;AAAA,SAAO,MAAM,iCAAiB;AAAA;AAClC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransactionalInteractionServer.d.ts","sourceRoot":"","sources":["../../../../src/node/server/TransactionalInteractionServer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAMrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kEAAkE,CAAC;
|
|
1
|
+
{"version":3,"file":"TransactionalInteractionServer.d.ts","sourceRoot":"","sources":["../../../../src/node/server/TransactionalInteractionServer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAMrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kEAAkE,CAAC;AAEvG,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAEtD,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAIxE,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAEpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAE9E,OAAO,EAEH,YAAY,EACZ,aAAa,EAChB,MAAM,oDAAoD,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,mDAAmD,CAAC;AACnF,OAAO,EACH,aAAa,EACb,WAAW,EACX,SAAS,EACT,iBAAiB,EACpB,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAY9C;;;;;;;;;;;GAWG;AACH,qBAAa,8BAA+B,SAAQ,iBAAiB;;gBASrD,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;IA8BjD,CAAC,MAAM,CAAC,YAAY,CAAC;IAM3B,gBAAgB;IAID,aAAa,CAAC,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC;IAiBpE,IAAI,SAAS,wBASZ;cAEwB,aAAa,CAClC,IAAI,EAAE,aAAa,EACnB,SAAS,EAAE,kBAAkB,CAAC,GAAG,CAAC,EAClC,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,cAAc,EAAE,OAAO,EACvB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB;;;;cAgBN,SAAS,CAC9B,IAAI,EAAE,SAAS,EACf,YAAY,EAAE,cAAc,CAAC,OAAO,cAAc,CAAC,EAAE,GAAG,SAAS,EACjE,KAAK,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,EAC5B,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,cAAc,EAAE,OAAO,EACvB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB,GAC5B,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;IAsBpB,kBAAkB,CAC7B,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,OAAO,GACjB,OAAO,CAAC,aAAa,CAAC;cAWA,cAAc,CACnC,IAAI,EAAE,aAAa,EACnB,SAAS,EAAE,eAAe,CAAC,GAAG,CAAC,EAC/B,KAAK,EAAE,GAAG,EACV,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,UAAQ,EACb,WAAW,CAAC,EAAE,OAAO;cA6BA,aAAa,CAClC,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,EAChC,QAAQ,EAAE,eAAe,CAAC,YAAY,CAAC,EACvC,aAAa,EAAE,GAAG,EAClB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,UAAQ;;;;;;CAmCpB"}
|
|
@@ -60,6 +60,7 @@ var import_ActionTracer = require("../../behavior/context/ActionTracer.js");
|
|
|
60
60
|
var import_NodeActivity = require("../../behavior/context/NodeActivity.js");
|
|
61
61
|
var import_OnlineContext = require("../../behavior/context/server/OnlineContext.js");
|
|
62
62
|
var import_AccessControlServer = require("../../behavior/definitions/access-control/AccessControlServer.js");
|
|
63
|
+
var import_AccessControlCluster = require("../../cluster/definitions/AccessControlCluster.js");
|
|
63
64
|
var import_MatterError = require("../../common/MatterError.js");
|
|
64
65
|
var import_EndpointServer = require("../../endpoint/EndpointServer.js");
|
|
65
66
|
var import_EndpointLifecycle = require("../../endpoint/properties/EndpointLifecycle.js");
|
|
@@ -76,6 +77,8 @@ var import_ServerStore = require("./storage/ServerStore.js");
|
|
|
76
77
|
* SPDX-License-Identifier: Apache-2.0
|
|
77
78
|
*/
|
|
78
79
|
const activityKey = Symbol("activity");
|
|
80
|
+
const AclClusterId = import_AccessControlCluster.AccessControlCluster.id;
|
|
81
|
+
const AclAttributeId = import_AccessControlCluster.AccessControlCluster.attributes.acl.id;
|
|
79
82
|
class TransactionalInteractionServer extends import_InteractionServer.InteractionServer {
|
|
80
83
|
#endpointStructure;
|
|
81
84
|
#changeListener;
|
|
@@ -83,6 +86,7 @@ class TransactionalInteractionServer extends import_InteractionServer.Interactio
|
|
|
83
86
|
#activity;
|
|
84
87
|
#newActivityBlocked = false;
|
|
85
88
|
#aclServer;
|
|
89
|
+
#aclUpdateIsDelayed = false;
|
|
86
90
|
constructor(endpoint) {
|
|
87
91
|
const structure = new import_InteractionEndpointStructure.InteractionEndpointStructure();
|
|
88
92
|
super({
|
|
@@ -173,13 +177,22 @@ class TransactionalInteractionServer extends import_InteractionServer.Interactio
|
|
|
173
177
|
}).act(readEvent);
|
|
174
178
|
}
|
|
175
179
|
async handleWriteRequest(exchange, writeRequest, message) {
|
|
176
|
-
this.aclServer.aclUpdateDelayed = true;
|
|
177
180
|
const result = await super.handleWriteRequest(exchange, writeRequest, message);
|
|
178
|
-
this
|
|
181
|
+
if (this.#aclUpdateIsDelayed) {
|
|
182
|
+
this.aclServer.aclUpdateDelayed = false;
|
|
183
|
+
this.#aclUpdateIsDelayed = false;
|
|
184
|
+
}
|
|
179
185
|
return result;
|
|
180
186
|
}
|
|
181
187
|
async writeAttribute(path, attribute, value, exchange, message, endpoint, timed = false, isListWrite) {
|
|
182
188
|
const writeAttribute = () => super.writeAttribute(path, attribute, value, exchange, message, endpoint, timed, isListWrite);
|
|
189
|
+
if (path.endpointId === 0 && path.clusterId === AclClusterId && path.attributeId === AclAttributeId) {
|
|
190
|
+
this.aclServer.aclUpdateDelayed = true;
|
|
191
|
+
this.#aclUpdateIsDelayed = true;
|
|
192
|
+
} else if (this.#aclUpdateIsDelayed) {
|
|
193
|
+
this.aclServer.aclUpdateDelayed = false;
|
|
194
|
+
this.#aclUpdateIsDelayed = false;
|
|
195
|
+
}
|
|
183
196
|
return (0, import_OnlineContext.OnlineContext)({
|
|
184
197
|
activity: exchange[activityKey],
|
|
185
198
|
timed,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/node/server/TransactionalInteractionServer.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { MatterDevice } from \"../../MatterDevice.js\";\nimport { AccessControl } from \"../../behavior/AccessControl.js\";\nimport { ActionContext } from \"../../behavior/context/ActionContext.js\";\nimport { ActionTracer } from \"../../behavior/context/ActionTracer.js\";\nimport { NodeActivity } from \"../../behavior/context/NodeActivity.js\";\nimport { OnlineContext } from \"../../behavior/context/server/OnlineContext.js\";\nimport { AccessControlServer } from \"../../behavior/definitions/access-control/AccessControlServer.js\";\nimport { AnyAttributeServer, AttributeServer } from \"../../cluster/server/AttributeServer.js\";\nimport { CommandServer } from \"../../cluster/server/CommandServer.js\";\nimport { EventServer } from \"../../cluster/server/EventServer.js\";\nimport { Message } from \"../../codec/MessageCodec.js\";\nimport { InternalError } from \"../../common/MatterError.js\";\nimport { Endpoint } from \"../../endpoint/Endpoint.js\";\nimport { EndpointInterface } from \"../../endpoint/EndpointInterface.js\";\nimport { EndpointServer } from \"../../endpoint/EndpointServer.js\";\nimport { EndpointLifecycle } from \"../../endpoint/properties/EndpointLifecycle.js\";\nimport { Diagnostic } from \"../../log/Diagnostic.js\";\nimport { MessageExchange } from \"../../protocol/MessageExchange.js\";\nimport { AccessDeniedError } from \"../../protocol/interaction/AccessControlManager.js\";\nimport { EventStorageData } from \"../../protocol/interaction/EventHandler.js\";\nimport { InteractionEndpointStructure } from \"../../protocol/interaction/InteractionEndpointStructure.js\";\nimport {\n InteractionServerMessenger,\n WriteRequest,\n WriteResponse,\n} from \"../../protocol/interaction/InteractionMessenger.js\";\nimport { TlvEventFilter } from \"../../protocol/interaction/InteractionProtocol.js\";\nimport {\n AttributePath,\n CommandPath,\n EventPath,\n InteractionServer,\n} from \"../../protocol/interaction/InteractionServer.js\";\nimport { TypeFromSchema } from \"../../tlv/TlvSchema.js\";\nimport { MaybePromise } from \"../../util/Promises.js\";\nimport { ServerNode } from \"../ServerNode.js\";\nimport { ServerStore } from \"./storage/ServerStore.js\";\n\nconst activityKey = Symbol(\"activity\");\n\ninterface WithActivity {\n [activityKey]?: NodeActivity.Activity;\n}\n\n/**\n * Wire up an InteractionServer that initializes an InvocationContext earlier than the cluster API supports.\n *\n * This is necessary for attributes because the ClusterServer attribute APIs are synchronous while transaction\n * management is asynchronous.\n *\n * It's not necessary for command handling because that API is entirely async. We do it here, however, just for the\n * sake of consistency.\n *\n * This could be integrated directly into InteractionServer but this further refactoring is probably warranted there\n * regardless. This keeps the touch light for now.\n */\nexport class TransactionalInteractionServer extends InteractionServer {\n #endpointStructure: InteractionEndpointStructure;\n #changeListener: (type: EndpointLifecycle.Change) => void;\n #endpoint: Endpoint<ServerNode.RootEndpoint>;\n #activity: NodeActivity;\n #newActivityBlocked = false;\n #aclServer?: AccessControlServer;\n\n constructor(endpoint: Endpoint<ServerNode.RootEndpoint>) {\n const structure = new InteractionEndpointStructure();\n\n super({\n eventHandler: endpoint.env.get(ServerStore).eventHandler,\n endpointStructure: structure,\n subscriptionOptions: endpoint.state.network.subscriptionOptions,\n });\n\n this.#activity = endpoint.env.get(NodeActivity);\n\n this.#endpoint = endpoint;\n this.#endpointStructure = structure;\n\n // TODO - rewrite element lookup so we don't need to build the secondary endpoint structure cache\n this.#updateStructure();\n this.#changeListener = type => {\n switch (type) {\n case EndpointLifecycle.Change.TreeReady:\n case EndpointLifecycle.Change.ClientsChanged:\n case EndpointLifecycle.Change.ServersChanged:\n case EndpointLifecycle.Change.Destroyed:\n this.#updateStructure();\n break;\n }\n };\n\n endpoint.lifecycle.changed.on(this.#changeListener);\n }\n\n async [Symbol.asyncDispose]() {\n this.#endpoint.lifecycle.changed.off(this.#changeListener);\n await this.close();\n this.#endpointStructure.close();\n }\n\n blockNewActivity() {\n this.#newActivityBlocked = true;\n }\n\n override async onNewExchange(exchange: MessageExchange<MatterDevice>) {\n // When closing, ignore anything newly incoming\n if (this.#newActivityBlocked || this.isClosing) {\n return;\n }\n\n // Activity tracking. This provides diagnostic information and prevents the server from shutting down whilst\n // the exchange is active\n using activity = this.#activity.begin(`session#${exchange.session.id.toString(16)}`);\n (exchange as WithActivity)[activityKey] = activity;\n\n // Delegate to InteractionServerMessenger\n return new InteractionServerMessenger(exchange)\n .handleRequest(this)\n .finally(() => delete (exchange as WithActivity)[activityKey]);\n }\n\n get aclServer() {\n if (this.#aclServer !== undefined) {\n return this.#aclServer;\n }\n const aclServer = this.#endpoint.act(agent => agent.get(AccessControlServer));\n if (MaybePromise.is(aclServer)) {\n throw new InternalError(\"AccessControlServer should already be initialized.\");\n }\n return (this.#aclServer = aclServer);\n }\n\n protected override async readAttribute(\n path: AttributePath,\n attribute: AnyAttributeServer<any>,\n exchange: MessageExchange<MatterDevice>,\n fabricFiltered: boolean,\n message: Message,\n endpoint: EndpointInterface,\n ) {\n const readAttribute = () => super.readAttribute(path, attribute, exchange, fabricFiltered, message, endpoint);\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n fabricFiltered,\n message,\n session: exchange.session,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Read,\n endpoint,\n root: this.#endpoint,\n }).act(readAttribute);\n }\n\n protected override async readEvent(\n path: EventPath,\n eventFilters: TypeFromSchema<typeof TlvEventFilter>[] | undefined,\n event: EventServer<any, any>,\n exchange: MessageExchange<MatterDevice>,\n fabricFiltered: boolean,\n message: Message,\n endpoint: EndpointInterface,\n ): Promise<EventStorageData<any>[]> {\n const readEvent = (context: ActionContext) => {\n if (!context.authorizedFor(event.readAcl, { cluster: path.clusterId } as AccessControl.Location)) {\n throw new AccessDeniedError(\n `Access to ${endpoint.number}/${Diagnostic.hex(path.clusterId)} denied on ${exchange.session.name}.`,\n );\n }\n return super.readEvent(path, eventFilters, event, exchange, fabricFiltered, message, endpoint);\n };\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n fabricFiltered,\n message,\n session: exchange.session,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Read,\n endpoint,\n root: this.#endpoint,\n }).act(readEvent);\n }\n\n override async handleWriteRequest(\n exchange: MessageExchange<MatterDevice>,\n writeRequest: WriteRequest,\n message: Message,\n ): Promise<WriteResponse> {\n // TODO: This is a hack to prevent the ACL from updating while we are in the middle of a write transaction and will\n // be removed again once we somehow handle relevant sub transactions\n this.aclServer.aclUpdateDelayed = true;\n\n const result = await super.handleWriteRequest(exchange, writeRequest, message);\n\n this.aclServer.aclUpdateDelayed = false;\n return result;\n }\n\n protected override async writeAttribute(\n path: AttributePath,\n attribute: AttributeServer<any>,\n value: any,\n exchange: MessageExchange<MatterDevice>,\n message: Message,\n endpoint: EndpointInterface,\n timed = false,\n isListWrite?: boolean,\n ) {\n const writeAttribute = () =>\n super.writeAttribute(path, attribute, value, exchange, message, endpoint, timed, isListWrite);\n\n // TODO add handling for List writes that require sub transactions and remove the delayed ACL update\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n timed,\n message,\n session: exchange.session,\n fabricFiltered: true,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Write,\n endpoint,\n root: this.#endpoint,\n }).act(writeAttribute);\n }\n\n protected override async invokeCommand(\n path: CommandPath,\n command: CommandServer<any, any>,\n exchange: MessageExchange<MatterDevice>,\n commandFields: any,\n message: Message,\n endpoint: EndpointInterface,\n timed = false,\n ) {\n const invokeCommand = (context: ActionContext) => {\n if (!context.authorizedFor(command.invokeAcl, { cluster: path.clusterId } as AccessControl.Location)) {\n throw new AccessDeniedError(\n `Access to ${endpoint.number}/${Diagnostic.hex(path.clusterId)} denied on ${exchange.session.name}.`,\n );\n }\n return super.invokeCommand(path, command, exchange, commandFields, message, endpoint, timed);\n };\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n command: true,\n timed,\n message,\n session: exchange.session,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Invoke,\n endpoint,\n root: this.#endpoint,\n }).act(invokeCommand);\n }\n\n get #tracer() {\n if (this.#endpoint.env.has(ActionTracer)) {\n return this.#endpoint.env.get(ActionTracer);\n }\n }\n\n #updateStructure() {\n if (this.#endpoint.lifecycle.isTreeReady) {\n this.#endpointStructure.initializeFromEndpoint(EndpointServer.forEndpoint(this.#endpoint));\n }\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,0BAA6B;AAC7B,0BAA6B;AAC7B,2BAA8B;AAC9B,iCAAoC;
|
|
4
|
+
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { MatterDevice } from \"../../MatterDevice.js\";\nimport { AccessControl } from \"../../behavior/AccessControl.js\";\nimport { ActionContext } from \"../../behavior/context/ActionContext.js\";\nimport { ActionTracer } from \"../../behavior/context/ActionTracer.js\";\nimport { NodeActivity } from \"../../behavior/context/NodeActivity.js\";\nimport { OnlineContext } from \"../../behavior/context/server/OnlineContext.js\";\nimport { AccessControlServer } from \"../../behavior/definitions/access-control/AccessControlServer.js\";\nimport { AccessControlCluster } from \"../../cluster/definitions/AccessControlCluster.js\";\nimport { AnyAttributeServer, AttributeServer } from \"../../cluster/server/AttributeServer.js\";\nimport { CommandServer } from \"../../cluster/server/CommandServer.js\";\nimport { EventServer } from \"../../cluster/server/EventServer.js\";\nimport { Message } from \"../../codec/MessageCodec.js\";\nimport { InternalError } from \"../../common/MatterError.js\";\nimport { Endpoint } from \"../../endpoint/Endpoint.js\";\nimport { EndpointInterface } from \"../../endpoint/EndpointInterface.js\";\nimport { EndpointServer } from \"../../endpoint/EndpointServer.js\";\nimport { EndpointLifecycle } from \"../../endpoint/properties/EndpointLifecycle.js\";\nimport { Diagnostic } from \"../../log/Diagnostic.js\";\nimport { MessageExchange } from \"../../protocol/MessageExchange.js\";\nimport { AccessDeniedError } from \"../../protocol/interaction/AccessControlManager.js\";\nimport { EventStorageData } from \"../../protocol/interaction/EventHandler.js\";\nimport { InteractionEndpointStructure } from \"../../protocol/interaction/InteractionEndpointStructure.js\";\nimport {\n InteractionServerMessenger,\n WriteRequest,\n WriteResponse,\n} from \"../../protocol/interaction/InteractionMessenger.js\";\nimport { TlvEventFilter } from \"../../protocol/interaction/InteractionProtocol.js\";\nimport {\n AttributePath,\n CommandPath,\n EventPath,\n InteractionServer,\n} from \"../../protocol/interaction/InteractionServer.js\";\nimport { TypeFromSchema } from \"../../tlv/TlvSchema.js\";\nimport { MaybePromise } from \"../../util/Promises.js\";\nimport { ServerNode } from \"../ServerNode.js\";\nimport { ServerStore } from \"./storage/ServerStore.js\";\n\nconst activityKey = Symbol(\"activity\");\n\ninterface WithActivity {\n [activityKey]?: NodeActivity.Activity;\n}\n\nconst AclClusterId = AccessControlCluster.id;\nconst AclAttributeId = AccessControlCluster.attributes.acl.id;\n\n/**\n * Wire up an InteractionServer that initializes an InvocationContext earlier than the cluster API supports.\n *\n * This is necessary for attributes because the ClusterServer attribute APIs are synchronous while transaction\n * management is asynchronous.\n *\n * It's not necessary for command handling because that API is entirely async. We do it here, however, just for the\n * sake of consistency.\n *\n * This could be integrated directly into InteractionServer but this further refactoring is probably warranted there\n * regardless. This keeps the touch light for now.\n */\nexport class TransactionalInteractionServer extends InteractionServer {\n #endpointStructure: InteractionEndpointStructure;\n #changeListener: (type: EndpointLifecycle.Change) => void;\n #endpoint: Endpoint<ServerNode.RootEndpoint>;\n #activity: NodeActivity;\n #newActivityBlocked = false;\n #aclServer?: AccessControlServer;\n #aclUpdateIsDelayed = false;\n\n constructor(endpoint: Endpoint<ServerNode.RootEndpoint>) {\n const structure = new InteractionEndpointStructure();\n\n super({\n eventHandler: endpoint.env.get(ServerStore).eventHandler,\n endpointStructure: structure,\n subscriptionOptions: endpoint.state.network.subscriptionOptions,\n });\n\n this.#activity = endpoint.env.get(NodeActivity);\n\n this.#endpoint = endpoint;\n this.#endpointStructure = structure;\n\n // TODO - rewrite element lookup so we don't need to build the secondary endpoint structure cache\n this.#updateStructure();\n this.#changeListener = type => {\n switch (type) {\n case EndpointLifecycle.Change.TreeReady:\n case EndpointLifecycle.Change.ClientsChanged:\n case EndpointLifecycle.Change.ServersChanged:\n case EndpointLifecycle.Change.Destroyed:\n this.#updateStructure();\n break;\n }\n };\n\n endpoint.lifecycle.changed.on(this.#changeListener);\n }\n\n async [Symbol.asyncDispose]() {\n this.#endpoint.lifecycle.changed.off(this.#changeListener);\n await this.close();\n this.#endpointStructure.close();\n }\n\n blockNewActivity() {\n this.#newActivityBlocked = true;\n }\n\n override async onNewExchange(exchange: MessageExchange<MatterDevice>) {\n // When closing, ignore anything newly incoming\n if (this.#newActivityBlocked || this.isClosing) {\n return;\n }\n\n // Activity tracking. This provides diagnostic information and prevents the server from shutting down whilst\n // the exchange is active\n using activity = this.#activity.begin(`session#${exchange.session.id.toString(16)}`);\n (exchange as WithActivity)[activityKey] = activity;\n\n // Delegate to InteractionServerMessenger\n return new InteractionServerMessenger(exchange)\n .handleRequest(this)\n .finally(() => delete (exchange as WithActivity)[activityKey]);\n }\n\n get aclServer() {\n if (this.#aclServer !== undefined) {\n return this.#aclServer;\n }\n const aclServer = this.#endpoint.act(agent => agent.get(AccessControlServer));\n if (MaybePromise.is(aclServer)) {\n throw new InternalError(\"AccessControlServer should already be initialized.\");\n }\n return (this.#aclServer = aclServer);\n }\n\n protected override async readAttribute(\n path: AttributePath,\n attribute: AnyAttributeServer<any>,\n exchange: MessageExchange<MatterDevice>,\n fabricFiltered: boolean,\n message: Message,\n endpoint: EndpointInterface,\n ) {\n const readAttribute = () => super.readAttribute(path, attribute, exchange, fabricFiltered, message, endpoint);\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n fabricFiltered,\n message,\n session: exchange.session,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Read,\n endpoint,\n root: this.#endpoint,\n }).act(readAttribute);\n }\n\n protected override async readEvent(\n path: EventPath,\n eventFilters: TypeFromSchema<typeof TlvEventFilter>[] | undefined,\n event: EventServer<any, any>,\n exchange: MessageExchange<MatterDevice>,\n fabricFiltered: boolean,\n message: Message,\n endpoint: EndpointInterface,\n ): Promise<EventStorageData<any>[]> {\n const readEvent = (context: ActionContext) => {\n if (!context.authorizedFor(event.readAcl, { cluster: path.clusterId } as AccessControl.Location)) {\n throw new AccessDeniedError(\n `Access to ${endpoint.number}/${Diagnostic.hex(path.clusterId)} denied on ${exchange.session.name}.`,\n );\n }\n return super.readEvent(path, eventFilters, event, exchange, fabricFiltered, message, endpoint);\n };\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n fabricFiltered,\n message,\n session: exchange.session,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Read,\n endpoint,\n root: this.#endpoint,\n }).act(readEvent);\n }\n\n override async handleWriteRequest(\n exchange: MessageExchange<MatterDevice>,\n writeRequest: WriteRequest,\n message: Message,\n ): Promise<WriteResponse> {\n const result = await super.handleWriteRequest(exchange, writeRequest, message);\n\n // We delayed the ACL update during the write transaction, so we need to update it now that anything is written\n if (this.#aclUpdateIsDelayed) {\n this.aclServer.aclUpdateDelayed = false;\n this.#aclUpdateIsDelayed = false;\n }\n return result;\n }\n\n protected override async writeAttribute(\n path: AttributePath,\n attribute: AttributeServer<any>,\n value: any,\n exchange: MessageExchange<MatterDevice>,\n message: Message,\n endpoint: EndpointInterface,\n timed = false,\n isListWrite?: boolean,\n ) {\n const writeAttribute = () =>\n super.writeAttribute(path, attribute, value, exchange, message, endpoint, timed, isListWrite);\n\n if (path.endpointId === 0 && path.clusterId === AclClusterId && path.attributeId === AclAttributeId) {\n // This is a hack to prevent the ACL from updating while we are in the middle of a write transaction\n // and is needed because Acl should not become effective during writing of the ACL itself.\n this.aclServer.aclUpdateDelayed = true;\n this.#aclUpdateIsDelayed = true;\n } else if (this.#aclUpdateIsDelayed) {\n // Ok it seems that acl was written, but we now write another path, so we can update Acl attribute now\n this.aclServer.aclUpdateDelayed = false;\n this.#aclUpdateIsDelayed = false;\n }\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n timed,\n message,\n session: exchange.session,\n fabricFiltered: true,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Write,\n endpoint,\n root: this.#endpoint,\n }).act(writeAttribute);\n }\n\n protected override async invokeCommand(\n path: CommandPath,\n command: CommandServer<any, any>,\n exchange: MessageExchange<MatterDevice>,\n commandFields: any,\n message: Message,\n endpoint: EndpointInterface,\n timed = false,\n ) {\n const invokeCommand = (context: ActionContext) => {\n if (!context.authorizedFor(command.invokeAcl, { cluster: path.clusterId } as AccessControl.Location)) {\n throw new AccessDeniedError(\n `Access to ${endpoint.number}/${Diagnostic.hex(path.clusterId)} denied on ${exchange.session.name}.`,\n );\n }\n return super.invokeCommand(path, command, exchange, commandFields, message, endpoint, timed);\n };\n\n return OnlineContext({\n activity: (exchange as WithActivity)[activityKey],\n command: true,\n timed,\n message,\n session: exchange.session,\n tracer: this.#tracer,\n actionType: ActionTracer.ActionType.Invoke,\n endpoint,\n root: this.#endpoint,\n }).act(invokeCommand);\n }\n\n get #tracer() {\n if (this.#endpoint.env.has(ActionTracer)) {\n return this.#endpoint.env.get(ActionTracer);\n }\n }\n\n #updateStructure() {\n if (this.#endpoint.lifecycle.isTreeReady) {\n this.#endpointStructure.initializeFromEndpoint(EndpointServer.forEndpoint(this.#endpoint));\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -48,7 +48,7 @@ class ChannelManager {
|
|
|
48
48
|
#findLeastActiveChannel(channels) {
|
|
49
49
|
let oldest = channels[0];
|
|
50
50
|
for (const channel of channels) {
|
|
51
|
-
if (channel.session.
|
|
51
|
+
if (channel.session.timestamp < oldest.session.timestamp) {
|
|
52
52
|
oldest = channel;
|
|
53
53
|
}
|
|
54
54
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/protocol/ChannelManager.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Channel } from \"../common/Channel.js\";\nimport { MatterError } from \"../common/MatterError.js\";\nimport { tryCatchAsync } from \"../common/TryCatchHandler.js\";\nimport { NodeId } from \"../datatype/NodeId.js\";\nimport { Fabric } from \"../fabric/Fabric.js\";\nimport { Logger } from \"../log/Logger.js\";\nimport { SecureSession } from \"../session/SecureSession.js\";\nimport { Session } from \"../session/Session.js\";\nimport { ByteArray } from \"../util/ByteArray.js\";\nimport { MessageChannel } from \"./ExchangeManager.js\";\n\nconst logger = Logger.get(\"ChannelManager\");\n\nexport class NoChannelError extends MatterError {}\n\nexport class ChannelManager {\n readonly #channels = new Map<string, MessageChannel<any>[]>();\n readonly #paseChannels = new Map<Session<any>, MessageChannel<any>>();\n readonly #caseSessionsPerFabricAndNode: number;\n\n // TODO evaluate with controller the effects of limiting the entries just for FabricIndex and not also NodeId\n constructor(caseSessionsPerFabricAndNode = 3) {\n this.#caseSessionsPerFabricAndNode = caseSessionsPerFabricAndNode;\n }\n\n #getChannelKey(fabric: Fabric, nodeId: NodeId) {\n return `${fabric.fabricIndex}/${nodeId}`;\n }\n\n #findLeastActiveChannel(channels: MessageChannel<any>[]) {\n let oldest = channels[0];\n for (const channel of channels) {\n if (channel.session.
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,yBAA4B;AAC5B,6BAA8B;AAG9B,oBAAuB;AAIvB,6BAA+B;AAf/B;AAAA;AAAA;AAAA;AAAA;AAiBA,MAAM,SAAS,qBAAO,IAAI,gBAAgB;AAEnC,MAAM,uBAAuB,+BAAY;AAAC;AAE1C,MAAM,eAAe;AAAA,EACf,YAAY,oBAAI,IAAmC;AAAA,EACnD,gBAAgB,oBAAI,IAAuC;AAAA,EAC3D;AAAA;AAAA,EAGT,YAAY,+BAA+B,GAAG;AAC1C,SAAK,gCAAgC;AAAA,EACzC;AAAA,EAEA,eAAe,QAAgB,QAAgB;AAC3C,WAAO,GAAG,OAAO,WAAW,IAAI,MAAM;AAAA,EAC1C;AAAA,EAEA,wBAAwB,UAAiC;AACrD,QAAI,SAAS,SAAS,CAAC;AACvB,eAAW,WAAW,UAAU;AAC5B,UAAI,QAAQ,QAAQ,
|
|
4
|
+
"sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Channel } from \"../common/Channel.js\";\nimport { MatterError } from \"../common/MatterError.js\";\nimport { tryCatchAsync } from \"../common/TryCatchHandler.js\";\nimport { NodeId } from \"../datatype/NodeId.js\";\nimport { Fabric } from \"../fabric/Fabric.js\";\nimport { Logger } from \"../log/Logger.js\";\nimport { SecureSession } from \"../session/SecureSession.js\";\nimport { Session } from \"../session/Session.js\";\nimport { ByteArray } from \"../util/ByteArray.js\";\nimport { MessageChannel } from \"./ExchangeManager.js\";\n\nconst logger = Logger.get(\"ChannelManager\");\n\nexport class NoChannelError extends MatterError {}\n\nexport class ChannelManager {\n readonly #channels = new Map<string, MessageChannel<any>[]>();\n readonly #paseChannels = new Map<Session<any>, MessageChannel<any>>();\n readonly #caseSessionsPerFabricAndNode: number;\n\n // TODO evaluate with controller the effects of limiting the entries just for FabricIndex and not also NodeId\n constructor(caseSessionsPerFabricAndNode = 3) {\n this.#caseSessionsPerFabricAndNode = caseSessionsPerFabricAndNode;\n }\n\n #getChannelKey(fabric: Fabric, nodeId: NodeId) {\n return `${fabric.fabricIndex}/${nodeId}`;\n }\n\n #findLeastActiveChannel(channels: MessageChannel<any>[]) {\n let oldest = channels[0];\n for (const channel of channels) {\n if (channel.session.timestamp < oldest.session.timestamp) {\n oldest = channel;\n }\n }\n return oldest;\n }\n\n async setChannel(fabric: Fabric, nodeId: NodeId, channel: MessageChannel<any>) {\n const channelsKey = this.#getChannelKey(fabric, nodeId);\n const currentChannels = this.#channels.get(channelsKey) ?? [];\n if (currentChannels.length >= this.#caseSessionsPerFabricAndNode) {\n const oldestChannel = this.#findLeastActiveChannel(currentChannels);\n currentChannels.splice(currentChannels.indexOf(oldestChannel), 1);\n currentChannels.push(channel);\n this.#channels.set(channelsKey, currentChannels);\n\n // Should always be the case\n const { session } = oldestChannel;\n if (session.id !== oldestChannel.session.id) {\n logger.debug(\n `Existing channel for fabricIndex ${fabric.fabricIndex} and node ${nodeId} with session ${session.name} gets replaced. Consider former session already inactive and so close it.`,\n );\n await session.destroy(false, false);\n }\n logger.info(`Close oldest channel for fabric ${fabric.fabricIndex} node ${nodeId}`);\n await oldestChannel.close();\n } else {\n currentChannels.push(channel);\n this.#channels.set(channelsKey, currentChannels);\n }\n }\n\n getChannel(fabric: Fabric, nodeId: NodeId, session?: Session<any>) {\n let results = this.#channels.get(this.#getChannelKey(fabric, nodeId)) ?? [];\n if (session !== undefined) {\n results = results.filter(channel => channel.session.id === session.id);\n }\n if (results.length === 0) throw new NoChannelError(`Can't find a channel to node ${nodeId}`);\n return results[results.length - 1]; // Return the latest added channel\n }\n\n /**\n * Returns the last established session for a Fabric and Node\n */\n getChannelForSession(session: Session<any>) {\n if (session.isSecure && !session.isPase) {\n const secureSession = session as SecureSession<any>;\n const fabric = secureSession.fabric;\n const nodeId = secureSession.peerNodeId;\n if (fabric === undefined) {\n return this.#paseChannels.get(session);\n }\n return this.getChannel(fabric, nodeId, session);\n }\n return this.#paseChannels.get(session);\n }\n\n async removeAllNodeChannels(fabric: Fabric, nodeId: NodeId) {\n const channelsKey = this.#getChannelKey(fabric, nodeId);\n const channelsToRemove = this.#channels.get(channelsKey) ?? [];\n for (const channel of channelsToRemove) {\n await channel.close();\n }\n }\n\n async removeChannel(fabric: Fabric, nodeId: NodeId, session: Session<any>) {\n const channelsKey = this.#getChannelKey(fabric, nodeId);\n const fabricChannels = this.#channels.get(channelsKey) ?? [];\n const channelEntry = fabricChannels.find(({ session: entrySession }) => entrySession.id === session.id);\n await channelEntry?.close();\n }\n\n private getOrCreateAsPaseChannel(byteArrayChannel: Channel<ByteArray>, session: Session<any>) {\n const msgChannel = new MessageChannel(\n byteArrayChannel,\n session,\n async () => void this.#paseChannels.delete(session),\n );\n this.#paseChannels.set(session, msgChannel);\n return msgChannel;\n }\n\n async getOrCreateChannel(byteArrayChannel: Channel<ByteArray>, session: Session<any>) {\n if (!session.isSecure) {\n return this.getOrCreateAsPaseChannel(byteArrayChannel, session);\n }\n const secureSession = session as SecureSession<any>;\n const fabric = secureSession.fabric;\n const nodeId = secureSession.peerNodeId;\n if (fabric === undefined) {\n return this.getOrCreateAsPaseChannel(byteArrayChannel, session);\n }\n\n return tryCatchAsync(\n async () => this.getChannel(fabric, nodeId, session),\n NoChannelError,\n async () => {\n const result = new MessageChannel(byteArrayChannel, session, async () =>\n this.removeChannel(fabric, nodeId, session),\n );\n await this.setChannel(fabric, nodeId, result);\n return result;\n },\n );\n }\n\n async close() {\n for (const channel of this.#paseChannels.values()) {\n await channel.close();\n }\n this.#paseChannels.clear();\n for (const channels of this.#channels.values()) {\n for (const channel of channels) {\n await channel.close();\n }\n }\n this.#channels.clear();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -25,8 +25,12 @@ import { InteractionRecipient, InteractionServerMessenger, InvokeRequest, Invoke
|
|
|
25
25
|
import { TlvAttributePath, TlvClusterPath, TlvEventFilter, TlvEventPath } from "./InteractionProtocol.js";
|
|
26
26
|
import { StatusCode } from "./StatusCode.js";
|
|
27
27
|
import { SubscriptionOptions } from "./SubscriptionOptions.js";
|
|
28
|
+
/** Protocol ID for the Interaction Protocol as per Matter specification. */
|
|
28
29
|
export declare const INTERACTION_PROTOCOL_ID = 1;
|
|
30
|
+
/** Backward compatible re-export for Interaction Model version we support currently. */
|
|
29
31
|
export declare const INTERACTION_MODEL_REVISION = 11;
|
|
32
|
+
/** Number of Invoke Path setting from our Interaction model implementation. */
|
|
33
|
+
export declare const MAX_PATHS_PER_INVOKE = 1;
|
|
30
34
|
export interface CommandPath {
|
|
31
35
|
nodeId?: NodeId;
|
|
32
36
|
endpointId: EndpointNumber;
|
|
@@ -62,6 +66,8 @@ export declare function commandPathToId({ endpointId, clusterId, commandId }: Co
|
|
|
62
66
|
export declare function attributePathToId({ endpointId, clusterId, attributeId }: TypeFromSchema<typeof TlvAttributePath>): string;
|
|
63
67
|
export declare function eventPathToId({ endpointId, clusterId, eventId }: TypeFromSchema<typeof TlvEventPath>): string;
|
|
64
68
|
export declare function clusterPathToId({ nodeId, endpointId, clusterId }: TypeFromSchema<typeof TlvClusterPath>): string;
|
|
69
|
+
export declare function validateReadAttributesPath(path: TypeFromSchema<typeof TlvAttributePath>, isGroupSession?: boolean): void;
|
|
70
|
+
export declare function validateReadEventPath(path: TypeFromSchema<typeof TlvEventPath>, isGroupSession?: boolean): void;
|
|
65
71
|
/**
|
|
66
72
|
* Translates interactions from the Matter protocol to Matter.js APIs.
|
|
67
73
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InteractionServer.d.ts","sourceRoot":"","sources":["../../../../src/protocol/interaction/InteractionServer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EACH,kBAAkB,EAClB,eAAe,EAElB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,EAAE,OAAO,EAAe,MAAM,6BAA6B,CAAC;AAKnE,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAEpD,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"InteractionServer.d.ts","sourceRoot":"","sources":["../../../../src/protocol/interaction/InteractionServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,11 +21,14 @@ __export(InteractionServer_exports, {
|
|
|
21
21
|
INTERACTION_MODEL_REVISION: () => INTERACTION_MODEL_REVISION,
|
|
22
22
|
INTERACTION_PROTOCOL_ID: () => INTERACTION_PROTOCOL_ID,
|
|
23
23
|
InteractionServer: () => InteractionServer,
|
|
24
|
+
MAX_PATHS_PER_INVOKE: () => MAX_PATHS_PER_INVOKE,
|
|
24
25
|
attributePathToId: () => attributePathToId,
|
|
25
26
|
clusterPathToId: () => clusterPathToId,
|
|
26
27
|
commandPathToId: () => commandPathToId,
|
|
27
28
|
eventPathToId: () => eventPathToId,
|
|
28
|
-
genericElementPathToId: () => genericElementPathToId
|
|
29
|
+
genericElementPathToId: () => genericElementPathToId,
|
|
30
|
+
validateReadAttributesPath: () => validateReadAttributesPath,
|
|
31
|
+
validateReadEventPath: () => validateReadEventPath
|
|
29
32
|
});
|
|
30
33
|
module.exports = __toCommonJS(InteractionServer_exports);
|
|
31
34
|
var import_Cluster = require("../../cluster/Cluster.js");
|
|
@@ -38,6 +41,7 @@ var import_Crypto = require("../../crypto/Crypto.js");
|
|
|
38
41
|
var import_EventNumber = require("../../datatype/EventNumber.js");
|
|
39
42
|
var import_Diagnostic = require("../../log/Diagnostic.js");
|
|
40
43
|
var import_Logger = require("../../log/Logger.js");
|
|
44
|
+
var import_model = require("../../model/index.js");
|
|
41
45
|
var import_SecureSession = require("../../session/SecureSession.js");
|
|
42
46
|
var import_TlvArray = require("../../tlv/TlvArray.js");
|
|
43
47
|
var import_TlvNoArguments = require("../../tlv/TlvNoArguments.js");
|
|
@@ -54,6 +58,7 @@ var import_SubscriptionOptions = require("./SubscriptionOptions.js");
|
|
|
54
58
|
*/
|
|
55
59
|
const INTERACTION_PROTOCOL_ID = 1;
|
|
56
60
|
const INTERACTION_MODEL_REVISION = 11;
|
|
61
|
+
const MAX_PATHS_PER_INVOKE = 1;
|
|
57
62
|
const logger = import_Logger.Logger.get("InteractionServer");
|
|
58
63
|
function genericElementPathToId(endpointId, clusterId, elementId) {
|
|
59
64
|
return `${endpointId}/${clusterId}/${elementId}`;
|
|
@@ -74,14 +79,61 @@ function isConcreteAttributePath(path) {
|
|
|
74
79
|
const { endpointId, clusterId, attributeId } = path;
|
|
75
80
|
return endpointId !== void 0 && clusterId !== void 0 && attributeId !== void 0;
|
|
76
81
|
}
|
|
82
|
+
function validateReadAttributesPath(path, isGroupSession = false) {
|
|
83
|
+
if (isGroupSession) {
|
|
84
|
+
throw new import_StatusCode.StatusResponseError("Illegal read request with group session", import_StatusCode.StatusCode.InvalidAction);
|
|
85
|
+
}
|
|
86
|
+
const { clusterId, attributeId } = path;
|
|
87
|
+
if (clusterId === void 0 && attributeId !== void 0) {
|
|
88
|
+
if (!import_model.GLOBAL_IDS.has(attributeId)) {
|
|
89
|
+
throw new import_StatusCode.StatusResponseError(
|
|
90
|
+
`Illegal read request for wildcard cluster and non global attribute ${attributeId}`,
|
|
91
|
+
import_StatusCode.StatusCode.InvalidAction
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function validateWriteAttributesPath(path, isGroupSession = false) {
|
|
97
|
+
const { endpointId, clusterId, attributeId } = path;
|
|
98
|
+
if (clusterId === void 0 || attributeId === void 0) {
|
|
99
|
+
throw new import_StatusCode.StatusResponseError(
|
|
100
|
+
"Illegal write request with wildcard cluster or attribute ID",
|
|
101
|
+
import_StatusCode.StatusCode.InvalidAction
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
if (isGroupSession && endpointId !== void 0) {
|
|
105
|
+
throw new import_StatusCode.StatusResponseError("Illegal write request with group ID and endpoint ID", import_StatusCode.StatusCode.InvalidAction);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
77
108
|
function isConcreteEventPath(path) {
|
|
78
109
|
const { endpointId, clusterId, eventId } = path;
|
|
79
110
|
return endpointId !== void 0 && clusterId !== void 0 && eventId !== void 0;
|
|
80
111
|
}
|
|
112
|
+
function validateReadEventPath(path, isGroupSession = false) {
|
|
113
|
+
const { clusterId, eventId } = path;
|
|
114
|
+
if (clusterId === void 0 && eventId !== void 0) {
|
|
115
|
+
throw new import_StatusCode.StatusResponseError("Illegal read request with wildcard cluster ID", import_StatusCode.StatusCode.InvalidAction);
|
|
116
|
+
}
|
|
117
|
+
if (isGroupSession) {
|
|
118
|
+
throw new import_StatusCode.StatusResponseError("Illegal read request with group session", import_StatusCode.StatusCode.InvalidAction);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
81
121
|
function isConcreteCommandPath(path) {
|
|
82
122
|
const { endpointId, clusterId, commandId } = path;
|
|
83
123
|
return endpointId !== void 0 && clusterId !== void 0 && commandId !== void 0;
|
|
84
124
|
}
|
|
125
|
+
function validateCommandPath(path, isGroupSession = false) {
|
|
126
|
+
const { endpointId, clusterId, commandId } = path;
|
|
127
|
+
if (clusterId === void 0 || commandId === void 0) {
|
|
128
|
+
throw new import_StatusCode.StatusResponseError(
|
|
129
|
+
"Illegal write request with wildcard cluster or attribute ID",
|
|
130
|
+
import_StatusCode.StatusCode.InvalidAction
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
if (isGroupSession && endpointId !== void 0) {
|
|
134
|
+
throw new import_StatusCode.StatusResponseError("Illegal write request with group ID and endpoint ID", import_StatusCode.StatusCode.InvalidAction);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
85
137
|
class InteractionServer {
|
|
86
138
|
#endpointStructure;
|
|
87
139
|
#nextSubscriptionId = import_Crypto.Crypto.getRandomUInt32();
|
|
@@ -131,6 +183,12 @@ class InteractionServer {
|
|
|
131
183
|
import_StatusCode.StatusCode.UnsupportedRead
|
|
132
184
|
);
|
|
133
185
|
}
|
|
186
|
+
if (message.packetHeader.sessionType !== import_MessageCodec.SessionType.Unicast) {
|
|
187
|
+
throw new import_StatusCode.StatusResponseError(
|
|
188
|
+
"Subscriptions are only allowed on unicast sessions",
|
|
189
|
+
import_StatusCode.StatusCode.InvalidAction
|
|
190
|
+
);
|
|
191
|
+
}
|
|
134
192
|
const dataVersionFilterMap = new Map(
|
|
135
193
|
dataVersionFilters?.map(({ path, dataVersion }) => [clusterPathToId(path), dataVersion]) ?? []
|
|
136
194
|
);
|
|
@@ -141,6 +199,7 @@ class InteractionServer {
|
|
|
141
199
|
}
|
|
142
200
|
const attributeReportsPayload = new Array();
|
|
143
201
|
for (const requestPath of attributeRequests ?? []) {
|
|
202
|
+
validateReadAttributesPath(requestPath);
|
|
144
203
|
const attributes = this.#endpointStructure.getAttributes([requestPath]);
|
|
145
204
|
if (attributes.length === 0) {
|
|
146
205
|
if (!isConcreteAttributePath(requestPath)) {
|
|
@@ -235,6 +294,7 @@ class InteractionServer {
|
|
|
235
294
|
if (eventRequests) {
|
|
236
295
|
eventReportsPayload = [];
|
|
237
296
|
for (const requestPath of eventRequests) {
|
|
297
|
+
validateReadEventPath(requestPath);
|
|
238
298
|
const events = this.#endpointStructure.getEvents([requestPath]);
|
|
239
299
|
if (events.length === 0) {
|
|
240
300
|
if (!isConcreteEventPath(requestPath)) {
|
|
@@ -395,19 +455,8 @@ class InteractionServer {
|
|
|
395
455
|
const inaccessiblePaths = /* @__PURE__ */ new Set();
|
|
396
456
|
for (const writeRequest of writeData) {
|
|
397
457
|
const { path: writePath, dataVersion } = writeRequest;
|
|
398
|
-
const {
|
|
399
|
-
|
|
400
|
-
throw new import_StatusCode.StatusResponseError(
|
|
401
|
-
"Illegal write request with wildcard cluster ID",
|
|
402
|
-
import_StatusCode.StatusCode.InvalidAction
|
|
403
|
-
);
|
|
404
|
-
}
|
|
405
|
-
if (attributeId === void 0) {
|
|
406
|
-
throw new import_StatusCode.StatusResponseError(
|
|
407
|
-
"Illegal write request with wildcard attribute ID",
|
|
408
|
-
import_StatusCode.StatusCode.InvalidAction
|
|
409
|
-
);
|
|
410
|
-
}
|
|
458
|
+
const { listIndex } = writePath;
|
|
459
|
+
validateWriteAttributesPath(writePath);
|
|
411
460
|
const attributes = this.#endpointStructure.getAttributes([writePath], true);
|
|
412
461
|
if (attributes.length === 0) {
|
|
413
462
|
if (!isConcreteAttributePath(writePath)) {
|
|
@@ -417,7 +466,7 @@ class InteractionServer {
|
|
|
417
466
|
)}: ignore non-existing (wildcard) attribute`
|
|
418
467
|
);
|
|
419
468
|
} else {
|
|
420
|
-
const { endpointId } = writePath;
|
|
469
|
+
const { endpointId, clusterId, attributeId } = writePath;
|
|
421
470
|
(0, import_TryCatchHandler.tryCatch)(
|
|
422
471
|
() => {
|
|
423
472
|
if (this.#endpointStructure.validateConcreteAttributePath(
|
|
@@ -448,7 +497,7 @@ class InteractionServer {
|
|
|
448
497
|
continue;
|
|
449
498
|
}
|
|
450
499
|
if (attributes.length === 1 && isConcreteAttributePath(writePath)) {
|
|
451
|
-
const { endpointId } = writePath;
|
|
500
|
+
const { endpointId, clusterId } = writePath;
|
|
452
501
|
const { attribute } = attributes[0];
|
|
453
502
|
if (attribute.requiresTimedInteraction && !receivedWithinTimedInteraction) {
|
|
454
503
|
logger.debug(`This write requires a timed interaction which is not initialized.`);
|
|
@@ -600,6 +649,12 @@ class InteractionServer {
|
|
|
600
649
|
`Interaction model revision of sender ${interactionModelRevision} is higher than supported ${INTERACTION_MODEL_REVISION}.`
|
|
601
650
|
);
|
|
602
651
|
}
|
|
652
|
+
if (message.packetHeader.sessionType !== import_MessageCodec.SessionType.Unicast) {
|
|
653
|
+
throw new import_StatusCode.StatusResponseError(
|
|
654
|
+
"Subscriptions are only allowed on unicast sessions",
|
|
655
|
+
import_StatusCode.StatusCode.InvalidAction
|
|
656
|
+
);
|
|
657
|
+
}
|
|
603
658
|
(0, import_SecureSession.assertSecureSession)(exchange.session, "Subscriptions are only implemented on secure sessions");
|
|
604
659
|
const session = exchange.session;
|
|
605
660
|
const fabric = session.fabric;
|
|
@@ -625,6 +680,8 @@ class InteractionServer {
|
|
|
625
680
|
logger.debug(
|
|
626
681
|
`Event filters: ${eventFilters.map((filter) => `${filter.nodeId}/${filter.eventMin}`).join(", ")}`
|
|
627
682
|
);
|
|
683
|
+
attributeRequests?.forEach((path) => validateReadAttributesPath(path));
|
|
684
|
+
eventRequests?.forEach((path) => validateReadEventPath(path));
|
|
628
685
|
if (minIntervalFloorSeconds < 0) {
|
|
629
686
|
throw new import_StatusCode.StatusResponseError(
|
|
630
687
|
"minIntervalFloorSeconds should be greater or equal to 0",
|
|
@@ -725,9 +782,6 @@ class InteractionServer {
|
|
|
725
782
|
`Interaction model revision of sender ${interactionModelRevision} is higher than supported ${INTERACTION_MODEL_REVISION}.`
|
|
726
783
|
);
|
|
727
784
|
}
|
|
728
|
-
const {
|
|
729
|
-
packetHeader: { sessionType }
|
|
730
|
-
} = message;
|
|
731
785
|
const receivedWithinTimedInteraction = exchange.hasActiveTimedInteraction();
|
|
732
786
|
if (exchange.hasExpiredTimedInteraction()) {
|
|
733
787
|
exchange.clearTimedInteraction();
|
|
@@ -742,7 +796,7 @@ class InteractionServer {
|
|
|
742
796
|
if (receivedWithinTimedInteraction) {
|
|
743
797
|
logger.debug(`Invoke request from ${exchange.channel.name} received while timed interaction is running.`);
|
|
744
798
|
exchange.clearTimedInteraction();
|
|
745
|
-
if (sessionType !== import_MessageCodec.SessionType.Unicast) {
|
|
799
|
+
if (message.packetHeader.sessionType !== import_MessageCodec.SessionType.Unicast) {
|
|
746
800
|
throw new import_StatusCode.StatusResponseError(
|
|
747
801
|
"Invoke requests are only allowed on unicast sessions when a timed interaction is running.",
|
|
748
802
|
import_StatusCode.StatusCode.InvalidAction
|
|
@@ -752,6 +806,7 @@ class InteractionServer {
|
|
|
752
806
|
if (invokeRequests.length > 1) {
|
|
753
807
|
throw new import_StatusCode.StatusResponseError("Multi-command invoke requests are not supported", import_StatusCode.StatusCode.InvalidAction);
|
|
754
808
|
}
|
|
809
|
+
invokeRequests.forEach(({ commandPath }) => validateCommandPath(commandPath));
|
|
755
810
|
const invokeResponses = [];
|
|
756
811
|
await Promise.all(
|
|
757
812
|
invokeRequests.flatMap(async ({ commandPath, commandFields }) => {
|