@matter/protocol 0.14.0 → 0.14.1-alpha.0-20250606-a9bcd03f9

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 (312) hide show
  1. package/dist/cjs/action/server/AccessControl.d.ts +5 -7
  2. package/dist/cjs/action/server/AccessControl.d.ts.map +1 -1
  3. package/dist/cjs/action/server/AccessControl.js.map +1 -1
  4. package/dist/cjs/action/server/AttributeWriteResponse.d.ts.map +1 -1
  5. package/dist/cjs/action/server/AttributeWriteResponse.js +23 -0
  6. package/dist/cjs/action/server/AttributeWriteResponse.js.map +1 -1
  7. package/dist/cjs/action/server/CommandInvokeResponse.d.ts.map +1 -1
  8. package/dist/cjs/action/server/CommandInvokeResponse.js +24 -1
  9. package/dist/cjs/action/server/CommandInvokeResponse.js.map +1 -1
  10. package/dist/cjs/action/server/DataResponse.d.ts +1 -1
  11. package/dist/cjs/action/server/DataResponse.d.ts.map +1 -1
  12. package/dist/cjs/action/server/Subject.d.ts +25 -0
  13. package/dist/cjs/action/server/Subject.d.ts.map +1 -0
  14. package/dist/cjs/action/server/Subject.js +54 -0
  15. package/dist/cjs/action/server/Subject.js.map +6 -0
  16. package/dist/cjs/action/server/index.d.ts +1 -0
  17. package/dist/cjs/action/server/index.d.ts.map +1 -1
  18. package/dist/cjs/action/server/index.js +1 -0
  19. package/dist/cjs/action/server/index.js.map +1 -1
  20. package/dist/cjs/certificate/DeviceCertification.d.ts +2 -2
  21. package/dist/cjs/certificate/DeviceCertification.d.ts.map +1 -1
  22. package/dist/cjs/certificate/DeviceCertification.js.map +1 -1
  23. package/dist/cjs/cluster/client/AttributeClient.d.ts +3 -3
  24. package/dist/cjs/cluster/client/AttributeClient.d.ts.map +1 -1
  25. package/dist/cjs/cluster/client/AttributeClient.js +14 -2
  26. package/dist/cjs/cluster/client/AttributeClient.js.map +1 -1
  27. package/dist/cjs/cluster/client/ClusterClient.d.ts +3 -2
  28. package/dist/cjs/cluster/client/ClusterClient.d.ts.map +1 -1
  29. package/dist/cjs/cluster/client/ClusterClient.js +60 -1
  30. package/dist/cjs/cluster/client/ClusterClient.js.map +1 -1
  31. package/dist/cjs/cluster/client/ClusterClientTypes.d.ts +33 -8
  32. package/dist/cjs/cluster/client/ClusterClientTypes.d.ts.map +1 -1
  33. package/dist/cjs/cluster/client/EventClient.d.ts +3 -3
  34. package/dist/cjs/cluster/client/EventClient.d.ts.map +1 -1
  35. package/dist/cjs/cluster/client/EventClient.js +7 -0
  36. package/dist/cjs/cluster/client/EventClient.js.map +1 -1
  37. package/dist/cjs/codec/MessageCodec.d.ts.map +1 -1
  38. package/dist/cjs/codec/MessageCodec.js +31 -6
  39. package/dist/cjs/codec/MessageCodec.js.map +1 -1
  40. package/dist/cjs/fabric/Fabric.d.ts +20 -30
  41. package/dist/cjs/fabric/Fabric.d.ts.map +1 -1
  42. package/dist/cjs/fabric/Fabric.js +38 -62
  43. package/dist/cjs/fabric/Fabric.js.map +2 -2
  44. package/dist/cjs/fabric/FabricManager.d.ts.map +1 -1
  45. package/dist/cjs/fabric/FabricManager.js +10 -4
  46. package/dist/cjs/fabric/FabricManager.js.map +1 -1
  47. package/dist/cjs/groups/FabricGroupsManager.d.ts +46 -0
  48. package/dist/cjs/groups/FabricGroupsManager.d.ts.map +1 -0
  49. package/dist/cjs/groups/FabricGroupsManager.js +155 -0
  50. package/dist/cjs/groups/FabricGroupsManager.js.map +6 -0
  51. package/dist/cjs/groups/Groups.d.ts +34 -0
  52. package/dist/cjs/groups/Groups.d.ts.map +1 -0
  53. package/dist/cjs/groups/Groups.js +89 -0
  54. package/dist/cjs/groups/Groups.js.map +6 -0
  55. package/dist/cjs/groups/KeySets.d.ts +64 -0
  56. package/dist/cjs/groups/KeySets.d.ts.map +1 -0
  57. package/dist/cjs/groups/KeySets.js +179 -0
  58. package/dist/cjs/groups/KeySets.js.map +6 -0
  59. package/dist/cjs/groups/MessagingState.d.ts +24 -0
  60. package/dist/cjs/groups/MessagingState.d.ts.map +1 -0
  61. package/dist/cjs/groups/MessagingState.js +91 -0
  62. package/dist/cjs/groups/MessagingState.js.map +6 -0
  63. package/dist/cjs/groups/index.d.ts +8 -0
  64. package/dist/cjs/groups/index.d.ts.map +1 -0
  65. package/dist/cjs/groups/index.js +25 -0
  66. package/dist/cjs/groups/index.js.map +6 -0
  67. package/dist/cjs/index.d.ts +1 -0
  68. package/dist/cjs/index.d.ts.map +1 -1
  69. package/dist/cjs/index.js +1 -0
  70. package/dist/cjs/index.js.map +1 -1
  71. package/dist/cjs/interaction/AccessControlManager.d.ts +4 -13
  72. package/dist/cjs/interaction/AccessControlManager.d.ts.map +1 -1
  73. package/dist/cjs/interaction/AccessControlManager.js +38 -47
  74. package/dist/cjs/interaction/AccessControlManager.js.map +1 -1
  75. package/dist/cjs/interaction/InteractionClient.d.ts +5 -4
  76. package/dist/cjs/interaction/InteractionClient.d.ts.map +1 -1
  77. package/dist/cjs/interaction/InteractionClient.js +53 -3
  78. package/dist/cjs/interaction/InteractionClient.js.map +1 -1
  79. package/dist/cjs/interaction/InteractionMessenger.d.ts.map +1 -1
  80. package/dist/cjs/interaction/InteractionMessenger.js +15 -0
  81. package/dist/cjs/interaction/InteractionMessenger.js.map +1 -1
  82. package/dist/cjs/interaction/Subscription.d.ts +3 -3
  83. package/dist/cjs/interaction/Subscription.d.ts.map +1 -1
  84. package/dist/cjs/interaction/Subscription.js.map +1 -1
  85. package/dist/cjs/peer/PeerAddress.d.ts +1 -0
  86. package/dist/cjs/peer/PeerAddress.d.ts.map +1 -1
  87. package/dist/cjs/peer/PeerAddress.js +5 -0
  88. package/dist/cjs/peer/PeerAddress.js.map +1 -1
  89. package/dist/cjs/peer/PeerSet.d.ts.map +1 -1
  90. package/dist/cjs/peer/PeerSet.js +31 -2
  91. package/dist/cjs/peer/PeerSet.js.map +1 -1
  92. package/dist/cjs/protocol/ChannelManager.d.ts.map +1 -1
  93. package/dist/cjs/protocol/ChannelManager.js +7 -8
  94. package/dist/cjs/protocol/ChannelManager.js.map +1 -1
  95. package/dist/cjs/protocol/ExchangeManager.d.ts.map +1 -1
  96. package/dist/cjs/protocol/ExchangeManager.js +39 -25
  97. package/dist/cjs/protocol/ExchangeManager.js.map +1 -1
  98. package/dist/cjs/protocol/MessageExchange.d.ts +1 -1
  99. package/dist/cjs/protocol/MessageExchange.d.ts.map +1 -1
  100. package/dist/cjs/protocol/MessageExchange.js +32 -4
  101. package/dist/cjs/protocol/MessageExchange.js.map +1 -1
  102. package/dist/cjs/protocol/MessageReceptionState.d.ts +1 -1
  103. package/dist/cjs/securechannel/SecureChannelProtocol.js +1 -1
  104. package/dist/cjs/securechannel/SecureChannelProtocol.js.map +1 -1
  105. package/dist/cjs/session/GroupSession.d.ts +56 -0
  106. package/dist/cjs/session/GroupSession.d.ts.map +1 -0
  107. package/dist/cjs/session/GroupSession.js +188 -0
  108. package/dist/cjs/session/GroupSession.js.map +6 -0
  109. package/dist/cjs/session/InsecureSession.d.ts +2 -1
  110. package/dist/cjs/session/InsecureSession.d.ts.map +1 -1
  111. package/dist/cjs/session/InsecureSession.js +3 -2
  112. package/dist/cjs/session/InsecureSession.js.map +1 -1
  113. package/dist/cjs/session/NodeSession.d.ts +88 -0
  114. package/dist/cjs/session/NodeSession.d.ts.map +1 -0
  115. package/dist/cjs/session/NodeSession.js +318 -0
  116. package/dist/cjs/session/NodeSession.js.map +6 -0
  117. package/dist/cjs/session/SecureSession.d.ts +10 -75
  118. package/dist/cjs/session/SecureSession.d.ts.map +1 -1
  119. package/dist/cjs/session/SecureSession.js +9 -280
  120. package/dist/cjs/session/SecureSession.js.map +2 -2
  121. package/dist/cjs/session/Session.d.ts +6 -5
  122. package/dist/cjs/session/Session.d.ts.map +1 -1
  123. package/dist/cjs/session/Session.js +11 -1
  124. package/dist/cjs/session/Session.js.map +1 -1
  125. package/dist/cjs/session/SessionManager.d.ts +27 -9
  126. package/dist/cjs/session/SessionManager.d.ts.map +1 -1
  127. package/dist/cjs/session/SessionManager.js +83 -5
  128. package/dist/cjs/session/SessionManager.js.map +2 -2
  129. package/dist/cjs/session/case/CaseClient.d.ts +1 -1
  130. package/dist/cjs/session/case/CaseClient.js +2 -2
  131. package/dist/cjs/session/case/CaseClient.js.map +1 -1
  132. package/dist/cjs/session/index.d.ts +2 -0
  133. package/dist/cjs/session/index.d.ts.map +1 -1
  134. package/dist/cjs/session/index.js +2 -0
  135. package/dist/cjs/session/index.js.map +1 -1
  136. package/dist/cjs/session/pase/PaseClient.d.ts +1 -1
  137. package/dist/esm/action/server/AccessControl.d.ts +5 -7
  138. package/dist/esm/action/server/AccessControl.d.ts.map +1 -1
  139. package/dist/esm/action/server/AccessControl.js.map +1 -1
  140. package/dist/esm/action/server/AttributeWriteResponse.d.ts.map +1 -1
  141. package/dist/esm/action/server/AttributeWriteResponse.js +23 -0
  142. package/dist/esm/action/server/AttributeWriteResponse.js.map +1 -1
  143. package/dist/esm/action/server/CommandInvokeResponse.d.ts.map +1 -1
  144. package/dist/esm/action/server/CommandInvokeResponse.js +24 -1
  145. package/dist/esm/action/server/CommandInvokeResponse.js.map +1 -1
  146. package/dist/esm/action/server/DataResponse.d.ts +1 -1
  147. package/dist/esm/action/server/DataResponse.d.ts.map +1 -1
  148. package/dist/esm/action/server/Subject.d.ts +25 -0
  149. package/dist/esm/action/server/Subject.d.ts.map +1 -0
  150. package/dist/esm/action/server/Subject.js +34 -0
  151. package/dist/esm/action/server/Subject.js.map +6 -0
  152. package/dist/esm/action/server/index.d.ts +1 -0
  153. package/dist/esm/action/server/index.d.ts.map +1 -1
  154. package/dist/esm/action/server/index.js +1 -0
  155. package/dist/esm/action/server/index.js.map +1 -1
  156. package/dist/esm/certificate/DeviceCertification.d.ts +2 -2
  157. package/dist/esm/certificate/DeviceCertification.d.ts.map +1 -1
  158. package/dist/esm/certificate/DeviceCertification.js.map +1 -1
  159. package/dist/esm/cluster/client/AttributeClient.d.ts +3 -3
  160. package/dist/esm/cluster/client/AttributeClient.d.ts.map +1 -1
  161. package/dist/esm/cluster/client/AttributeClient.js +13 -1
  162. package/dist/esm/cluster/client/AttributeClient.js.map +1 -1
  163. package/dist/esm/cluster/client/ClusterClient.d.ts +3 -2
  164. package/dist/esm/cluster/client/ClusterClient.d.ts.map +1 -1
  165. package/dist/esm/cluster/client/ClusterClient.js +61 -2
  166. package/dist/esm/cluster/client/ClusterClient.js.map +1 -1
  167. package/dist/esm/cluster/client/ClusterClientTypes.d.ts +33 -8
  168. package/dist/esm/cluster/client/ClusterClientTypes.d.ts.map +1 -1
  169. package/dist/esm/cluster/client/EventClient.d.ts +3 -3
  170. package/dist/esm/cluster/client/EventClient.d.ts.map +1 -1
  171. package/dist/esm/cluster/client/EventClient.js +7 -0
  172. package/dist/esm/cluster/client/EventClient.js.map +1 -1
  173. package/dist/esm/codec/MessageCodec.d.ts.map +1 -1
  174. package/dist/esm/codec/MessageCodec.js +41 -7
  175. package/dist/esm/codec/MessageCodec.js.map +1 -1
  176. package/dist/esm/fabric/Fabric.d.ts +20 -30
  177. package/dist/esm/fabric/Fabric.d.ts.map +1 -1
  178. package/dist/esm/fabric/Fabric.js +38 -62
  179. package/dist/esm/fabric/Fabric.js.map +2 -2
  180. package/dist/esm/fabric/FabricManager.d.ts.map +1 -1
  181. package/dist/esm/fabric/FabricManager.js +10 -4
  182. package/dist/esm/fabric/FabricManager.js.map +1 -1
  183. package/dist/esm/groups/FabricGroupsManager.d.ts +46 -0
  184. package/dist/esm/groups/FabricGroupsManager.d.ts.map +1 -0
  185. package/dist/esm/groups/FabricGroupsManager.js +135 -0
  186. package/dist/esm/groups/FabricGroupsManager.js.map +6 -0
  187. package/dist/esm/groups/Groups.d.ts +34 -0
  188. package/dist/esm/groups/Groups.d.ts.map +1 -0
  189. package/dist/esm/groups/Groups.js +69 -0
  190. package/dist/esm/groups/Groups.js.map +6 -0
  191. package/dist/esm/groups/KeySets.d.ts +64 -0
  192. package/dist/esm/groups/KeySets.d.ts.map +1 -0
  193. package/dist/esm/groups/KeySets.js +159 -0
  194. package/dist/esm/groups/KeySets.js.map +6 -0
  195. package/dist/esm/groups/MessagingState.d.ts +24 -0
  196. package/dist/esm/groups/MessagingState.d.ts.map +1 -0
  197. package/dist/esm/groups/MessagingState.js +71 -0
  198. package/dist/esm/groups/MessagingState.js.map +6 -0
  199. package/dist/esm/groups/index.d.ts +8 -0
  200. package/dist/esm/groups/index.d.ts.map +1 -0
  201. package/dist/esm/groups/index.js +8 -0
  202. package/dist/esm/groups/index.js.map +6 -0
  203. package/dist/esm/index.d.ts +1 -0
  204. package/dist/esm/index.d.ts.map +1 -1
  205. package/dist/esm/index.js +1 -0
  206. package/dist/esm/index.js.map +1 -1
  207. package/dist/esm/interaction/AccessControlManager.d.ts +4 -13
  208. package/dist/esm/interaction/AccessControlManager.d.ts.map +1 -1
  209. package/dist/esm/interaction/AccessControlManager.js +39 -48
  210. package/dist/esm/interaction/AccessControlManager.js.map +1 -1
  211. package/dist/esm/interaction/InteractionClient.d.ts +5 -4
  212. package/dist/esm/interaction/InteractionClient.d.ts.map +1 -1
  213. package/dist/esm/interaction/InteractionClient.js +54 -4
  214. package/dist/esm/interaction/InteractionClient.js.map +1 -1
  215. package/dist/esm/interaction/InteractionMessenger.d.ts.map +1 -1
  216. package/dist/esm/interaction/InteractionMessenger.js +15 -0
  217. package/dist/esm/interaction/InteractionMessenger.js.map +1 -1
  218. package/dist/esm/interaction/Subscription.d.ts +3 -3
  219. package/dist/esm/interaction/Subscription.d.ts.map +1 -1
  220. package/dist/esm/interaction/Subscription.js.map +1 -1
  221. package/dist/esm/peer/PeerAddress.d.ts +1 -0
  222. package/dist/esm/peer/PeerAddress.d.ts.map +1 -1
  223. package/dist/esm/peer/PeerAddress.js +5 -0
  224. package/dist/esm/peer/PeerAddress.js.map +1 -1
  225. package/dist/esm/peer/PeerSet.d.ts.map +1 -1
  226. package/dist/esm/peer/PeerSet.js +33 -3
  227. package/dist/esm/peer/PeerSet.js.map +1 -1
  228. package/dist/esm/protocol/ChannelManager.d.ts.map +1 -1
  229. package/dist/esm/protocol/ChannelManager.js +7 -8
  230. package/dist/esm/protocol/ChannelManager.js.map +1 -1
  231. package/dist/esm/protocol/ExchangeManager.d.ts.map +1 -1
  232. package/dist/esm/protocol/ExchangeManager.js +41 -27
  233. package/dist/esm/protocol/ExchangeManager.js.map +1 -1
  234. package/dist/esm/protocol/MessageExchange.d.ts +1 -1
  235. package/dist/esm/protocol/MessageExchange.d.ts.map +1 -1
  236. package/dist/esm/protocol/MessageExchange.js +39 -5
  237. package/dist/esm/protocol/MessageExchange.js.map +1 -1
  238. package/dist/esm/protocol/MessageReceptionState.d.ts +1 -1
  239. package/dist/esm/securechannel/SecureChannelProtocol.js +2 -2
  240. package/dist/esm/securechannel/SecureChannelProtocol.js.map +1 -1
  241. package/dist/esm/session/GroupSession.d.ts +56 -0
  242. package/dist/esm/session/GroupSession.d.ts.map +1 -0
  243. package/dist/esm/session/GroupSession.js +177 -0
  244. package/dist/esm/session/GroupSession.js.map +6 -0
  245. package/dist/esm/session/InsecureSession.d.ts +2 -1
  246. package/dist/esm/session/InsecureSession.d.ts.map +1 -1
  247. package/dist/esm/session/InsecureSession.js +3 -2
  248. package/dist/esm/session/InsecureSession.js.map +1 -1
  249. package/dist/esm/session/NodeSession.d.ts +88 -0
  250. package/dist/esm/session/NodeSession.d.ts.map +1 -0
  251. package/dist/esm/session/NodeSession.js +298 -0
  252. package/dist/esm/session/NodeSession.js.map +6 -0
  253. package/dist/esm/session/SecureSession.d.ts +10 -75
  254. package/dist/esm/session/SecureSession.d.ts.map +1 -1
  255. package/dist/esm/session/SecureSession.js +10 -291
  256. package/dist/esm/session/SecureSession.js.map +2 -2
  257. package/dist/esm/session/Session.d.ts +6 -5
  258. package/dist/esm/session/Session.d.ts.map +1 -1
  259. package/dist/esm/session/Session.js +12 -2
  260. package/dist/esm/session/Session.js.map +1 -1
  261. package/dist/esm/session/SessionManager.d.ts +27 -9
  262. package/dist/esm/session/SessionManager.d.ts.map +1 -1
  263. package/dist/esm/session/SessionManager.js +84 -6
  264. package/dist/esm/session/SessionManager.js.map +1 -1
  265. package/dist/esm/session/case/CaseClient.d.ts +1 -1
  266. package/dist/esm/session/case/CaseClient.js +2 -2
  267. package/dist/esm/session/case/CaseClient.js.map +1 -1
  268. package/dist/esm/session/index.d.ts +2 -0
  269. package/dist/esm/session/index.d.ts.map +1 -1
  270. package/dist/esm/session/index.js +2 -0
  271. package/dist/esm/session/index.js.map +1 -1
  272. package/dist/esm/session/pase/PaseClient.d.ts +1 -1
  273. package/package.json +6 -6
  274. package/src/action/server/AccessControl.ts +4 -7
  275. package/src/action/server/AttributeWriteResponse.ts +29 -7
  276. package/src/action/server/CommandInvokeResponse.ts +28 -7
  277. package/src/action/server/DataResponse.ts +1 -1
  278. package/src/action/server/Subject.ts +45 -0
  279. package/src/action/server/index.ts +1 -0
  280. package/src/certificate/DeviceCertification.ts +2 -2
  281. package/src/cluster/client/AttributeClient.ts +15 -3
  282. package/src/cluster/client/ClusterClient.ts +90 -4
  283. package/src/cluster/client/ClusterClientTypes.ts +38 -9
  284. package/src/cluster/client/EventClient.ts +9 -2
  285. package/src/codec/MessageCodec.ts +49 -8
  286. package/src/fabric/Fabric.ts +51 -85
  287. package/src/fabric/FabricManager.ts +11 -4
  288. package/src/groups/FabricGroupsManager.ts +164 -0
  289. package/src/groups/Groups.ts +81 -0
  290. package/src/groups/KeySets.ts +194 -0
  291. package/src/groups/MessagingState.ts +76 -0
  292. package/src/groups/index.ts +8 -0
  293. package/src/index.ts +1 -0
  294. package/src/interaction/AccessControlManager.ts +49 -81
  295. package/src/interaction/InteractionClient.ts +66 -6
  296. package/src/interaction/InteractionMessenger.ts +15 -0
  297. package/src/interaction/Subscription.ts +3 -3
  298. package/src/peer/PeerAddress.ts +4 -0
  299. package/src/peer/PeerSet.ts +39 -4
  300. package/src/protocol/ChannelManager.ts +7 -9
  301. package/src/protocol/ExchangeManager.ts +51 -35
  302. package/src/protocol/MessageExchange.ts +42 -7
  303. package/src/protocol/MessageReceptionState.ts +2 -2
  304. package/src/securechannel/SecureChannelProtocol.ts +2 -2
  305. package/src/session/GroupSession.ts +223 -0
  306. package/src/session/InsecureSession.ts +3 -2
  307. package/src/session/NodeSession.ts +367 -0
  308. package/src/session/SecureSession.ts +14 -363
  309. package/src/session/Session.ts +17 -6
  310. package/src/session/SessionManager.ts +94 -14
  311. package/src/session/case/CaseClient.ts +2 -2
  312. package/src/session/index.ts +2 -3
