1#![allow(clippy::too_many_arguments)]
7
8use crate::tlv;
9use anyhow;
10use serde_json;
11
12
13use crate::clusters::helpers::{serialize_opt_bytes_as_hex};
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
19#[repr(u8)]
20pub enum DatastoreAccessControlEntryAuthMode {
21 Pase = 1,
23 Case = 2,
25 Group = 3,
27}
28
29impl DatastoreAccessControlEntryAuthMode {
30 pub fn from_u8(value: u8) -> Option<Self> {
32 match value {
33 1 => Some(DatastoreAccessControlEntryAuthMode::Pase),
34 2 => Some(DatastoreAccessControlEntryAuthMode::Case),
35 3 => Some(DatastoreAccessControlEntryAuthMode::Group),
36 _ => None,
37 }
38 }
39
40 pub fn to_u8(self) -> u8 {
42 self as u8
43 }
44}
45
46impl From<DatastoreAccessControlEntryAuthMode> for u8 {
47 fn from(val: DatastoreAccessControlEntryAuthMode) -> Self {
48 val as u8
49 }
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
53#[repr(u8)]
54pub enum DatastoreAccessControlEntryPrivilege {
55 View = 1,
57 Proxyview = 2,
58 Operate = 3,
60 Manage = 4,
62 Administer = 5,
64}
65
66impl DatastoreAccessControlEntryPrivilege {
67 pub fn from_u8(value: u8) -> Option<Self> {
69 match value {
70 1 => Some(DatastoreAccessControlEntryPrivilege::View),
71 2 => Some(DatastoreAccessControlEntryPrivilege::Proxyview),
72 3 => Some(DatastoreAccessControlEntryPrivilege::Operate),
73 4 => Some(DatastoreAccessControlEntryPrivilege::Manage),
74 5 => Some(DatastoreAccessControlEntryPrivilege::Administer),
75 _ => None,
76 }
77 }
78
79 pub fn to_u8(self) -> u8 {
81 self as u8
82 }
83}
84
85impl From<DatastoreAccessControlEntryPrivilege> for u8 {
86 fn from(val: DatastoreAccessControlEntryPrivilege) -> Self {
87 val as u8
88 }
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
92#[repr(u8)]
93pub enum DatastoreGroupKeyMulticastPolicy {
94 Pergroupid = 0,
96 Allnodes = 1,
98}
99
100impl DatastoreGroupKeyMulticastPolicy {
101 pub fn from_u8(value: u8) -> Option<Self> {
103 match value {
104 0 => Some(DatastoreGroupKeyMulticastPolicy::Pergroupid),
105 1 => Some(DatastoreGroupKeyMulticastPolicy::Allnodes),
106 _ => None,
107 }
108 }
109
110 pub fn to_u8(self) -> u8 {
112 self as u8
113 }
114}
115
116impl From<DatastoreGroupKeyMulticastPolicy> for u8 {
117 fn from(val: DatastoreGroupKeyMulticastPolicy) -> Self {
118 val as u8
119 }
120}
121
122#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
123#[repr(u8)]
124pub enum DatastoreGroupKeySecurityPolicy {
125 Trustfirst = 0,
127}
128
129impl DatastoreGroupKeySecurityPolicy {
130 pub fn from_u8(value: u8) -> Option<Self> {
132 match value {
133 0 => Some(DatastoreGroupKeySecurityPolicy::Trustfirst),
134 _ => None,
135 }
136 }
137
138 pub fn to_u8(self) -> u8 {
140 self as u8
141 }
142}
143
144impl From<DatastoreGroupKeySecurityPolicy> for u8 {
145 fn from(val: DatastoreGroupKeySecurityPolicy) -> Self {
146 val as u8
147 }
148}
149
150#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
151#[repr(u8)]
152pub enum DatastoreState {
153 Pending = 0,
155 Committed = 1,
157 Deletepending = 2,
159 Commitfailed = 3,
161}
162
163impl DatastoreState {
164 pub fn from_u8(value: u8) -> Option<Self> {
166 match value {
167 0 => Some(DatastoreState::Pending),
168 1 => Some(DatastoreState::Committed),
169 2 => Some(DatastoreState::Deletepending),
170 3 => Some(DatastoreState::Commitfailed),
171 _ => None,
172 }
173 }
174
175 pub fn to_u8(self) -> u8 {
177 self as u8
178 }
179}
180
181impl From<DatastoreState> for u8 {
182 fn from(val: DatastoreState) -> Self {
183 val as u8
184 }
185}
186
187#[derive(Debug, serde::Serialize)]
190pub struct DatastoreACLEntry {
191 pub node_id: Option<u64>,
192 pub list_id: Option<u16>,
193 pub acl_entry: Option<DatastoreAccessControlEntry>,
194 pub status_entry: Option<DatastoreStatusEntry>,
195}
196
197#[derive(Debug, serde::Serialize)]
198pub struct DatastoreAccessControlEntry {
199 pub privilege: Option<DatastoreAccessControlEntryPrivilege>,
200 pub auth_mode: Option<DatastoreAccessControlEntryAuthMode>,
201 pub subjects: Option<Vec<u64>>,
202 pub targets: Option<Vec<DatastoreAccessControlTarget>>,
203}
204
205#[derive(Debug, serde::Serialize)]
206pub struct DatastoreAccessControlTarget {
207 pub cluster: Option<u32>,
208 pub endpoint: Option<u16>,
209 pub device_type: Option<u32>,
210}
211
212#[derive(Debug, serde::Serialize)]
213pub struct DatastoreAdministratorInformationEntry {
214 pub node_id: Option<u64>,
215 pub friendly_name: Option<String>,
216 pub vendor_id: Option<u16>,
217 #[serde(serialize_with = "serialize_opt_bytes_as_hex")]
218 pub icac: Option<Vec<u8>>,
219}
220
221#[derive(Debug, serde::Serialize)]
222pub struct DatastoreBindingTarget {
223 pub node: Option<u64>,
224 pub group: Option<u8>,
225 pub endpoint: Option<u16>,
226 pub cluster: Option<u32>,
227}
228
229#[derive(Debug, serde::Serialize)]
230pub struct DatastoreEndpointBindingEntry {
231 pub node_id: Option<u64>,
232 pub endpoint_id: Option<u16>,
233 pub list_id: Option<u16>,
234 pub binding: Option<DatastoreBindingTarget>,
235 pub status_entry: Option<DatastoreStatusEntry>,
236}
237
238#[derive(Debug, serde::Serialize)]
239pub struct DatastoreEndpointEntry {
240 pub endpoint_id: Option<u16>,
241 pub node_id: Option<u64>,
242 pub friendly_name: Option<String>,
243 pub status_entry: Option<DatastoreStatusEntry>,
244}
245
246#[derive(Debug, serde::Serialize)]
247pub struct DatastoreEndpointGroupIDEntry {
248 pub node_id: Option<u64>,
249 pub endpoint_id: Option<u16>,
250 pub group_id: Option<u8>,
251 pub status_entry: Option<DatastoreStatusEntry>,
252}
253
254#[derive(Debug, serde::Serialize)]
255pub struct DatastoreGroupInformationEntry {
256 pub group_id: Option<u64>,
257 pub friendly_name: Option<String>,
258 pub group_key_set_id: Option<u16>,
259 pub group_cat: Option<u16>,
260 pub group_cat_version: Option<u16>,
261 pub group_permission: Option<DatastoreAccessControlEntryPrivilege>,
262}
263
264#[derive(Debug, serde::Serialize)]
265pub struct DatastoreGroupKeySet {
266 pub group_key_set_id: Option<u16>,
267 pub group_key_security_policy: Option<DatastoreGroupKeySecurityPolicy>,
268 #[serde(serialize_with = "serialize_opt_bytes_as_hex")]
269 pub epoch_key0: Option<Vec<u8>>,
270 pub epoch_start_time0: Option<u64>,
271 #[serde(serialize_with = "serialize_opt_bytes_as_hex")]
272 pub epoch_key1: Option<Vec<u8>>,
273 pub epoch_start_time1: Option<u64>,
274 #[serde(serialize_with = "serialize_opt_bytes_as_hex")]
275 pub epoch_key2: Option<Vec<u8>>,
276 pub epoch_start_time2: Option<u64>,
277 pub group_key_multicast_policy: Option<DatastoreGroupKeyMulticastPolicy>,
278}
279
280#[derive(Debug, serde::Serialize)]
281pub struct DatastoreNodeInformationEntry {
282 pub node_id: Option<u64>,
283 pub friendly_name: Option<String>,
284 pub commissioning_status_entry: Option<DatastoreStatusEntry>,
285}
286
287#[derive(Debug, serde::Serialize)]
288pub struct DatastoreNodeKeySetEntry {
289 pub node_id: Option<u64>,
290 pub group_key_set_id: Option<u16>,
291 pub status_entry: Option<DatastoreStatusEntry>,
292}
293
294#[derive(Debug, serde::Serialize)]
295pub struct DatastoreStatusEntry {
296 pub state: Option<DatastoreState>,
297 pub update_timestamp: Option<u64>,
298 pub failure_code: Option<u8>,
299}
300
301pub fn encode_add_key_set(group_key_set: DatastoreGroupKeySet) -> anyhow::Result<Vec<u8>> {
305 let mut group_key_set_fields = Vec::new();
307 if let Some(x) = group_key_set.group_key_set_id { group_key_set_fields.push((0, tlv::TlvItemValueEnc::UInt16(x)).into()); }
308 if let Some(x) = group_key_set.group_key_security_policy { group_key_set_fields.push((1, tlv::TlvItemValueEnc::UInt8(x.to_u8())).into()); }
309 if let Some(x) = group_key_set.epoch_key0 { group_key_set_fields.push((2, tlv::TlvItemValueEnc::OctetString(x.clone())).into()); }
310 if let Some(x) = group_key_set.epoch_start_time0 { group_key_set_fields.push((3, tlv::TlvItemValueEnc::UInt64(x)).into()); }
311 if let Some(x) = group_key_set.epoch_key1 { group_key_set_fields.push((4, tlv::TlvItemValueEnc::OctetString(x.clone())).into()); }
312 if let Some(x) = group_key_set.epoch_start_time1 { group_key_set_fields.push((5, tlv::TlvItemValueEnc::UInt64(x)).into()); }
313 if let Some(x) = group_key_set.epoch_key2 { group_key_set_fields.push((6, tlv::TlvItemValueEnc::OctetString(x.clone())).into()); }
314 if let Some(x) = group_key_set.epoch_start_time2 { group_key_set_fields.push((7, tlv::TlvItemValueEnc::UInt64(x)).into()); }
315 if let Some(x) = group_key_set.group_key_multicast_policy { group_key_set_fields.push((8, tlv::TlvItemValueEnc::UInt8(x.to_u8())).into()); }
316 let tlv = tlv::TlvItemEnc {
317 tag: 0,
318 value: tlv::TlvItemValueEnc::StructInvisible(vec![
319 (0, tlv::TlvItemValueEnc::StructInvisible(group_key_set_fields)).into(),
320 ]),
321 };
322 Ok(tlv.encode()?)
323}
324
325pub fn encode_update_key_set(group_key_set: DatastoreGroupKeySet) -> anyhow::Result<Vec<u8>> {
327 let mut group_key_set_fields = Vec::new();
329 if let Some(x) = group_key_set.group_key_set_id { group_key_set_fields.push((0, tlv::TlvItemValueEnc::UInt16(x)).into()); }
330 if let Some(x) = group_key_set.group_key_security_policy { group_key_set_fields.push((1, tlv::TlvItemValueEnc::UInt8(x.to_u8())).into()); }
331 if let Some(x) = group_key_set.epoch_key0 { group_key_set_fields.push((2, tlv::TlvItemValueEnc::OctetString(x.clone())).into()); }
332 if let Some(x) = group_key_set.epoch_start_time0 { group_key_set_fields.push((3, tlv::TlvItemValueEnc::UInt64(x)).into()); }
333 if let Some(x) = group_key_set.epoch_key1 { group_key_set_fields.push((4, tlv::TlvItemValueEnc::OctetString(x.clone())).into()); }
334 if let Some(x) = group_key_set.epoch_start_time1 { group_key_set_fields.push((5, tlv::TlvItemValueEnc::UInt64(x)).into()); }
335 if let Some(x) = group_key_set.epoch_key2 { group_key_set_fields.push((6, tlv::TlvItemValueEnc::OctetString(x.clone())).into()); }
336 if let Some(x) = group_key_set.epoch_start_time2 { group_key_set_fields.push((7, tlv::TlvItemValueEnc::UInt64(x)).into()); }
337 if let Some(x) = group_key_set.group_key_multicast_policy { group_key_set_fields.push((8, tlv::TlvItemValueEnc::UInt8(x.to_u8())).into()); }
338 let tlv = tlv::TlvItemEnc {
339 tag: 0,
340 value: tlv::TlvItemValueEnc::StructInvisible(vec![
341 (0, tlv::TlvItemValueEnc::StructInvisible(group_key_set_fields)).into(),
342 ]),
343 };
344 Ok(tlv.encode()?)
345}
346
347pub fn encode_remove_key_set(group_key_set_id: u16) -> anyhow::Result<Vec<u8>> {
349 let tlv = tlv::TlvItemEnc {
350 tag: 0,
351 value: tlv::TlvItemValueEnc::StructInvisible(vec![
352 (0, tlv::TlvItemValueEnc::UInt16(group_key_set_id)).into(),
353 ]),
354 };
355 Ok(tlv.encode()?)
356}
357
358pub fn encode_add_group(group_id: u8, friendly_name: String, group_key_set_id: Option<u16>, group_cat: Option<u16>, group_cat_version: Option<u16>, group_permission: DatastoreAccessControlEntryPrivilege) -> anyhow::Result<Vec<u8>> {
360 let tlv = tlv::TlvItemEnc {
361 tag: 0,
362 value: tlv::TlvItemValueEnc::StructInvisible(vec![
363 (0, tlv::TlvItemValueEnc::UInt8(group_id)).into(),
364 (1, tlv::TlvItemValueEnc::String(friendly_name)).into(),
365 (2, tlv::TlvItemValueEnc::UInt16(group_key_set_id.unwrap_or(0))).into(),
366 (3, tlv::TlvItemValueEnc::UInt16(group_cat.unwrap_or(0))).into(),
367 (4, tlv::TlvItemValueEnc::UInt16(group_cat_version.unwrap_or(0))).into(),
368 (5, tlv::TlvItemValueEnc::UInt8(group_permission.to_u8())).into(),
369 ]),
370 };
371 Ok(tlv.encode()?)
372}
373
374pub fn encode_update_group(group_id: u8, friendly_name: Option<String>, group_key_set_id: Option<u16>, group_cat: Option<u16>, group_cat_version: Option<u16>, group_permission: Option<DatastoreAccessControlEntryPrivilege>) -> anyhow::Result<Vec<u8>> {
376 let tlv = tlv::TlvItemEnc {
377 tag: 0,
378 value: tlv::TlvItemValueEnc::StructInvisible(vec![
379 (0, tlv::TlvItemValueEnc::UInt8(group_id)).into(),
380 (1, tlv::TlvItemValueEnc::String(friendly_name.unwrap_or("".to_string()))).into(),
381 (2, tlv::TlvItemValueEnc::UInt16(group_key_set_id.unwrap_or(0))).into(),
382 (3, tlv::TlvItemValueEnc::UInt16(group_cat.unwrap_or(0))).into(),
383 (4, tlv::TlvItemValueEnc::UInt16(group_cat_version.unwrap_or(0))).into(),
384 (5, tlv::TlvItemValueEnc::UInt8(group_permission.map(|e| e.to_u8()).unwrap_or(0))).into(),
385 ]),
386 };
387 Ok(tlv.encode()?)
388}
389
390pub fn encode_remove_group(group_id: u8) -> anyhow::Result<Vec<u8>> {
392 let tlv = tlv::TlvItemEnc {
393 tag: 0,
394 value: tlv::TlvItemValueEnc::StructInvisible(vec![
395 (0, tlv::TlvItemValueEnc::UInt8(group_id)).into(),
396 ]),
397 };
398 Ok(tlv.encode()?)
399}
400
401pub fn encode_add_admin(node_id: u64, friendly_name: String, vendor_id: u16, icac: Vec<u8>) -> anyhow::Result<Vec<u8>> {
403 let tlv = tlv::TlvItemEnc {
404 tag: 0,
405 value: tlv::TlvItemValueEnc::StructInvisible(vec![
406 (1, tlv::TlvItemValueEnc::UInt64(node_id)).into(),
407 (2, tlv::TlvItemValueEnc::String(friendly_name)).into(),
408 (3, tlv::TlvItemValueEnc::UInt16(vendor_id)).into(),
409 (4, tlv::TlvItemValueEnc::OctetString(icac)).into(),
410 ]),
411 };
412 Ok(tlv.encode()?)
413}
414
415pub fn encode_update_admin(node_id: Option<u64>, friendly_name: Option<String>, icac: Option<Vec<u8>>) -> anyhow::Result<Vec<u8>> {
417 let tlv = tlv::TlvItemEnc {
418 tag: 0,
419 value: tlv::TlvItemValueEnc::StructInvisible(vec![
420 (0, tlv::TlvItemValueEnc::UInt64(node_id.unwrap_or(0))).into(),
421 (1, tlv::TlvItemValueEnc::String(friendly_name.unwrap_or("".to_string()))).into(),
422 (2, tlv::TlvItemValueEnc::OctetString(icac.unwrap_or(vec![]))).into(),
423 ]),
424 };
425 Ok(tlv.encode()?)
426}
427
428pub fn encode_remove_admin(node_id: u64) -> anyhow::Result<Vec<u8>> {
430 let tlv = tlv::TlvItemEnc {
431 tag: 0,
432 value: tlv::TlvItemValueEnc::StructInvisible(vec![
433 (0, tlv::TlvItemValueEnc::UInt64(node_id)).into(),
434 ]),
435 };
436 Ok(tlv.encode()?)
437}
438
439pub fn encode_add_pending_node(node_id: u64, friendly_name: String) -> anyhow::Result<Vec<u8>> {
441 let tlv = tlv::TlvItemEnc {
442 tag: 0,
443 value: tlv::TlvItemValueEnc::StructInvisible(vec![
444 (0, tlv::TlvItemValueEnc::UInt64(node_id)).into(),
445 (1, tlv::TlvItemValueEnc::String(friendly_name)).into(),
446 ]),
447 };
448 Ok(tlv.encode()?)
449}
450
451pub fn encode_refresh_node(node_id: u64) -> anyhow::Result<Vec<u8>> {
453 let tlv = tlv::TlvItemEnc {
454 tag: 0,
455 value: tlv::TlvItemValueEnc::StructInvisible(vec![
456 (0, tlv::TlvItemValueEnc::UInt64(node_id)).into(),
457 ]),
458 };
459 Ok(tlv.encode()?)
460}
461
462pub fn encode_update_node(node_id: u64, friendly_name: String) -> anyhow::Result<Vec<u8>> {
464 let tlv = tlv::TlvItemEnc {
465 tag: 0,
466 value: tlv::TlvItemValueEnc::StructInvisible(vec![
467 (0, tlv::TlvItemValueEnc::UInt64(node_id)).into(),
468 (1, tlv::TlvItemValueEnc::String(friendly_name)).into(),
469 ]),
470 };
471 Ok(tlv.encode()?)
472}
473
474pub fn encode_remove_node(node_id: u64) -> anyhow::Result<Vec<u8>> {
476 let tlv = tlv::TlvItemEnc {
477 tag: 0,
478 value: tlv::TlvItemValueEnc::StructInvisible(vec![
479 (0, tlv::TlvItemValueEnc::UInt64(node_id)).into(),
480 ]),
481 };
482 Ok(tlv.encode()?)
483}
484
485pub fn encode_update_endpoint_for_node(endpoint_id: u16, node_id: u64, friendly_name: String) -> anyhow::Result<Vec<u8>> {
487 let tlv = tlv::TlvItemEnc {
488 tag: 0,
489 value: tlv::TlvItemValueEnc::StructInvisible(vec![
490 (0, tlv::TlvItemValueEnc::UInt16(endpoint_id)).into(),
491 (1, tlv::TlvItemValueEnc::UInt64(node_id)).into(),
492 (2, tlv::TlvItemValueEnc::String(friendly_name)).into(),
493 ]),
494 };
495 Ok(tlv.encode()?)
496}
497
498pub fn encode_add_group_id_to_endpoint_for_node(node_id: u64, endpoint_id: u16, group_id: u8) -> anyhow::Result<Vec<u8>> {
500 let tlv = tlv::TlvItemEnc {
501 tag: 0,
502 value: tlv::TlvItemValueEnc::StructInvisible(vec![
503 (0, tlv::TlvItemValueEnc::UInt64(node_id)).into(),
504 (1, tlv::TlvItemValueEnc::UInt16(endpoint_id)).into(),
505 (2, tlv::TlvItemValueEnc::UInt8(group_id)).into(),
506 ]),
507 };
508 Ok(tlv.encode()?)
509}
510
511pub fn encode_remove_group_id_from_endpoint_for_node(node_id: u64, endpoint_id: u16, group_id: u8) -> anyhow::Result<Vec<u8>> {
513 let tlv = tlv::TlvItemEnc {
514 tag: 0,
515 value: tlv::TlvItemValueEnc::StructInvisible(vec![
516 (0, tlv::TlvItemValueEnc::UInt64(node_id)).into(),
517 (1, tlv::TlvItemValueEnc::UInt16(endpoint_id)).into(),
518 (2, tlv::TlvItemValueEnc::UInt8(group_id)).into(),
519 ]),
520 };
521 Ok(tlv.encode()?)
522}
523
524pub fn encode_add_binding_to_endpoint_for_node(node_id: u64, endpoint_id: u16, binding: DatastoreBindingTarget) -> anyhow::Result<Vec<u8>> {
526 let mut binding_fields = Vec::new();
528 if let Some(x) = binding.node { binding_fields.push((1, tlv::TlvItemValueEnc::UInt64(x)).into()); }
529 if let Some(x) = binding.endpoint { binding_fields.push((3, tlv::TlvItemValueEnc::UInt16(x)).into()); }
531 if let Some(x) = binding.cluster { binding_fields.push((4, tlv::TlvItemValueEnc::UInt32(x)).into()); }
532 let tlv = tlv::TlvItemEnc {
533 tag: 0,
534 value: tlv::TlvItemValueEnc::StructInvisible(vec![
535 (0, tlv::TlvItemValueEnc::UInt64(node_id)).into(),
536 (1, tlv::TlvItemValueEnc::UInt16(endpoint_id)).into(),
537 (2, tlv::TlvItemValueEnc::StructInvisible(binding_fields)).into(),
538 ]),
539 };
540 Ok(tlv.encode()?)
541}
542
543pub fn encode_remove_binding_from_endpoint_for_node(list_id: u16, endpoint_id: u16, node_id: u64) -> anyhow::Result<Vec<u8>> {
545 let tlv = tlv::TlvItemEnc {
546 tag: 0,
547 value: tlv::TlvItemValueEnc::StructInvisible(vec![
548 (0, tlv::TlvItemValueEnc::UInt16(list_id)).into(),
549 (1, tlv::TlvItemValueEnc::UInt16(endpoint_id)).into(),
550 (2, tlv::TlvItemValueEnc::UInt64(node_id)).into(),
551 ]),
552 };
553 Ok(tlv.encode()?)
554}
555
556pub fn encode_add_acl_to_node(node_id: u64, acl_entry: DatastoreAccessControlEntry) -> anyhow::Result<Vec<u8>> {
558 let mut acl_entry_fields = Vec::new();
560 if let Some(x) = acl_entry.privilege { acl_entry_fields.push((1, tlv::TlvItemValueEnc::UInt8(x.to_u8())).into()); }
561 if let Some(x) = acl_entry.auth_mode { acl_entry_fields.push((2, tlv::TlvItemValueEnc::UInt8(x.to_u8())).into()); }
562 if let Some(listv) = acl_entry.subjects { acl_entry_fields.push((3, tlv::TlvItemValueEnc::StructAnon(listv.into_iter().map(|x| (0, tlv::TlvItemValueEnc::UInt64(x)).into()).collect())).into()); }
563 if let Some(listv) = acl_entry.targets {
564 let inner_vec: Vec<_> = listv.into_iter().map(|inner| {
565 let mut nested_fields = Vec::new();
566 if let Some(x) = inner.cluster { nested_fields.push((0, tlv::TlvItemValueEnc::UInt32(x)).into()); }
567 if let Some(x) = inner.endpoint { nested_fields.push((1, tlv::TlvItemValueEnc::UInt16(x)).into()); }
568 if let Some(x) = inner.device_type { nested_fields.push((2, tlv::TlvItemValueEnc::UInt32(x)).into()); }
569 (0, tlv::TlvItemValueEnc::StructAnon(nested_fields)).into()
570 }).collect();
571 acl_entry_fields.push((4, tlv::TlvItemValueEnc::Array(inner_vec)).into());
572 }
573 let tlv = tlv::TlvItemEnc {
574 tag: 0,
575 value: tlv::TlvItemValueEnc::StructInvisible(vec![
576 (0, tlv::TlvItemValueEnc::UInt64(node_id)).into(),
577 (1, tlv::TlvItemValueEnc::StructInvisible(acl_entry_fields)).into(),
578 ]),
579 };
580 Ok(tlv.encode()?)
581}
582
583pub fn encode_remove_acl_from_node(list_id: u16, node_id: u64) -> anyhow::Result<Vec<u8>> {
585 let tlv = tlv::TlvItemEnc {
586 tag: 0,
587 value: tlv::TlvItemValueEnc::StructInvisible(vec![
588 (0, tlv::TlvItemValueEnc::UInt16(list_id)).into(),
589 (1, tlv::TlvItemValueEnc::UInt64(node_id)).into(),
590 ]),
591 };
592 Ok(tlv.encode()?)
593}
594
595pub fn decode_anchor_root_ca(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<u8>> {
599 if let tlv::TlvItemValue::OctetString(v) = inp {
600 Ok(v.clone())
601 } else {
602 Err(anyhow::anyhow!("Expected OctetString"))
603 }
604}
605
606pub fn decode_anchor_node_id(inp: &tlv::TlvItemValue) -> anyhow::Result<u64> {
608 if let tlv::TlvItemValue::Int(v) = inp {
609 Ok(*v)
610 } else {
611 Err(anyhow::anyhow!("Expected UInt64"))
612 }
613}
614
615pub fn decode_anchor_vendor_id(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
617 if let tlv::TlvItemValue::Int(v) = inp {
618 Ok(*v as u16)
619 } else {
620 Err(anyhow::anyhow!("Expected UInt16"))
621 }
622}
623
624pub fn decode_friendly_name(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
626 if let tlv::TlvItemValue::String(v) = inp {
627 Ok(v.clone())
628 } else {
629 Err(anyhow::anyhow!("Expected String"))
630 }
631}
632
633pub fn decode_group_key_set_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<DatastoreGroupKeySet>> {
635 let mut res = Vec::new();
636 if let tlv::TlvItemValue::List(v) = inp {
637 for item in v {
638 res.push(DatastoreGroupKeySet {
639 group_key_set_id: item.get_int(&[0]).map(|v| v as u16),
640 group_key_security_policy: item.get_int(&[1]).and_then(|v| DatastoreGroupKeySecurityPolicy::from_u8(v as u8)),
641 epoch_key0: item.get_octet_string_owned(&[2]),
642 epoch_start_time0: item.get_int(&[3]),
643 epoch_key1: item.get_octet_string_owned(&[4]),
644 epoch_start_time1: item.get_int(&[5]),
645 epoch_key2: item.get_octet_string_owned(&[6]),
646 epoch_start_time2: item.get_int(&[7]),
647 group_key_multicast_policy: item.get_int(&[8]).and_then(|v| DatastoreGroupKeyMulticastPolicy::from_u8(v as u8)),
648 });
649 }
650 }
651 Ok(res)
652}
653
654pub fn decode_group_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<DatastoreGroupInformationEntry>> {
656 let mut res = Vec::new();
657 if let tlv::TlvItemValue::List(v) = inp {
658 for item in v {
659 res.push(DatastoreGroupInformationEntry {
660 group_id: item.get_int(&[0]),
661 friendly_name: item.get_string_owned(&[1]),
662 group_key_set_id: item.get_int(&[2]).map(|v| v as u16),
663 group_cat: item.get_int(&[3]).map(|v| v as u16),
664 group_cat_version: item.get_int(&[4]).map(|v| v as u16),
665 group_permission: item.get_int(&[5]).and_then(|v| DatastoreAccessControlEntryPrivilege::from_u8(v as u8)),
666 });
667 }
668 }
669 Ok(res)
670}
671
672pub fn decode_node_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<DatastoreNodeInformationEntry>> {
674 let mut res = Vec::new();
675 if let tlv::TlvItemValue::List(v) = inp {
676 for item in v {
677 res.push(DatastoreNodeInformationEntry {
678 node_id: item.get_int(&[1]),
679 friendly_name: item.get_string_owned(&[2]),
680 commissioning_status_entry: {
681 if let Some(nested_tlv) = item.get(&[3]) {
682 if let tlv::TlvItemValue::List(_) = nested_tlv {
683 let nested_item = tlv::TlvItem { tag: 3, value: nested_tlv.clone() };
684 Some(DatastoreStatusEntry {
685 state: nested_item.get_int(&[0]).and_then(|v| DatastoreState::from_u8(v as u8)),
686 update_timestamp: nested_item.get_int(&[1]),
687 failure_code: nested_item.get_int(&[2]).map(|v| v as u8),
688 })
689 } else {
690 None
691 }
692 } else {
693 None
694 }
695 },
696 });
697 }
698 }
699 Ok(res)
700}
701
702pub fn decode_admin_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<DatastoreAdministratorInformationEntry>> {
704 let mut res = Vec::new();
705 if let tlv::TlvItemValue::List(v) = inp {
706 for item in v {
707 res.push(DatastoreAdministratorInformationEntry {
708 node_id: item.get_int(&[1]),
709 friendly_name: item.get_string_owned(&[2]),
710 vendor_id: item.get_int(&[3]).map(|v| v as u16),
711 icac: item.get_octet_string_owned(&[4]),
712 });
713 }
714 }
715 Ok(res)
716}
717
718pub fn decode_status(inp: &tlv::TlvItemValue) -> anyhow::Result<DatastoreStatusEntry> {
720 if let tlv::TlvItemValue::List(_fields) = inp {
721 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
723 Ok(DatastoreStatusEntry {
724 state: item.get_int(&[0]).and_then(|v| DatastoreState::from_u8(v as u8)),
725 update_timestamp: item.get_int(&[1]),
726 failure_code: item.get_int(&[2]).map(|v| v as u8),
727 })
728 } else {
729 Err(anyhow::anyhow!("Expected struct fields"))
730 }
731}
732
733pub fn decode_endpoint_group_id_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<DatastoreEndpointGroupIDEntry>> {
735 let mut res = Vec::new();
736 if let tlv::TlvItemValue::List(v) = inp {
737 for item in v {
738 res.push(DatastoreEndpointGroupIDEntry {
739 node_id: item.get_int(&[0]),
740 endpoint_id: item.get_int(&[1]).map(|v| v as u16),
741 group_id: item.get_int(&[2]).map(|v| v as u8),
742 status_entry: {
743 if let Some(nested_tlv) = item.get(&[3]) {
744 if let tlv::TlvItemValue::List(_) = nested_tlv {
745 let nested_item = tlv::TlvItem { tag: 3, value: nested_tlv.clone() };
746 Some(DatastoreStatusEntry {
747 state: nested_item.get_int(&[0]).and_then(|v| DatastoreState::from_u8(v as u8)),
748 update_timestamp: nested_item.get_int(&[1]),
749 failure_code: nested_item.get_int(&[2]).map(|v| v as u8),
750 })
751 } else {
752 None
753 }
754 } else {
755 None
756 }
757 },
758 });
759 }
760 }
761 Ok(res)
762}
763
764pub fn decode_endpoint_binding_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<DatastoreEndpointBindingEntry>> {
766 let mut res = Vec::new();
767 if let tlv::TlvItemValue::List(v) = inp {
768 for item in v {
769 res.push(DatastoreEndpointBindingEntry {
770 node_id: item.get_int(&[0]),
771 endpoint_id: item.get_int(&[1]).map(|v| v as u16),
772 list_id: item.get_int(&[2]).map(|v| v as u16),
773 binding: {
774 if let Some(nested_tlv) = item.get(&[3]) {
775 if let tlv::TlvItemValue::List(_) = nested_tlv {
776 let nested_item = tlv::TlvItem { tag: 3, value: nested_tlv.clone() };
777 Some(DatastoreBindingTarget {
778 node: nested_item.get_int(&[1]),
779 group: nested_item.get_int(&[2]).map(|v| v as u8),
780 endpoint: nested_item.get_int(&[3]).map(|v| v as u16),
781 cluster: nested_item.get_int(&[4]).map(|v| v as u32),
782 })
783 } else {
784 None
785 }
786 } else {
787 None
788 }
789 },
790 status_entry: {
791 if let Some(nested_tlv) = item.get(&[4]) {
792 if let tlv::TlvItemValue::List(_) = nested_tlv {
793 let nested_item = tlv::TlvItem { tag: 4, value: nested_tlv.clone() };
794 Some(DatastoreStatusEntry {
795 state: nested_item.get_int(&[0]).and_then(|v| DatastoreState::from_u8(v as u8)),
796 update_timestamp: nested_item.get_int(&[1]),
797 failure_code: nested_item.get_int(&[2]).map(|v| v as u8),
798 })
799 } else {
800 None
801 }
802 } else {
803 None
804 }
805 },
806 });
807 }
808 }
809 Ok(res)
810}
811
812pub fn decode_node_key_set_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<DatastoreNodeKeySetEntry>> {
814 let mut res = Vec::new();
815 if let tlv::TlvItemValue::List(v) = inp {
816 for item in v {
817 res.push(DatastoreNodeKeySetEntry {
818 node_id: item.get_int(&[0]),
819 group_key_set_id: item.get_int(&[1]).map(|v| v as u16),
820 status_entry: {
821 if let Some(nested_tlv) = item.get(&[2]) {
822 if let tlv::TlvItemValue::List(_) = nested_tlv {
823 let nested_item = tlv::TlvItem { tag: 2, value: nested_tlv.clone() };
824 Some(DatastoreStatusEntry {
825 state: nested_item.get_int(&[0]).and_then(|v| DatastoreState::from_u8(v as u8)),
826 update_timestamp: nested_item.get_int(&[1]),
827 failure_code: nested_item.get_int(&[2]).map(|v| v as u8),
828 })
829 } else {
830 None
831 }
832 } else {
833 None
834 }
835 },
836 });
837 }
838 }
839 Ok(res)
840}
841
842pub fn decode_node_acl_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<DatastoreACLEntry>> {
844 let mut res = Vec::new();
845 if let tlv::TlvItemValue::List(v) = inp {
846 for item in v {
847 res.push(DatastoreACLEntry {
848 node_id: item.get_int(&[0]),
849 list_id: item.get_int(&[1]).map(|v| v as u16),
850 acl_entry: {
851 if let Some(nested_tlv) = item.get(&[2]) {
852 if let tlv::TlvItemValue::List(_) = nested_tlv {
853 let nested_item = tlv::TlvItem { tag: 2, value: nested_tlv.clone() };
854 Some(DatastoreAccessControlEntry {
855 privilege: nested_item.get_int(&[1]).and_then(|v| DatastoreAccessControlEntryPrivilege::from_u8(v as u8)),
856 auth_mode: nested_item.get_int(&[2]).and_then(|v| DatastoreAccessControlEntryAuthMode::from_u8(v as u8)),
857 subjects: {
858 if let Some(tlv::TlvItemValue::List(l)) = nested_item.get(&[3]) {
859 let items: Vec<u64> = l.iter().filter_map(|e| { if let tlv::TlvItemValue::Int(v) = &e.value { Some(*v) } else { None } }).collect();
860 Some(items)
861 } else {
862 None
863 }
864 },
865 targets: {
866 if let Some(tlv::TlvItemValue::List(l)) = nested_item.get(&[4]) {
867 let mut items = Vec::new();
868 for list_item in l {
869 items.push(DatastoreAccessControlTarget {
870 cluster: list_item.get_int(&[0]).map(|v| v as u32),
871 endpoint: list_item.get_int(&[1]).map(|v| v as u16),
872 device_type: list_item.get_int(&[2]).map(|v| v as u32),
873 });
874 }
875 Some(items)
876 } else {
877 None
878 }
879 },
880 })
881 } else {
882 None
883 }
884 } else {
885 None
886 }
887 },
888 status_entry: {
889 if let Some(nested_tlv) = item.get(&[3]) {
890 if let tlv::TlvItemValue::List(_) = nested_tlv {
891 let nested_item = tlv::TlvItem { tag: 3, value: nested_tlv.clone() };
892 Some(DatastoreStatusEntry {
893 state: nested_item.get_int(&[0]).and_then(|v| DatastoreState::from_u8(v as u8)),
894 update_timestamp: nested_item.get_int(&[1]),
895 failure_code: nested_item.get_int(&[2]).map(|v| v as u8),
896 })
897 } else {
898 None
899 }
900 } else {
901 None
902 }
903 },
904 });
905 }
906 }
907 Ok(res)
908}
909
910pub fn decode_node_endpoint_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<DatastoreEndpointEntry>> {
912 let mut res = Vec::new();
913 if let tlv::TlvItemValue::List(v) = inp {
914 for item in v {
915 res.push(DatastoreEndpointEntry {
916 endpoint_id: item.get_int(&[0]).map(|v| v as u16),
917 node_id: item.get_int(&[1]),
918 friendly_name: item.get_string_owned(&[2]),
919 status_entry: {
920 if let Some(nested_tlv) = item.get(&[3]) {
921 if let tlv::TlvItemValue::List(_) = nested_tlv {
922 let nested_item = tlv::TlvItem { tag: 3, value: nested_tlv.clone() };
923 Some(DatastoreStatusEntry {
924 state: nested_item.get_int(&[0]).and_then(|v| DatastoreState::from_u8(v as u8)),
925 update_timestamp: nested_item.get_int(&[1]),
926 failure_code: nested_item.get_int(&[2]).map(|v| v as u8),
927 })
928 } else {
929 None
930 }
931 } else {
932 None
933 }
934 },
935 });
936 }
937 }
938 Ok(res)
939}
940
941
942pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
954 if cluster_id != 0x0752 {
956 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0752, got {}\"}}", cluster_id);
957 }
958
959 match attribute_id {
960 0x0000 => {
961 match decode_anchor_root_ca(tlv_value) {
962 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
963 Err(e) => format!("{{\"error\": \"{}\"}}", e),
964 }
965 }
966 0x0001 => {
967 match decode_anchor_node_id(tlv_value) {
968 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
969 Err(e) => format!("{{\"error\": \"{}\"}}", e),
970 }
971 }
972 0x0002 => {
973 match decode_anchor_vendor_id(tlv_value) {
974 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
975 Err(e) => format!("{{\"error\": \"{}\"}}", e),
976 }
977 }
978 0x0003 => {
979 match decode_friendly_name(tlv_value) {
980 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
981 Err(e) => format!("{{\"error\": \"{}\"}}", e),
982 }
983 }
984 0x0004 => {
985 match decode_group_key_set_list(tlv_value) {
986 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
987 Err(e) => format!("{{\"error\": \"{}\"}}", e),
988 }
989 }
990 0x0005 => {
991 match decode_group_list(tlv_value) {
992 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
993 Err(e) => format!("{{\"error\": \"{}\"}}", e),
994 }
995 }
996 0x0006 => {
997 match decode_node_list(tlv_value) {
998 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
999 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1000 }
1001 }
1002 0x0007 => {
1003 match decode_admin_list(tlv_value) {
1004 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1005 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1006 }
1007 }
1008 0x0008 => {
1009 match decode_status(tlv_value) {
1010 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1011 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1012 }
1013 }
1014 0x0009 => {
1015 match decode_endpoint_group_id_list(tlv_value) {
1016 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1017 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1018 }
1019 }
1020 0x000A => {
1021 match decode_endpoint_binding_list(tlv_value) {
1022 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1023 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1024 }
1025 }
1026 0x000B => {
1027 match decode_node_key_set_list(tlv_value) {
1028 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1029 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1030 }
1031 }
1032 0x000C => {
1033 match decode_node_acl_list(tlv_value) {
1034 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1035 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1036 }
1037 }
1038 0x000D => {
1039 match decode_node_endpoint_list(tlv_value) {
1040 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1041 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1042 }
1043 }
1044 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
1045 }
1046}
1047
1048pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
1053 vec![
1054 (0x0000, "AnchorRootCA"),
1055 (0x0001, "AnchorNodeID"),
1056 (0x0002, "AnchorVendorID"),
1057 (0x0003, "FriendlyName"),
1058 (0x0004, "GroupKeySetList"),
1059 (0x0005, "GroupList"),
1060 (0x0006, "NodeList"),
1061 (0x0007, "AdminList"),
1062 (0x0008, "Status"),
1063 (0x0009, "EndpointGroupIDList"),
1064 (0x000A, "EndpointBindingList"),
1065 (0x000B, "NodeKeySetList"),
1066 (0x000C, "NodeACLList"),
1067 (0x000D, "NodeEndpointList"),
1068 ]
1069}
1070
1071pub fn get_command_list() -> Vec<(u32, &'static str)> {
1074 vec![
1075 (0x00, "AddKeySet"),
1076 (0x01, "UpdateKeySet"),
1077 (0x02, "RemoveKeySet"),
1078 (0x03, "AddGroup"),
1079 (0x04, "UpdateGroup"),
1080 (0x05, "RemoveGroup"),
1081 (0x06, "AddAdmin"),
1082 (0x07, "UpdateAdmin"),
1083 (0x08, "RemoveAdmin"),
1084 (0x09, "AddPendingNode"),
1085 (0x0A, "RefreshNode"),
1086 (0x0B, "UpdateNode"),
1087 (0x0C, "RemoveNode"),
1088 (0x0D, "UpdateEndpointForNode"),
1089 (0x0E, "AddGroupIDToEndpointForNode"),
1090 (0x0F, "RemoveGroupIDFromEndpointForNode"),
1091 (0x10, "AddBindingToEndpointForNode"),
1092 (0x11, "RemoveBindingFromEndpointForNode"),
1093 (0x12, "AddACLToNode"),
1094 (0x13, "RemoveACLFromNode"),
1095 ]
1096}
1097
1098pub fn get_command_name(cmd_id: u32) -> Option<&'static str> {
1099 match cmd_id {
1100 0x00 => Some("AddKeySet"),
1101 0x01 => Some("UpdateKeySet"),
1102 0x02 => Some("RemoveKeySet"),
1103 0x03 => Some("AddGroup"),
1104 0x04 => Some("UpdateGroup"),
1105 0x05 => Some("RemoveGroup"),
1106 0x06 => Some("AddAdmin"),
1107 0x07 => Some("UpdateAdmin"),
1108 0x08 => Some("RemoveAdmin"),
1109 0x09 => Some("AddPendingNode"),
1110 0x0A => Some("RefreshNode"),
1111 0x0B => Some("UpdateNode"),
1112 0x0C => Some("RemoveNode"),
1113 0x0D => Some("UpdateEndpointForNode"),
1114 0x0E => Some("AddGroupIDToEndpointForNode"),
1115 0x0F => Some("RemoveGroupIDFromEndpointForNode"),
1116 0x10 => Some("AddBindingToEndpointForNode"),
1117 0x11 => Some("RemoveBindingFromEndpointForNode"),
1118 0x12 => Some("AddACLToNode"),
1119 0x13 => Some("RemoveACLFromNode"),
1120 _ => None,
1121 }
1122}
1123
1124pub fn get_command_schema(cmd_id: u32) -> Option<Vec<crate::clusters::codec::CommandField>> {
1125 match cmd_id {
1126 0x00 => Some(vec![
1127 crate::clusters::codec::CommandField { tag: 0, name: "group_key_set", kind: crate::clusters::codec::FieldKind::Struct { name: "DatastoreGroupKeySetStruct" }, optional: false, nullable: false },
1128 ]),
1129 0x01 => Some(vec![
1130 crate::clusters::codec::CommandField { tag: 0, name: "group_key_set", kind: crate::clusters::codec::FieldKind::Struct { name: "DatastoreGroupKeySetStruct" }, optional: false, nullable: false },
1131 ]),
1132 0x02 => Some(vec![
1133 crate::clusters::codec::CommandField { tag: 0, name: "group_key_set_id", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1134 ]),
1135 0x03 => Some(vec![
1136 crate::clusters::codec::CommandField { tag: 0, name: "group_id", kind: crate::clusters::codec::FieldKind::U32, optional: false, nullable: false },
1137 crate::clusters::codec::CommandField { tag: 1, name: "friendly_name", kind: crate::clusters::codec::FieldKind::String, optional: false, nullable: false },
1138 crate::clusters::codec::CommandField { tag: 2, name: "group_key_set_id", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: true },
1139 crate::clusters::codec::CommandField { tag: 3, name: "group_cat", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: true },
1140 crate::clusters::codec::CommandField { tag: 4, name: "group_cat_version", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: true },
1141 crate::clusters::codec::CommandField { tag: 5, name: "group_permission", kind: crate::clusters::codec::FieldKind::Enum { name: "DatastoreAccessControlEntryPrivilege", variants: &[(1, "View"), (2, "Proxyview"), (3, "Operate"), (4, "Manage"), (5, "Administer")] }, optional: false, nullable: false },
1142 ]),
1143 0x04 => Some(vec![
1144 crate::clusters::codec::CommandField { tag: 0, name: "group_id", kind: crate::clusters::codec::FieldKind::U32, optional: false, nullable: false },
1145 crate::clusters::codec::CommandField { tag: 1, name: "friendly_name", kind: crate::clusters::codec::FieldKind::String, optional: false, nullable: true },
1146 crate::clusters::codec::CommandField { tag: 2, name: "group_key_set_id", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: true },
1147 crate::clusters::codec::CommandField { tag: 3, name: "group_cat", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: true },
1148 crate::clusters::codec::CommandField { tag: 4, name: "group_cat_version", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: true },
1149 crate::clusters::codec::CommandField { tag: 5, name: "group_permission", kind: crate::clusters::codec::FieldKind::Enum { name: "DatastoreAccessControlEntryPrivilege", variants: &[(1, "View"), (2, "Proxyview"), (3, "Operate"), (4, "Manage"), (5, "Administer")] }, optional: false, nullable: true },
1150 ]),
1151 0x05 => Some(vec![
1152 crate::clusters::codec::CommandField { tag: 0, name: "group_id", kind: crate::clusters::codec::FieldKind::U32, optional: false, nullable: false },
1153 ]),
1154 0x06 => Some(vec![
1155 crate::clusters::codec::CommandField { tag: 1, name: "node_id", kind: crate::clusters::codec::FieldKind::U64, optional: false, nullable: false },
1156 crate::clusters::codec::CommandField { tag: 2, name: "friendly_name", kind: crate::clusters::codec::FieldKind::String, optional: false, nullable: false },
1157 crate::clusters::codec::CommandField { tag: 3, name: "vendor_id", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1158 crate::clusters::codec::CommandField { tag: 4, name: "icac", kind: crate::clusters::codec::FieldKind::OctetString, optional: false, nullable: false },
1159 ]),
1160 0x07 => Some(vec![
1161 crate::clusters::codec::CommandField { tag: 0, name: "node_id", kind: crate::clusters::codec::FieldKind::U64, optional: false, nullable: true },
1162 crate::clusters::codec::CommandField { tag: 1, name: "friendly_name", kind: crate::clusters::codec::FieldKind::String, optional: false, nullable: true },
1163 crate::clusters::codec::CommandField { tag: 2, name: "icac", kind: crate::clusters::codec::FieldKind::OctetString, optional: false, nullable: true },
1164 ]),
1165 0x08 => Some(vec![
1166 crate::clusters::codec::CommandField { tag: 0, name: "node_id", kind: crate::clusters::codec::FieldKind::U64, optional: false, nullable: false },
1167 ]),
1168 0x09 => Some(vec![
1169 crate::clusters::codec::CommandField { tag: 0, name: "node_id", kind: crate::clusters::codec::FieldKind::U64, optional: false, nullable: false },
1170 crate::clusters::codec::CommandField { tag: 1, name: "friendly_name", kind: crate::clusters::codec::FieldKind::String, optional: false, nullable: false },
1171 ]),
1172 0x0A => Some(vec![
1173 crate::clusters::codec::CommandField { tag: 0, name: "node_id", kind: crate::clusters::codec::FieldKind::U64, optional: false, nullable: false },
1174 ]),
1175 0x0B => Some(vec![
1176 crate::clusters::codec::CommandField { tag: 0, name: "node_id", kind: crate::clusters::codec::FieldKind::U64, optional: false, nullable: false },
1177 crate::clusters::codec::CommandField { tag: 1, name: "friendly_name", kind: crate::clusters::codec::FieldKind::String, optional: false, nullable: false },
1178 ]),
1179 0x0C => Some(vec![
1180 crate::clusters::codec::CommandField { tag: 0, name: "node_id", kind: crate::clusters::codec::FieldKind::U64, optional: false, nullable: false },
1181 ]),
1182 0x0D => Some(vec![
1183 crate::clusters::codec::CommandField { tag: 0, name: "endpoint_id", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1184 crate::clusters::codec::CommandField { tag: 1, name: "node_id", kind: crate::clusters::codec::FieldKind::U64, optional: false, nullable: false },
1185 crate::clusters::codec::CommandField { tag: 2, name: "friendly_name", kind: crate::clusters::codec::FieldKind::String, optional: false, nullable: false },
1186 ]),
1187 0x0E => Some(vec![
1188 crate::clusters::codec::CommandField { tag: 0, name: "node_id", kind: crate::clusters::codec::FieldKind::U64, optional: false, nullable: false },
1189 crate::clusters::codec::CommandField { tag: 1, name: "endpoint_id", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1190 crate::clusters::codec::CommandField { tag: 2, name: "group_id", kind: crate::clusters::codec::FieldKind::U32, optional: false, nullable: false },
1191 ]),
1192 0x0F => Some(vec![
1193 crate::clusters::codec::CommandField { tag: 0, name: "node_id", kind: crate::clusters::codec::FieldKind::U64, optional: false, nullable: false },
1194 crate::clusters::codec::CommandField { tag: 1, name: "endpoint_id", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1195 crate::clusters::codec::CommandField { tag: 2, name: "group_id", kind: crate::clusters::codec::FieldKind::U32, optional: false, nullable: false },
1196 ]),
1197 0x10 => Some(vec![
1198 crate::clusters::codec::CommandField { tag: 0, name: "node_id", kind: crate::clusters::codec::FieldKind::U64, optional: false, nullable: false },
1199 crate::clusters::codec::CommandField { tag: 1, name: "endpoint_id", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1200 crate::clusters::codec::CommandField { tag: 2, name: "binding", kind: crate::clusters::codec::FieldKind::Struct { name: "DatastoreBindingTargetStruct" }, optional: false, nullable: false },
1201 ]),
1202 0x11 => Some(vec![
1203 crate::clusters::codec::CommandField { tag: 0, name: "list_id", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1204 crate::clusters::codec::CommandField { tag: 1, name: "endpoint_id", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1205 crate::clusters::codec::CommandField { tag: 2, name: "node_id", kind: crate::clusters::codec::FieldKind::U64, optional: false, nullable: false },
1206 ]),
1207 0x12 => Some(vec![
1208 crate::clusters::codec::CommandField { tag: 0, name: "node_id", kind: crate::clusters::codec::FieldKind::U64, optional: false, nullable: false },
1209 crate::clusters::codec::CommandField { tag: 1, name: "acl_entry", kind: crate::clusters::codec::FieldKind::Struct { name: "DatastoreAccessControlEntryStruct" }, optional: false, nullable: false },
1210 ]),
1211 0x13 => Some(vec![
1212 crate::clusters::codec::CommandField { tag: 0, name: "list_id", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1213 crate::clusters::codec::CommandField { tag: 1, name: "node_id", kind: crate::clusters::codec::FieldKind::U64, optional: false, nullable: false },
1214 ]),
1215 _ => None,
1216 }
1217}
1218
1219pub fn encode_command_json(cmd_id: u32, args: &serde_json::Value) -> anyhow::Result<Vec<u8>> {
1220 match cmd_id {
1221 0x00 => Err(anyhow::anyhow!("command \"AddKeySet\" has complex args: use raw mode")),
1222 0x01 => Err(anyhow::anyhow!("command \"UpdateKeySet\" has complex args: use raw mode")),
1223 0x02 => {
1224 let group_key_set_id = crate::clusters::codec::json_util::get_u16(args, "group_key_set_id")?;
1225 encode_remove_key_set(group_key_set_id)
1226 }
1227 0x03 => {
1228 let group_id = crate::clusters::codec::json_util::get_u8(args, "group_id")?;
1229 let friendly_name = crate::clusters::codec::json_util::get_string(args, "friendly_name")?;
1230 let group_key_set_id = crate::clusters::codec::json_util::get_opt_u16(args, "group_key_set_id")?;
1231 let group_cat = crate::clusters::codec::json_util::get_opt_u16(args, "group_cat")?;
1232 let group_cat_version = crate::clusters::codec::json_util::get_opt_u16(args, "group_cat_version")?;
1233 let group_permission = {
1234 let n = crate::clusters::codec::json_util::get_u64(args, "group_permission")?;
1235 DatastoreAccessControlEntryPrivilege::from_u8(n as u8).ok_or_else(|| anyhow::anyhow!("invalid DatastoreAccessControlEntryPrivilege: {}", n))?
1236 };
1237 encode_add_group(group_id, friendly_name, group_key_set_id, group_cat, group_cat_version, group_permission)
1238 }
1239 0x04 => {
1240 let group_id = crate::clusters::codec::json_util::get_u8(args, "group_id")?;
1241 let friendly_name = crate::clusters::codec::json_util::get_opt_string(args, "friendly_name")?;
1242 let group_key_set_id = crate::clusters::codec::json_util::get_opt_u16(args, "group_key_set_id")?;
1243 let group_cat = crate::clusters::codec::json_util::get_opt_u16(args, "group_cat")?;
1244 let group_cat_version = crate::clusters::codec::json_util::get_opt_u16(args, "group_cat_version")?;
1245 let group_permission = crate::clusters::codec::json_util::get_opt_u64(args, "group_permission")?
1246 .and_then(|n| DatastoreAccessControlEntryPrivilege::from_u8(n as u8));
1247 encode_update_group(group_id, friendly_name, group_key_set_id, group_cat, group_cat_version, group_permission)
1248 }
1249 0x05 => {
1250 let group_id = crate::clusters::codec::json_util::get_u8(args, "group_id")?;
1251 encode_remove_group(group_id)
1252 }
1253 0x06 => {
1254 let node_id = crate::clusters::codec::json_util::get_u64(args, "node_id")?;
1255 let friendly_name = crate::clusters::codec::json_util::get_string(args, "friendly_name")?;
1256 let vendor_id = crate::clusters::codec::json_util::get_u16(args, "vendor_id")?;
1257 let icac = crate::clusters::codec::json_util::get_octstr(args, "icac")?;
1258 encode_add_admin(node_id, friendly_name, vendor_id, icac)
1259 }
1260 0x07 => {
1261 let node_id = crate::clusters::codec::json_util::get_opt_u64(args, "node_id")?;
1262 let friendly_name = crate::clusters::codec::json_util::get_opt_string(args, "friendly_name")?;
1263 let icac = crate::clusters::codec::json_util::get_opt_octstr(args, "icac")?;
1264 encode_update_admin(node_id, friendly_name, icac)
1265 }
1266 0x08 => {
1267 let node_id = crate::clusters::codec::json_util::get_u64(args, "node_id")?;
1268 encode_remove_admin(node_id)
1269 }
1270 0x09 => {
1271 let node_id = crate::clusters::codec::json_util::get_u64(args, "node_id")?;
1272 let friendly_name = crate::clusters::codec::json_util::get_string(args, "friendly_name")?;
1273 encode_add_pending_node(node_id, friendly_name)
1274 }
1275 0x0A => {
1276 let node_id = crate::clusters::codec::json_util::get_u64(args, "node_id")?;
1277 encode_refresh_node(node_id)
1278 }
1279 0x0B => {
1280 let node_id = crate::clusters::codec::json_util::get_u64(args, "node_id")?;
1281 let friendly_name = crate::clusters::codec::json_util::get_string(args, "friendly_name")?;
1282 encode_update_node(node_id, friendly_name)
1283 }
1284 0x0C => {
1285 let node_id = crate::clusters::codec::json_util::get_u64(args, "node_id")?;
1286 encode_remove_node(node_id)
1287 }
1288 0x0D => {
1289 let endpoint_id = crate::clusters::codec::json_util::get_u16(args, "endpoint_id")?;
1290 let node_id = crate::clusters::codec::json_util::get_u64(args, "node_id")?;
1291 let friendly_name = crate::clusters::codec::json_util::get_string(args, "friendly_name")?;
1292 encode_update_endpoint_for_node(endpoint_id, node_id, friendly_name)
1293 }
1294 0x0E => {
1295 let node_id = crate::clusters::codec::json_util::get_u64(args, "node_id")?;
1296 let endpoint_id = crate::clusters::codec::json_util::get_u16(args, "endpoint_id")?;
1297 let group_id = crate::clusters::codec::json_util::get_u8(args, "group_id")?;
1298 encode_add_group_id_to_endpoint_for_node(node_id, endpoint_id, group_id)
1299 }
1300 0x0F => {
1301 let node_id = crate::clusters::codec::json_util::get_u64(args, "node_id")?;
1302 let endpoint_id = crate::clusters::codec::json_util::get_u16(args, "endpoint_id")?;
1303 let group_id = crate::clusters::codec::json_util::get_u8(args, "group_id")?;
1304 encode_remove_group_id_from_endpoint_for_node(node_id, endpoint_id, group_id)
1305 }
1306 0x10 => Err(anyhow::anyhow!("command \"AddBindingToEndpointForNode\" has complex args: use raw mode")),
1307 0x11 => {
1308 let list_id = crate::clusters::codec::json_util::get_u16(args, "list_id")?;
1309 let endpoint_id = crate::clusters::codec::json_util::get_u16(args, "endpoint_id")?;
1310 let node_id = crate::clusters::codec::json_util::get_u64(args, "node_id")?;
1311 encode_remove_binding_from_endpoint_for_node(list_id, endpoint_id, node_id)
1312 }
1313 0x12 => Err(anyhow::anyhow!("command \"AddACLToNode\" has complex args: use raw mode")),
1314 0x13 => {
1315 let list_id = crate::clusters::codec::json_util::get_u16(args, "list_id")?;
1316 let node_id = crate::clusters::codec::json_util::get_u64(args, "node_id")?;
1317 encode_remove_acl_from_node(list_id, node_id)
1318 }
1319 _ => Err(anyhow::anyhow!("unknown command ID: 0x{:02X}", cmd_id)),
1320 }
1321}
1322
1323pub async fn add_key_set(conn: &crate::controller::Connection, endpoint: u16, group_key_set: DatastoreGroupKeySet) -> anyhow::Result<()> {
1327 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_ADDKEYSET, &encode_add_key_set(group_key_set)?).await?;
1328 Ok(())
1329}
1330
1331pub async fn update_key_set(conn: &crate::controller::Connection, endpoint: u16, group_key_set: DatastoreGroupKeySet) -> anyhow::Result<()> {
1333 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_UPDATEKEYSET, &encode_update_key_set(group_key_set)?).await?;
1334 Ok(())
1335}
1336
1337pub async fn remove_key_set(conn: &crate::controller::Connection, endpoint: u16, group_key_set_id: u16) -> anyhow::Result<()> {
1339 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_REMOVEKEYSET, &encode_remove_key_set(group_key_set_id)?).await?;
1340 Ok(())
1341}
1342
1343pub async fn add_group(conn: &crate::controller::Connection, endpoint: u16, group_id: u8, friendly_name: String, group_key_set_id: Option<u16>, group_cat: Option<u16>, group_cat_version: Option<u16>, group_permission: DatastoreAccessControlEntryPrivilege) -> anyhow::Result<()> {
1345 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_ADDGROUP, &encode_add_group(group_id, friendly_name, group_key_set_id, group_cat, group_cat_version, group_permission)?).await?;
1346 Ok(())
1347}
1348
1349pub async fn update_group(conn: &crate::controller::Connection, endpoint: u16, group_id: u8, friendly_name: Option<String>, group_key_set_id: Option<u16>, group_cat: Option<u16>, group_cat_version: Option<u16>, group_permission: Option<DatastoreAccessControlEntryPrivilege>) -> anyhow::Result<()> {
1351 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_UPDATEGROUP, &encode_update_group(group_id, friendly_name, group_key_set_id, group_cat, group_cat_version, group_permission)?).await?;
1352 Ok(())
1353}
1354
1355pub async fn remove_group(conn: &crate::controller::Connection, endpoint: u16, group_id: u8) -> anyhow::Result<()> {
1357 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_REMOVEGROUP, &encode_remove_group(group_id)?).await?;
1358 Ok(())
1359}
1360
1361pub async fn add_admin(conn: &crate::controller::Connection, endpoint: u16, node_id: u64, friendly_name: String, vendor_id: u16, icac: Vec<u8>) -> anyhow::Result<()> {
1363 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_ADDADMIN, &encode_add_admin(node_id, friendly_name, vendor_id, icac)?).await?;
1364 Ok(())
1365}
1366
1367pub async fn update_admin(conn: &crate::controller::Connection, endpoint: u16, node_id: Option<u64>, friendly_name: Option<String>, icac: Option<Vec<u8>>) -> anyhow::Result<()> {
1369 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_UPDATEADMIN, &encode_update_admin(node_id, friendly_name, icac)?).await?;
1370 Ok(())
1371}
1372
1373pub async fn remove_admin(conn: &crate::controller::Connection, endpoint: u16, node_id: u64) -> anyhow::Result<()> {
1375 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_REMOVEADMIN, &encode_remove_admin(node_id)?).await?;
1376 Ok(())
1377}
1378
1379pub async fn add_pending_node(conn: &crate::controller::Connection, endpoint: u16, node_id: u64, friendly_name: String) -> anyhow::Result<()> {
1381 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_ADDPENDINGNODE, &encode_add_pending_node(node_id, friendly_name)?).await?;
1382 Ok(())
1383}
1384
1385pub async fn refresh_node(conn: &crate::controller::Connection, endpoint: u16, node_id: u64) -> anyhow::Result<()> {
1387 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_REFRESHNODE, &encode_refresh_node(node_id)?).await?;
1388 Ok(())
1389}
1390
1391pub async fn update_node(conn: &crate::controller::Connection, endpoint: u16, node_id: u64, friendly_name: String) -> anyhow::Result<()> {
1393 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_UPDATENODE, &encode_update_node(node_id, friendly_name)?).await?;
1394 Ok(())
1395}
1396
1397pub async fn remove_node(conn: &crate::controller::Connection, endpoint: u16, node_id: u64) -> anyhow::Result<()> {
1399 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_REMOVENODE, &encode_remove_node(node_id)?).await?;
1400 Ok(())
1401}
1402
1403pub async fn update_endpoint_for_node(conn: &crate::controller::Connection, endpoint: u16, endpoint_id: u16, node_id: u64, friendly_name: String) -> anyhow::Result<()> {
1405 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_UPDATEENDPOINTFORNODE, &encode_update_endpoint_for_node(endpoint_id, node_id, friendly_name)?).await?;
1406 Ok(())
1407}
1408
1409pub async fn add_group_id_to_endpoint_for_node(conn: &crate::controller::Connection, endpoint: u16, node_id: u64, endpoint_id: u16, group_id: u8) -> anyhow::Result<()> {
1411 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_ADDGROUPIDTOENDPOINTFORNODE, &encode_add_group_id_to_endpoint_for_node(node_id, endpoint_id, group_id)?).await?;
1412 Ok(())
1413}
1414
1415pub async fn remove_group_id_from_endpoint_for_node(conn: &crate::controller::Connection, endpoint: u16, node_id: u64, endpoint_id: u16, group_id: u8) -> anyhow::Result<()> {
1417 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_REMOVEGROUPIDFROMENDPOINTFORNODE, &encode_remove_group_id_from_endpoint_for_node(node_id, endpoint_id, group_id)?).await?;
1418 Ok(())
1419}
1420
1421pub async fn add_binding_to_endpoint_for_node(conn: &crate::controller::Connection, endpoint: u16, node_id: u64, endpoint_id: u16, binding: DatastoreBindingTarget) -> anyhow::Result<()> {
1423 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_ADDBINDINGTOENDPOINTFORNODE, &encode_add_binding_to_endpoint_for_node(node_id, endpoint_id, binding)?).await?;
1424 Ok(())
1425}
1426
1427pub async fn remove_binding_from_endpoint_for_node(conn: &crate::controller::Connection, endpoint: u16, list_id: u16, endpoint_id: u16, node_id: u64) -> anyhow::Result<()> {
1429 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_REMOVEBINDINGFROMENDPOINTFORNODE, &encode_remove_binding_from_endpoint_for_node(list_id, endpoint_id, node_id)?).await?;
1430 Ok(())
1431}
1432
1433pub async fn add_acl_to_node(conn: &crate::controller::Connection, endpoint: u16, node_id: u64, acl_entry: DatastoreAccessControlEntry) -> anyhow::Result<()> {
1435 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_ADDACLTONODE, &encode_add_acl_to_node(node_id, acl_entry)?).await?;
1436 Ok(())
1437}
1438
1439pub async fn remove_acl_from_node(conn: &crate::controller::Connection, endpoint: u16, list_id: u16, node_id: u64) -> anyhow::Result<()> {
1441 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_CMD_ID_REMOVEACLFROMNODE, &encode_remove_acl_from_node(list_id, node_id)?).await?;
1442 Ok(())
1443}
1444
1445pub async fn read_anchor_root_ca(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<u8>> {
1447 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_ATTR_ID_ANCHORROOTCA).await?;
1448 decode_anchor_root_ca(&tlv)
1449}
1450
1451pub async fn read_anchor_node_id(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u64> {
1453 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_ATTR_ID_ANCHORNODEID).await?;
1454 decode_anchor_node_id(&tlv)
1455}
1456
1457pub async fn read_anchor_vendor_id(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
1459 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_ATTR_ID_ANCHORVENDORID).await?;
1460 decode_anchor_vendor_id(&tlv)
1461}
1462
1463pub async fn read_friendly_name(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<String> {
1465 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_ATTR_ID_FRIENDLYNAME).await?;
1466 decode_friendly_name(&tlv)
1467}
1468
1469pub async fn read_group_key_set_list(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<DatastoreGroupKeySet>> {
1471 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_ATTR_ID_GROUPKEYSETLIST).await?;
1472 decode_group_key_set_list(&tlv)
1473}
1474
1475pub async fn read_group_list(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<DatastoreGroupInformationEntry>> {
1477 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_ATTR_ID_GROUPLIST).await?;
1478 decode_group_list(&tlv)
1479}
1480
1481pub async fn read_node_list(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<DatastoreNodeInformationEntry>> {
1483 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_ATTR_ID_NODELIST).await?;
1484 decode_node_list(&tlv)
1485}
1486
1487pub async fn read_admin_list(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<DatastoreAdministratorInformationEntry>> {
1489 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_ATTR_ID_ADMINLIST).await?;
1490 decode_admin_list(&tlv)
1491}
1492
1493pub async fn read_status(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<DatastoreStatusEntry> {
1495 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_ATTR_ID_STATUS).await?;
1496 decode_status(&tlv)
1497}
1498
1499pub async fn read_endpoint_group_id_list(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<DatastoreEndpointGroupIDEntry>> {
1501 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_ATTR_ID_ENDPOINTGROUPIDLIST).await?;
1502 decode_endpoint_group_id_list(&tlv)
1503}
1504
1505pub async fn read_endpoint_binding_list(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<DatastoreEndpointBindingEntry>> {
1507 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_ATTR_ID_ENDPOINTBINDINGLIST).await?;
1508 decode_endpoint_binding_list(&tlv)
1509}
1510
1511pub async fn read_node_key_set_list(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<DatastoreNodeKeySetEntry>> {
1513 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_ATTR_ID_NODEKEYSETLIST).await?;
1514 decode_node_key_set_list(&tlv)
1515}
1516
1517pub async fn read_node_acl_list(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<DatastoreACLEntry>> {
1519 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_ATTR_ID_NODEACLLIST).await?;
1520 decode_node_acl_list(&tlv)
1521}
1522
1523pub async fn read_node_endpoint_list(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Vec<DatastoreEndpointEntry>> {
1525 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_JOINT_FABRIC_DATASTORE, crate::clusters::defs::CLUSTER_JOINT_FABRIC_DATASTORE_ATTR_ID_NODEENDPOINTLIST).await?;
1526 decode_node_endpoint_list(&tlv)
1527}
1528