@matter/protocol 0.14.1-alpha.0-20250605-9fc134af0 → 0.14.1-alpha.0-20250607-a93593303

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 +66 -1
  30. package/dist/cjs/cluster/client/ClusterClient.js.map +1 -1
  31. package/dist/cjs/cluster/client/ClusterClientTypes.d.ts +36 -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 +67 -2
  166. package/dist/esm/cluster/client/ClusterClient.js.map +1 -1
  167. package/dist/esm/cluster/client/ClusterClientTypes.d.ts +36 -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 +97 -4
  283. package/src/cluster/client/ClusterClientTypes.ts +45 -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
@@ -4,7 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
- import { capitalize, Diagnostic, Logger, Merge } from "#general";
7
+ import { capitalize, Diagnostic, ImplementationError, Logger, Merge } from "#general";
8
8
  import {
9
9
  Attribute,
10
10
  AttributeId,
@@ -31,18 +31,37 @@ import {
31
31
  AttributeClientValues,
32
32
  ClusterClientObj,
33
33
  EventClients,
34
+ GroupClusterClientObj,
34
35
  SignatureFromCommandSpec,
36
+ SignatureFromCommandSpecWithoutResponse,
35
37
  } from "./ClusterClientTypes.js";
36
38
  import { createEventClient } from "./EventClient.js";
37
39
 
38
40
  const logger = Logger.get("ClusterClient");
39
41
 
42
+ export function GroupClusterClient<const T extends ClusterType>(
43
+ clusterDef: T,
44
+ interactionClient: InteractionClient,
45
+ globalAttributeValues: Partial<AttributeClientValues<GlobalAttributes<T["features"]>>> = {},
46
+ ): GroupClusterClientObj<T> {
47
+ if (!interactionClient.isGroupAddress) {
48
+ throw new Error("GroupClusterClient must be used with a GroupAddress InteractionClient");
49
+ }
50
+
51
+ return ClusterClient(clusterDef, undefined, interactionClient, globalAttributeValues);
52
+ }
53
+
40
54
  export function ClusterClient<const T extends ClusterType>(
41
55
  clusterDef: T,
42
- endpointId: EndpointNumber,
56
+ endpointId: EndpointNumber | undefined,
43
57
  interactionClient: InteractionClient,
44
58
  globalAttributeValues: Partial<AttributeClientValues<GlobalAttributes<T["features"]>>> = {},
45
59
  ): ClusterClientObj<T> {
60
+ const isGroupAddress = interactionClient.isGroupAddress;
61
+ if (isGroupAddress !== (endpointId === undefined)) {
62
+ throw new Error("Endpoint ID must be defined for a Non-Group ClusterClient");
63
+ }
64
+
46
65
  function addAttributeToResult(attribute: Attribute<any, any>, attributeName: string) {
47
66
  (attributes as any)[attributeName] = createAttributeClient(
48
67
  attribute,
@@ -59,6 +78,10 @@ export function ClusterClient<const T extends ClusterType>(
59
78
  requestFromRemote?: boolean,
60
79
  isFabricFiltered = true,
61
80
  ) => {
81
+ if (isGroupAddress) {
82
+ throw new ImplementationError("Group cluster clients do not support reading attributes");
83
+ }
84
+
62
85
  try {
63
86
  return await (attributes as any)[attributeName].get(requestFromRemote, isFabricFiltered);
64
87
  } catch (e) {
@@ -68,6 +91,13 @@ export function ClusterClient<const T extends ClusterType>(
68
91
  throw e;
69
92
  }
70
93
  };
94
+ result[`get${capitalizedAttributeName}AttributeFromCache`] = () => {
95
+ if (isGroupAddress) {
96
+ throw new ImplementationError("Group cluster clients do not support reading attributes");
97
+ }
98
+
99
+ return (attributes as any)[attributeName].getLocal();
100
+ };
71
101
  result[`set${capitalizedAttributeName}Attribute`] = async <T>(value: T, dataVersion?: number) =>
72
102
  (attributes as any)[attributeName].set(value, dataVersion);
73
103
  result[`subscribe${capitalizedAttributeName}Attribute`] = async <T>(
@@ -77,6 +107,10 @@ export function ClusterClient<const T extends ClusterType>(
77
107
  knownDataVersion?: number,
78
108
  isFabricFiltered?: boolean,
79
109
  ) => {
110
+ if (isGroupAddress) {
111
+ throw new ImplementationError("Group cluster clients do not support subscribing attributes");
112
+ }
113
+
80
114
  (attributes as any)[attributeName].addListener(listener);
81
115
  return (attributes as any)[attributeName].subscribe(
82
116
  minIntervalS,
@@ -86,9 +120,17 @@ export function ClusterClient<const T extends ClusterType>(
86
120
  );
87
121
  };
88
122
  result[`add${capitalizedAttributeName}AttributeListener`] = <T>(listener: (value: T) => void) => {
123
+ if (isGroupAddress) {
124
+ throw new ImplementationError("Group cluster clients do not support subscribing attributes");
125
+ }
126
+
89
127
  (attributes as any)[attributeName].addListener(listener);
90
128
  };
91
129
  result[`remove${capitalizedAttributeName}AttributeListener`] = <T>(listener: (value: T) => void) => {
130
+ if (isGroupAddress) {
131
+ throw new ImplementationError("Group cluster clients do not support subscribing attributes");
132
+ }
133
+
92
134
  (attributes as any)[attributeName].removeListener(listener);
93
135
  };
94
136
  }
@@ -102,6 +144,10 @@ export function ClusterClient<const T extends ClusterType>(
102
144
  minimumEventNumber?: number | bigint,
103
145
  isFabricFiltered?: boolean,
104
146
  ) => {
147
+ if (isGroupAddress) {
148
+ throw new ImplementationError("Group cluster clients do not support reading events");
149
+ }
150
+
105
151
  try {
106
152
  return await (events as any)[eventName].get(minimumEventNumber, isFabricFiltered);
107
153
  } catch (e) {
@@ -119,6 +165,10 @@ export function ClusterClient<const T extends ClusterType>(
119
165
  minimumEventNumber?: number | bigint,
120
166
  isFabricFiltered?: boolean,
121
167
  ) => {
168
+ if (isGroupAddress) {
169
+ throw new ImplementationError("Group cluster clients do not support subscribing to events");
170
+ }
171
+
122
172
  (events as any)[eventName].addListener(listener);
123
173
  return (events as any)[eventName].subscribe(
124
174
  minIntervalS,
@@ -129,9 +179,17 @@ export function ClusterClient<const T extends ClusterType>(
129
179
  );
130
180
  };
131
181
  result[`add${capitalizedEventName}EventListener`] = <T>(listener: (value: DecodedEventData<T>) => void) => {
182
+ if (isGroupAddress) {
183
+ throw new ImplementationError("Group cluster clients do not support subscribing events");
184
+ }
185
+
132
186
  (events as any)[eventName].addListener(listener);
133
187
  };
134
188
  result[`remove${capitalizedEventName}EventListener`] = <T>(listener: (value: DecodedEventData<T>) => void) => {
189
+ if (isGroupAddress) {
190
+ throw new ImplementationError("Group cluster clients do not support subscribing events");
191
+ }
192
+
135
193
  (events as any)[eventName].removeListener(listener);
136
194
  };
137
195
  }
@@ -149,7 +207,13 @@ export function ClusterClient<const T extends ClusterType>(
149
207
  } = clusterDef;
150
208
  const attributes = <AttributeClients<T["features"], T["attributes"]>>{};
151
209
  const events = <EventClients<T["events"]>>{};
152
- const commands = <{ [P in keyof T["commands"]]: SignatureFromCommandSpec<T["commands"][P]> }>{};
210
+ const commands = <
211
+ {
212
+ [P in keyof T["commands"]]:
213
+ | SignatureFromCommandSpec<T["commands"][P]>
214
+ | SignatureFromCommandSpecWithoutResponse<T["commands"][P]>;
215
+ }
216
+ >{};
153
217
 
154
218
  let reportedFeatures: TypeFromPartialBitSchema<T["features"]> | undefined = undefined;
155
219
  // If we have global attribute values we use them to modify
@@ -178,6 +242,10 @@ export function ClusterClient<const T extends ClusterType>(
178
242
  eventFilters?: TypeFromSchema<typeof TlvEventFilter>[];
179
243
  dataVersionFilters?: { endpointId: EndpointNumber; clusterId: ClusterId; dataVersion: number }[];
180
244
  }) => {
245
+ if (isGroupAddress) {
246
+ throw new ImplementationError("Group cluster clients do not support subscribing attributes");
247
+ }
248
+
181
249
  const {
182
250
  minIntervalFloorSeconds,
183
251
  maxIntervalCeilingSeconds,
@@ -237,10 +305,18 @@ export function ClusterClient<const T extends ClusterType>(
237
305
  },
238
306
 
239
307
  isAttributeSupported: (attributeId: AttributeId) => {
308
+ if (isGroupAddress) {
309
+ throw new ImplementationError("Group cluster clients do not allow to determine attribute existence.");
310
+ }
311
+
240
312
  return !!globalAttributeValues?.attributeList?.includes(attributeId);
241
313
  },
242
314
 
243
315
  isAttributeSupportedByName: (attributeName: string) => {
316
+ if (isGroupAddress) {
317
+ throw new ImplementationError("Group cluster clients do not allow to determine attribute existence.");
318
+ }
319
+
244
320
  const attribute = (attributes as any)[attributeName];
245
321
  if (attribute === undefined) {
246
322
  return false;
@@ -249,10 +325,18 @@ export function ClusterClient<const T extends ClusterType>(
249
325
  },
250
326
 
251
327
  isCommandSupported: (commandId: CommandId) => {
328
+ if (isGroupAddress) {
329
+ throw new ImplementationError("Group cluster clients do not allow to determine command existence.");
330
+ }
331
+
252
332
  return !!globalAttributeValues?.acceptedCommandList?.includes(commandId);
253
333
  },
254
334
 
255
335
  isCommandSupportedByName: (commandName: string) => {
336
+ if (isGroupAddress) {
337
+ throw new ImplementationError("Group cluster clients do not allow to determine attribute existence.");
338
+ }
339
+
256
340
  const command = commandDef[commandName];
257
341
  if (command === undefined) {
258
342
  return false;
@@ -308,8 +392,17 @@ export function ClusterClient<const T extends ClusterType>(
308
392
  } = {},
309
393
  ) => {
310
394
  const { asTimedRequest, timedRequestTimeoutMs, useExtendedFailSafeMessageResponseTimeout } = options;
395
+ if (isGroupAddress) {
396
+ return interactionClient.invokeWithSuppressedResponse<Command<RequestT, ResponseT, any>>({
397
+ clusterId,
398
+ command: commandDef[commandName],
399
+ request,
400
+ asTimedRequest,
401
+ timedRequestTimeoutMs,
402
+ });
403
+ }
311
404
  return interactionClient.invoke<Command<RequestT, ResponseT, any>>({
312
- endpointId,
405
+ endpointId: endpointId!,
313
406
  clusterId,
314
407
  command: commandDef[commandName],
315
408
  request,
@@ -72,6 +72,23 @@ export type SignatureFromCommandSpec<C extends Command<any, any, any>> = (
72
72
  useExtendedFailSafeMessageResponseTimeout?: boolean;
73
73
  },
74
74
  ) => Promise<ResponseType<C>>;
75
+
76
+ export type SignatureFromCommandSpecWithoutResponse<C extends Command<any, any, any>> = (
77
+ request: RequestType<C>,
78
+ options?: {
79
+ /** Send this command as a timed request also when not required. Default timeout are 10 seconds. */
80
+ asTimedRequest?: boolean;
81
+
82
+ /** Override the request timeout when the command is sent as times request. Default are 10s. */
83
+ timedRequestTimeoutMs?: number;
84
+
85
+ /**
86
+ * Use the extended fail-safe message response timeout of 30 seconds. Use this for all commands
87
+ * executed during an activated FailSafe context!
88
+ */
89
+ useExtendedFailSafeMessageResponseTimeout?: boolean;
90
+ },
91
+ ) => Promise<void>;
75
92
  type GetterTypeFromSpec<A extends Attribute<any, any>> =
76
93
  A extends OptionalAttribute<infer T, any> ? T | undefined : AttributeJsType<A>;
77
94
  type ClientAttributeGetters<A extends Attributes> = Omit<
@@ -83,6 +100,12 @@ type ClientAttributeGetters<A extends Attributes> = Omit<
83
100
  },
84
101
  keyof GlobalAttributes<any>
85
102
  >;
103
+ type ClientLocalAttributeGetters<A extends Attributes> = Omit<
104
+ {
105
+ [P in keyof A as `get${Capitalize<string & P>}AttributeFromCache`]: () => GetterTypeFromSpec<A[P]> | undefined;
106
+ },
107
+ keyof GlobalAttributes<any>
108
+ >;
86
109
  type ClientGlobalAttributeGetters<F extends BitSchema> = {
87
110
  [P in GlobalAttributeNames<F> as `get${Capitalize<string & P>}Attribute`]: () => Promise<
88
111
  GetterTypeFromSpec<GlobalAttributes<F>[P]>
@@ -116,6 +139,7 @@ type ClientAttributeListeners<A extends Attributes> = {
116
139
  };
117
140
 
118
141
  type CommandServers<C extends Commands> = { [P in keyof C]: SignatureFromCommandSpec<C[P]> };
142
+ type NoResponseCommandServers<C extends Commands> = { [P in keyof C]: SignatureFromCommandSpecWithoutResponse<C[P]> };
119
143
 
120
144
  type ClientEventGetters<E extends Events> = {
121
145
  [P in keyof E as `get${Capitalize<string & P>}Event`]: (
@@ -143,8 +167,8 @@ type ClientEventListeners<E extends Events> = {
143
167
  ) => void;
144
168
  };
145
169
 
146
- /** Strongly typed interface of a cluster client */
147
- export type ClusterClientObj<T extends ClusterType = ClusterType> = {
170
+ /** Strongly typed interface of a group cluster client (limited functionalities) */
171
+ export type BaseClusterClientObj<T extends ClusterType = ClusterType> = {
148
172
  /**
149
173
  * Cluster ID
150
174
  * @readonly
@@ -177,12 +201,6 @@ export type ClusterClientObj<T extends ClusterType = ClusterType> = {
177
201
  */
178
202
  readonly isUnknown: boolean;
179
203
 
180
- /**
181
- * Endpoint ID the cluster is on.
182
- * @readonly
183
- */
184
- readonly endpointId: number;
185
-
186
204
  /**
187
205
  * Supported Features of the cluster
188
206
  * @readonly
@@ -195,6 +213,24 @@ export type ClusterClientObj<T extends ClusterType = ClusterType> = {
195
213
  * @readonly
196
214
  */
197
215
  readonly attributes: AttributeClients<T["features"], T["attributes"]>;
216
+ } & ClientAttributeSetters<T["attributes"]>;
217
+
218
+ export type GroupClusterClientObj<T extends ClusterType = ClusterType> = BaseClusterClientObj<T> & {
219
+ /**
220
+ * Commands of the cluster as object with named keys. This can be used to discover the commands of the cluster
221
+ * programmatically.
222
+ * @readonly
223
+ */
224
+ readonly commands: NoResponseCommandServers<T["commands"]>;
225
+ } & NoResponseCommandServers<T["commands"]>;
226
+
227
+ /** Strongly typed interface of a cluster client */
228
+ export type ClusterClientObj<T extends ClusterType = ClusterType> = BaseClusterClientObj<T> & {
229
+ /**
230
+ * Endpoint ID the cluster is on.
231
+ * @readonly
232
+ */
233
+ readonly endpointId: number;
198
234
 
199
235
  /**
200
236
  * Events of the cluster as object with named keys. This can be used to discover the events of the cluster
@@ -235,8 +271,8 @@ export type ClusterClientObj<T extends ClusterType = ClusterType> = {
235
271
  /** Returns if a given Command with provided name is present and supported at the connected cluster server. */
236
272
  isCommandSupportedByName: (commandName: string) => boolean;
237
273
  } & ClientAttributeGetters<T["attributes"]> &
274
+ ClientLocalAttributeGetters<T["attributes"]> &
238
275
  ClientGlobalAttributeGetters<T["features"]> &
239
- ClientAttributeSetters<T["attributes"]> &
240
276
  ClientAttributeSubscribers<T["attributes"]> &
241
277
  ClientAttributeListeners<T["attributes"]> &
242
278
  CommandServers<T["commands"]> &
@@ -4,6 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
+ import { ImplementationError } from "#general";
7
8
  import { ClusterId, EndpointNumber, Event, EventId, EventNumber } from "#types";
8
9
  import { DecodedEventData } from "../../interaction/EventDataDecoder.js";
9
10
  import { InteractionClient } from "../../interaction/InteractionClient.js";
@@ -14,7 +15,7 @@ import { InteractionClient } from "../../interaction/InteractionClient.js";
14
15
  export function createEventClient<T>(
15
16
  event: Event<T, any>,
16
17
  name: string,
17
- endpointId: EndpointNumber,
18
+ endpointId: EndpointNumber | undefined,
18
19
  clusterId: ClusterId,
19
20
  interactionClient: InteractionClient,
20
21
  ): EventClient<T> {
@@ -32,7 +33,7 @@ export class EventClient<T> {
32
33
  constructor(
33
34
  readonly event: Event<T, any>,
34
35
  readonly name: string,
35
- readonly endpointId: EndpointNumber,
36
+ readonly endpointId: EndpointNumber | undefined,
36
37
  readonly clusterId: ClusterId,
37
38
  interactionClient: InteractionClient,
38
39
  ) {
@@ -44,6 +45,9 @@ export class EventClient<T> {
44
45
  minimumEventNumber?: EventNumber,
45
46
  isFabricFiltered?: boolean,
46
47
  ): Promise<DecodedEventData<T>[] | undefined> {
48
+ if (this.endpointId === undefined) {
49
+ throw new ImplementationError("Cannot read event without endpointId");
50
+ }
47
51
  return await this.#interactionClient.getEvent({
48
52
  endpointId: this.endpointId,
49
53
  clusterId: this.clusterId,
@@ -60,6 +64,9 @@ export class EventClient<T> {
60
64
  minimumEventNumber?: EventNumber,
61
65
  isFabricFiltered?: boolean,
62
66
  ) {
67
+ if (this.endpointId === undefined) {
68
+ throw new ImplementationError("Cannot read event without endpointId");
69
+ }
63
70
  return await this.#interactionClient.subscribeEvent({
64
71
  endpointId: this.endpointId,
65
72
  clusterId: this.clusterId,
@@ -4,7 +4,16 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
- import { Bytes, DataReader, DataWriter, Diagnostic, Endian, NotImplementedError, UnexpectedDataError } from "#general";
7
+ import {
8
+ Bytes,
9
+ DataReader,
10
+ DataWriter,
11
+ Diagnostic,
12
+ Endian,
13
+ InternalError,
14
+ NotImplementedError,
15
+ UnexpectedDataError,
16
+ } from "#general";
8
17
  import { ExchangeLogContext } from "#protocol/index.js";
9
18
  import { GroupId, INTERACTION_PROTOCOL_ID, NodeId, SECURE_CHANNEL_PROTOCOL_ID, SecureMessageType } from "#types";
10
19
  import { MessageType } from "../interaction/InteractionMessenger.js";
@@ -84,6 +93,7 @@ const enum SecurityFlag {
84
93
  HasPrivacyEnhancements = 0b10000000,
85
94
  IsControlMessage = 0b01000000,
86
95
  HasMessageExtension = 0b00100000,
96
+ SessionTypeMask = 0b00000011,
87
97
  }
88
98
 
89
99
  function mapProtocolAndMessageType(protocolId: number, messageType: number): { type: string; for?: string } {
@@ -129,6 +139,13 @@ export class MessageCodec {
129
139
  const extensionLength = reader.readUInt16();
130
140
  securityExtension = reader.readByteArray(extensionLength);
131
141
  }
142
+
143
+ if (header.sessionType === SessionType.Group && !header.isControlMessage) {
144
+ if (payloadHeader.requiresAck || payloadHeader.ackedMessageId) {
145
+ throw new UnexpectedDataError(`Group data messages cannot have requiresAck or ackedMessageId set.`);
146
+ }
147
+ }
148
+
132
149
  return {
133
150
  packetHeader: header,
134
151
  payloadHeader,
@@ -176,13 +193,31 @@ export class MessageCodec {
176
193
  const destNodeId = hasDestNodeId ? NodeId(reader.readUInt64()) : undefined;
177
194
  const destGroupId = hasDestGroupId ? GroupId(reader.readUInt16()) : undefined;
178
195
 
179
- const sessionType = securityFlags & 0b00000011;
180
- if (sessionType !== SessionType.Group && sessionType !== SessionType.Unicast)
181
- throw new UnexpectedDataError(`Unsupported session type ${sessionType}`);
196
+ const sessionType = securityFlags & SecurityFlag.SessionTypeMask;
197
+
198
+ if (sessionType !== SessionType.Group && sessionType !== SessionType.Unicast) {
199
+ throw new UnexpectedDataError(`Unsupported session type ${sessionType}.`);
200
+ }
201
+ if (sessionType === SessionType.Unicast && hasDestGroupId) {
202
+ throw new UnexpectedDataError(`Unicast session cannot have destination group id.`);
203
+ }
204
+ if (sessionType === SessionType.Group) {
205
+ if (!hasDestGroupId && !hasDestNodeId) {
206
+ throw new UnexpectedDataError(`Group session must have destination group id or destination node id.`);
207
+ }
208
+ if (!hasSourceNodeId) {
209
+ throw new UnexpectedDataError(`Group session must have source node id.`);
210
+ }
211
+ }
182
212
  const hasPrivacyEnhancements = (securityFlags & SecurityFlag.HasPrivacyEnhancements) !== 0;
183
- if (hasPrivacyEnhancements) throw new NotImplementedError(`Privacy enhancements not supported`);
213
+ if (hasPrivacyEnhancements) {
214
+ throw new NotImplementedError(`Privacy enhancements not supported.`);
215
+ }
184
216
  const isControlMessage = (securityFlags & SecurityFlag.IsControlMessage) !== 0;
185
- if (isControlMessage) throw new NotImplementedError(`Control Messages not supported`);
217
+ if (isControlMessage) {
218
+ // And also currently not needed because MCP is not relevant
219
+ throw new NotImplementedError(`Control Messages not supported.`);
220
+ }
186
221
  const hasMessageExtensions = (securityFlags & SecurityFlag.HasMessageExtension) !== 0;
187
222
 
188
223
  return {
@@ -207,7 +242,7 @@ export class MessageCodec {
207
242
  const hasSecuredExtension = (exchangeFlags & PayloadHeaderFlag.HasSecureExtension) !== 0;
208
243
  const hasVendorId = (exchangeFlags & PayloadHeaderFlag.HasVendorId) !== 0;
209
244
 
210
- const messageType = reader.readUInt8();
245
+ const messageType = reader.readUInt8(); // Protocol Opcode
211
246
  const exchangeId = reader.readUInt16();
212
247
  const vendorId = hasVendorId ? reader.readUInt16() : COMMON_VENDOR_ID;
213
248
  const protocolId = (vendorId << 16) | reader.readUInt16();
@@ -232,6 +267,12 @@ export class MessageCodec {
232
267
  sourceNodeId,
233
268
  sessionType,
234
269
  }: PacketHeader) {
270
+ if (
271
+ sessionType === SessionType.Group &&
272
+ (destGroupId === undefined || sourceNodeId === undefined || destNodeId !== undefined)
273
+ ) {
274
+ throw new InternalError(`Group session must have destination group id or source node id.`);
275
+ }
235
276
  const writer = new DataWriter(Endian.Little);
236
277
  const flags =
237
278
  (HEADER_VERSION << 4) |
@@ -246,7 +287,7 @@ export class MessageCodec {
246
287
  writer.writeUInt32(messageCounter);
247
288
  if (sourceNodeId !== undefined) writer.writeUInt64(sourceNodeId);
248
289
  if (destNodeId !== undefined) writer.writeUInt64(destNodeId);
249
- if (destGroupId !== undefined) writer.writeUInt32(destGroupId);
290
+ if (destGroupId !== undefined) writer.writeUInt16(destGroupId);
250
291
  return writer.toByteArray();
251
292
  }
252
293