@@ -15,18 +15,18 @@ import {
15
15
  MatterAggregateError,
16
16
  MatterError,
17
17
  MatterFlowError,
18
- NotImplementedError,
19
18
  ObserverGroup,
20
19
  TransportInterface,
21
20
  TransportInterfaceSet,
22
21
  UdpInterface,
22
+ UnexpectedDataError,
23
23
  } from "#general";
24
24
  import { PeerAddress } from "#peer/PeerAddress.js";
25
25
  import { NodeId, SECURE_CHANNEL_PROTOCOL_ID, SecureMessageType } from "#types";
26
- import { Message, MessageCodec, SessionType } from "../codec/MessageCodec.js";
26
+ import { DecodedMessage, Message, MessageCodec, SessionType } from "../codec/MessageCodec.js";
27
27
  import { SecureChannelMessenger } from "../securechannel/SecureChannelMessenger.js";
28
28
  import { SecureChannelProtocol } from "../securechannel/SecureChannelProtocol.js";
29
- import { SecureSession } from "../session/SecureSession.js";
29
+ import { NodeSession } from "../session/NodeSession.js";
30
30
  import { Session } from "../session/Session.js";
31
31
  import { SessionManager, UNICAST_UNSECURE_SESSION_ID } from "../session/SessionManager.js";
