@project-chip/matter.js 0.9.2 → 0.9.4

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 (288) hide show
  1. package/dist/cjs/CommissioningServer.d.ts.map +1 -1
  2. package/dist/cjs/CommissioningServer.js +0 -1
  3. package/dist/cjs/CommissioningServer.js.map +2 -2
  4. package/dist/cjs/MatterDevice.d.ts +3 -0
  5. package/dist/cjs/MatterDevice.d.ts.map +1 -1
  6. package/dist/cjs/MatterDevice.js +21 -7
  7. package/dist/cjs/MatterDevice.js.map +2 -2
  8. package/dist/cjs/behavior/AccessControl.js +2 -2
  9. package/dist/cjs/behavior/AccessControl.js.map +2 -2
  10. package/dist/cjs/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.d.ts +1 -0
  11. package/dist/cjs/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.d.ts.map +1 -1
  12. package/dist/cjs/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.js +14 -0
  13. package/dist/cjs/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.js.map +2 -2
  14. package/dist/cjs/behavior/definitions/operational-credentials/OperationalCredentialsServer.d.ts.map +1 -1
  15. package/dist/cjs/behavior/definitions/operational-credentials/OperationalCredentialsServer.js +11 -2
  16. package/dist/cjs/behavior/definitions/operational-credentials/OperationalCredentialsServer.js.map +2 -2
  17. package/dist/cjs/behavior/state/transaction/Transaction.d.ts +18 -18
  18. package/dist/cjs/certificate/CertificateManager.d.ts.map +1 -1
  19. package/dist/cjs/certificate/CertificateManager.js +1 -0
  20. package/dist/cjs/certificate/CertificateManager.js.map +2 -2
  21. package/dist/cjs/certificate/CertificationDeclarationManager.d.ts +1 -1
  22. package/dist/cjs/certificate/CertificationDeclarationManager.d.ts.map +1 -1
  23. package/dist/cjs/certificate/CertificationDeclarationManager.js +3 -2
  24. package/dist/cjs/certificate/CertificationDeclarationManager.js.map +2 -2
  25. package/dist/cjs/cluster/server/AccessControlServer.js.map +1 -1
  26. package/dist/cjs/cluster/server/AttributeServer.d.ts +9 -0
  27. package/dist/cjs/cluster/server/AttributeServer.d.ts.map +1 -1
  28. package/dist/cjs/cluster/server/AttributeServer.js +62 -0
  29. package/dist/cjs/cluster/server/AttributeServer.js.map +3 -3
  30. package/dist/cjs/cluster/server/ClusterServer.d.ts.map +1 -1
  31. package/dist/cjs/cluster/server/ClusterServer.js +8 -1
  32. package/dist/cjs/cluster/server/ClusterServer.js.map +2 -2
  33. package/dist/cjs/cluster/server/ClusterServerTypes.d.ts +3 -3
  34. package/dist/cjs/cluster/server/ClusterServerTypes.d.ts.map +1 -1
  35. package/dist/cjs/cluster/server/ClusterServerTypes.js.map +1 -1
  36. package/dist/cjs/cluster/server/EventServer.d.ts +8 -2
  37. package/dist/cjs/cluster/server/EventServer.d.ts.map +1 -1
  38. package/dist/cjs/cluster/server/EventServer.js +33 -7
  39. package/dist/cjs/cluster/server/EventServer.js.map +2 -2
  40. package/dist/cjs/cluster/server/OperationalCredentialsServer.d.ts.map +1 -1
  41. package/dist/cjs/cluster/server/OperationalCredentialsServer.js +31 -8
  42. package/dist/cjs/cluster/server/OperationalCredentialsServer.js.map +2 -2
  43. package/dist/cjs/common/FailsafeContext.d.ts +1 -0
  44. package/dist/cjs/common/FailsafeContext.d.ts.map +1 -1
  45. package/dist/cjs/common/FailsafeContext.js +16 -2
  46. package/dist/cjs/common/FailsafeContext.js.map +2 -2
  47. package/dist/cjs/crypto/Crypto.d.ts +1 -1
  48. package/dist/cjs/crypto/Crypto.d.ts.map +1 -1
  49. package/dist/cjs/crypto/Crypto.js +2 -2
  50. package/dist/cjs/crypto/Crypto.js.map +2 -2
  51. package/dist/cjs/device/LegacyInteractionServer.d.ts +2 -2
  52. package/dist/cjs/device/LegacyInteractionServer.d.ts.map +1 -1
  53. package/dist/cjs/device/LegacyInteractionServer.js +13 -1
  54. package/dist/cjs/device/LegacyInteractionServer.js.map +2 -2
  55. package/dist/cjs/fabric/Fabric.d.ts +1 -0
  56. package/dist/cjs/fabric/Fabric.d.ts.map +1 -1
  57. package/dist/cjs/fabric/Fabric.js +5 -0
  58. package/dist/cjs/fabric/Fabric.js.map +2 -2
  59. package/dist/cjs/fabric/FabricManager.d.ts +1 -0
  60. package/dist/cjs/fabric/FabricManager.d.ts.map +1 -1
  61. package/dist/cjs/fabric/FabricManager.js +2 -1
  62. package/dist/cjs/fabric/FabricManager.js.map +2 -2
  63. package/dist/cjs/model/models/EventModel.d.ts +1 -0
  64. package/dist/cjs/model/models/EventModel.d.ts.map +1 -1
  65. package/dist/cjs/model/models/EventModel.js +3 -0
  66. package/dist/cjs/model/models/EventModel.js.map +2 -2
  67. package/dist/cjs/model/models/FieldModel.d.ts +1 -0
  68. package/dist/cjs/model/models/FieldModel.d.ts.map +1 -1
  69. package/dist/cjs/model/models/FieldModel.js +3 -0
  70. package/dist/cjs/model/models/FieldModel.js.map +2 -2
  71. package/dist/cjs/node/server/TransactionalInteractionServer.d.ts +2 -2
  72. package/dist/cjs/node/server/TransactionalInteractionServer.d.ts.map +1 -1
  73. package/dist/cjs/node/server/TransactionalInteractionServer.js +0 -2
  74. package/dist/cjs/node/server/TransactionalInteractionServer.js.map +2 -2
  75. package/dist/cjs/protocol/interaction/AttributeDataEncoder.d.ts +6 -3
  76. package/dist/cjs/protocol/interaction/AttributeDataEncoder.d.ts.map +1 -1
  77. package/dist/cjs/protocol/interaction/AttributeDataEncoder.js +14 -8
  78. package/dist/cjs/protocol/interaction/AttributeDataEncoder.js.map +2 -2
  79. package/dist/cjs/protocol/interaction/EventHandler.d.ts.map +1 -1
  80. package/dist/cjs/protocol/interaction/EventHandler.js +1 -3
  81. package/dist/cjs/protocol/interaction/EventHandler.js.map +2 -2
  82. package/dist/cjs/protocol/interaction/InteractionClient.js +1 -1
  83. package/dist/cjs/protocol/interaction/InteractionClient.js.map +2 -2
  84. package/dist/cjs/protocol/interaction/InteractionEndpointStructure.d.ts +3 -3
  85. package/dist/cjs/protocol/interaction/InteractionEndpointStructure.d.ts.map +1 -1
  86. package/dist/cjs/protocol/interaction/InteractionEndpointStructure.js +1 -0
  87. package/dist/cjs/protocol/interaction/InteractionEndpointStructure.js.map +2 -2
  88. package/dist/cjs/protocol/interaction/InteractionMessenger.d.ts +1 -1
  89. package/dist/cjs/protocol/interaction/InteractionMessenger.d.ts.map +1 -1
  90. package/dist/cjs/protocol/interaction/InteractionMessenger.js +11 -4
  91. package/dist/cjs/protocol/interaction/InteractionMessenger.js.map +2 -2
  92. package/dist/cjs/protocol/interaction/InteractionServer.d.ts +5 -6
  93. package/dist/cjs/protocol/interaction/InteractionServer.d.ts.map +1 -1
  94. package/dist/cjs/protocol/interaction/InteractionServer.js +44 -37
  95. package/dist/cjs/protocol/interaction/InteractionServer.js.map +2 -2
  96. package/dist/cjs/protocol/interaction/SubscriptionHandler.d.ts +31 -12
  97. package/dist/cjs/protocol/interaction/SubscriptionHandler.d.ts.map +1 -1
  98. package/dist/cjs/protocol/interaction/SubscriptionHandler.js +161 -69
  99. package/dist/cjs/protocol/interaction/SubscriptionHandler.js.map +3 -3
  100. package/dist/cjs/session/SecureSession.d.ts.map +1 -1
  101. package/dist/cjs/session/SecureSession.js +2 -1
  102. package/dist/cjs/session/SecureSession.js.map +2 -2
  103. package/dist/cjs/session/SessionManager.d.ts +2 -0
  104. package/dist/cjs/session/SessionManager.d.ts.map +1 -1
  105. package/dist/cjs/session/SessionManager.js +7 -0
  106. package/dist/cjs/session/SessionManager.js.map +2 -2
  107. package/dist/cjs/tlv/TlvArray.d.ts +2 -2
  108. package/dist/cjs/tlv/TlvArray.d.ts.map +1 -1
  109. package/dist/cjs/tlv/TlvArray.js +2 -2
  110. package/dist/cjs/tlv/TlvArray.js.map +2 -2
  111. package/dist/cjs/tlv/TlvNullable.d.ts +2 -2
  112. package/dist/cjs/tlv/TlvNullable.d.ts.map +1 -1
  113. package/dist/cjs/tlv/TlvNullable.js +2 -2
  114. package/dist/cjs/tlv/TlvNullable.js.map +2 -2
  115. package/dist/cjs/tlv/TlvObject.d.ts +2 -2
  116. package/dist/cjs/tlv/TlvObject.d.ts.map +1 -1
  117. package/dist/cjs/tlv/TlvObject.js +18 -12
  118. package/dist/cjs/tlv/TlvObject.js.map +2 -2
  119. package/dist/cjs/tlv/TlvSchema.d.ts +14 -2
  120. package/dist/cjs/tlv/TlvSchema.d.ts.map +1 -1
  121. package/dist/cjs/tlv/TlvSchema.js +2 -2
  122. package/dist/cjs/tlv/TlvSchema.js.map +2 -2
  123. package/dist/cjs/tlv/TlvWrapper.d.ts +2 -2
  124. package/dist/cjs/tlv/TlvWrapper.d.ts.map +1 -1
  125. package/dist/cjs/tlv/TlvWrapper.js +2 -2
  126. package/dist/cjs/tlv/TlvWrapper.js.map +2 -2
  127. package/dist/esm/CommissioningServer.d.ts.map +1 -1
  128. package/dist/esm/CommissioningServer.js +0 -1
  129. package/dist/esm/CommissioningServer.js.map +2 -2
  130. package/dist/esm/MatterDevice.d.ts +3 -0
  131. package/dist/esm/MatterDevice.d.ts.map +1 -1
  132. package/dist/esm/MatterDevice.js +21 -7
  133. package/dist/esm/MatterDevice.js.map +2 -2
  134. package/dist/esm/behavior/AccessControl.js +2 -2
  135. package/dist/esm/behavior/AccessControl.js.map +2 -2
  136. package/dist/esm/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.d.ts +1 -0
  137. package/dist/esm/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.d.ts.map +1 -1
  138. package/dist/esm/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.js +15 -1
  139. package/dist/esm/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.js.map +2 -2
  140. package/dist/esm/behavior/definitions/operational-credentials/OperationalCredentialsServer.d.ts.map +1 -1
  141. package/dist/esm/behavior/definitions/operational-credentials/OperationalCredentialsServer.js +11 -2
  142. package/dist/esm/behavior/definitions/operational-credentials/OperationalCredentialsServer.js.map +2 -2
  143. package/dist/esm/behavior/state/transaction/Transaction.d.ts +18 -18
  144. package/dist/esm/certificate/CertificateManager.d.ts.map +1 -1
  145. package/dist/esm/certificate/CertificateManager.js +1 -0
  146. package/dist/esm/certificate/CertificateManager.js.map +2 -2
  147. package/dist/esm/certificate/CertificationDeclarationManager.d.ts +1 -1
  148. package/dist/esm/certificate/CertificationDeclarationManager.d.ts.map +1 -1
  149. package/dist/esm/certificate/CertificationDeclarationManager.js +3 -2
  150. package/dist/esm/certificate/CertificationDeclarationManager.js.map +2 -2
  151. package/dist/esm/cluster/server/AccessControlServer.js.map +1 -1
  152. package/dist/esm/cluster/server/AttributeServer.d.ts +9 -0
  153. package/dist/esm/cluster/server/AttributeServer.d.ts.map +1 -1
  154. package/dist/esm/cluster/server/AttributeServer.js +69 -1
  155. package/dist/esm/cluster/server/AttributeServer.js.map +2 -2
  156. package/dist/esm/cluster/server/ClusterServer.d.ts.map +1 -1
  157. package/dist/esm/cluster/server/ClusterServer.js +9 -2
  158. package/dist/esm/cluster/server/ClusterServer.js.map +2 -2
  159. package/dist/esm/cluster/server/ClusterServerTypes.d.ts +3 -3
  160. package/dist/esm/cluster/server/ClusterServerTypes.d.ts.map +1 -1
  161. package/dist/esm/cluster/server/ClusterServerTypes.js.map +1 -1
  162. package/dist/esm/cluster/server/EventServer.d.ts +8 -2
  163. package/dist/esm/cluster/server/EventServer.d.ts.map +1 -1
  164. package/dist/esm/cluster/server/EventServer.js +33 -7
  165. package/dist/esm/cluster/server/EventServer.js.map +2 -2
  166. package/dist/esm/cluster/server/OperationalCredentialsServer.d.ts.map +1 -1
  167. package/dist/esm/cluster/server/OperationalCredentialsServer.js +31 -8
  168. package/dist/esm/cluster/server/OperationalCredentialsServer.js.map +2 -2
  169. package/dist/esm/common/FailsafeContext.d.ts +1 -0
  170. package/dist/esm/common/FailsafeContext.d.ts.map +1 -1
  171. package/dist/esm/common/FailsafeContext.js +17 -3
  172. package/dist/esm/common/FailsafeContext.js.map +2 -2
  173. package/dist/esm/crypto/Crypto.d.ts +1 -1
  174. package/dist/esm/crypto/Crypto.d.ts.map +1 -1
  175. package/dist/esm/crypto/Crypto.js +2 -2
  176. package/dist/esm/crypto/Crypto.js.map +2 -2
  177. package/dist/esm/device/LegacyInteractionServer.d.ts +2 -2
  178. package/dist/esm/device/LegacyInteractionServer.d.ts.map +1 -1
  179. package/dist/esm/device/LegacyInteractionServer.js +13 -1
  180. package/dist/esm/device/LegacyInteractionServer.js.map +2 -2
  181. package/dist/esm/fabric/Fabric.d.ts +1 -0
  182. package/dist/esm/fabric/Fabric.d.ts.map +1 -1
  183. package/dist/esm/fabric/Fabric.js +5 -0
  184. package/dist/esm/fabric/Fabric.js.map +2 -2
  185. package/dist/esm/fabric/FabricManager.d.ts +1 -0
  186. package/dist/esm/fabric/FabricManager.d.ts.map +1 -1
  187. package/dist/esm/fabric/FabricManager.js +2 -1
  188. package/dist/esm/fabric/FabricManager.js.map +2 -2
  189. package/dist/esm/model/models/EventModel.d.ts +1 -0
  190. package/dist/esm/model/models/EventModel.d.ts.map +1 -1
  191. package/dist/esm/model/models/EventModel.js +3 -0
  192. package/dist/esm/model/models/EventModel.js.map +2 -2
  193. package/dist/esm/model/models/FieldModel.d.ts +1 -0
  194. package/dist/esm/model/models/FieldModel.d.ts.map +1 -1
  195. package/dist/esm/model/models/FieldModel.js +3 -0
  196. package/dist/esm/model/models/FieldModel.js.map +2 -2
  197. package/dist/esm/node/server/TransactionalInteractionServer.d.ts +2 -2
  198. package/dist/esm/node/server/TransactionalInteractionServer.d.ts.map +1 -1
  199. package/dist/esm/node/server/TransactionalInteractionServer.js +0 -2
  200. package/dist/esm/node/server/TransactionalInteractionServer.js.map +2 -2
  201. package/dist/esm/protocol/interaction/AttributeDataEncoder.d.ts +6 -3
  202. package/dist/esm/protocol/interaction/AttributeDataEncoder.d.ts.map +1 -1
  203. package/dist/esm/protocol/interaction/AttributeDataEncoder.js +14 -8
  204. package/dist/esm/protocol/interaction/AttributeDataEncoder.js.map +2 -2
  205. package/dist/esm/protocol/interaction/EventHandler.d.ts.map +1 -1
  206. package/dist/esm/protocol/interaction/EventHandler.js +1 -3
  207. package/dist/esm/protocol/interaction/EventHandler.js.map +2 -2
  208. package/dist/esm/protocol/interaction/InteractionClient.js +1 -1
  209. package/dist/esm/protocol/interaction/InteractionClient.js.map +2 -2
  210. package/dist/esm/protocol/interaction/InteractionEndpointStructure.d.ts +3 -3
  211. package/dist/esm/protocol/interaction/InteractionEndpointStructure.d.ts.map +1 -1
  212. package/dist/esm/protocol/interaction/InteractionEndpointStructure.js +1 -0
  213. package/dist/esm/protocol/interaction/InteractionEndpointStructure.js.map +2 -2
  214. package/dist/esm/protocol/interaction/InteractionMessenger.d.ts +1 -1
  215. package/dist/esm/protocol/interaction/InteractionMessenger.d.ts.map +1 -1
  216. package/dist/esm/protocol/interaction/InteractionMessenger.js +11 -4
  217. package/dist/esm/protocol/interaction/InteractionMessenger.js.map +2 -2
  218. package/dist/esm/protocol/interaction/InteractionServer.d.ts +5 -6
  219. package/dist/esm/protocol/interaction/InteractionServer.d.ts.map +1 -1
  220. package/dist/esm/protocol/interaction/InteractionServer.js +44 -37
  221. package/dist/esm/protocol/interaction/InteractionServer.js.map +2 -2
  222. package/dist/esm/protocol/interaction/SubscriptionHandler.d.ts +31 -12
  223. package/dist/esm/protocol/interaction/SubscriptionHandler.d.ts.map +1 -1
  224. package/dist/esm/protocol/interaction/SubscriptionHandler.js +161 -69
  225. package/dist/esm/protocol/interaction/SubscriptionHandler.js.map +3 -3
  226. package/dist/esm/session/SecureSession.d.ts.map +1 -1
  227. package/dist/esm/session/SecureSession.js +2 -1
  228. package/dist/esm/session/SecureSession.js.map +2 -2
  229. package/dist/esm/session/SessionManager.d.ts +2 -0
  230. package/dist/esm/session/SessionManager.d.ts.map +1 -1
  231. package/dist/esm/session/SessionManager.js +7 -0
  232. package/dist/esm/session/SessionManager.js.map +2 -2
  233. package/dist/esm/tlv/TlvArray.d.ts +2 -2
  234. package/dist/esm/tlv/TlvArray.d.ts.map +1 -1
  235. package/dist/esm/tlv/TlvArray.js +2 -2
  236. package/dist/esm/tlv/TlvArray.js.map +2 -2
  237. package/dist/esm/tlv/TlvNullable.d.ts +2 -2
  238. package/dist/esm/tlv/TlvNullable.d.ts.map +1 -1
  239. package/dist/esm/tlv/TlvNullable.js +2 -2
  240. package/dist/esm/tlv/TlvNullable.js.map +2 -2
  241. package/dist/esm/tlv/TlvObject.d.ts +2 -2
  242. package/dist/esm/tlv/TlvObject.d.ts.map +1 -1
  243. package/dist/esm/tlv/TlvObject.js +19 -13
  244. package/dist/esm/tlv/TlvObject.js.map +2 -2
  245. package/dist/esm/tlv/TlvSchema.d.ts +14 -2
  246. package/dist/esm/tlv/TlvSchema.d.ts.map +1 -1
  247. package/dist/esm/tlv/TlvSchema.js +2 -2
  248. package/dist/esm/tlv/TlvSchema.js.map +2 -2
  249. package/dist/esm/tlv/TlvWrapper.d.ts +2 -2
  250. package/dist/esm/tlv/TlvWrapper.d.ts.map +1 -1
  251. package/dist/esm/tlv/TlvWrapper.js +2 -2
  252. package/dist/esm/tlv/TlvWrapper.js.map +2 -2
  253. package/package.json +3 -3
  254. package/src/CommissioningServer.ts +0 -1
  255. package/src/MatterDevice.ts +34 -7
  256. package/src/behavior/AccessControl.ts +2 -2
  257. package/src/behavior/definitions/general-commissioning/ServerNodeFailsafeContext.ts +21 -1
  258. package/src/behavior/definitions/operational-credentials/OperationalCredentialsServer.ts +13 -0
  259. package/src/certificate/CertificateManager.ts +1 -2
  260. package/src/certificate/CertificationDeclarationManager.ts +2 -2
  261. package/src/cluster/server/AccessControlServer.ts +3 -3
  262. package/src/cluster/server/AttributeServer.ts +79 -1
  263. package/src/cluster/server/ClusterServer.ts +9 -2
  264. package/src/cluster/server/ClusterServerTypes.ts +3 -3
  265. package/src/cluster/server/EventServer.ts +57 -10
  266. package/src/cluster/server/OperationalCredentialsServer.ts +35 -5
  267. package/src/common/FailsafeContext.ts +19 -7
  268. package/src/crypto/Crypto.ts +1 -1
  269. package/src/device/LegacyInteractionServer.ts +15 -4
  270. package/src/fabric/Fabric.ts +6 -0
  271. package/src/fabric/FabricManager.ts +1 -0
  272. package/src/model/models/EventModel.ts +4 -0
  273. package/src/model/models/FieldModel.ts +4 -0
  274. package/src/node/server/TransactionalInteractionServer.ts +2 -4
  275. package/src/protocol/interaction/AttributeDataEncoder.ts +20 -9
  276. package/src/protocol/interaction/EventHandler.ts +1 -3
  277. package/src/protocol/interaction/InteractionClient.ts +1 -1
  278. package/src/protocol/interaction/InteractionEndpointStructure.ts +4 -4
  279. package/src/protocol/interaction/InteractionMessenger.ts +12 -3
  280. package/src/protocol/interaction/InteractionServer.ts +53 -52
  281. package/src/protocol/interaction/SubscriptionHandler.ts +215 -92
  282. package/src/session/SecureSession.ts +2 -1
  283. package/src/session/SessionManager.ts +9 -0
  284. package/src/tlv/TlvArray.ts +3 -3
  285. package/src/tlv/TlvNullable.ts +3 -3
  286. package/src/tlv/TlvObject.ts +20 -14
  287. package/src/tlv/TlvSchema.ts +17 -3
  288. package/src/tlv/TlvWrapper.ts +3 -3
