1#![allow(
5 clippy::all,
6 clippy::pedantic,
7 dead_code,
8 unreachable_pub,
9 unused_imports
10)]
11
12use crate::datatypes::SemanticTagStruct;
13use crate::error::ClusterError;
14use crate::types::Nullable;
15use matter_codec::{ContainerKind, Element, Tag, TlvReader, TlvWriter, Value};
16
17pub const CLUSTER_ID: u32 = 0x003F;
19pub const CLUSTER_REVISION: u16 = 2;
21
22pub mod command_id {
24 pub const KEY_SET_WRITE: u32 = 0x00;
26 pub const KEY_SET_READ: u32 = 0x01;
28 pub const KEY_SET_READ_RESPONSE: u32 = 0x02;
30 pub const KEY_SET_REMOVE: u32 = 0x03;
32 pub const KEY_SET_READ_ALL_INDICES: u32 = 0x04;
34 pub const KEY_SET_READ_ALL_INDICES_RESPONSE: u32 = 0x05;
36}
37
38pub mod attribute_id {
40 pub const GROUP_KEY_MAP: u32 = 0x0000;
42 pub const GROUP_TABLE: u32 = 0x0001;
44 pub const MAX_GROUPS_PER_FABRIC: u32 = 0x0002;
46 pub const MAX_GROUP_KEYS_PER_FABRIC: u32 = 0x0003;
48}
49
50bitflags::bitflags! {
51 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
53 pub struct Feature: u32 {
54 const CS = 1 << 0;
56 }
57}
58
59#[derive(Clone, Debug, PartialEq)]
61#[non_exhaustive]
62pub struct GroupInfoMapStruct {
63 pub group_id: u16,
65 pub endpoints: Vec<u16>,
67 pub group_name: Option<String>,
69 pub fabric_index: u8,
71}
72
73#[derive(Clone, Debug, PartialEq)]
75#[non_exhaustive]
76pub struct GroupKeyMapStruct {
77 pub group_id: u16,
79 pub group_key_set_id: u16,
81 pub fabric_index: u8,
83}
84
85#[derive(Copy, Clone, Debug, PartialEq, Eq)]
87pub enum GroupKeyMulticastPolicyEnum {
88 PerGroupId,
90 AllNodes,
92 Unknown(u8),
94}
95
96impl GroupKeyMulticastPolicyEnum {
97 #[must_use]
99 pub fn from_raw(v: u8) -> Self {
100 match v {
101 0 => Self::PerGroupId,
102 1 => Self::AllNodes,
103 other => Self::Unknown(other),
104 }
105 }
106 #[must_use]
108 pub fn to_raw(self) -> u8 {
109 match self {
110 Self::PerGroupId => 0,
111 Self::AllNodes => 1,
112 Self::Unknown(v) => v,
113 }
114 }
115}
116
117#[derive(Copy, Clone, Debug, PartialEq, Eq)]
119pub enum GroupKeySecurityPolicyEnum {
120 TrustFirst,
122 CacheAndSync,
124 Unknown(u8),
126}
127
128impl GroupKeySecurityPolicyEnum {
129 #[must_use]
131 pub fn from_raw(v: u8) -> Self {
132 match v {
133 0 => Self::TrustFirst,
134 1 => Self::CacheAndSync,
135 other => Self::Unknown(other),
136 }
137 }
138 #[must_use]
140 pub fn to_raw(self) -> u8 {
141 match self {
142 Self::TrustFirst => 0,
143 Self::CacheAndSync => 1,
144 Self::Unknown(v) => v,
145 }
146 }
147}
148
149#[derive(Clone, Debug, PartialEq)]
151pub struct GroupKeySetStruct {
152 pub group_key_set_id: u16,
154 pub group_key_security_policy: GroupKeySecurityPolicyEnum,
156 pub epoch_key0: Nullable<Vec<u8>>,
158 pub epoch_start_time0: Nullable<u64>,
160 pub epoch_key1: Nullable<Vec<u8>>,
162 pub epoch_start_time1: Nullable<u64>,
164 pub epoch_key2: Nullable<Vec<u8>>,
166 pub epoch_start_time2: Nullable<u64>,
168 pub group_key_multicast_policy: Option<GroupKeyMulticastPolicyEnum>,
170 pub fabric_index: Option<u8>,
172}
173
174impl GroupInfoMapStruct {
175 pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
181 let mut f_group_id: Option<u16> = None;
182 let mut f_endpoints: Option<Vec<u16>> = None;
183 let mut f_group_name: Option<String> = None;
184 let mut f_fabric_index: Option<u8> = None;
185 loop {
186 match r.next()? {
187 Some(Element::ContainerEnd) => break,
188 Some(Element::Scalar {
189 tag: Tag::Context(1),
190 value: Value::Uint(v),
191 }) => {
192 f_group_id =
193 Some(u16::try_from(v).map_err(|_| ClusterError::InvalidLength("GroupId"))?)
194 }
195 Some(Element::ContainerStart {
196 tag: Tag::Context(2),
197 kind: ContainerKind::Array,
198 }) => {
199 let mut out = Vec::new();
200 loop {
201 match r.next()? {
202 Some(Element::ContainerEnd) => break,
203 Some(Element::Scalar {
204 value: Value::Uint(v),
205 ..
206 }) => out.push(
207 u16::try_from(v)
208 .map_err(|_| ClusterError::InvalidLength("Endpoints"))?,
209 ),
210 None => {
211 return Err(ClusterError::Tlv(
212 matter_codec::Error::UnclosedContainer,
213 ))
214 }
215 Some(Element::ContainerStart { .. }) => r.skip_container()?,
216 Some(_) => {} }
218 }
219 f_endpoints = Some(out);
220 }
221 Some(Element::Scalar {
222 tag: Tag::Context(3),
223 value: Value::Utf8(v),
224 }) => f_group_name = Some(v),
225 Some(Element::Scalar {
226 tag: Tag::Context(254),
227 value: Value::Uint(v),
228 }) => {
229 f_fabric_index = Some(
230 u8::try_from(v).map_err(|_| ClusterError::InvalidLength("FabricIndex"))?,
231 )
232 }
233 None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
234 Some(Element::ContainerStart { .. }) => r.skip_container()?,
235 Some(_) => {} }
237 }
238 Ok(Self {
239 group_id: f_group_id.ok_or(ClusterError::MissingField("GroupId"))?,
240 endpoints: f_endpoints.ok_or(ClusterError::MissingField("Endpoints"))?,
241 group_name: f_group_name,
242 fabric_index: f_fabric_index.ok_or(ClusterError::MissingField("FabricIndex"))?,
243 })
244 }
245 pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
250 let mut r = TlvReader::new(tlv);
251 match r.next()? {
252 Some(Element::ContainerStart {
253 kind: ContainerKind::Structure,
254 ..
255 }) => {}
256 _ => {
257 return Err(ClusterError::UnexpectedType {
258 context: "GroupInfoMapStruct",
259 })
260 }
261 }
262 Self::decode_from(&mut r)
263 }
264}
265
266impl GroupKeyMapStruct {
267 pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
273 let mut f_group_id: Option<u16> = None;
274 let mut f_group_key_set_id: Option<u16> = None;
275 let mut f_fabric_index: Option<u8> = None;
276 loop {
277 match r.next()? {
278 Some(Element::ContainerEnd) => break,
279 Some(Element::Scalar {
280 tag: Tag::Context(1),
281 value: Value::Uint(v),
282 }) => {
283 f_group_id =
284 Some(u16::try_from(v).map_err(|_| ClusterError::InvalidLength("GroupId"))?)
285 }
286 Some(Element::Scalar {
287 tag: Tag::Context(2),
288 value: Value::Uint(v),
289 }) => {
290 f_group_key_set_id = Some(
291 u16::try_from(v)
292 .map_err(|_| ClusterError::InvalidLength("GroupKeySetId"))?,
293 )
294 }
295 Some(Element::Scalar {
296 tag: Tag::Context(254),
297 value: Value::Uint(v),
298 }) => {
299 f_fabric_index = Some(
300 u8::try_from(v).map_err(|_| ClusterError::InvalidLength("FabricIndex"))?,
301 )
302 }
303 None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
304 Some(Element::ContainerStart { .. }) => r.skip_container()?,
305 Some(_) => {} }
307 }
308 Ok(Self {
309 group_id: f_group_id.ok_or(ClusterError::MissingField("GroupId"))?,
310 group_key_set_id: f_group_key_set_id
311 .ok_or(ClusterError::MissingField("GroupKeySetId"))?,
312 fabric_index: f_fabric_index.ok_or(ClusterError::MissingField("FabricIndex"))?,
313 })
314 }
315 pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
320 let mut r = TlvReader::new(tlv);
321 match r.next()? {
322 Some(Element::ContainerStart {
323 kind: ContainerKind::Structure,
324 ..
325 }) => {}
326 _ => {
327 return Err(ClusterError::UnexpectedType {
328 context: "GroupKeyMapStruct",
329 })
330 }
331 }
332 Self::decode_from(&mut r)
333 }
334 #[allow(clippy::expect_used)] pub fn write_fields(&self, w: &mut TlvWriter<'_>) {
337 w.put_uint(Tag::Context(1), u64::from(self.group_id))
338 .expect("infallible: vec writer");
339 w.put_uint(Tag::Context(2), u64::from(self.group_key_set_id))
340 .expect("infallible: vec writer");
341 w.put_uint(Tag::Context(254), u64::from(self.fabric_index))
342 .expect("infallible: vec writer");
343 }
344 #[must_use]
346 #[allow(clippy::expect_used)] pub fn encode(&self) -> Vec<u8> {
348 let mut buf = Vec::new();
349 let mut w = TlvWriter::new(&mut buf);
350 w.start_structure(Tag::Anonymous)
351 .expect("infallible: vec writer");
352 self.write_fields(&mut w);
353 w.end_container().expect("infallible: vec writer");
354 buf
355 }
356}
357
358impl GroupKeySetStruct {
359 pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
365 let mut f_group_key_set_id: Option<u16> = None;
366 let mut f_group_key_security_policy: Option<GroupKeySecurityPolicyEnum> = None;
367 let mut f_epoch_key0: Option<Nullable<Vec<u8>>> = None;
368 let mut f_epoch_start_time0: Option<Nullable<u64>> = None;
369 let mut f_epoch_key1: Option<Nullable<Vec<u8>>> = None;
370 let mut f_epoch_start_time1: Option<Nullable<u64>> = None;
371 let mut f_epoch_key2: Option<Nullable<Vec<u8>>> = None;
372 let mut f_epoch_start_time2: Option<Nullable<u64>> = None;
373 let mut f_group_key_multicast_policy: Option<GroupKeyMulticastPolicyEnum> = None;
374 let mut f_fabric_index: Option<u8> = None;
375 loop {
376 match r.next()? {
377 Some(Element::ContainerEnd) => break,
378 Some(Element::Scalar {
379 tag: Tag::Context(0),
380 value: Value::Uint(v),
381 }) => {
382 f_group_key_set_id = Some(
383 u16::try_from(v)
384 .map_err(|_| ClusterError::InvalidLength("GroupKeySetId"))?,
385 )
386 }
387 Some(Element::Scalar {
388 tag: Tag::Context(1),
389 value: Value::Uint(v),
390 }) => {
391 f_group_key_security_policy = Some(GroupKeySecurityPolicyEnum::from_raw(
392 u8::try_from(v)
393 .map_err(|_| ClusterError::InvalidLength("GroupKeySecurityPolicy"))?,
394 ))
395 }
396 Some(Element::Scalar {
397 tag: Tag::Context(2),
398 value: Value::Null,
399 }) => f_epoch_key0 = Some(Nullable::Null),
400 Some(Element::Scalar {
401 tag: Tag::Context(2),
402 value: Value::Bytes(v),
403 }) => f_epoch_key0 = Some(Nullable::Value(v)),
404 Some(Element::Scalar {
405 tag: Tag::Context(3),
406 value: Value::Null,
407 }) => f_epoch_start_time0 = Some(Nullable::Null),
408 Some(Element::Scalar {
409 tag: Tag::Context(3),
410 value: Value::Uint(v),
411 }) => {
412 f_epoch_start_time0 =
413 Some(Nullable::Value(u64::try_from(v).map_err(|_| {
414 ClusterError::InvalidLength("EpochStartTime0")
415 })?))
416 }
417 Some(Element::Scalar {
418 tag: Tag::Context(4),
419 value: Value::Null,
420 }) => f_epoch_key1 = Some(Nullable::Null),
421 Some(Element::Scalar {
422 tag: Tag::Context(4),
423 value: Value::Bytes(v),
424 }) => f_epoch_key1 = Some(Nullable::Value(v)),
425 Some(Element::Scalar {
426 tag: Tag::Context(5),
427 value: Value::Null,
428 }) => f_epoch_start_time1 = Some(Nullable::Null),
429 Some(Element::Scalar {
430 tag: Tag::Context(5),
431 value: Value::Uint(v),
432 }) => {
433 f_epoch_start_time1 =
434 Some(Nullable::Value(u64::try_from(v).map_err(|_| {
435 ClusterError::InvalidLength("EpochStartTime1")
436 })?))
437 }
438 Some(Element::Scalar {
439 tag: Tag::Context(6),
440 value: Value::Null,
441 }) => f_epoch_key2 = Some(Nullable::Null),
442 Some(Element::Scalar {
443 tag: Tag::Context(6),
444 value: Value::Bytes(v),
445 }) => f_epoch_key2 = Some(Nullable::Value(v)),
446 Some(Element::Scalar {
447 tag: Tag::Context(7),
448 value: Value::Null,
449 }) => f_epoch_start_time2 = Some(Nullable::Null),
450 Some(Element::Scalar {
451 tag: Tag::Context(7),
452 value: Value::Uint(v),
453 }) => {
454 f_epoch_start_time2 =
455 Some(Nullable::Value(u64::try_from(v).map_err(|_| {
456 ClusterError::InvalidLength("EpochStartTime2")
457 })?))
458 }
459 Some(Element::Scalar {
460 tag: Tag::Context(8),
461 value: Value::Uint(v),
462 }) => {
463 f_group_key_multicast_policy = Some(GroupKeyMulticastPolicyEnum::from_raw(
464 u8::try_from(v)
465 .map_err(|_| ClusterError::InvalidLength("GroupKeyMulticastPolicy"))?,
466 ))
467 }
468 Some(Element::Scalar {
469 tag: Tag::Context(254),
470 value: Value::Uint(v),
471 }) => {
472 f_fabric_index = Some(
473 u8::try_from(v).map_err(|_| ClusterError::InvalidLength("FabricIndex"))?,
474 )
475 }
476 None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
477 Some(Element::ContainerStart { .. }) => r.skip_container()?,
478 Some(_) => {} }
480 }
481 Ok(Self {
482 group_key_set_id: f_group_key_set_id
483 .ok_or(ClusterError::MissingField("GroupKeySetId"))?,
484 group_key_security_policy: f_group_key_security_policy
485 .ok_or(ClusterError::MissingField("GroupKeySecurityPolicy"))?,
486 epoch_key0: f_epoch_key0.ok_or(ClusterError::MissingField("EpochKey0"))?,
487 epoch_start_time0: f_epoch_start_time0
488 .ok_or(ClusterError::MissingField("EpochStartTime0"))?,
489 epoch_key1: f_epoch_key1.ok_or(ClusterError::MissingField("EpochKey1"))?,
490 epoch_start_time1: f_epoch_start_time1
491 .ok_or(ClusterError::MissingField("EpochStartTime1"))?,
492 epoch_key2: f_epoch_key2.ok_or(ClusterError::MissingField("EpochKey2"))?,
493 epoch_start_time2: f_epoch_start_time2
494 .ok_or(ClusterError::MissingField("EpochStartTime2"))?,
495 group_key_multicast_policy: f_group_key_multicast_policy,
496 fabric_index: f_fabric_index,
497 })
498 }
499 pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
504 let mut r = TlvReader::new(tlv);
505 match r.next()? {
506 Some(Element::ContainerStart {
507 kind: ContainerKind::Structure,
508 ..
509 }) => {}
510 _ => {
511 return Err(ClusterError::UnexpectedType {
512 context: "GroupKeySetStruct",
513 })
514 }
515 }
516 Self::decode_from(&mut r)
517 }
518 #[allow(clippy::expect_used)] pub fn write_fields(&self, w: &mut TlvWriter<'_>) {
521 w.put_uint(Tag::Context(0), u64::from(self.group_key_set_id))
522 .expect("infallible: vec writer");
523 w.put_uint(
524 Tag::Context(1),
525 u64::from(self.group_key_security_policy.to_raw()),
526 )
527 .expect("infallible: vec writer");
528 match &self.epoch_key0 {
529 Nullable::Null => w.put_null(Tag::Context(2)).expect("infallible: vec writer"),
530 Nullable::Value(epoch_key0) => {
531 w.put_bytes(Tag::Context(2), &*epoch_key0)
532 .expect("infallible: vec writer");
533 }
534 }
535 match &self.epoch_start_time0 {
536 Nullable::Null => w.put_null(Tag::Context(3)).expect("infallible: vec writer"),
537 Nullable::Value(epoch_start_time0) => {
538 w.put_uint(Tag::Context(3), u64::from(*epoch_start_time0))
539 .expect("infallible: vec writer");
540 }
541 }
542 match &self.epoch_key1 {
543 Nullable::Null => w.put_null(Tag::Context(4)).expect("infallible: vec writer"),
544 Nullable::Value(epoch_key1) => {
545 w.put_bytes(Tag::Context(4), &*epoch_key1)
546 .expect("infallible: vec writer");
547 }
548 }
549 match &self.epoch_start_time1 {
550 Nullable::Null => w.put_null(Tag::Context(5)).expect("infallible: vec writer"),
551 Nullable::Value(epoch_start_time1) => {
552 w.put_uint(Tag::Context(5), u64::from(*epoch_start_time1))
553 .expect("infallible: vec writer");
554 }
555 }
556 match &self.epoch_key2 {
557 Nullable::Null => w.put_null(Tag::Context(6)).expect("infallible: vec writer"),
558 Nullable::Value(epoch_key2) => {
559 w.put_bytes(Tag::Context(6), &*epoch_key2)
560 .expect("infallible: vec writer");
561 }
562 }
563 match &self.epoch_start_time2 {
564 Nullable::Null => w.put_null(Tag::Context(7)).expect("infallible: vec writer"),
565 Nullable::Value(epoch_start_time2) => {
566 w.put_uint(Tag::Context(7), u64::from(*epoch_start_time2))
567 .expect("infallible: vec writer");
568 }
569 }
570 if let Some(group_key_multicast_policy) = &self.group_key_multicast_policy {
571 w.put_uint(
572 Tag::Context(8),
573 u64::from((*group_key_multicast_policy).to_raw()),
574 )
575 .expect("infallible: vec writer");
576 }
577 if let Some(fabric_index) = &self.fabric_index {
578 w.put_uint(Tag::Context(254), u64::from(*fabric_index))
579 .expect("infallible: vec writer");
580 }
581 }
582 #[must_use]
584 #[allow(clippy::expect_used)] pub fn encode(&self) -> Vec<u8> {
586 let mut buf = Vec::new();
587 let mut w = TlvWriter::new(&mut buf);
588 w.start_structure(Tag::Anonymous)
589 .expect("infallible: vec writer");
590 self.write_fields(&mut w);
591 w.end_container().expect("infallible: vec writer");
592 buf
593 }
594}
595
596pub fn decode_group_key_map(tlv: &[u8]) -> Result<Vec<GroupKeyMapStruct>, ClusterError> {
601 let mut r = TlvReader::new(tlv);
602 match r.next()? {
603 Some(Element::ContainerStart {
604 kind: ContainerKind::Array,
605 ..
606 }) => {}
607 _ => {
608 return Err(ClusterError::UnexpectedType {
609 context: "GroupKeyMap",
610 })
611 }
612 }
613 let r = &mut r;
614 let mut out = Vec::new();
615 loop {
616 match r.next()? {
617 Some(Element::ContainerEnd) => break,
618 Some(Element::ContainerStart {
619 kind: ContainerKind::Structure,
620 ..
621 }) => {
622 out.push(GroupKeyMapStruct::decode_from(r)?);
623 }
624 None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
625 Some(Element::ContainerStart { .. }) => r.skip_container()?,
626 Some(_) => {} }
628 }
629 Ok(out)
630}
631
632pub fn decode_group_table(tlv: &[u8]) -> Result<Vec<GroupInfoMapStruct>, ClusterError> {
637 let mut r = TlvReader::new(tlv);
638 match r.next()? {
639 Some(Element::ContainerStart {
640 kind: ContainerKind::Array,
641 ..
642 }) => {}
643 _ => {
644 return Err(ClusterError::UnexpectedType {
645 context: "GroupTable",
646 })
647 }
648 }
649 let r = &mut r;
650 let mut out = Vec::new();
651 loop {
652 match r.next()? {
653 Some(Element::ContainerEnd) => break,
654 Some(Element::ContainerStart {
655 kind: ContainerKind::Structure,
656 ..
657 }) => {
658 out.push(GroupInfoMapStruct::decode_from(r)?);
659 }
660 None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
661 Some(Element::ContainerStart { .. }) => r.skip_container()?,
662 Some(_) => {} }
664 }
665 Ok(out)
666}
667
668pub fn decode_max_groups_per_fabric(tlv: &[u8]) -> Result<u16, ClusterError> {
673 let mut r = TlvReader::new(tlv);
674 match r.next()? {
675 Some(Element::Scalar {
676 value: Value::Uint(v),
677 ..
678 }) => Ok(u16::try_from(v).map_err(|_| ClusterError::InvalidLength("MaxGroupsPerFabric"))?),
679 _ => Err(ClusterError::UnexpectedType {
680 context: "MaxGroupsPerFabric",
681 }),
682 }
683}
684
685pub fn decode_max_group_keys_per_fabric(tlv: &[u8]) -> Result<u16, ClusterError> {
690 let mut r = TlvReader::new(tlv);
691 match r.next()? {
692 Some(Element::Scalar {
693 value: Value::Uint(v),
694 ..
695 }) => {
696 Ok(u16::try_from(v)
697 .map_err(|_| ClusterError::InvalidLength("MaxGroupKeysPerFabric"))?)
698 }
699 _ => Err(ClusterError::UnexpectedType {
700 context: "MaxGroupKeysPerFabric",
701 }),
702 }
703}
704
705#[must_use]
707#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_key_set_write(group_key_set: GroupKeySetStruct) -> Vec<u8> {
709 let mut buf = Vec::new();
710 let mut w = TlvWriter::new(&mut buf);
711 w.start_structure(Tag::Anonymous)
712 .expect("infallible: vec writer");
713 w.start_structure(Tag::Context(0))
714 .expect("infallible: vec writer");
715 group_key_set.write_fields(&mut w);
716 w.end_container().expect("infallible: vec writer");
717 w.end_container().expect("infallible: vec writer");
718 buf
719}
720
721#[must_use]
723#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_key_set_read(group_key_set_id: u16) -> Vec<u8> {
725 let mut buf = Vec::new();
726 let mut w = TlvWriter::new(&mut buf);
727 w.start_structure(Tag::Anonymous)
728 .expect("infallible: vec writer");
729 w.put_uint(Tag::Context(0), u64::from(group_key_set_id))
730 .expect("infallible: vec writer");
731 w.end_container().expect("infallible: vec writer");
732 buf
733}
734
735#[derive(Clone, Debug, PartialEq)]
737#[non_exhaustive]
738pub struct KeySetReadResponse {
739 pub group_key_set: GroupKeySetStruct,
741}
742
743impl KeySetReadResponse {
744 pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
750 let mut f_group_key_set: Option<GroupKeySetStruct> = None;
751 loop {
752 match r.next()? {
753 Some(Element::ContainerEnd) => break,
754 Some(Element::ContainerStart {
755 tag: Tag::Context(0),
756 kind: ContainerKind::Structure,
757 }) => f_group_key_set = Some(GroupKeySetStruct::decode_from(r)?),
758 None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
759 Some(Element::ContainerStart { .. }) => r.skip_container()?,
760 Some(_) => {} }
762 }
763 Ok(Self {
764 group_key_set: f_group_key_set.ok_or(ClusterError::MissingField("GroupKeySet"))?,
765 })
766 }
767 pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
772 let mut r = TlvReader::new(tlv);
773 match r.next()? {
774 Some(Element::ContainerStart {
775 kind: ContainerKind::Structure,
776 ..
777 }) => {}
778 _ => {
779 return Err(ClusterError::UnexpectedType {
780 context: "KeySetReadResponse",
781 })
782 }
783 }
784 Self::decode_from(&mut r)
785 }
786}
787
788#[must_use]
790#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_key_set_remove(group_key_set_id: u16) -> Vec<u8> {
792 let mut buf = Vec::new();
793 let mut w = TlvWriter::new(&mut buf);
794 w.start_structure(Tag::Anonymous)
795 .expect("infallible: vec writer");
796 w.put_uint(Tag::Context(0), u64::from(group_key_set_id))
797 .expect("infallible: vec writer");
798 w.end_container().expect("infallible: vec writer");
799 buf
800}
801
802#[must_use]
804#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_key_set_read_all_indices() -> Vec<u8> {
806 let mut buf = Vec::new();
807 let mut w = TlvWriter::new(&mut buf);
808 w.start_structure(Tag::Anonymous)
809 .expect("infallible: vec writer");
810 w.end_container().expect("infallible: vec writer");
811 buf
812}
813
814#[derive(Clone, Debug, PartialEq)]
816#[non_exhaustive]
817pub struct KeySetReadAllIndicesResponse {
818 pub group_key_set_i_ds: Vec<u16>,
820}
821
822impl KeySetReadAllIndicesResponse {
823 pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
829 let mut f_group_key_set_i_ds: Option<Vec<u16>> = None;
830 loop {
831 match r.next()? {
832 Some(Element::ContainerEnd) => break,
833 Some(Element::ContainerStart {
834 tag: Tag::Context(0),
835 kind: ContainerKind::Array,
836 }) => {
837 let mut out = Vec::new();
838 loop {
839 match r.next()? {
840 Some(Element::ContainerEnd) => break,
841 Some(Element::Scalar {
842 value: Value::Uint(v),
843 ..
844 }) => out.push(
845 u16::try_from(v)
846 .map_err(|_| ClusterError::InvalidLength("GroupKeySetIDs"))?,
847 ),
848 None => {
849 return Err(ClusterError::Tlv(
850 matter_codec::Error::UnclosedContainer,
851 ))
852 }
853 Some(Element::ContainerStart { .. }) => r.skip_container()?,
854 Some(_) => {} }
856 }
857 f_group_key_set_i_ds = Some(out);
858 }
859 None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
860 Some(Element::ContainerStart { .. }) => r.skip_container()?,
861 Some(_) => {} }
863 }
864 Ok(Self {
865 group_key_set_i_ds: f_group_key_set_i_ds
866 .ok_or(ClusterError::MissingField("GroupKeySetIDs"))?,
867 })
868 }
869 pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
874 let mut r = TlvReader::new(tlv);
875 match r.next()? {
876 Some(Element::ContainerStart {
877 kind: ContainerKind::Structure,
878 ..
879 }) => {}
880 _ => {
881 return Err(ClusterError::UnexpectedType {
882 context: "KeySetReadAllIndicesResponse",
883 })
884 }
885 }
886 Self::decode_from(&mut r)
887 }
888}