32
32
  import { ChannelManager } from "./ChannelManager.js";
@@ -73,7 +73,7 @@ export class MessageChannel implements Channel<Message> {
73
73
  return this.channel.maxPayloadSize;
74
74
  }
75
75
 
76
- send(message: Message, logContext?: ExchangeLogContext): Promise<void> {
76
+ async send(message: Message, logContext?: ExchangeLogContext) {
77
77
  logger.debug("Message »", MessageCodec.messageDiagnostics(message, logContext));
78
78
  const packet = this.session.encode(message);
79
79
  const bytes = MessageCodec.encodePacket(packet);
@@ -83,7 +83,7 @@ export class MessageChannel implements Channel<Message> {
83
83
  );
84
84
  }
85
85
 
86
- return this.channel.send(bytes);
86
+ return await this.channel.send(bytes);
87
87
  }
88
88
 
89
89
  get name() {
@@ -202,11 +202,13 @@ export class ExchangeManager {
202
202
 
203
203
  private async onMessage(channel: Channel<Uint8Array>, messageBytes: Uint8Array) {
204
204
  const packet = MessageCodec.decodePacket(messageBytes);
205
+ const aad = messageBytes.slice(0, messageBytes.length - packet.applicationPayload.length); // Header+Extensions
205
206
 
206
- if (packet.header.sessionType === SessionType.Group)
207
- throw new NotImplementedError("Group messages are not supported");
207
+ const messageId = packet.header.messageId;
208
208
 
209
+ let isDuplicate: boolean;
209
210
  let session: Session | undefined;
211
+ let message: DecodedMessage | undefined;
210
212
  if (packet.header.sessionType === SessionType.Unicast) {
211
213
  if (packet.header.sessionId === UNICAST_UNSECURE_SESSION_ID) {
212
214
  if (this.#closing) return;
@@ -219,35 +221,46 @@ export class ExchangeManager {
219
221
  } else {
220
222
  session = this.#sessionManager.getSession(packet.header.sessionId);
221
223
  }
224
+
225
+ if (session === undefined) {
226
+ throw new MatterFlowError(
227
+ `Cannot find a session for ID ${packet.header.sessionId}${
228
+ packet.header.sourceNodeId !== undefined
229
+ ? ` and source NodeId ${packet.header.sourceNodeId}`
230
+ : ""
231
+ }`,
232
+ );
233
+ }
234
+
235
+ message = session.decode(packet, aad);
236
+
237
+ try {
238
+ session.updateMessageCounter(messageId);
239
+ isDuplicate = false;
240
+ } catch (e) {
241
+ DuplicateMessageError.accept(e);
242
+ isDuplicate = true;
243
+ }
222
244
  } else if (packet.header.sessionType === SessionType.Group) {
223
245
  if (this.#closing) return;
224
- if (packet.header.sourceNodeId !== undefined) {
225
- //session = this.sessionManager.findGroupSession(packet.header.destGroupId, packet.header.sessionId);
246
+ if (packet.header.sourceNodeId === undefined) {
247
+ throw new UnexpectedDataError("Group session message must include a source NodeId");
226
248
  }
227
- // if (packet.header.destGroupId !== undefined) { ???
228
- }
229
249
 
230
- if (session === undefined) {
231
- throw new MatterFlowError(
232
- `Cannot find a session for ID ${packet.header.sessionId}${
233
- packet.header.sourceNodeId !== undefined ? ` and source NodeId ${packet.header.sourceNodeId}` : ""
234
- }`,
235
- );
236
- }
237
-
238
- const messageId = packet.header.messageId;
250
+ let key: Uint8Array;
251
+ ({ session, message, key } = this.#sessionManager.groupSessionFromPacket(packet, aad));
239
252
 
240
- let isDuplicate;
241
- try {
242
- session.updateMessageCounter(packet.header.messageId, packet.header.sourceNodeId);
243
- isDuplicate = false;
244
- } catch (e) {
245
- DuplicateMessageError.accept(e);
246
- isDuplicate = true;
253
+ try {
254
+ session.updateMessageCounter(messageId, packet.header.sourceNodeId, key);
255
+ isDuplicate = false;
256
+ } catch (e) {
257
+ DuplicateMessageError.accept(e);
258
+ isDuplicate = true;
259
+ }
260
+ } else {
261
+ throw new MatterFlowError(`Unsupported session type: ${packet.header.sessionType}`);
247
262
  }
248
263
 
249
- const aad = messageBytes.slice(0, messageBytes.length - packet.applicationPayload.length); // Header+Extensions
250
- const message = session.decode(packet, aad);
251
264
  const exchangeIndex = message.payloadHeader.isInitiatorMessage
252
265
  ? message.payloadHeader.exchangeId
253
266
  : message.payloadHeader.exchangeId | 0x10000;
@@ -343,9 +356,12 @@ export class ExchangeManager {
343
356
  throw new MatterFlowError(`Unsupported protocol ${message.payloadHeader.protocolId}`);
344
357
  }
345
358
  if (isDuplicate) {
346
- logger.info(
347
- `Ignoring duplicate message ${messageId} (requires no ack) for protocol ${message.payloadHeader.protocolId} on channel ${channel.name}`,
348
- );
359
+ if (message.packetHeader.destGroupId === undefined) {
360
+ // Duplicate Non-Group messages are still interesting to log to know them
361
+ logger.info(
362
+ `Ignoring duplicate message ${messageId} (requires no ack) for protocol ${message.payloadHeader.protocolId} on channel ${channel.name}`,
363
+ );
364
+ }
349
365
  return;
350
366
  } else {
351
367
  logger.info(
@@ -365,12 +381,12 @@ export class ExchangeManager {
365
381
  return;
366
382
  }
367
383
  const { session } = exchange;
368
- if (session.isSecure && session.closingAfterExchangeFinished) {
384
+ if (NodeSession.is(session) && session.closingAfterExchangeFinished) {
369
385
  logger.debug(
370
386
  `Exchange index ${exchangeIndex} Session ${session.name} is already marked for closure. Close session now.`,
371
387
  );
372
388
  try {
373
- await this.#closeSession(session as SecureSession);
389
+ await this.#closeSession(session);
374
390
  } catch (error) {
375
391
  logger.error(`Error closing session ${session.name}. Ignoring.`, error);
376
392
  }
@@ -378,7 +394,7 @@ export class ExchangeManager {
378
394
  this.#exchanges.delete(exchangeIndex);
379
395
  }
380
396
 
381
- async #closeSession(session: SecureSession) {
397
+ async #closeSession(session: NodeSession) {
382
398
  const sessionId = session.id;
383
399
  const sessionName = session.name;
384
400
 
@@ -18,8 +18,16 @@ import {
18
18
  Timer,
19
19
  createPromise,
20
20
  } from "#general";
21
- import { NodeId, SECURE_CHANNEL_PROTOCOL_ID, SecureMessageType, StatusCode, StatusResponseError } from "#types";
22
- import { Message, MessageCodec, SessionType } from "../codec/MessageCodec.js";
21
+ import { GroupSession } from "#session/index.js";
22
+ import {
23
+ GroupId,
24
+ NodeId,
25
+ SECURE_CHANNEL_PROTOCOL_ID,
26
+ SecureMessageType,
27
+ StatusCode,
28
+ StatusResponseError,
29
+ } from "#types";
30
+ import { Message, MessageCodec, PacketHeader, SessionType } from "../codec/MessageCodec.js";
23
31
  import { SecureChannelProtocol } from "../securechannel/SecureChannelProtocol.js";
24
32
  import {
25
33
  SESSION_ACTIVE_INTERVAL_MS,
@@ -404,18 +412,43 @@ export class MessageExchange {
404
412
  }
405
413
  }
406
414
 
407
- // TODO Add support to also send controlMessages for Group messages, use different messagecounter!
408
- const message: Message = {
409
- packetHeader: {
415
+ let packetHeader: PacketHeader;
416
+ if (this.session.type === SessionType.Unicast) {
417
+ packetHeader = {
410
418
  sessionId: this.#peerSessionId,
411
- sessionType: SessionType.Unicast, // TODO: support multicast/groups
419
+ sessionType: SessionType.Unicast,
412
420
  messageId: await this.session.getIncrementedMessageCounter(),
413
421
  destNodeId: this.#peerNodeId,
414
422
  sourceNodeId: this.#nodeId,
415
423
  hasPrivacyEnhancements: false,
416
424
  isControlMessage: false,
417
425
  hasMessageExtensions: false,
418
- },
426
+ };
427
+ } else if (this.session.type === SessionType.Group) {
428
+ const session = this.session;
429
+ if (!GroupSession.is(session)) {
430
+ throw new InternalError("Session is not a GroupSession, but session type is Group.");
431
+ }
432
+ const destGroupId = GroupId.fromNodeId(this.#peerNodeId!); // TODO !!! Where get from?
433
+ if (destGroupId === 0) {
434
+ throw new InternalError(`Invalid GroupId extracted from NodeId ${this.#peerNodeId}`);
435
+ }
436
+ packetHeader = {
437
+ sessionId: this.#peerSessionId,
438
+ sessionType: SessionType.Group,
439
+ messageId: await session.getIncrementedMessageCounter(),
440
+ destGroupId,
441
+ sourceNodeId: this.#nodeId, // We are the source node, so use our NodeId
442
+ hasPrivacyEnhancements: false,
443
+ isControlMessage: false,
444
+ hasMessageExtensions: false,
445
+ };
446
+ } else {
447
+ throw new InternalError(`Unknown session type: ${this.session.type}`);
448
+ }
449
+
450
+ const message: Message = {
451
+ packetHeader,
419
452
  payloadHeader: {
420
453
  exchangeId: this.#exchangeId,
421
454
  protocolId:
@@ -466,6 +499,8 @@ export class MessageExchange {
466
499
  let timeout: number;
467
500
  if (options?.timeoutMs !== undefined) {
468
501
  timeout = options.timeoutMs;
502
+ } else if (this.#messagesQueue.size > 0) {
503
+ timeout = 0; // If we have messages in the queue, we can return them immediately
469
504
  } else {
470
505
  switch (this.channel.type) {
471
506
  case "tcp":
@@ -21,7 +21,7 @@ export abstract class MessageReceptionState {
21
21
 
22
22
  /**
23
23
  * Implements a message reception state for encrypted messages without rollover.
24
- * A counter in the range [(max_message_counter + 1) to (232 - 1)] SHALL be considered new, and cause the
24
+ * A counter in the range [(max_message_counter + 1) to (2^31 - 1)] SHALL be considered new, and cause the
25
25
  * max_message_counter value to be updated.
26
26
  * Message counters within the range of the bitmap SHALL be considered duplicate if the corresponding bit
27
27
  * offset is set to true. All other message counters SHALL be considered duplicate.
@@ -121,7 +121,7 @@ export class MessageReceptionStateEncryptedWithoutRollover extends MessageRecept
121
121
  }
122
122
 
123
123
  const diff = this.calculateDiff(messageCounter);
124
- // A counter in the range [(max_message_counter + 1) to (232 - 1)] SHALL be considered new, and cause the
124
+ // A counter in the range [(max_message_counter + 1) to (2^31 - 1)] SHALL be considered new, and cause the
125
125
  // max_message_counter value to be updated.
126
126
  // Message counters within the range of the bitmap SHALL be considered duplicate if the corresponding bit
127
127
  // offset is set to true. All other message counters SHALL be considered duplicate.
@@ -19,7 +19,7 @@ import {
19
19
  import { Message } from "../codec/MessageCodec.js";
20
20
  import { MessageExchange } from "../protocol/MessageExchange.js";
21
21
  import { ProtocolHandler } from "../protocol/ProtocolHandler.js";
22
- import { assertSecureSession } from "../session/SecureSession.js";
22
+ import { SecureSession } from "../session/SecureSession.js";
23
23
  import { CaseServer } from "../session/case/CaseServer.js";
24
24
  import { MaximumPasePairingErrorsReachedError, PaseServer } from "../session/pase/PaseServer.js";
25
25
  import { ChannelStatusResponseError, SecureChannelMessenger } from "./SecureChannelMessenger.js";
@@ -79,7 +79,7 @@ export class StatusReportOnlySecureChannelProtocol implements ProtocolHandler {
79
79
  }
80
80
 
81
81
  const { session } = exchange;
82
- assertSecureSession(session);
82
+ SecureSession.assert(session);
83
83
  logger.debug(`Peer requested to close session ${session.name}. Remove session now.`);
84
84
  // TODO: and do more - see Core Specs 5.5
85
85
  await session.destroy(false, false);
@@ -0,0 +1,223 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2023 Project CHIP Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { Subject } from "#action/server/Subject.js";
7
+ import { DecodedMessage, DecodedPacket, Message, MessageCodec, Packet, SessionType } from "#codec/index.js";
8
+ import { Fabric } from "#fabric/Fabric.js";
9
+ import { FabricManager } from "#fabric/FabricManager.js";
10
+ import {
11
+ Bytes,
12
+ Crypto,
13
+ CryptoDecryptError,
14
+ ImplementationError,
15
+ InternalError,
16
+ Logger,
17
+ MatterFlowError,
18
+ UnexpectedDataError,
19
+ } from "#general";
20
+ import type { SessionManager } from "#session/SessionManager.js";
21
+ import { GroupId, NodeId } from "#types";
22
+ import { SecureSession } from "./SecureSession.js";
23
+ import { Session } from "./Session.js";
24
+
25
+ const logger = Logger.get("SecureGroupSession");
26
+
27
+ /** Secure Group session instance */
28
+ export class GroupSession extends SecureSession {
29
+ readonly #id: number;
30
+ readonly #fabric: Fabric;
31
+ readonly #peerNodeId: NodeId;
32
+ readonly #operationalGroupKey: Uint8Array;
33
+ readonly supportsMRP = false;
34
+ readonly closingAfterExchangeFinished = false; // Group sessions do not close after exchange finished, they are long-lived
35
+
36
+ readonly keySetId: number;
37
+
38
+ constructor(args: {
39
+ manager?: SessionManager;
40
+ id: number; // Records the Group Session ID derived from the Operational Group Key used to encrypt the message.
41
+ fabric: Fabric;
42
+ keySetId: number; // The Group Key Set ID that was used to encrypt the incoming group message.
43
+ peerNodeId: NodeId; //The Target Group Node Id
44
+ operationalGroupKey: Uint8Array; // The Operational Group Key that was used to encrypt the incoming group message.
45
+ }) {
46
+ const { manager, fabric, operationalGroupKey, id, peerNodeId, keySetId } = args;
47
+ super({
48
+ ...args,
49
+ setActiveTimestamp: false, // We always set the active timestamp for Secure sessions TODO Check
50
+ messageCounter: fabric.groups.messaging.counterFor(operationalGroupKey),
51
+ });
52
+ this.#id = id;
53
+ this.#fabric = fabric;
54
+ this.#peerNodeId = peerNodeId;
55
+ this.keySetId = keySetId;
56
+ this.#operationalGroupKey = operationalGroupKey;
57
+
58
+ manager?.registerGroupSession(this);
59
+ fabric.addSession(this);
60
+
61
+ logger.debug(`Created secure GROUP session for fabric index ${fabric.fabricIndex}`, this.name);
62
+ }
63
+
64
+ override get type() {
65
+ return SessionType.Group;
66
+ }
67
+
68
+ get fabric(): Fabric {
69
+ return this.#fabric;
70
+ }
71
+
72
+ get id() {
73
+ return this.#id;
74
+ }
75
+
76
+ get peerSessionId(): number {
77
+ return this.#id; // we use the same peer session ID then ours because should be the same keys
78
+ }
79
+
80
+ get name() {
81
+ return `group/${this.#id}`;
82
+ }
83
+
84
+ get nodeId() {
85
+ return this.#fabric.nodeId;
86
+ }
87
+
88
+ get peerNodeId() {
89
+ return this.#peerNodeId;
90
+ }
91
+
92
+ get associatedFabric(): Fabric {
93
+ return this.#fabric;
94
+ }
95
+
96
+ subjectFor(message?: Message): Subject {
97
+ if (message === undefined || message.packetHeader.destGroupId === undefined) {
98
+ throw new ImplementationError("GroupSession requires a message with destGroupId");
99
+ }
100
+ return this.fabric.groups.subjectForGroup(GroupId(message.packetHeader.destGroupId), this.keySetId);
101
+ }
102
+
103
+ override notifyActivity(_messageReceived: boolean) {
104
+ // Group sessions do not have a specific activity notification, so we do nothing here
105
+ }
106
+
107
+ override updateMessageCounter(messageCounter: number, sourceNodeId: NodeId, operationalKey: Uint8Array) {
108
+ if (sourceNodeId === undefined || operationalKey === undefined) {
109
+ throw new InternalError("Source Node ID is required for GroupSession updateMessageCounter.");
110
+ }
111
+ const receptionState = this.#fabric.groups.messaging.receptionStateFor(sourceNodeId, operationalKey);
112
+ receptionState.updateMessageCounter(messageCounter);
113
+ }
114
+
115
+ encode(message: Message): Packet {
116
+ message.packetHeader.sessionId = this.#id;
117
+ const { header, applicationPayload } = MessageCodec.encodePayload(message);
118
+ if (header.destGroupId === undefined) {
119
+ // Just to be sure
120
+ throw new UnexpectedDataError("Group ID is required for GroupSession encode.");
121
+ }
122
+
123
+ const headerBytes = MessageCodec.encodePacketHeader(message.packetHeader);
124
+ const securityFlags = headerBytes[3];
125
+ const nonce = Session.generateNonce(securityFlags, header.messageId, this.#fabric.nodeId);
126
+
127
+ return {
128
+ header,
129
+ applicationPayload: Crypto.encrypt(this.#operationalGroupKey, applicationPayload, nonce, headerBytes),
130
+ };
131
+ }
132
+
133
+ decode(): DecodedMessage {
134
+ throw new InternalError("GroupSession does not support decode on instance.");
135
+ }
136
+
137
+ static decode(
138
+ fabrics: FabricManager,
139
+ { header, applicationPayload, messageExtension }: DecodedPacket,
140
+ aad: Uint8Array,
141
+ ): {
142
+ message: DecodedMessage;
143
+ key: Uint8Array;
144
+ sessionId: number;
145
+ sourceNodeId: NodeId;
146
+ keySetId: number;
147
+ fabric: Fabric;
148
+ } {
149
+ if (header.hasMessageExtensions) {
150
+ logger.info(
151
+ `Message extensions are not supported. Ignoring ${messageExtension ? Bytes.toHex(messageExtension) : undefined}`,
152
+ );
153
+ }
154
+ const sourceNodeId = header.sourceNodeId;
155
+ if (sourceNodeId === undefined) {
156
+ // Already checked on decoding, but validate twice
157
+ throw new UnexpectedDataError("Source Node ID is required for GroupSession decode.");
158
+ }
159
+ const nonce = Session.generateNonce(header.securityFlags, header.messageId, sourceNodeId);
160
+ const sessionId = header.sessionId;
161
+ const keys = new Array<{ key: Uint8Array; keySetId: number; fabric: Fabric }>();
162
+ for (const fabric of fabrics) {
163
+ const sessions = fabric.groups.sessions.get(sessionId);
164
+ if (sessions?.length) {
165
+ for (const session of sessions) {
166
+ keys.push({ ...session, fabric });
167
+ }
168
+ }
169
+ }
170
+ if (keys.length === 0) {
171
+ throw new MatterFlowError("No key candidate found for group session decryption.");
172
+ }
173
+ let message: DecodedMessage | undefined;
174
+ let key: Uint8Array | undefined;
175
+ let fabric: Fabric | undefined;
176
+ let keySetId: number | undefined;
177
+ let found = false;
178
+ for ({ key, keySetId, fabric } of keys) {
179
+ try {
180
+ message = MessageCodec.decodePayload({
181
+ header,
182
+ applicationPayload: Crypto.decrypt(key, applicationPayload, nonce, aad),
183
+ });
184
+ found = true;
185
+ break; // Exit loop on first successful decryption
186
+ } catch (error) {
187
+ CryptoDecryptError.accept(error);
188
+ }
189
+ }
190
+ if (!found || !message || !key || !keySetId || !fabric) {
191
+ throw new MatterFlowError("Failed to decode group message with any key candidate.");
192
+ }
193
+
194
+ if (message.payloadHeader.hasSecuredExtension) {
195
+ logger.info(
196
+ `Secured extensions are not supported. Ignoring ${message.securityExtension ? Bytes.toHex(message.securityExtension) : undefined}`,
197
+ );
198
+ }
199
+
200
+ return { message, key, sessionId, sourceNodeId, keySetId, fabric };
201
+ }
202
+
203
+ async destroy() {
204
+ logger.info(`End group session ${this.name}`);
205
+ this.manager?.removeGroupSession(this);
206
+ }
207
+
208
+ end() {
209
+ return this.destroy();
210
+ }
211
+ }
212
+
213
+ export namespace GroupSession {
214
+ export function assert(session?: Session, errorText?: string): asserts session is GroupSession {
215
+ if (!is(session)) {
216
+ throw new MatterFlowError(errorText ?? "Insecure session in secure context");
217
+ }
218
+ }
219
+
220
+ export function is(session?: Session): session is GroupSession {
221
+ return session?.type === SessionType.Group;
222
+ }
223
+ }
@@ -6,11 +6,11 @@
6
6
 
7
7
  import { Logger, MatterFlowError } from "#general";
8
8
  import { NodeId } from "#types";
9
- import { DecodedMessage, DecodedPacket, Message, MessageCodec, Packet } from "../codec/MessageCodec.js";
9
+ import { DecodedMessage, DecodedPacket, Message, MessageCodec, Packet, SessionType } from "../codec/MessageCodec.js";
10
10
  import { Fabric } from "../fabric/Fabric.js";
11
11
  import { MessageCounter } from "../protocol/MessageCounter.js";
12
12
  import { MessageReceptionStateUnencryptedWithRollover } from "../protocol/MessageReceptionState.js";
13
- import { NoAssociatedFabricError } from "./SecureSession.js";
13
+ import { NoAssociatedFabricError } from "./NodeSession.js";
14
14
  import { Session, SessionParameterOptions } from "./Session.js";
15
15
  import { SessionManager, UNICAST_UNSECURE_SESSION_ID } from "./SessionManager.js";
16
16
 
@@ -20,6 +20,7 @@ export class InsecureSession extends Session {
20
20
  readonly #initiatorNodeId: NodeId;
21
21
  readonly closingAfterExchangeFinished = false;
22
22
  readonly supportsMRP = true;
23
+ readonly type = SessionType.Unicast;
23
24
 
24
25
  constructor(args: {
25
26
  manager?: SessionManager;