@@ -248,7 +248,8 @@ class SecureSession extends import_Session.Session {
248
248
  }
249
249
  }
250
250
  async clearSubscriptions(flushSubscriptions = false) {
251
- for (const subscription of this.#subscriptions) {
251
+ const subscriptions = [...this.#subscriptions];
252
+ for (const subscription of subscriptions) {
252
253
  await subscription.cancel(flushSubscriptions);
253
254
  }
254
255
  this.#subscriptions.length = 0;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/session/SecureSession.ts"],
4
- "sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { DecodedMessage, DecodedPacket, Message, MessageCodec, Packet } from \"../codec/MessageCodec.js\";\nimport { MatterFlowError } from \"../common/MatterError.js\";\nimport { CRYPTO_SYMMETRIC_KEY_LENGTH, Crypto } from \"../crypto/Crypto.js\";\nimport { CaseAuthenticatedTag } from \"../datatype/CaseAuthenticatedTag.js\";\nimport { NodeId } from \"../datatype/NodeId.js\";\nimport { Fabric } from \"../fabric/Fabric.js\";\nimport { Diagnostic } from \"../log/Diagnostic.js\";\nimport { Logger } from \"../log/Logger.js\";\nimport { MessageCounter } from \"../protocol/MessageCounter.js\";\nimport { MessageReceptionStateEncryptedWithoutRollover } from \"../protocol/MessageReceptionState.js\";\nimport { StatusCode, StatusResponseError } from \"../protocol/interaction/StatusCode.js\";\nimport { SubscriptionHandler } from \"../protocol/interaction/SubscriptionHandler.js\";\nimport { ByteArray, Endian } from \"../util/ByteArray.js\";\nimport { DataWriter } from \"../util/DataWriter.js\";\nimport { Session, SessionParameterOptions } from \"./Session.js\";\n\nconst logger = Logger.get(\"SecureSession\");\n\nconst SESSION_KEYS_INFO = ByteArray.fromString(\"SessionKeys\");\nconst SESSION_RESUMPTION_KEYS_INFO = ByteArray.fromString(\"SessionResumptionKeys\");\n\nexport class NoAssociatedFabricError extends StatusResponseError {\n constructor(message: string) {\n super(message, StatusCode.UnsupportedAccess);\n }\n}\n\nexport class SecureSession<T> extends Session<T> {\n readonly #subscriptions = new Array<SubscriptionHandler>();\n #closingAfterExchangeFinished = false;\n #sendCloseMessageWhenClosing = true;\n readonly #context: T;\n readonly #id: number;\n #fabric: Fabric | undefined;\n readonly #peerNodeId: NodeId;\n readonly #peerSessionId: number;\n readonly #decryptKey: ByteArray;\n readonly #encryptKey: ByteArray;\n readonly #attestationKey: ByteArray;\n readonly #subscriptionChangedCallback: () => void;\n #caseAuthenticatedTags: CaseAuthenticatedTag[];\n\n static async create<T>(args: {\n context: T;\n id: number;\n fabric: Fabric | undefined;\n peerNodeId: NodeId;\n peerSessionId: number;\n sharedSecret: ByteArray;\n salt: ByteArray;\n isInitiator: boolean;\n isResumption: boolean;\n closeCallback: () => Promise<void>;\n subscriptionChangedCallback?: () => void;\n sessionParameters?: SessionParameterOptions;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n }) {\n const {\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n sharedSecret,\n salt,\n isInitiator,\n isResumption,\n closeCallback,\n sessionParameters,\n caseAuthenticatedTags,\n subscriptionChangedCallback,\n } = args;\n const keys = await Crypto.hkdf(\n sharedSecret,\n salt,\n isResumption ? SESSION_RESUMPTION_KEYS_INFO : SESSION_KEYS_INFO,\n CRYPTO_SYMMETRIC_KEY_LENGTH * 3,\n );\n const decryptKey = isInitiator ? keys.slice(16, 32) : keys.slice(0, 16);\n const encryptKey = isInitiator ? keys.slice(0, 16) : keys.slice(16, 32);\n const attestationKey = keys.slice(32, 48);\n return new SecureSession({\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n decryptKey,\n encryptKey,\n attestationKey,\n closeCallback,\n subscriptionChangedCallback,\n sessionParameters,\n isInitiator,\n caseAuthenticatedTags,\n });\n }\n\n constructor(args: {\n context: T;\n id: number;\n fabric: Fabric | undefined;\n peerNodeId: NodeId;\n peerSessionId: number;\n decryptKey: ByteArray;\n encryptKey: ByteArray;\n attestationKey: ByteArray;\n closeCallback: () => Promise<void>;\n subscriptionChangedCallback?: () => void;\n sessionParameters?: SessionParameterOptions;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n isInitiator: boolean;\n }) {\n super({\n ...args,\n setActiveTimestamp: true, // We always set the active timestamp for Secure sessions\n // Can be changed to a PersistedMessageCounter if we implement session storage\n messageCounter: new MessageCounter(() => {\n // Secure Session Message Counter\n // Expire/End the session before the counter rolls over\n this.end(true, true).catch(error => logger.error(`Error while closing session: ${error}`));\n }),\n messageReceptionState: new MessageReceptionStateEncryptedWithoutRollover(),\n });\n const {\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n decryptKey,\n encryptKey,\n attestationKey,\n subscriptionChangedCallback = () => {},\n caseAuthenticatedTags,\n } = args;\n\n this.#context = context;\n this.#id = id;\n this.#fabric = fabric;\n this.#peerNodeId = peerNodeId;\n this.#peerSessionId = peerSessionId;\n this.#decryptKey = decryptKey;\n this.#encryptKey = encryptKey;\n this.#attestationKey = attestationKey;\n this.#subscriptionChangedCallback = subscriptionChangedCallback;\n this.#caseAuthenticatedTags = caseAuthenticatedTags ?? fabric?.caseAuthenticatedTags ?? [];\n\n fabric?.addSession(this);\n\n logger.debug(\n `Created secure ${this.isPase ? \"PASE\" : \"CASE\"} session for fabric index ${fabric?.fabricIndex}`,\n this.name,\n Diagnostic.dict({\n idleIntervalMs: this.idleIntervalMs,\n activeIntervalMs: this.activeIntervalMs,\n activeThresholdMs: this.activeThresholdMs,\n }),\n );\n }\n\n get caseAuthenticatedTags() {\n return this.#caseAuthenticatedTags;\n }\n\n get closingAfterExchangeFinished() {\n return this.#closingAfterExchangeFinished;\n }\n\n get sendCloseMessageWhenClosing() {\n return this.#sendCloseMessageWhenClosing;\n }\n\n get isSecure(): boolean {\n return true;\n }\n\n get isPase(): boolean {\n return this.#peerNodeId === NodeId.UNSPECIFIED_NODE_ID;\n }\n\n async close(closeAfterExchangeFinished?: boolean) {\n if (closeAfterExchangeFinished === undefined) {\n closeAfterExchangeFinished = this.isPeerActive(); // We delay session close if the peer is actively communicating with us\n }\n await this.end(true, closeAfterExchangeFinished);\n }\n\n decode({ header, applicationPayload, messageExtension }: DecodedPacket, aad: ByteArray): DecodedMessage {\n if (header.hasMessageExtensions) {\n logger.info(`Message extensions are not supported. Ignoring ${messageExtension?.toHex()}`);\n }\n const nonce = this.generateNonce(header.securityFlags, header.messageId, this.#peerNodeId);\n const message = MessageCodec.decodePayload({\n header,\n applicationPayload: Crypto.decrypt(this.#decryptKey, applicationPayload, nonce, aad),\n });\n\n if (message.payloadHeader.hasSecuredExtension) {\n logger.info(`Secured extensions are not supported. Ignoring ${message.securityExtension?.toHex()}`);\n }\n\n return message;\n }\n\n encode(message: Message): Packet {\n message.packetHeader.sessionId = this.#peerSessionId;\n const { header, applicationPayload } = MessageCodec.encodePayload(message);\n const headerBytes = MessageCodec.encodePacketHeader(message.packetHeader);\n const securityFlags = headerBytes[3];\n const sessionNodeId = this.isPase\n ? NodeId.UNSPECIFIED_NODE_ID\n : this.#fabric?.nodeId ?? NodeId.UNSPECIFIED_NODE_ID;\n const nonce = this.generateNonce(securityFlags, header.messageId, sessionNodeId);\n return { header, applicationPayload: Crypto.encrypt(this.#encryptKey, applicationPayload, nonce, headerBytes) };\n }\n\n getAttestationChallengeKey(): ByteArray {\n return this.#attestationKey;\n }\n\n get fabric() {\n return this.#fabric;\n }\n\n addAssociatedFabric(fabric: Fabric) {\n if (this.#fabric !== undefined) {\n throw new MatterFlowError(\"Session already has an associated Fabric. Cannot change this.\");\n }\n this.#fabric = fabric;\n this.#caseAuthenticatedTags = fabric.caseAuthenticatedTags;\n }\n\n get id() {\n return this.#id;\n }\n\n get name() {\n return `secure/${this.#id}`;\n }\n\n get context() {\n return this.#context;\n }\n\n get peerSessionId(): number {\n return this.#peerSessionId;\n }\n\n get nodeId() {\n return this.#fabric?.nodeId ?? NodeId.UNSPECIFIED_NODE_ID;\n }\n\n get peerNodeId() {\n return this.#peerNodeId;\n }\n\n get numberOfActiveSubscriptions() {\n return this.#subscriptions.length;\n }\n\n get associatedFabric(): Fabric {\n if (this.#fabric === undefined) {\n throw new NoAssociatedFabricError(\n `${this.isPase ? \"PASE \" : \"\"}Session needs to have an associated Fabric for fabric sensitive data handling.`,\n );\n }\n return this.#fabric;\n }\n\n addSubscription(subscription: SubscriptionHandler) {\n this.#subscriptions.push(subscription);\n logger.debug(`Added subscription ${subscription.subscriptionId} to ${this.name}`);\n this.#subscriptionChangedCallback();\n }\n\n removeSubscription(subscriptionId: number) {\n const index = this.#subscriptions.findIndex(subscription => subscription.subscriptionId === subscriptionId);\n if (index !== -1) {\n this.#subscriptions.splice(index, 1);\n logger.debug(`Removed subscription ${subscriptionId} from ${this.name}`);\n this.#subscriptionChangedCallback();\n }\n }\n\n async clearSubscriptions(flushSubscriptions = false) {\n for (const subscription of this.#subscriptions) {\n await subscription.cancel(flushSubscriptions);\n }\n this.#subscriptions.length = 0;\n }\n\n /** Ends a session. Outstanding subscription data will be flushed before the session is destroyed. */\n async end(sendClose: boolean, closeAfterExchangeFinished = false) {\n await this.clearSubscriptions(true);\n await this.destroy(sendClose, closeAfterExchangeFinished);\n }\n\n /** Destroys a session. Outstanding subscription data will be discarded. */\n async destroy(sendClose = false, closeAfterExchangeFinished = true) {\n await this.clearSubscriptions(false);\n this.#fabric?.removeSession(this);\n if (!sendClose) {\n this.#sendCloseMessageWhenClosing = false;\n }\n\n if (closeAfterExchangeFinished) {\n logger.info(`Register Session ${this.name} to send a close when exchange is ended.`);\n this.#closingAfterExchangeFinished = true;\n } else {\n await this.closeCallback();\n }\n }\n\n private generateNonce(securityFlags: number, messageId: number, nodeId: NodeId) {\n const writer = new DataWriter(Endian.Little);\n writer.writeUInt8(securityFlags);\n writer.writeUInt32(messageId);\n writer.writeUInt64(nodeId);\n return writer.toByteArray();\n }\n}\n\nexport function assertSecureSession<T>(session: Session<T>, errorText?: string): asserts session is SecureSession<T> {\n if (!session.isSecure) {\n throw new MatterFlowError(errorText ?? \"Insecure session in secure context\");\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 { DecodedMessage, DecodedPacket, Message, MessageCodec, Packet } from \"../codec/MessageCodec.js\";\nimport { MatterFlowError } from \"../common/MatterError.js\";\nimport { CRYPTO_SYMMETRIC_KEY_LENGTH, Crypto } from \"../crypto/Crypto.js\";\nimport { CaseAuthenticatedTag } from \"../datatype/CaseAuthenticatedTag.js\";\nimport { NodeId } from \"../datatype/NodeId.js\";\nimport { Fabric } from \"../fabric/Fabric.js\";\nimport { Diagnostic } from \"../log/Diagnostic.js\";\nimport { Logger } from \"../log/Logger.js\";\nimport { MessageCounter } from \"../protocol/MessageCounter.js\";\nimport { MessageReceptionStateEncryptedWithoutRollover } from \"../protocol/MessageReceptionState.js\";\nimport { StatusCode, StatusResponseError } from \"../protocol/interaction/StatusCode.js\";\nimport { SubscriptionHandler } from \"../protocol/interaction/SubscriptionHandler.js\";\nimport { ByteArray, Endian } from \"../util/ByteArray.js\";\nimport { DataWriter } from \"../util/DataWriter.js\";\nimport { Session, SessionParameterOptions } from \"./Session.js\";\n\nconst logger = Logger.get(\"SecureSession\");\n\nconst SESSION_KEYS_INFO = ByteArray.fromString(\"SessionKeys\");\nconst SESSION_RESUMPTION_KEYS_INFO = ByteArray.fromString(\"SessionResumptionKeys\");\n\nexport class NoAssociatedFabricError extends StatusResponseError {\n constructor(message: string) {\n super(message, StatusCode.UnsupportedAccess);\n }\n}\n\nexport class SecureSession<T> extends Session<T> {\n readonly #subscriptions = new Array<SubscriptionHandler>();\n #closingAfterExchangeFinished = false;\n #sendCloseMessageWhenClosing = true;\n readonly #context: T;\n readonly #id: number;\n #fabric: Fabric | undefined;\n readonly #peerNodeId: NodeId;\n readonly #peerSessionId: number;\n readonly #decryptKey: ByteArray;\n readonly #encryptKey: ByteArray;\n readonly #attestationKey: ByteArray;\n readonly #subscriptionChangedCallback: () => void;\n #caseAuthenticatedTags: CaseAuthenticatedTag[];\n\n static async create<T>(args: {\n context: T;\n id: number;\n fabric: Fabric | undefined;\n peerNodeId: NodeId;\n peerSessionId: number;\n sharedSecret: ByteArray;\n salt: ByteArray;\n isInitiator: boolean;\n isResumption: boolean;\n closeCallback: () => Promise<void>;\n subscriptionChangedCallback?: () => void;\n sessionParameters?: SessionParameterOptions;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n }) {\n const {\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n sharedSecret,\n salt,\n isInitiator,\n isResumption,\n closeCallback,\n sessionParameters,\n caseAuthenticatedTags,\n subscriptionChangedCallback,\n } = args;\n const keys = await Crypto.hkdf(\n sharedSecret,\n salt,\n isResumption ? SESSION_RESUMPTION_KEYS_INFO : SESSION_KEYS_INFO,\n CRYPTO_SYMMETRIC_KEY_LENGTH * 3,\n );\n const decryptKey = isInitiator ? keys.slice(16, 32) : keys.slice(0, 16);\n const encryptKey = isInitiator ? keys.slice(0, 16) : keys.slice(16, 32);\n const attestationKey = keys.slice(32, 48);\n return new SecureSession({\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n decryptKey,\n encryptKey,\n attestationKey,\n closeCallback,\n subscriptionChangedCallback,\n sessionParameters,\n isInitiator,\n caseAuthenticatedTags,\n });\n }\n\n constructor(args: {\n context: T;\n id: number;\n fabric: Fabric | undefined;\n peerNodeId: NodeId;\n peerSessionId: number;\n decryptKey: ByteArray;\n encryptKey: ByteArray;\n attestationKey: ByteArray;\n closeCallback: () => Promise<void>;\n subscriptionChangedCallback?: () => void;\n sessionParameters?: SessionParameterOptions;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n isInitiator: boolean;\n }) {\n super({\n ...args,\n setActiveTimestamp: true, // We always set the active timestamp for Secure sessions\n // Can be changed to a PersistedMessageCounter if we implement session storage\n messageCounter: new MessageCounter(() => {\n // Secure Session Message Counter\n // Expire/End the session before the counter rolls over\n this.end(true, true).catch(error => logger.error(`Error while closing session: ${error}`));\n }),\n messageReceptionState: new MessageReceptionStateEncryptedWithoutRollover(),\n });\n const {\n context,\n id,\n fabric,\n peerNodeId,\n peerSessionId,\n decryptKey,\n encryptKey,\n attestationKey,\n subscriptionChangedCallback = () => {},\n caseAuthenticatedTags,\n } = args;\n\n this.#context = context;\n this.#id = id;\n this.#fabric = fabric;\n this.#peerNodeId = peerNodeId;\n this.#peerSessionId = peerSessionId;\n this.#decryptKey = decryptKey;\n this.#encryptKey = encryptKey;\n this.#attestationKey = attestationKey;\n this.#subscriptionChangedCallback = subscriptionChangedCallback;\n this.#caseAuthenticatedTags = caseAuthenticatedTags ?? fabric?.caseAuthenticatedTags ?? [];\n\n fabric?.addSession(this);\n\n logger.debug(\n `Created secure ${this.isPase ? \"PASE\" : \"CASE\"} session for fabric index ${fabric?.fabricIndex}`,\n this.name,\n Diagnostic.dict({\n idleIntervalMs: this.idleIntervalMs,\n activeIntervalMs: this.activeIntervalMs,\n activeThresholdMs: this.activeThresholdMs,\n }),\n );\n }\n\n get caseAuthenticatedTags() {\n return this.#caseAuthenticatedTags;\n }\n\n get closingAfterExchangeFinished() {\n return this.#closingAfterExchangeFinished;\n }\n\n get sendCloseMessageWhenClosing() {\n return this.#sendCloseMessageWhenClosing;\n }\n\n get isSecure(): boolean {\n return true;\n }\n\n get isPase(): boolean {\n return this.#peerNodeId === NodeId.UNSPECIFIED_NODE_ID;\n }\n\n async close(closeAfterExchangeFinished?: boolean) {\n if (closeAfterExchangeFinished === undefined) {\n closeAfterExchangeFinished = this.isPeerActive(); // We delay session close if the peer is actively communicating with us\n }\n await this.end(true, closeAfterExchangeFinished);\n }\n\n decode({ header, applicationPayload, messageExtension }: DecodedPacket, aad: ByteArray): DecodedMessage {\n if (header.hasMessageExtensions) {\n logger.info(`Message extensions are not supported. Ignoring ${messageExtension?.toHex()}`);\n }\n const nonce = this.generateNonce(header.securityFlags, header.messageId, this.#peerNodeId);\n const message = MessageCodec.decodePayload({\n header,\n applicationPayload: Crypto.decrypt(this.#decryptKey, applicationPayload, nonce, aad),\n });\n\n if (message.payloadHeader.hasSecuredExtension) {\n logger.info(`Secured extensions are not supported. Ignoring ${message.securityExtension?.toHex()}`);\n }\n\n return message;\n }\n\n encode(message: Message): Packet {\n message.packetHeader.sessionId = this.#peerSessionId;\n const { header, applicationPayload } = MessageCodec.encodePayload(message);\n const headerBytes = MessageCodec.encodePacketHeader(message.packetHeader);\n const securityFlags = headerBytes[3];\n const sessionNodeId = this.isPase\n ? NodeId.UNSPECIFIED_NODE_ID\n : this.#fabric?.nodeId ?? NodeId.UNSPECIFIED_NODE_ID;\n const nonce = this.generateNonce(securityFlags, header.messageId, sessionNodeId);\n return { header, applicationPayload: Crypto.encrypt(this.#encryptKey, applicationPayload, nonce, headerBytes) };\n }\n\n getAttestationChallengeKey(): ByteArray {\n return this.#attestationKey;\n }\n\n get fabric() {\n return this.#fabric;\n }\n\n addAssociatedFabric(fabric: Fabric) {\n if (this.#fabric !== undefined) {\n throw new MatterFlowError(\"Session already has an associated Fabric. Cannot change this.\");\n }\n this.#fabric = fabric;\n this.#caseAuthenticatedTags = fabric.caseAuthenticatedTags;\n }\n\n get id() {\n return this.#id;\n }\n\n get name() {\n return `secure/${this.#id}`;\n }\n\n get context() {\n return this.#context;\n }\n\n get peerSessionId(): number {\n return this.#peerSessionId;\n }\n\n get nodeId() {\n return this.#fabric?.nodeId ?? NodeId.UNSPECIFIED_NODE_ID;\n }\n\n get peerNodeId() {\n return this.#peerNodeId;\n }\n\n get numberOfActiveSubscriptions() {\n return this.#subscriptions.length;\n }\n\n get associatedFabric(): Fabric {\n if (this.#fabric === undefined) {\n throw new NoAssociatedFabricError(\n `${this.isPase ? \"PASE \" : \"\"}Session needs to have an associated Fabric for fabric sensitive data handling.`,\n );\n }\n return this.#fabric;\n }\n\n addSubscription(subscription: SubscriptionHandler) {\n this.#subscriptions.push(subscription);\n logger.debug(`Added subscription ${subscription.subscriptionId} to ${this.name}`);\n this.#subscriptionChangedCallback();\n }\n\n removeSubscription(subscriptionId: number) {\n const index = this.#subscriptions.findIndex(subscription => subscription.subscriptionId === subscriptionId);\n if (index !== -1) {\n this.#subscriptions.splice(index, 1);\n logger.debug(`Removed subscription ${subscriptionId} from ${this.name}`);\n this.#subscriptionChangedCallback();\n }\n }\n\n async clearSubscriptions(flushSubscriptions = false) {\n const subscriptions = [...this.#subscriptions]; // get all values because subscriptions will remove themselves when cancelled\n for (const subscription of subscriptions) {\n await subscription.cancel(flushSubscriptions);\n }\n this.#subscriptions.length = 0;\n }\n\n /** Ends a session. Outstanding subscription data will be flushed before the session is destroyed. */\n async end(sendClose: boolean, closeAfterExchangeFinished = false) {\n await this.clearSubscriptions(true);\n await this.destroy(sendClose, closeAfterExchangeFinished);\n }\n\n /** Destroys a session. Outstanding subscription data will be discarded. */\n async destroy(sendClose = false, closeAfterExchangeFinished = true) {\n await this.clearSubscriptions(false);\n this.#fabric?.removeSession(this);\n if (!sendClose) {\n this.#sendCloseMessageWhenClosing = false;\n }\n\n if (closeAfterExchangeFinished) {\n logger.info(`Register Session ${this.name} to send a close when exchange is ended.`);\n this.#closingAfterExchangeFinished = true;\n } else {\n await this.closeCallback();\n }\n }\n\n private generateNonce(securityFlags: number, messageId: number, nodeId: NodeId) {\n const writer = new DataWriter(Endian.Little);\n writer.writeUInt8(securityFlags);\n writer.writeUInt32(messageId);\n writer.writeUInt64(nodeId);\n return writer.toByteArray();\n }\n}\n\nexport function assertSecureSession<T>(session: Session<T>, errorText?: string): asserts session is SecureSession<T> {\n if (!session.isSecure) {\n throw new MatterFlowError(errorText ?? \"Insecure session in secure context\");\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -4,6 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { CaseAuthenticatedTag } from "../datatype/CaseAuthenticatedTag.js";
7
+ import { FabricIndex } from "../datatype/FabricIndex.js";
7
8
  import { NodeId } from "../datatype/NodeId.js";
8
9
  import { Fabric } from "../fabric/Fabric.js";
9
10
  import { StorageContext } from "../storage/StorageContext.js";
@@ -72,6 +73,7 @@ export declare class SessionManager<ContextT> {
72
73
  lastActiveTimestamp: number | undefined;
73
74
  numberOfActiveSubscriptions: number;
74
75
  }[];
76
+ clearSubscriptionsForNode(fabricIndex: FabricIndex, nodeId: NodeId, flushSubscriptions?: boolean): Promise<void>;
75
77
  close(): Promise<void>;
76
78
  }
77
79
  //# sourceMappingURL=SessionManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SessionManager.d.ts","sourceRoot":"","sources":["../../../src/session/SessionManager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAI1E,eAAO,MAAM,2BAA2B,IAAS,CAAC;AAElD,MAAM,WAAW,gBAAgB;IAC7B,YAAY,EAAE,SAAS,CAAC;IACxB,YAAY,EAAE,SAAS,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,qBAAqB,CAAC,EAAE,oBAAoB,EAAE,CAAC;CAClD;AAgBD,qBAAa,cAAc,CAAC,QAAQ;;IAY5B,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,QAAQ,EAClC,cAAc,EAAE,cAAc;IAKlC,IAAI,oBAAoB,yDAEvB;IAED,IAAI,aAAa,yDAEhB;IAED,IAAI,aAAa,8DAEhB;IAED,qBAAqB,CAAC,OAAO,EAAE;QAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;QAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;KACzB;IA4BK,mBAAmB,CAAC,IAAI,EAAE;QAC5B,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,SAAS,CAAC;QACxB,IAAI,EAAE,SAAS,CAAC;QAChB,WAAW,EAAE,OAAO,CAAC;QACrB,YAAY,EAAE,OAAO,CAAC;QACtB,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;QAC5C,qBAAqB,CAAC,EAAE,oBAAoB,EAAE,CAAC;KAClD;IA0CD,aAAa,CAAC,SAAS,EAAE,MAAM;IAOzB,sBAAsB,CAAC,UAAU,EAAE,MAAM;IAK/C,yBAAyB;IAanB,yBAAyB;IAkB/B,UAAU,CAAC,SAAS,EAAE,MAAM;IAI5B,cAAc;IAMd,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAS1C,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,UAAQ;IAUhE,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM;IAOxC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;IASxD,wBAAwB,CAAC,YAAY,EAAE,SAAS;IAIhD,4BAA4B,CAAC,MAAM,EAAE,MAAM;IAIrC,oBAAoB,CAAC,gBAAgB,EAAE,gBAAgB;IAKvD,gCAAgC,CAAC,MAAM,EAAE,MAAM;IAS/C,sBAAsB;IAqBtB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE;IAkCvC,2BAA2B;;;;;;;;;;;IAgBrB,KAAK;CAWd"}
1
+ {"version":3,"file":"SessionManager.d.ts","sourceRoot":"","sources":["../../../src/session/SessionManager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAI1E,eAAO,MAAM,2BAA2B,IAAS,CAAC;AAElD,MAAM,WAAW,gBAAgB;IAC7B,YAAY,EAAE,SAAS,CAAC;IACxB,YAAY,EAAE,SAAS,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,qBAAqB,CAAC,EAAE,oBAAoB,EAAE,CAAC;CAClD;AAgBD,qBAAa,cAAc,CAAC,QAAQ;;IAY5B,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,QAAQ,EAClC,cAAc,EAAE,cAAc;IAKlC,IAAI,oBAAoB,yDAEvB;IAED,IAAI,aAAa,yDAEhB;IAED,IAAI,aAAa,8DAEhB;IAED,qBAAqB,CAAC,OAAO,EAAE;QAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;QAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;KACzB;IA4BK,mBAAmB,CAAC,IAAI,EAAE;QAC5B,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,SAAS,CAAC;QACxB,IAAI,EAAE,SAAS,CAAC;QAChB,WAAW,EAAE,OAAO,CAAC;QACrB,YAAY,EAAE,OAAO,CAAC;QACtB,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;QAC5C,qBAAqB,CAAC,EAAE,oBAAoB,EAAE,CAAC;KAClD;IA0CD,aAAa,CAAC,SAAS,EAAE,MAAM;IAOzB,sBAAsB,CAAC,UAAU,EAAE,MAAM;IAK/C,yBAAyB;IAanB,yBAAyB;IAkB/B,UAAU,CAAC,SAAS,EAAE,MAAM;IAI5B,cAAc;IAMd,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAS1C,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,UAAQ;IAUhE,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM;IAOxC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;IASxD,wBAAwB,CAAC,YAAY,EAAE,SAAS;IAIhD,4BAA4B,CAAC,MAAM,EAAE,MAAM;IAIrC,oBAAoB,CAAC,gBAAgB,EAAE,gBAAgB;IAKvD,gCAAgC,CAAC,MAAM,EAAE,MAAM;IAS/C,sBAAsB;IAqBtB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE;IAkCvC,2BAA2B;;;;;;;;;;;IAgBrB,yBAAyB,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,CAAC,EAAE,OAAO;IAQhG,KAAK;CAWd"}
@@ -275,6 +275,13 @@ class SessionManager {
275
275
  numberOfActiveSubscriptions: session instanceof import_SecureSession.SecureSession ? session.numberOfActiveSubscriptions : 0
276
276
  }));
277
277
  }
