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