@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.
Files changed (38) hide show
  1. package/dist/cjs/model/models/AttributeModel.d.ts +1 -0
  2. package/dist/cjs/model/models/AttributeModel.d.ts.map +1 -1
  3. package/dist/cjs/model/models/AttributeModel.js +3 -1
  4. package/dist/cjs/model/models/AttributeModel.js.map +2 -2
  5. package/dist/cjs/node/server/TransactionalInteractionServer.d.ts.map +1 -1
  6. package/dist/cjs/node/server/TransactionalInteractionServer.js +15 -2
  7. package/dist/cjs/node/server/TransactionalInteractionServer.js.map +2 -2
  8. package/dist/cjs/protocol/ChannelManager.js +1 -1
  9. package/dist/cjs/protocol/ChannelManager.js.map +2 -2
  10. package/dist/cjs/protocol/interaction/InteractionServer.d.ts +6 -0
  11. package/dist/cjs/protocol/interaction/InteractionServer.d.ts.map +1 -1
  12. package/dist/cjs/protocol/interaction/InteractionServer.js +75 -20
  13. package/dist/cjs/protocol/interaction/InteractionServer.js.map +2 -2
  14. package/dist/cjs/protocol/securechannel/SecureChannelProtocol.d.ts.map +1 -1
  15. package/dist/cjs/protocol/securechannel/SecureChannelProtocol.js +4 -2
  16. package/dist/cjs/protocol/securechannel/SecureChannelProtocol.js.map +2 -2
  17. package/dist/esm/model/models/AttributeModel.d.ts +1 -0
  18. package/dist/esm/model/models/AttributeModel.d.ts.map +1 -1
  19. package/dist/esm/model/models/AttributeModel.js +3 -1
  20. package/dist/esm/model/models/AttributeModel.js.map +2 -2
  21. package/dist/esm/node/server/TransactionalInteractionServer.d.ts.map +1 -1
  22. package/dist/esm/node/server/TransactionalInteractionServer.js +15 -2
  23. package/dist/esm/node/server/TransactionalInteractionServer.js.map +2 -2
  24. package/dist/esm/protocol/ChannelManager.js +1 -1
  25. package/dist/esm/protocol/ChannelManager.js.map +2 -2
  26. package/dist/esm/protocol/interaction/InteractionServer.d.ts +6 -0
  27. package/dist/esm/protocol/interaction/InteractionServer.d.ts.map +1 -1
  28. package/dist/esm/protocol/interaction/InteractionServer.js +75 -20
  29. package/dist/esm/protocol/interaction/InteractionServer.js.map +2 -2
  30. package/dist/esm/protocol/securechannel/SecureChannelProtocol.d.ts.map +1 -1
  31. package/dist/esm/protocol/securechannel/SecureChannelProtocol.js +4 -2
  32. package/dist/esm/protocol/securechannel/SecureChannelProtocol.js.map +2 -2
  33. package/package.json +3 -3
  34. package/src/model/models/AttributeModel.ts +2 -0
  35. package/src/node/server/TransactionalInteractionServer.ts +21 -6
  36. package/src/protocol/ChannelManager.ts +1 -1
  37. package/src/protocol/interaction/InteractionServer.ts +87 -22
  38. 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;AASnD,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"}
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;AAYA,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;",
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;AACvG,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;AAS9C;;;;;;;;;;;GAWG;AACH,qBAAa,8BAA+B,SAAQ,iBAAiB;;gBAQrD,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;cAmBA,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"}
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.aclServer.aclUpdateDelayed = false;
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": "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",
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": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,0BAA6B;AAC7B,0BAA6B;AAC7B,2BAA8B;AAC9B,iCAAoC;AACpC,kCAAqC;AAKrC,yBAA8B;AAG9B,4BAA+B;AAC/B,+BAAkC;AAClC,wBAA2B;AAE3B,kCAAkC;AAElC,0CAA6C;AAC7C,kCAIO;AAEP,+BAKO;AAEP,sBAA6B;AAE7B,yBAA4B;AA3C5B;AAAA;AAAA;AAAA;AAAA;AA6CA,MAAM,cAAc,OAAO,UAAU;AAMrC,MAAM,eAAe,iDAAqB;AAC1C,MAAM,iBAAiB,iDAAqB,WAAW,IAAI;AAcpD,MAAM,uCAAuC,2CAAkB;AAAA,EAClE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,sBAAsB;AAAA,EACtB;AAAA,EACA,sBAAsB;AAAA,EAEtB,YAAY,UAA6C;AACrD,UAAM,YAAY,IAAI,iEAA6B;AAEnD,UAAM;AAAA,MACF,cAAc,SAAS,IAAI,IAAI,8BAAW,EAAE;AAAA,MAC5C,mBAAmB;AAAA,MACnB,qBAAqB,SAAS,MAAM,QAAQ;AAAA,IAChD,CAAC;AAED,SAAK,YAAY,SAAS,IAAI,IAAI,gCAAY;AAE9C,SAAK,YAAY;AACjB,SAAK,qBAAqB;AAG1B,SAAK,iBAAiB;AACtB,SAAK,kBAAkB,UAAQ;AAC3B,cAAQ,MAAM;AAAA,QACV,KAAK,2CAAkB,OAAO;AAAA,QAC9B,KAAK,2CAAkB,OAAO;AAAA,QAC9B,KAAK,2CAAkB,OAAO;AAAA,QAC9B,KAAK,2CAAkB,OAAO;AAC1B,eAAK,iBAAiB;AACtB;AAAA,MACR;AAAA,IACJ;AAEA,aAAS,UAAU,QAAQ,GAAG,KAAK,eAAe;AAAA,EACtD;AAAA,EAEA,OAAO,OAAO,YAAY,IAAI;AAC1B,SAAK,UAAU,UAAU,QAAQ,IAAI,KAAK,eAAe;AACzD,UAAM,KAAK,MAAM;AACjB,SAAK,mBAAmB,MAAM;AAAA,EAClC;AAAA,EAEA,mBAAmB;AACf,SAAK,sBAAsB;AAAA,EAC/B;AAAA,EAEA,MAAe,cAAc,UAAyC;AAQlE;AAAA;AANA,UAAI,KAAK,uBAAuB,KAAK,WAAW;AAC5C;AAAA,MACJ;AAIA,YAAM,WAAW,qBAAK,UAAU,MAAM,WAAW,SAAS,QAAQ,GAAG,SAAS,EAAE,CAAC,EAAE;AACnF,MAAC,SAA0B,WAAW,IAAI;AAG1C,aAAO,IAAI,uDAA2B,QAAQ,EACzC,cAAc,IAAI,EAClB,QAAQ,MAAM,OAAQ,SAA0B,WAAW,CAAC;AAAA,aANjE;AAAA;AAAA;AAAA;AAAA;AAAA,EAOJ;AAAA,EAEA,IAAI,YAAY;AACZ,QAAI,KAAK,eAAe,QAAW;AAC/B,aAAO,KAAK;AAAA,IAChB;AACA,UAAM,YAAY,KAAK,UAAU,IAAI,WAAS,MAAM,IAAI,8CAAmB,CAAC;AAC5E,QAAI,6BAAa,GAAG,SAAS,GAAG;AAC5B,YAAM,IAAI,iCAAc,oDAAoD;AAAA,IAChF;AACA,WAAQ,KAAK,aAAa;AAAA,EAC9B;AAAA,EAEA,MAAyB,cACrB,MACA,WACA,UACA,gBACA,SACA,UACF;AACE,UAAM,gBAAgB,MAAM,MAAM,cAAc,MAAM,WAAW,UAAU,gBAAgB,SAAS,QAAQ;AAE5G,eAAO,oCAAc;AAAA,MACjB,UAAW,SAA0B,WAAW;AAAA,MAChD;AAAA,MACA;AAAA,MACA,SAAS,SAAS;AAAA,MAClB,QAAQ,KAAK;AAAA,MACb,YAAY,iCAAa,WAAW;AAAA,MACpC;AAAA,MACA,MAAM,KAAK;AAAA,IACf,CAAC,EAAE,IAAI,aAAa;AAAA,EACxB;AAAA,EAEA,MAAyB,UACrB,MACA,cACA,OACA,UACA,gBACA,SACA,UACgC;AAChC,UAAM,YAAY,CAAC,YAA2B;AAC1C,UAAI,CAAC,QAAQ,cAAc,MAAM,SAAS,EAAE,SAAS,KAAK,UAAU,CAA2B,GAAG;AAC9F,cAAM,IAAI;AAAA,UACN,aAAa,SAAS,MAAM,IAAI,6BAAW,IAAI,KAAK,SAAS,CAAC,cAAc,SAAS,QAAQ,IAAI;AAAA,QACrG;AAAA,MACJ;AACA,aAAO,MAAM,UAAU,MAAM,cAAc,OAAO,UAAU,gBAAgB,SAAS,QAAQ;AAAA,IACjG;AAEA,eAAO,oCAAc;AAAA,MACjB,UAAW,SAA0B,WAAW;AAAA,MAChD;AAAA,MACA;AAAA,MACA,SAAS,SAAS;AAAA,MAClB,QAAQ,KAAK;AAAA,MACb,YAAY,iCAAa,WAAW;AAAA,MACpC;AAAA,MACA,MAAM,KAAK;AAAA,IACf,CAAC,EAAE,IAAI,SAAS;AAAA,EACpB;AAAA,EAEA,MAAe,mBACX,UACA,cACA,SACsB;AACtB,UAAM,SAAS,MAAM,MAAM,mBAAmB,UAAU,cAAc,OAAO;AAG7E,QAAI,KAAK,qBAAqB;AAC1B,WAAK,UAAU,mBAAmB;AAClC,WAAK,sBAAsB;AAAA,IAC/B;AACA,WAAO;AAAA,EACX;AAAA,EAEA,MAAyB,eACrB,MACA,WACA,OACA,UACA,SACA,UACA,QAAQ,OACR,aACF;AACE,UAAM,iBAAiB,MACnB,MAAM,eAAe,MAAM,WAAW,OAAO,UAAU,SAAS,UAAU,OAAO,WAAW;AAEhG,QAAI,KAAK,eAAe,KAAK,KAAK,cAAc,gBAAgB,KAAK,gBAAgB,gBAAgB;AAGjG,WAAK,UAAU,mBAAmB;AAClC,WAAK,sBAAsB;AAAA,IAC/B,WAAW,KAAK,qBAAqB;AAEjC,WAAK,UAAU,mBAAmB;AAClC,WAAK,sBAAsB;AAAA,IAC/B;AAEA,eAAO,oCAAc;AAAA,MACjB,UAAW,SAA0B,WAAW;AAAA,MAChD;AAAA,MACA;AAAA,MACA,SAAS,SAAS;AAAA,MAClB,gBAAgB;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,YAAY,iCAAa,WAAW;AAAA,MACpC;AAAA,MACA,MAAM,KAAK;AAAA,IACf,CAAC,EAAE,IAAI,cAAc;AAAA,EACzB;AAAA,EAEA,MAAyB,cACrB,MACA,SACA,UACA,eACA,SACA,UACA,QAAQ,OACV;AACE,UAAM,gBAAgB,CAAC,YAA2B;AAC9C,UAAI,CAAC,QAAQ,cAAc,QAAQ,WAAW,EAAE,SAAS,KAAK,UAAU,CAA2B,GAAG;AAClG,cAAM,IAAI;AAAA,UACN,aAAa,SAAS,MAAM,IAAI,6BAAW,IAAI,KAAK,SAAS,CAAC,cAAc,SAAS,QAAQ,IAAI;AAAA,QACrG;AAAA,MACJ;AACA,aAAO,MAAM,cAAc,MAAM,SAAS,UAAU,eAAe,SAAS,UAAU,KAAK;AAAA,IAC/F;AAEA,eAAO,oCAAc;AAAA,MACjB,UAAW,SAA0B,WAAW;AAAA,MAChD,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA,SAAS,SAAS;AAAA,MAClB,QAAQ,KAAK;AAAA,MACb,YAAY,iCAAa,WAAW;AAAA,MACpC;AAAA,MACA,MAAM,KAAK;AAAA,IACf,CAAC,EAAE,IAAI,aAAa;AAAA,EACxB;AAAA,EAEA,IAAI,UAAU;AACV,QAAI,KAAK,UAAU,IAAI,IAAI,gCAAY,GAAG;AACtC,aAAO,KAAK,UAAU,IAAI,IAAI,gCAAY;AAAA,IAC9C;AAAA,EACJ;AAAA,EAEA,mBAAmB;AACf,QAAI,KAAK,UAAU,UAAU,aAAa;AACtC,WAAK,mBAAmB,uBAAuB,qCAAe,YAAY,KAAK,SAAS,CAAC;AAAA,IAC7F;AAAA,EACJ;AACJ;",
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.activeTimestamp < oldest.session.activeTimestamp) {
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.activeTimestamp < oldest.session.activeTimestamp) {\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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",
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":"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"}
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 { clusterId, attributeId, listIndex } = writePath;
399
- if (clusterId === void 0) {
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 }) => {