278
+ async clearSubscriptionsForNode(fabricIndex, nodeId, flushSubscriptions) {
279
+ for (const session of this.#sessions) {
280
+ if (session.fabric?.fabricIndex === fabricIndex && session.peerNodeId === nodeId) {
281
+ await session.clearSubscriptions(flushSubscriptions);
282
+ }
283
+ }
284
+ }
278
285
  async close() {
279
286
  await this.storeResumptionRecords();
280
287
  for (const session of this.#sessions) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/session/SessionManager.ts"],
4
- "sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { MatterFlowError } from \"../common/MatterError.js\";\nimport { Crypto } from \"../crypto/Crypto.js\";\nimport { CaseAuthenticatedTag } from \"../datatype/CaseAuthenticatedTag.js\";\nimport { FabricId } from \"../datatype/FabricId.js\";\nimport { NodeId } from \"../datatype/NodeId.js\";\nimport { Fabric } from \"../fabric/Fabric.js\";\nimport { Logger } from \"../log/Logger.js\";\nimport { MessageCounter } from \"../protocol/MessageCounter.js\";\nimport { StorageContext } from \"../storage/StorageContext.js\";\nimport { ByteArray } from \"../util/ByteArray.js\";\nimport { AsyncObservable, Observable } from \"../util/Observable.js\";\nimport { BasicSet } from \"../util/Set.js\";\nimport { InsecureSession } from \"./InsecureSession.js\";\nimport { SecureSession } from \"./SecureSession.js\";\nimport { SessionParameterOptions, SessionParameters } from \"./Session.js\";\n\nconst logger = Logger.get(\"SessionManager\");\n\nexport const UNICAST_UNSECURE_SESSION_ID = 0x0000;\n\nexport interface ResumptionRecord {\n sharedSecret: ByteArray;\n resumptionId: ByteArray;\n fabric: Fabric;\n peerNodeId: NodeId;\n sessionParameters: SessionParameters;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n}\n\ntype ResumptionStorageRecord = {\n nodeId: NodeId;\n sharedSecret: Uint8Array;\n resumptionId: Uint8Array;\n fabricId: FabricId;\n peerNodeId: NodeId;\n sessionParameters: {\n idleIntervalMs: number;\n activeIntervalMs: number;\n activeThresholdMs: number;\n };\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n};\n\nexport class SessionManager<ContextT> {\n readonly #insecureSessions = new Map<NodeId, InsecureSession<ContextT>>();\n readonly #sessions = new BasicSet<SecureSession<ContextT>>();\n #nextSessionId = Crypto.getRandomUInt16();\n #resumptionRecords = new Map<NodeId, ResumptionRecord>();\n readonly #sessionStorage: StorageContext;\n readonly #globalUnencryptedMessageCounter = new MessageCounter();\n readonly #subscriptionsChanged = new Observable<[session: SecureSession<ContextT>]>();\n readonly #sessionOpened = new Observable<[session: SecureSession<ContextT>]>();\n readonly #sessionClosed = new AsyncObservable<[session: SecureSession<ContextT>], void>();\n\n constructor(\n private readonly context: ContextT,\n sessionStorage: StorageContext,\n ) {\n this.#sessionStorage = sessionStorage;\n }\n\n get subscriptionsChanged() {\n return this.#subscriptionsChanged;\n }\n\n get sessionOpened() {\n return this.#sessionOpened;\n }\n\n get sessionClosed() {\n return this.#sessionClosed;\n }\n\n createUnsecureSession(options: {\n initiatorNodeId?: NodeId;\n sessionParameters?: SessionParameterOptions;\n isInitiator?: boolean;\n }) {\n const { initiatorNodeId, sessionParameters, isInitiator } = options;\n if (initiatorNodeId !== undefined) {\n if (this.#insecureSessions.has(initiatorNodeId)) {\n throw new MatterFlowError(`UnsecureSession with NodeId ${initiatorNodeId} already exists.`);\n }\n }\n while (true) {\n const session = new InsecureSession({\n context: this.context,\n messageCounter: this.#globalUnencryptedMessageCounter,\n closeCallback: async () => {\n logger.info(`End insecure session ${session.name}`);\n this.#insecureSessions.delete(session.nodeId);\n },\n initiatorNodeId,\n sessionParameters,\n isInitiator: isInitiator ?? false,\n });\n\n const ephermalNodeId = session.nodeId;\n if (this.#insecureSessions.has(ephermalNodeId)) continue;\n\n this.#insecureSessions.set(ephermalNodeId, session);\n return session;\n }\n }\n\n async createSecureSession(args: {\n sessionId: number;\n fabric: Fabric | undefined;\n peerNodeId: NodeId;\n peerSessionId: number;\n sharedSecret: ByteArray;\n salt: ByteArray;\n isInitiator: boolean;\n isResumption: boolean;\n sessionParameters?: SessionParameterOptions;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n }) {\n const {\n sessionId,\n fabric,\n peerNodeId,\n peerSessionId,\n sharedSecret,\n salt,\n isInitiator,\n isResumption,\n sessionParameters,\n caseAuthenticatedTags,\n } = args;\n const session = await SecureSession.create({\n context: this.context,\n id: sessionId,\n fabric,\n peerNodeId,\n peerSessionId,\n sharedSecret,\n salt,\n isInitiator,\n isResumption,\n closeCallback: async () => {\n logger.info(`End ${session.isPase ? \"PASE\" : \"CASE\"} session ${session.name}`);\n this.#sessions.delete(session);\n await this.#sessionClosed.emit(session);\n },\n sessionParameters,\n caseAuthenticatedTags,\n subscriptionChangedCallback: () => {\n this.#subscriptionsChanged.emit(session);\n },\n });\n\n this.#sessions.add(session);\n this.#sessionOpened.emit(session);\n\n // TODO: Add a maximum of sessions and respect/close the \"least recently used\" session. See Core Specs 4.10.1.1\n return session;\n }\n\n removeSession(sessionId: number) {\n const session = this.getSession(sessionId);\n if (session !== undefined) {\n this.#sessions.delete(session);\n }\n }\n\n async removeResumptionRecord(peerNodeId: NodeId) {\n this.#resumptionRecords.delete(peerNodeId);\n await this.storeResumptionRecords();\n }\n\n findOldestInactiveSession() {\n let oldestSession: SecureSession<ContextT> | undefined = undefined;\n for (const session of this.#sessions) {\n if (!oldestSession || session.activeTimestamp < oldestSession.activeTimestamp) {\n oldestSession = session;\n }\n }\n if (oldestSession === undefined) {\n throw new MatterFlowError(\"No session found to close and all session ids are taken.\");\n }\n return oldestSession;\n }\n\n async getNextAvailableSessionId() {\n for (let i = 0; i < 0xffff; i++) {\n const id = this.#nextSessionId;\n this.#nextSessionId = (this.#nextSessionId + 1) & 0xffff;\n if (this.#nextSessionId === 0) this.#nextSessionId++;\n\n if (this.getSession(id) === undefined) {\n return id;\n }\n }\n\n // All session ids are taken, search for the oldest unused session, and close it and re-use its ID\n const oldestSession = this.findOldestInactiveSession();\n await oldestSession.end(true, false);\n this.#nextSessionId = oldestSession.id;\n return this.#nextSessionId++;\n }\n\n getSession(sessionId: number) {\n return this.#sessions.get(\"id\", sessionId);\n }\n\n getPaseSession() {\n return [...this.#sessions].find(\n session => session.isSecure && session.isPase && !session.closingAfterExchangeFinished,\n ) as SecureSession<ContextT>;\n }\n\n getSessionForNode(fabric: Fabric, nodeId: NodeId) {\n //TODO: It can have multiple sessions for one node ...\n return [...this.#sessions].find(session => {\n if (!session.isSecure) return false;\n const secureSession = session as SecureSession<any>;\n return secureSession.fabric?.fabricId === fabric.fabricId && secureSession.peerNodeId === nodeId;\n });\n }\n\n async removeAllSessionsForNode(nodeId: NodeId, sendClose = false) {\n for (const session of this.#sessions) {\n if (!session.isSecure) continue;\n const secureSession = session as SecureSession<any>;\n if (secureSession.peerNodeId === nodeId) {\n await secureSession.destroy(sendClose, false);\n }\n }\n }\n\n getUnsecureSession(sourceNodeId?: NodeId) {\n if (sourceNodeId === undefined) {\n return this.#insecureSessions.get(NodeId.UNSPECIFIED_NODE_ID);\n }\n return this.#insecureSessions.get(sourceNodeId);\n }\n\n findGroupSession(groupId: number, groupSessionId: number) {\n // Use groupsession id to find the key ??!!\n // The Group Session ID MAY help receiving nodes efficiently locate the Operational Group Key used to encrypt an incoming groupcast message. It SHALL NOT be used as the sole means to locate the asso\u00AD ciated Operational Group Key, since it MAY collide within the fabric. Instead, the Group Session ID provides receiving nodes a means to identify Operational Group Key candidates without the need to first attempt to decrypt groupcast messages using all available keys.\n // On receipt of a message of Group Session Type, all valid, installed, operational group key candidates referenced by the given Group Session ID SHALL be attempted until authentication is passed or there are no more operational group keys to try. This is done because the same Group Session ID might arise from different keys. The chance of a Group Session ID collision is 2-16 but the chance of both a Group Session ID collision and the message MIC matching two different operational group keys is 2-80.\n\n // TODO\n throw new Error(`Not implemented ${groupId} ${groupSessionId}`);\n }\n\n findResumptionRecordById(resumptionId: ByteArray) {\n return [...this.#resumptionRecords.values()].find(record => record.resumptionId.equals(resumptionId));\n }\n\n findResumptionRecordByNodeId(nodeId: NodeId) {\n return this.#resumptionRecords.get(nodeId);\n }\n\n async saveResumptionRecord(resumptionRecord: ResumptionRecord) {\n this.#resumptionRecords.set(resumptionRecord.peerNodeId, resumptionRecord);\n await this.storeResumptionRecords();\n }\n\n async updateFabricForResumptionRecords(fabric: Fabric) {\n const record = this.#resumptionRecords.get(fabric.rootNodeId);\n if (record === undefined) {\n throw new MatterFlowError(\"Resumption record not found. Should never happen.\");\n }\n this.#resumptionRecords.set(fabric.rootNodeId, { ...record, fabric });\n await this.storeResumptionRecords();\n }\n\n async storeResumptionRecords() {\n await this.#sessionStorage.set(\n \"resumptionRecords\",\n [...this.#resumptionRecords].map(\n ([\n nodeId,\n { sharedSecret, resumptionId, peerNodeId, fabric, sessionParameters, caseAuthenticatedTags },\n ]) =>\n ({\n nodeId,\n sharedSecret,\n resumptionId,\n fabricId: fabric.fabricId,\n peerNodeId: peerNodeId,\n sessionParameters,\n caseAuthenticatedTags,\n }) as ResumptionStorageRecord,\n ),\n );\n }\n\n async initFromStorage(fabrics: Fabric[]) {\n const storedResumptionRecords = await this.#sessionStorage.get<ResumptionStorageRecord[]>(\n \"resumptionRecords\",\n [],\n );\n\n storedResumptionRecords.forEach(\n ({\n nodeId,\n sharedSecret,\n resumptionId,\n fabricId,\n peerNodeId,\n sessionParameters,\n caseAuthenticatedTags,\n }) => {\n logger.info(\"restoring resumption record for node\", nodeId);\n const fabric = fabrics.find(fabric => fabric.fabricId === fabricId);\n if (!fabric) {\n logger.error(\"fabric not found for resumption record\", fabricId);\n return;\n }\n this.#resumptionRecords.set(nodeId, {\n sharedSecret,\n resumptionId,\n fabric,\n peerNodeId,\n sessionParameters,\n caseAuthenticatedTags,\n });\n },\n );\n }\n\n getActiveSessionInformation() {\n return [...this.#sessions]\n .filter(session => session.isSecure && !session.isPase)\n .map(session => ({\n name: session.name,\n nodeId: session.nodeId,\n peerNodeId: session.peerNodeId,\n fabric: session instanceof SecureSession ? session.fabric?.externalInformation : undefined,\n isPeerActive: session.isPeerActive(),\n secure: session.isSecure,\n lastInteractionTimestamp: session instanceof SecureSession ? session.timestamp : undefined,\n lastActiveTimestamp: session instanceof SecureSession ? session.activeTimestamp : undefined,\n numberOfActiveSubscriptions: session instanceof SecureSession ? session.numberOfActiveSubscriptions : 0,\n }));\n }\n\n async close() {\n await this.storeResumptionRecords();\n for (const session of this.#sessions) {\n await session?.end(false);\n this.#sessions.delete(session);\n }\n for (const session of this.#insecureSessions.values()) {\n await session?.end();\n this.#insecureSessions.delete(session.nodeId);\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 { MatterFlowError } from \"../common/MatterError.js\";\nimport { Crypto } from \"../crypto/Crypto.js\";\nimport { CaseAuthenticatedTag } from \"../datatype/CaseAuthenticatedTag.js\";\nimport { FabricId } from \"../datatype/FabricId.js\";\nimport { FabricIndex } from \"../datatype/FabricIndex.js\";\nimport { NodeId } from \"../datatype/NodeId.js\";\nimport { Fabric } from \"../fabric/Fabric.js\";\nimport { Logger } from \"../log/Logger.js\";\nimport { MessageCounter } from \"../protocol/MessageCounter.js\";\nimport { StorageContext } from \"../storage/StorageContext.js\";\nimport { ByteArray } from \"../util/ByteArray.js\";\nimport { AsyncObservable, Observable } from \"../util/Observable.js\";\nimport { BasicSet } from \"../util/Set.js\";\nimport { InsecureSession } from \"./InsecureSession.js\";\nimport { SecureSession } from \"./SecureSession.js\";\nimport { SessionParameterOptions, SessionParameters } from \"./Session.js\";\n\nconst logger = Logger.get(\"SessionManager\");\n\nexport const UNICAST_UNSECURE_SESSION_ID = 0x0000;\n\nexport interface ResumptionRecord {\n sharedSecret: ByteArray;\n resumptionId: ByteArray;\n fabric: Fabric;\n peerNodeId: NodeId;\n sessionParameters: SessionParameters;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n}\n\ntype ResumptionStorageRecord = {\n nodeId: NodeId;\n sharedSecret: Uint8Array;\n resumptionId: Uint8Array;\n fabricId: FabricId;\n peerNodeId: NodeId;\n sessionParameters: {\n idleIntervalMs: number;\n activeIntervalMs: number;\n activeThresholdMs: number;\n };\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n};\n\nexport class SessionManager<ContextT> {\n readonly #insecureSessions = new Map<NodeId, InsecureSession<ContextT>>();\n readonly #sessions = new BasicSet<SecureSession<ContextT>>();\n #nextSessionId = Crypto.getRandomUInt16();\n #resumptionRecords = new Map<NodeId, ResumptionRecord>();\n readonly #sessionStorage: StorageContext;\n readonly #globalUnencryptedMessageCounter = new MessageCounter();\n readonly #subscriptionsChanged = new Observable<[session: SecureSession<ContextT>]>();\n readonly #sessionOpened = new Observable<[session: SecureSession<ContextT>]>();\n readonly #sessionClosed = new AsyncObservable<[session: SecureSession<ContextT>], void>();\n\n constructor(\n private readonly context: ContextT,\n sessionStorage: StorageContext,\n ) {\n this.#sessionStorage = sessionStorage;\n }\n\n get subscriptionsChanged() {\n return this.#subscriptionsChanged;\n }\n\n get sessionOpened() {\n return this.#sessionOpened;\n }\n\n get sessionClosed() {\n return this.#sessionClosed;\n }\n\n createUnsecureSession(options: {\n initiatorNodeId?: NodeId;\n sessionParameters?: SessionParameterOptions;\n isInitiator?: boolean;\n }) {\n const { initiatorNodeId, sessionParameters, isInitiator } = options;\n if (initiatorNodeId !== undefined) {\n if (this.#insecureSessions.has(initiatorNodeId)) {\n throw new MatterFlowError(`UnsecureSession with NodeId ${initiatorNodeId} already exists.`);\n }\n }\n while (true) {\n const session = new InsecureSession({\n context: this.context,\n messageCounter: this.#globalUnencryptedMessageCounter,\n closeCallback: async () => {\n logger.info(`End insecure session ${session.name}`);\n this.#insecureSessions.delete(session.nodeId);\n },\n initiatorNodeId,\n sessionParameters,\n isInitiator: isInitiator ?? false,\n });\n\n const ephermalNodeId = session.nodeId;\n if (this.#insecureSessions.has(ephermalNodeId)) continue;\n\n this.#insecureSessions.set(ephermalNodeId, session);\n return session;\n }\n }\n\n async createSecureSession(args: {\n sessionId: number;\n fabric: Fabric | undefined;\n peerNodeId: NodeId;\n peerSessionId: number;\n sharedSecret: ByteArray;\n salt: ByteArray;\n isInitiator: boolean;\n isResumption: boolean;\n sessionParameters?: SessionParameterOptions;\n caseAuthenticatedTags?: CaseAuthenticatedTag[];\n }) {\n const {\n sessionId,\n fabric,\n peerNodeId,\n peerSessionId,\n sharedSecret,\n salt,\n isInitiator,\n isResumption,\n sessionParameters,\n caseAuthenticatedTags,\n } = args;\n const session = await SecureSession.create({\n context: this.context,\n id: sessionId,\n fabric,\n peerNodeId,\n peerSessionId,\n sharedSecret,\n salt,\n isInitiator,\n isResumption,\n closeCallback: async () => {\n logger.info(`End ${session.isPase ? \"PASE\" : \"CASE\"} session ${session.name}`);\n this.#sessions.delete(session);\n await this.#sessionClosed.emit(session);\n },\n sessionParameters,\n caseAuthenticatedTags,\n subscriptionChangedCallback: () => {\n this.#subscriptionsChanged.emit(session);\n },\n });\n\n this.#sessions.add(session);\n this.#sessionOpened.emit(session);\n\n // TODO: Add a maximum of sessions and respect/close the \"least recently used\" session. See Core Specs 4.10.1.1\n return session;\n }\n\n removeSession(sessionId: number) {\n const session = this.getSession(sessionId);\n if (session !== undefined) {\n this.#sessions.delete(session);\n }\n }\n\n async removeResumptionRecord(peerNodeId: NodeId) {\n this.#resumptionRecords.delete(peerNodeId);\n await this.storeResumptionRecords();\n }\n\n findOldestInactiveSession() {\n let oldestSession: SecureSession<ContextT> | undefined = undefined;\n for (const session of this.#sessions) {\n if (!oldestSession || session.activeTimestamp < oldestSession.activeTimestamp) {\n oldestSession = session;\n }\n }\n if (oldestSession === undefined) {\n throw new MatterFlowError(\"No session found to close and all session ids are taken.\");\n }\n return oldestSession;\n }\n\n async getNextAvailableSessionId() {\n for (let i = 0; i < 0xffff; i++) {\n const id = this.#nextSessionId;\n this.#nextSessionId = (this.#nextSessionId + 1) & 0xffff;\n if (this.#nextSessionId === 0) this.#nextSessionId++;\n\n if (this.getSession(id) === undefined) {\n return id;\n }\n }\n\n // All session ids are taken, search for the oldest unused session, and close it and re-use its ID\n const oldestSession = this.findOldestInactiveSession();\n await oldestSession.end(true, false);\n this.#nextSessionId = oldestSession.id;\n return this.#nextSessionId++;\n }\n\n getSession(sessionId: number) {\n return this.#sessions.get(\"id\", sessionId);\n }\n\n getPaseSession() {\n return [...this.#sessions].find(\n session => session.isSecure && session.isPase && !session.closingAfterExchangeFinished,\n ) as SecureSession<ContextT>;\n }\n\n getSessionForNode(fabric: Fabric, nodeId: NodeId) {\n //TODO: It can have multiple sessions for one node ...\n return [...this.#sessions].find(session => {\n if (!session.isSecure) return false;\n const secureSession = session as SecureSession<any>;\n return secureSession.fabric?.fabricId === fabric.fabricId && secureSession.peerNodeId === nodeId;\n });\n }\n\n async removeAllSessionsForNode(nodeId: NodeId, sendClose = false) {\n for (const session of this.#sessions) {\n if (!session.isSecure) continue;\n const secureSession = session as SecureSession<any>;\n if (secureSession.peerNodeId === nodeId) {\n await secureSession.destroy(sendClose, false);\n }\n }\n }\n\n getUnsecureSession(sourceNodeId?: NodeId) {\n if (sourceNodeId === undefined) {\n return this.#insecureSessions.get(NodeId.UNSPECIFIED_NODE_ID);\n }\n return this.#insecureSessions.get(sourceNodeId);\n }\n\n findGroupSession(groupId: number, groupSessionId: number) {\n // Use groupsession id to find the key ??!!\n // The Group Session ID MAY help receiving nodes efficiently locate the Operational Group Key used to encrypt an incoming groupcast message. It SHALL NOT be used as the sole means to locate the asso\u00AD ciated Operational Group Key, since it MAY collide within the fabric. Instead, the Group Session ID provides receiving nodes a means to identify Operational Group Key candidates without the need to first attempt to decrypt groupcast messages using all available keys.\n // On receipt of a message of Group Session Type, all valid, installed, operational group key candidates referenced by the given Group Session ID SHALL be attempted until authentication is passed or there are no more operational group keys to try. This is done because the same Group Session ID might arise from different keys. The chance of a Group Session ID collision is 2-16 but the chance of both a Group Session ID collision and the message MIC matching two different operational group keys is 2-80.\n\n // TODO\n throw new Error(`Not implemented ${groupId} ${groupSessionId}`);\n }\n\n findResumptionRecordById(resumptionId: ByteArray) {\n return [...this.#resumptionRecords.values()].find(record => record.resumptionId.equals(resumptionId));\n }\n\n findResumptionRecordByNodeId(nodeId: NodeId) {\n return this.#resumptionRecords.get(nodeId);\n }\n\n async saveResumptionRecord(resumptionRecord: ResumptionRecord) {\n this.#resumptionRecords.set(resumptionRecord.peerNodeId, resumptionRecord);\n await this.storeResumptionRecords();\n }\n\n async updateFabricForResumptionRecords(fabric: Fabric) {\n const record = this.#resumptionRecords.get(fabric.rootNodeId);\n if (record === undefined) {\n throw new MatterFlowError(\"Resumption record not found. Should never happen.\");\n }\n this.#resumptionRecords.set(fabric.rootNodeId, { ...record, fabric });\n await this.storeResumptionRecords();\n }\n\n async storeResumptionRecords() {\n await this.#sessionStorage.set(\n \"resumptionRecords\",\n [...this.#resumptionRecords].map(\n ([\n nodeId,\n { sharedSecret, resumptionId, peerNodeId, fabric, sessionParameters, caseAuthenticatedTags },\n ]) =>\n ({\n nodeId,\n sharedSecret,\n resumptionId,\n fabricId: fabric.fabricId,\n peerNodeId: peerNodeId,\n sessionParameters,\n caseAuthenticatedTags,\n }) as ResumptionStorageRecord,\n ),\n );\n }\n\n async initFromStorage(fabrics: Fabric[]) {\n const storedResumptionRecords = await this.#sessionStorage.get<ResumptionStorageRecord[]>(\n \"resumptionRecords\",\n [],\n );\n\n storedResumptionRecords.forEach(\n ({\n nodeId,\n sharedSecret,\n resumptionId,\n fabricId,\n peerNodeId,\n sessionParameters,\n caseAuthenticatedTags,\n }) => {\n logger.info(\"restoring resumption record for node\", nodeId);\n const fabric = fabrics.find(fabric => fabric.fabricId === fabricId);\n if (!fabric) {\n logger.error(\"fabric not found for resumption record\", fabricId);\n return;\n }\n this.#resumptionRecords.set(nodeId, {\n sharedSecret,\n resumptionId,\n fabric,\n peerNodeId,\n sessionParameters,\n caseAuthenticatedTags,\n });\n },\n );\n }\n\n getActiveSessionInformation() {\n return [...this.#sessions]\n .filter(session => session.isSecure && !session.isPase)\n .map(session => ({\n name: session.name,\n nodeId: session.nodeId,\n peerNodeId: session.peerNodeId,\n fabric: session instanceof SecureSession ? session.fabric?.externalInformation : undefined,\n isPeerActive: session.isPeerActive(),\n secure: session.isSecure,\n lastInteractionTimestamp: session instanceof SecureSession ? session.timestamp : undefined,\n lastActiveTimestamp: session instanceof SecureSession ? session.activeTimestamp : undefined,\n numberOfActiveSubscriptions: session instanceof SecureSession ? session.numberOfActiveSubscriptions : 0,\n }));\n }\n\n async clearSubscriptionsForNode(fabricIndex: FabricIndex, nodeId: NodeId, flushSubscriptions?: boolean) {\n for (const session of this.#sessions) {\n if (session.fabric?.fabricIndex === fabricIndex && session.peerNodeId === nodeId) {\n await session.clearSubscriptions(flushSubscriptions);\n }\n }\n }\n\n async close() {\n await this.storeResumptionRecords();\n for (const session of this.#sessions) {\n await session?.end(false);\n this.#sessions.delete(session);\n }\n for (const session of this.#insecureSessions.values()) {\n await session?.end();\n this.#insecureSessions.delete(session.nodeId);\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["fabric"]
7
7
  }
@@ -4,7 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { TlvTag, TlvTypeLength } from "./TlvCodec.js";
7
- import { TlvReader, TlvSchema, TlvStream, TlvWriter } from "./TlvSchema.js";
7
+ import { TlvEncodingOptions, TlvReader, TlvSchema, TlvStream, TlvWriter } from "./TlvSchema.js";
8
8
  export type LengthConstraints = {
9
9
  minLength?: number;
10
10
  maxLength?: number;
@@ -25,7 +25,7 @@ export declare class ArraySchema<T> extends TlvSchema<T[]> {
25
25
  readonly minLength: number;
26
26
  readonly maxLength: number;
27
27
  constructor(elementSchema: TlvSchema<T>, minLength?: number, maxLength?: number);
28
- encodeTlvInternal(writer: TlvWriter, value: T[], tag?: TlvTag, forWriteInteraction?: boolean): void;
28
+ encodeTlvInternal(writer: TlvWriter, value: T[], tag?: TlvTag, options?: TlvEncodingOptions): void;
29
29
  decodeTlvInternalValue(reader: TlvReader, typeLength: TlvTypeLength): T[];
30
30
  injectField(value: T[], fieldId: number, fieldValue: any, injectChecker: (fieldValue: any) => boolean): T[];
31
31
  removeField(value: T[], fieldId: number, removeChecker: (fieldValue: any) => boolean): T[];
@@ -1 +1 @@
1
- {"version":3,"file":"TlvArray.d.ts","sourceRoot":"","sources":["../../../src/tlv/TlvArray.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,EAAE,MAAM,EAAW,aAAa,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE5E,MAAM,MAAM,iBAAiB,GAAG;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,cAAc,GAAG;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACrC,OAAO,EAAE,SAAS,CAAC;CACtB,CAAC;AACF,MAAM,MAAM,cAAc,GAAG,cAAc,EAAE,CAAC;AAE9C;;;;GAIG;AACH,qBAAa,WAAW,CAAC,CAAC,CAAE,SAAQ,SAAS,CAAC,CAAC,EAAE,CAAC;IAE1C,QAAQ,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM;gBAFjB,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC,EAC3B,SAAS,GAAE,MAAU,EACrB,SAAS,GAAE,MAAc;IAK7B,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,mBAAmB,CAAC,EAAE,OAAO,GAAG,IAAI;IAMnG,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,GAAG,CAAC,EAAE;IAazE,WAAW,CAChB,KAAK,EAAE,CAAC,EAAE,EACV,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,GAAG,EACf,aAAa,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,OAAO,GAC5C,CAAC,EAAE;IAUG,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,OAAO,GAAG,CAAC,EAAE;IAS1F,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI;IAkBlC,sBAAsB,CAAC,MAAM,EAAE,cAAc,EAAE,YAAY,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE;IA0BvE,oBAAoB,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,cAAc;CASnD;AAED,wBAAwB;AACxB,eAAO,MAAM,QAAQ,qBAAsB,UAAU,CAAC,CAAC,qCAAoC,iBAAiB,mBAChC,CAAC"}
1
+ {"version":3,"file":"TlvArray.d.ts","sourceRoot":"","sources":["../../../src/tlv/TlvArray.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,EAAE,MAAM,EAAW,aAAa,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhG,MAAM,MAAM,iBAAiB,GAAG;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,cAAc,GAAG;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACrC,OAAO,EAAE,SAAS,CAAC;CACtB,CAAC;AACF,MAAM,MAAM,cAAc,GAAG,cAAc,EAAE,CAAC;AAE9C;;;;GAIG;AACH,qBAAa,WAAW,CAAC,CAAC,CAAE,SAAQ,SAAS,CAAC,CAAC,EAAE,CAAC;IAE1C,QAAQ,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM;gBAFjB,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC,EAC3B,SAAS,GAAE,MAAU,EACrB,SAAS,GAAE,MAAc;IAK7B,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,IAAI;IAMlG,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,GAAG,CAAC,EAAE;IAazE,WAAW,CAChB,KAAK,EAAE,CAAC,EAAE,EACV,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,GAAG,EACf,aAAa,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,OAAO,GAC5C,CAAC,EAAE;IAUG,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,OAAO,GAAG,CAAC,EAAE;IAS1F,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI;IAkBlC,sBAAsB,CAAC,MAAM,EAAE,cAAc,EAAE,YAAY,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE;IA0BvE,oBAAoB,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,cAAc;CASnD;AAED,wBAAwB;AACxB,eAAO,MAAM,QAAQ,qBAAsB,UAAU,CAAC,CAAC,qCAAoC,iBAAiB,mBAChC,CAAC"}
@@ -41,9 +41,9 @@ class ArraySchema extends import_TlvSchema.TlvSchema {
41
41
  this.minLength = minLength;
42
42
  this.maxLength = maxLength;
43
43
  }
44
- encodeTlvInternal(writer, value, tag, forWriteInteraction) {
44
+ encodeTlvInternal(writer, value, tag, options) {
45
45
  writer.writeTag({ type: import_TlvCodec.TlvType.Array }, tag);
46
- value.forEach((element) => this.elementSchema.encodeTlvInternal(writer, element, void 0, forWriteInteraction));
46
+ value.forEach((element) => this.elementSchema.encodeTlvInternal(writer, element, void 0, options));
47
47
  writer.writeTag({ type: import_TlvCodec.TlvType.EndOfContainer });
48
48
  }
49
49
  decodeTlvInternalValue(reader, typeLength) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tlv/TlvArray.ts"],
4
- "sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { UnexpectedDataError } from \"../common/MatterError.js\";\nimport { tryCatch } from \"../common/TryCatchHandler.js\";\nimport { ValidationError } from \"../common/ValidationError.js\";\nimport { deepCopy } from \"../util/DeepCopy.js\";\nimport { serialize } from \"../util/String.js\";\nimport { TlvTag, TlvType, TlvTypeLength } from \"./TlvCodec.js\";\nimport { TlvReader, TlvSchema, TlvStream, TlvWriter } from \"./TlvSchema.js\";\n\nexport type LengthConstraints = {\n minLength?: number;\n maxLength?: number;\n length?: number;\n};\n\ntype ArrayChunkData = {\n listIndex: number | null | undefined;\n element: TlvStream;\n};\nexport type ArrayAsChunked = ArrayChunkData[];\n\n/**\n * Schema to encode an array or string in TLV.\n *\n * @see {@link MatterSpecification.v10.Core} \u00A7 A.11.2 and A.11.4\n */\nexport class ArraySchema<T> extends TlvSchema<T[]> {\n constructor(\n readonly elementSchema: TlvSchema<T>,\n readonly minLength: number = 0,\n readonly maxLength: number = 65535,\n ) {\n super();\n }\n\n override encodeTlvInternal(writer: TlvWriter, value: T[], tag?: TlvTag, forWriteInteraction?: boolean): void {\n writer.writeTag({ type: TlvType.Array }, tag);\n value.forEach(element => this.elementSchema.encodeTlvInternal(writer, element, undefined, forWriteInteraction));\n writer.writeTag({ type: TlvType.EndOfContainer });\n }\n\n override decodeTlvInternalValue(reader: TlvReader, typeLength: TlvTypeLength): T[] {\n if (typeLength.type !== TlvType.Array)\n throw new UnexpectedDataError(`Unexpected type ${typeLength.type}, expected Array (${TlvType.Array}).`);\n const result = new Array<T>();\n while (true) {\n const { tag: elementTag, typeLength: elementTypeLength } = reader.readTagType();\n if (elementTag !== undefined) throw new UnexpectedDataError(\"Array element tags should be anonymous.\");\n if (elementTypeLength.type === TlvType.EndOfContainer) break;\n result.push(this.elementSchema.decodeTlvInternalValue(reader, elementTypeLength));\n }\n return result;\n }\n\n override injectField(\n value: T[],\n fieldId: number,\n fieldValue: any,\n injectChecker: (fieldValue: any) => boolean,\n ): T[] {\n if (Array.isArray(value)) {\n value.forEach(\n (item, index) =>\n (value[index] = this.elementSchema.injectField(item, fieldId, fieldValue, injectChecker)),\n );\n }\n return value;\n }\n\n override removeField(value: T[], fieldId: number, removeChecker: (fieldValue: any) => boolean): T[] {\n if (Array.isArray(value)) {\n value.forEach(\n (item, index) => (value[index] = this.elementSchema.removeField(item, fieldId, removeChecker)),\n );\n }\n return value;\n }\n\n override validate(data: T[]): void {\n if (!Array.isArray(data)) throw new ValidationError(`Expected array, got ${typeof data}.`);\n if (data.length > this.maxLength)\n throw new ValidationError(`Array ${serialize(data)} is too long: ${data.length}, max ${this.maxLength}.`);\n if (data.length < this.minLength)\n throw new ValidationError(`Array ${serialize(data)} is too short: ${data.length}, min ${this.minLength}.`);\n data.forEach((element, index) => {\n tryCatch(\n () => this.elementSchema.validate(element),\n ValidationError,\n error => {\n error.fieldName = `[${index}]${error.fieldName !== undefined ? `.${error.fieldName}` : \"\"}`;\n throw error;\n },\n );\n });\n }\n\n decodeFromChunkedArray(chunks: ArrayAsChunked, currentValue?: T[]): T[] {\n if (currentValue === undefined && chunks[0].listIndex !== undefined) {\n throw new UnexpectedDataError(\n `When no current value is supplied the first chunked element needs to have a list index of undefined, but received ${chunks[0].listIndex}.`,\n );\n }\n currentValue = currentValue !== undefined ? deepCopy(currentValue) : []; // For the sake of typing; the above check makes sure it is an array\n for (const { listIndex, element } of chunks) {\n if (listIndex === undefined) {\n // not set listIndex means \"Override the whole array\"\n currentValue = this.decodeTlv(element);\n } else if (listIndex === null) {\n // null listIndex means \"Append to the array\"\n const decodedElement = this.elementSchema.decodeTlv(element);\n currentValue.push(decodedElement);\n } else if (element[0].typeLength.type === TlvType.Null) {\n // null element means \"Remove from the array\"\n currentValue.splice(listIndex, 1);\n } else {\n // otherwise, set the element at the given index\n currentValue[listIndex] = this.elementSchema.decodeTlv(element);\n }\n }\n return currentValue;\n }\n\n encodeAsChunkedArray(value: T[]): ArrayAsChunked {\n const result: ArrayAsChunked = [];\n result.push({ listIndex: undefined, element: this.encodeTlv([]) });\n value.forEach(element => {\n const elementStream = this.elementSchema.encodeTlv(element);\n result.push({ listIndex: null, element: elementStream });\n });\n return result;\n }\n}\n\n/** Array TLV schema. */\nexport const TlvArray = <T>(elementSchema: TlvSchema<T>, { minLength, maxLength, length }: LengthConstraints = {}) =>\n new ArraySchema(elementSchema, length ?? minLength, length ?? maxLength);\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 { UnexpectedDataError } from \"../common/MatterError.js\";\nimport { tryCatch } from \"../common/TryCatchHandler.js\";\nimport { ValidationError } from \"../common/ValidationError.js\";\nimport { deepCopy } from \"../util/DeepCopy.js\";\nimport { serialize } from \"../util/String.js\";\nimport { TlvTag, TlvType, TlvTypeLength } from \"./TlvCodec.js\";\nimport { TlvEncodingOptions, TlvReader, TlvSchema, TlvStream, TlvWriter } from \"./TlvSchema.js\";\n\nexport type LengthConstraints = {\n minLength?: number;\n maxLength?: number;\n length?: number;\n};\n\ntype ArrayChunkData = {\n listIndex: number | null | undefined;\n element: TlvStream;\n};\nexport type ArrayAsChunked = ArrayChunkData[];\n\n/**\n * Schema to encode an array or string in TLV.\n *\n * @see {@link MatterSpecification.v10.Core} \u00A7 A.11.2 and A.11.4\n */\nexport class ArraySchema<T> extends TlvSchema<T[]> {\n constructor(\n readonly elementSchema: TlvSchema<T>,\n readonly minLength: number = 0,\n readonly maxLength: number = 65535,\n ) {\n super();\n }\n\n override encodeTlvInternal(writer: TlvWriter, value: T[], tag?: TlvTag, options?: TlvEncodingOptions): void {\n writer.writeTag({ type: TlvType.Array }, tag);\n value.forEach(element => this.elementSchema.encodeTlvInternal(writer, element, undefined, options));\n writer.writeTag({ type: TlvType.EndOfContainer });\n }\n\n override decodeTlvInternalValue(reader: TlvReader, typeLength: TlvTypeLength): T[] {\n if (typeLength.type !== TlvType.Array)\n throw new UnexpectedDataError(`Unexpected type ${typeLength.type}, expected Array (${TlvType.Array}).`);\n const result = new Array<T>();\n while (true) {\n const { tag: elementTag, typeLength: elementTypeLength } = reader.readTagType();\n if (elementTag !== undefined) throw new UnexpectedDataError(\"Array element tags should be anonymous.\");\n if (elementTypeLength.type === TlvType.EndOfContainer) break;\n result.push(this.elementSchema.decodeTlvInternalValue(reader, elementTypeLength));\n }\n return result;\n }\n\n override injectField(\n value: T[],\n fieldId: number,\n fieldValue: any,\n injectChecker: (fieldValue: any) => boolean,\n ): T[] {\n if (Array.isArray(value)) {\n value.forEach(\n (item, index) =>\n (value[index] = this.elementSchema.injectField(item, fieldId, fieldValue, injectChecker)),\n );\n }\n return value;\n }\n\n override removeField(value: T[], fieldId: number, removeChecker: (fieldValue: any) => boolean): T[] {\n if (Array.isArray(value)) {\n value.forEach(\n (item, index) => (value[index] = this.elementSchema.removeField(item, fieldId, removeChecker)),\n );\n }\n return value;\n }\n\n override validate(data: T[]): void {\n if (!Array.isArray(data)) throw new ValidationError(`Expected array, got ${typeof data}.`);\n if (data.length > this.maxLength)\n throw new ValidationError(`Array ${serialize(data)} is too long: ${data.length}, max ${this.maxLength}.`);\n if (data.length < this.minLength)\n throw new ValidationError(`Array ${serialize(data)} is too short: ${data.length}, min ${this.minLength}.`);\n data.forEach((element, index) => {\n tryCatch(\n () => this.elementSchema.validate(element),\n ValidationError,\n error => {\n error.fieldName = `[${index}]${error.fieldName !== undefined ? `.${error.fieldName}` : \"\"}`;\n throw error;\n },\n );\n });\n }\n\n decodeFromChunkedArray(chunks: ArrayAsChunked, currentValue?: T[]): T[] {\n if (currentValue === undefined && chunks[0].listIndex !== undefined) {\n throw new UnexpectedDataError(\n `When no current value is supplied the first chunked element needs to have a list index of undefined, but received ${chunks[0].listIndex}.`,\n );\n }\n currentValue = currentValue !== undefined ? deepCopy(currentValue) : []; // For the sake of typing; the above check makes sure it is an array\n for (const { listIndex, element } of chunks) {\n if (listIndex === undefined) {\n // not set listIndex means \"Override the whole array\"\n currentValue = this.decodeTlv(element);\n } else if (listIndex === null) {\n // null listIndex means \"Append to the array\"\n const decodedElement = this.elementSchema.decodeTlv(element);\n currentValue.push(decodedElement);\n } else if (element[0].typeLength.type === TlvType.Null) {\n // null element means \"Remove from the array\"\n currentValue.splice(listIndex, 1);\n } else {\n // otherwise, set the element at the given index\n currentValue[listIndex] = this.elementSchema.decodeTlv(element);\n }\n }\n return currentValue;\n }\n\n encodeAsChunkedArray(value: T[]): ArrayAsChunked {\n const result: ArrayAsChunked = [];\n result.push({ listIndex: undefined, element: this.encodeTlv([]) });\n value.forEach(element => {\n const elementStream = this.elementSchema.encodeTlv(element);\n result.push({ listIndex: null, element: elementStream });\n });\n return result;\n }\n}\n\n/** Array TLV schema. */\nexport const TlvArray = <T>(elementSchema: TlvSchema<T>, { minLength, maxLength, length }: LengthConstraints = {}) =>\n new ArraySchema(elementSchema, length ?? minLength, length ?? maxLength);\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -4,7 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { TlvTag, TlvTypeLength } from "./TlvCodec.js";
7
- import { TlvReader, TlvSchema, TlvWriter } from "./TlvSchema.js";
7
+ import { TlvEncodingOptions, TlvReader, TlvSchema, TlvWriter } from "./TlvSchema.js";
8
8
  /**
9
9
  * Schema to encode a nullable value in TLV.
10
10
  *
@@ -13,7 +13,7 @@ import { TlvReader, TlvSchema, TlvWriter } from "./TlvSchema.js";
13
13
  export declare class NullableSchema<T> extends TlvSchema<T | null> {
14
14
  private readonly schema;
15
15
  constructor(schema: TlvSchema<T>);
16
- encodeTlvInternal(writer: TlvWriter, value: T | null, tag?: TlvTag, forWriteInteraction?: boolean): void;
16
+ encodeTlvInternal(writer: TlvWriter, value: T | null, tag?: TlvTag, options?: TlvEncodingOptions): void;
17
17
  decodeTlvInternalValue(reader: TlvReader, typeLength: TlvTypeLength): T | null;
18
18
  validate(value: T | null): void;
19
19
  injectField(value: T, fieldId: number, fieldValue: any, injectChecker: (fieldValue: any) => boolean): T;
@@ -1 +1 @@
1
- {"version":3,"file":"TlvNullable.d.ts","sourceRoot":"","sources":["../../../src/tlv/TlvNullable.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,MAAM,EAAW,aAAa,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGjE;;;;GAIG;AACH,qBAAa,cAAc,CAAC,CAAC,CAAE,SAAQ,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAIxC,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,mBAAmB,CAAC,EAAE,OAAO,GAAG,IAAI;IAQxG,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,GAAG,CAAC,GAAG,IAAI;IAgB9E,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI;IAI/B,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,OAAO,GAAG,CAAC;IAOvG,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,OAAO,GAAG,CAAC;CAMlG;AAED,2BAA2B;AAC3B,eAAO,MAAM,WAAW,cAAe,UAAU,CAAC,CAAC,sBAA+B,CAAC"}
1
+ {"version":3,"file":"TlvNullable.d.ts","sourceRoot":"","sources":["../../../src/tlv/TlvNullable.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,MAAM,EAAW,aAAa,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGrF;;;;GAIG;AACH,qBAAa,cAAc,CAAC,CAAC,CAAE,SAAQ,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAIxC,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,IAAI;IAQvG,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,GAAG,CAAC,GAAG,IAAI;IAgB9E,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI;IAI/B,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,OAAO,GAAG,CAAC;IAOvG,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,OAAO,GAAG,CAAC;CAMlG;AAED,2BAA2B;AAC3B,eAAO,MAAM,WAAW,cAAe,UAAU,CAAC,CAAC,sBAA+B,CAAC"}
@@ -36,11 +36,11 @@ class NullableSchema extends import_TlvSchema.TlvSchema {
36
36
  super();
37
37
  this.schema = schema;
38
38
  }
39
- encodeTlvInternal(writer, value, tag, forWriteInteraction) {
39
+ encodeTlvInternal(writer, value, tag, options) {
40
40
  if (value === null) {
41
41
  writer.writeTag({ type: import_TlvCodec.TlvType.Null }, tag);
42
42
  } else {
43
- this.schema.encodeTlvInternal(writer, value, tag, forWriteInteraction);
43
+ this.schema.encodeTlvInternal(writer, value, tag, options);
44
44
  }
45
45
  }
46
46
  decodeTlvInternalValue(reader, typeLength) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tlv/TlvNullable.ts"],
4
- "sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ArraySchema } from \"./TlvArray.js\";\nimport { TlvTag, TlvType, TlvTypeLength } from \"./TlvCodec.js\";\nimport { TlvReader, TlvSchema, TlvWriter } from \"./TlvSchema.js\";\nimport { StringSchema } from \"./TlvString.js\";\n\n/**\n * Schema to encode a nullable value in TLV.\n *\n * @see {@link MatterSpecification.v10.Core} \u00A7 A.11.6\n */\nexport class NullableSchema<T> extends TlvSchema<T | null> {\n constructor(private readonly schema: TlvSchema<T>) {\n super();\n }\n\n override encodeTlvInternal(writer: TlvWriter, value: T | null, tag?: TlvTag, forWriteInteraction?: boolean): void {\n if (value === null) {\n writer.writeTag({ type: TlvType.Null }, tag);\n } else {\n this.schema.encodeTlvInternal(writer, value, tag, forWriteInteraction);\n }\n }\n\n override decodeTlvInternalValue(reader: TlvReader, typeLength: TlvTypeLength): T | null {\n if (typeLength.type === TlvType.Null) return null;\n const value = this.schema.decodeTlvInternalValue(reader, typeLength);\n // The Matter standard allows to send an empty string or Array for nullable elements that have a length.\n // This should be handled like null, so make sure to convert that correctly when decoding.\n // @see {@link MatterSpecification.v12.Core} \u00A7 7.17.1\n if (\n value !== null &&\n (this.schema instanceof ArraySchema || this.schema instanceof StringSchema) &&\n (value as any).length === 0\n ) {\n return null;\n }\n return value;\n }\n\n override validate(value: T | null): void {\n if (value !== null) this.schema.validate(value);\n }\n\n override injectField(value: T, fieldId: number, fieldValue: any, injectChecker: (fieldValue: any) => boolean): T {\n if (value !== null) {\n return this.schema.injectField(value, fieldId, fieldValue, injectChecker);\n }\n return value;\n }\n\n override removeField(value: T, fieldId: number, removeChecker: (fieldValue: any) => boolean): T {\n if (value !== null) {\n return this.schema.removeField(value, fieldId, removeChecker);\n }\n return value;\n }\n}\n\n/** Nullable TLV schema. */\nexport const TlvNullable = <T>(schema: TlvSchema<T>) => new NullableSchema(schema);\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,sBAA4B;AAC5B,sBAA+C;AAC/C,uBAAgD;AAChD,uBAA6B;AAT7B;AAAA;AAAA;AAAA;AAAA;AAgBO,MAAM,uBAA0B,2BAAoB;AAAA,EACvD,YAA6B,QAAsB;AAC/C,UAAM;AADmB;AAAA,EAE7B;AAAA,EAES,kBAAkB,QAAmB,OAAiB,KAAc,qBAAqC;AAC9G,QAAI,UAAU,MAAM;AAChB,aAAO,SAAS,EAAE,MAAM,wBAAQ,KAAK,GAAG,GAAG;AAAA,IAC/C,OAAO;AACH,WAAK,OAAO,kBAAkB,QAAQ,OAAO,KAAK,mBAAmB;AAAA,IACzE;AAAA,EACJ;AAAA,EAES,uBAAuB,QAAmB,YAAqC;AACpF,QAAI,WAAW,SAAS,wBAAQ,KAAM,QAAO;AAC7C,UAAM,QAAQ,KAAK,OAAO,uBAAuB,QAAQ,UAAU;AAInE,QACI,UAAU,SACT,KAAK,kBAAkB,+BAAe,KAAK,kBAAkB,kCAC7D,MAAc,WAAW,GAC5B;AACE,aAAO;AAAA,IACX;AACA,WAAO;AAAA,EACX;AAAA,EAES,SAAS,OAAuB;AACrC,QAAI,UAAU,KAAM,MAAK,OAAO,SAAS,KAAK;AAAA,EAClD;AAAA,EAES,YAAY,OAAU,SAAiB,YAAiB,eAAgD;AAC7G,QAAI,UAAU,MAAM;AAChB,aAAO,KAAK,OAAO,YAAY,OAAO,SAAS,YAAY,aAAa;AAAA,IAC5E;AACA,WAAO;AAAA,EACX;AAAA,EAES,YAAY,OAAU,SAAiB,eAAgD;AAC5F,QAAI,UAAU,MAAM;AAChB,aAAO,KAAK,OAAO,YAAY,OAAO,SAAS,aAAa;AAAA,IAChE;AACA,WAAO;AAAA,EACX;AACJ;AAGO,MAAM,cAAc,CAAI,WAAyB,IAAI,eAAe,MAAM;",
4
+ "sourcesContent": ["/**\n * @license\n * Copyright 2022-2024 Matter.js Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ArraySchema } from \"./TlvArray.js\";\nimport { TlvTag, TlvType, TlvTypeLength } from \"./TlvCodec.js\";\nimport { TlvEncodingOptions, TlvReader, TlvSchema, TlvWriter } from \"./TlvSchema.js\";\nimport { StringSchema } from \"./TlvString.js\";\n\n/**\n * Schema to encode a nullable value in TLV.\n *\n * @see {@link MatterSpecification.v10.Core} \u00A7 A.11.6\n */\nexport class NullableSchema<T> extends TlvSchema<T | null> {\n constructor(private readonly schema: TlvSchema<T>) {\n super();\n }\n\n override encodeTlvInternal(writer: TlvWriter, value: T | null, tag?: TlvTag, options?: TlvEncodingOptions): void {\n if (value === null) {\n writer.writeTag({ type: TlvType.Null }, tag);\n } else {\n this.schema.encodeTlvInternal(writer, value, tag, options);\n }\n }\n\n override decodeTlvInternalValue(reader: TlvReader, typeLength: TlvTypeLength): T | null {\n if (typeLength.type === TlvType.Null) return null;\n const value = this.schema.decodeTlvInternalValue(reader, typeLength);\n // The Matter standard allows to send an empty string or Array for nullable elements that have a length.\n // This should be handled like null, so make sure to convert that correctly when decoding.\n // @see {@link MatterSpecification.v12.Core} \u00A7 7.17.1\n if (\n value !== null &&\n (this.schema instanceof ArraySchema || this.schema instanceof StringSchema) &&\n (value as any).length === 0\n ) {\n return null;\n }\n return value;\n }\n\n override validate(value: T | null): void {\n if (value !== null) this.schema.validate(value);\n }\n\n override injectField(value: T, fieldId: number, fieldValue: any, injectChecker: (fieldValue: any) => boolean): T {\n if (value !== null) {\n return this.schema.injectField(value, fieldId, fieldValue, injectChecker);\n }\n return value;\n }\n\n override removeField(value: T, fieldId: number, removeChecker: (fieldValue: any) => boolean): T {\n if (value !== null) {\n return this.schema.removeField(value, fieldId, removeChecker);\n }\n return value;\n }\n}\n\n/** Nullable TLV schema. */\nexport const TlvNullable = <T>(schema: TlvSchema<T>) => new NullableSchema(schema);\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,sBAA4B;AAC5B,sBAA+C;AAC/C,uBAAoE;AACpE,uBAA6B;AAT7B;AAAA;AAAA;AAAA;AAAA;AAgBO,MAAM,uBAA0B,2BAAoB;AAAA,EACvD,YAA6B,QAAsB;AAC/C,UAAM;AADmB;AAAA,EAE7B;AAAA,EAES,kBAAkB,QAAmB,OAAiB,KAAc,SAAoC;AAC7G,QAAI,UAAU,MAAM;AAChB,aAAO,SAAS,EAAE,MAAM,wBAAQ,KAAK,GAAG,GAAG;AAAA,IAC/C,OAAO;AACH,WAAK,OAAO,kBAAkB,QAAQ,OAAO,KAAK,OAAO;AAAA,IAC7D;AAAA,EACJ;AAAA,EAES,uBAAuB,QAAmB,YAAqC;AACpF,QAAI,WAAW,SAAS,wBAAQ,KAAM,QAAO;AAC7C,UAAM,QAAQ,KAAK,OAAO,uBAAuB,QAAQ,UAAU;AAInE,QACI,UAAU,SACT,KAAK,kBAAkB,+BAAe,KAAK,kBAAkB,kCAC7D,MAAc,WAAW,GAC5B;AACE,aAAO;AAAA,IACX;AACA,WAAO;AAAA,EACX;AAAA,EAES,SAAS,OAAuB;AACrC,QAAI,UAAU,KAAM,MAAK,OAAO,SAAS,KAAK;AAAA,EAClD;AAAA,EAES,YAAY,OAAU,SAAiB,YAAiB,eAAgD;AAC7G,QAAI,UAAU,MAAM;AAChB,aAAO,KAAK,OAAO,YAAY,OAAO,SAAS,YAAY,aAAa;AAAA,IAC5E;AACA,WAAO;AAAA,EACX;AAAA,EAES,YAAY,OAAU,SAAiB,eAAgD;AAC5F,QAAI,UAAU,MAAM;AAChB,aAAO,KAAK,OAAO,YAAY,OAAO,SAAS,aAAa;AAAA,IAChE;AACA,WAAO;AAAA,EACX;AACJ;AAGO,MAAM,cAAc,CAAI,WAAyB,IAAI,eAAe,MAAM;",
6
6
  "names": []
7
7
  }
@@ -6,7 +6,7 @@
6
6
  import { Merge } from "../util/Type.js";
7
7
  import { LengthConstraints } from "./TlvArray.js";
8
8
  import { TlvTag, TlvType, TlvTypeLength } from "./TlvCodec.js";
9
- import { TlvReader, TlvSchema, TlvWriter } from "./TlvSchema.js";
9
+ import { TlvEncodingOptions, TlvReader, TlvSchema, TlvWriter } from "./TlvSchema.js";
10
10
  export interface FieldType<T> {
11
11
  id: number;
12
12
  schema: TlvSchema<T>;
@@ -55,7 +55,7 @@ export declare class ObjectSchema<F extends TlvFields> extends TlvSchema<TypeFro
55
55
  private readonly allowProtocolSpecificTags;
56
56
  private readonly fieldById;
57
57
  constructor(fieldDefinitions: F, type?: TlvType.Structure | TlvType.List, allowProtocolSpecificTags?: boolean);
58
- encodeTlvInternal(writer: TlvWriter, value: TypeFromFields<F>, tag?: TlvTag, forWriteInteraction?: boolean): void;
58
+ encodeTlvInternal(writer: TlvWriter, value: TypeFromFields<F>, tag?: TlvTag, options?: TlvEncodingOptions): void;
59
59
  decodeTlvInternalValue(reader: TlvReader, typeLength: TlvTypeLength): TypeFromFields<F>;
60
60
  validate(value: TypeFromFields<F>): void;
61
61
  injectField(value: TypeFromFields<F>, fieldId: number, fieldValue: any, injectChecker: (fieldValue: any) => boolean): TypeFromFields<F>;
@@ -1 +1 @@
1
- {"version":3,"file":"TlvObject.d.ts","sourceRoot":"","sources":["../../../src/tlv/TlvObject.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TlvObject.d.ts","sourceRoot":"","sources":["../../../src/tlv/TlvObject.ts"],"names":[],"mappings":"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"}
@@ -54,11 +54,17 @@ class ObjectSchema extends import_TlvSchema.TlvSchema {
54
54
  this.fieldById[field.id] = { name, field };
55
55
  }
56
56
  }
57
- #encodeEntryToTlv(writer, name, value, forWriteInteraction) {
57
+ #encodeEntryToTlv(writer, name, value, options) {
58
58
  const { id, schema, optional: isOptional, repeated: isRepeated } = this.fieldDefinitions[name];
59
+ const { forWriteInteraction = false, allowMissingFieldsForNonFabricFilteredRead = false } = options ?? {};
60
+ if (forWriteInteraction && allowMissingFieldsForNonFabricFilteredRead) {
61
+ throw new import_MatterError.InternalError(
62
+ "Encode options can not indicate a write interaction and a fabric filtered read interaction at the same time."
63
+ );
64
+ }
59
65
  const fieldValue = value[name];
60
66
  if (fieldValue === void 0) {
61
- if (!isOptional) {
67
+ if (!isOptional && !allowMissingFieldsForNonFabricFilteredRead) {
62
68
  if (forWriteInteraction && id === import_model.Globals.FabricIndex.id) {
63
69
  return;
64
70
  }
@@ -71,40 +77,40 @@ class ObjectSchema extends import_TlvSchema.TlvSchema {
71
77
  throw new import_ValidationError.ValidationError(`Repeated field ${name} should be an array.`, name);
72
78
  }
73
79
  for (const element of fieldValue) {
74
- schema.encodeTlvInternal(writer, element, { id }, forWriteInteraction);
80
+ schema.encodeTlvInternal(writer, element, { id }, options);
75
81
  }
76
82
  } else {
77
- schema.encodeTlvInternal(writer, fieldValue, { id }, forWriteInteraction);
83
+ schema.encodeTlvInternal(writer, fieldValue, { id }, options);
78
84
  }
79
85
  }
80
86
  /**
81
87
  * Encode the object as Structure, by the order of field definitions.
82
88
  */
83
- #encodeStructure(writer, value, forWriteInteraction) {
89
+ #encodeStructure(writer, value, options) {
84
90
  for (const name in this.fieldDefinitions) {
85
- this.#encodeEntryToTlv(writer, name, value, forWriteInteraction);
91
+ this.#encodeEntryToTlv(writer, name, value, options);
86
92
  }
87
93
  }
88
94
  /**
89
95
  * Encode the object as List, by the order of the fields in the object.
90
96
  */
91
- #encodeList(writer, value, forWriteInteraction) {
97
+ #encodeList(writer, value, options) {
92
98
  const encodedFields = /* @__PURE__ */ new Set();
93
99
  for (const name of Object.keys(value)) {
94
- this.#encodeEntryToTlv(writer, name, value, forWriteInteraction);
100
+ this.#encodeEntryToTlv(writer, name, value, options);
95
101
  encodedFields.add(name);
96
102
  }
97
103
  for (const name in this.fieldDefinitions) {
98
104
  if (encodedFields.has(name)) continue;
99
- this.#encodeEntryToTlv(writer, name, value, forWriteInteraction);
105
+ this.#encodeEntryToTlv(writer, name, value, options);
100
106
  }
101
107
  }
102
- encodeTlvInternal(writer, value, tag, forWriteInteraction) {
108
+ encodeTlvInternal(writer, value, tag, options) {
103
109
  writer.writeTag({ type: this.type }, tag);
104
110
  if (this.type === import_TlvCodec.TlvType.Structure) {
105
- this.#encodeStructure(writer, value, forWriteInteraction);
111
+ this.#encodeStructure(writer, value, options);
106
112
  } else {
107
- this.#encodeList(writer, value, forWriteInteraction);
113
+ this.#encodeList(writer, value, options);
108
114
  }
109
115
  writer.writeTag({ type: import_TlvCodec.TlvType.EndOfContainer });
110
116
  }