#![allow(
clippy::all,
clippy::pedantic,
dead_code,
unreachable_pub,
unused_imports
)]
use crate::datatypes::SemanticTagStruct;
use crate::error::ClusterError;
use crate::types::Nullable;
use matter_codec::{ContainerKind, Element, Tag, TlvReader, TlvWriter, Value};
pub const CLUSTER_ID: u32 = 0x001F;
pub const CLUSTER_REVISION: u16 = 2;
pub mod command_id {
pub const REVIEW_FABRIC_RESTRICTIONS: u32 = 0x00;
pub const REVIEW_FABRIC_RESTRICTIONS_RESPONSE: u32 = 0x01;
}
pub mod attribute_id {
pub const ACL: u32 = 0x0000;
pub const EXTENSION: u32 = 0x0001;
pub const SUBJECTS_PER_ACCESS_CONTROL_ENTRY: u32 = 0x0002;
pub const TARGETS_PER_ACCESS_CONTROL_ENTRY: u32 = 0x0003;
pub const ACCESS_CONTROL_ENTRIES_PER_FABRIC: u32 = 0x0004;
pub const COMMISSIONING_ARL: u32 = 0x0005;
pub const ARL: u32 = 0x0006;
}
bitflags::bitflags! {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct Feature: u32 {
const EXTS = 1 << 0;
const MNGD = 1 << 1;
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum AccessControlEntryAuthModeEnum {
Pase,
Case,
Group,
Unknown(u8),
}
impl AccessControlEntryAuthModeEnum {
#[must_use]
pub fn from_raw(v: u8) -> Self {
match v {
1 => Self::Pase,
2 => Self::Case,
3 => Self::Group,
other => Self::Unknown(other),
}
}
#[must_use]
pub fn to_raw(self) -> u8 {
match self {
Self::Pase => 1,
Self::Case => 2,
Self::Group => 3,
Self::Unknown(v) => v,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum AccessControlEntryPrivilegeEnum {
View,
ProxyView,
Operate,
Manage,
Administer,
Unknown(u8),
}
impl AccessControlEntryPrivilegeEnum {
#[must_use]
pub fn from_raw(v: u8) -> Self {
match v {
1 => Self::View,
2 => Self::ProxyView,
3 => Self::Operate,
4 => Self::Manage,
5 => Self::Administer,
other => Self::Unknown(other),
}
}
#[must_use]
pub fn to_raw(self) -> u8 {
match self {
Self::View => 1,
Self::ProxyView => 2,
Self::Operate => 3,
Self::Manage => 4,
Self::Administer => 5,
Self::Unknown(v) => v,
}
}
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct AccessControlEntryStruct {
pub privilege: AccessControlEntryPrivilegeEnum,
pub auth_mode: AccessControlEntryAuthModeEnum,
pub subjects: Nullable<Vec<u64>>,
pub targets: Nullable<Vec<AccessControlTargetStruct>>,
pub fabric_index: u8,
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct AccessControlExtensionStruct {
pub data: Vec<u8>,
pub fabric_index: u8,
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct AccessControlTargetStruct {
pub cluster: Nullable<u32>,
pub endpoint: Nullable<u16>,
pub device_type: Nullable<u32>,
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct AccessRestrictionEntryStruct {
pub endpoint: u16,
pub cluster: u32,
pub restrictions: Vec<AccessRestrictionStruct>,
pub fabric_index: u8,
}
#[derive(Clone, Debug, PartialEq)]
pub struct AccessRestrictionStruct {
pub r#type: AccessRestrictionTypeEnum,
pub id: Nullable<u32>,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum AccessRestrictionTypeEnum {
AttributeAccessForbidden,
AttributeWriteForbidden,
CommandForbidden,
EventForbidden,
Unknown(u8),
}
impl AccessRestrictionTypeEnum {
#[must_use]
pub fn from_raw(v: u8) -> Self {
match v {
0 => Self::AttributeAccessForbidden,
1 => Self::AttributeWriteForbidden,
2 => Self::CommandForbidden,
3 => Self::EventForbidden,
other => Self::Unknown(other),
}
}
#[must_use]
pub fn to_raw(self) -> u8 {
match self {
Self::AttributeAccessForbidden => 0,
Self::AttributeWriteForbidden => 1,
Self::CommandForbidden => 2,
Self::EventForbidden => 3,
Self::Unknown(v) => v,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ChangeTypeEnum {
Changed,
Added,
Removed,
Unknown(u8),
}
impl ChangeTypeEnum {
#[must_use]
pub fn from_raw(v: u8) -> Self {
match v {
0 => Self::Changed,
1 => Self::Added,
2 => Self::Removed,
other => Self::Unknown(other),
}
}
#[must_use]
pub fn to_raw(self) -> u8 {
match self {
Self::Changed => 0,
Self::Added => 1,
Self::Removed => 2,
Self::Unknown(v) => v,
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct CommissioningAccessRestrictionEntryStruct {
pub endpoint: u16,
pub cluster: u32,
pub restrictions: Vec<AccessRestrictionStruct>,
}
impl AccessControlEntryStruct {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_privilege: Option<AccessControlEntryPrivilegeEnum> = None;
let mut f_auth_mode: Option<AccessControlEntryAuthModeEnum> = None;
let mut f_subjects: Option<Nullable<Vec<u64>>> = None;
let mut f_targets: Option<Nullable<Vec<AccessControlTargetStruct>>> = None;
let mut f_fabric_index: Option<u8> = None;
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Uint(v),
}) => {
f_privilege = Some(AccessControlEntryPrivilegeEnum::from_raw(
u8::try_from(v).map_err(|_| ClusterError::InvalidLength("Privilege"))?,
))
}
Some(Element::Scalar {
tag: Tag::Context(2),
value: Value::Uint(v),
}) => {
f_auth_mode = Some(AccessControlEntryAuthModeEnum::from_raw(
u8::try_from(v).map_err(|_| ClusterError::InvalidLength("AuthMode"))?,
))
}
Some(Element::Scalar {
tag: Tag::Context(3),
value: Value::Null,
}) => f_subjects = Some(Nullable::Null),
Some(Element::ContainerStart {
tag: Tag::Context(3),
kind: ContainerKind::Array,
}) => {
let mut out = Vec::new();
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => out.push(
u64::try_from(v)
.map_err(|_| ClusterError::InvalidLength("Subjects"))?,
),
None => {
return Err(ClusterError::Tlv(
matter_codec::Error::UnclosedContainer,
))
}
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
f_subjects = Some(Nullable::Value(out));
}
Some(Element::Scalar {
tag: Tag::Context(4),
value: Value::Null,
}) => f_targets = Some(Nullable::Null),
Some(Element::ContainerStart {
tag: Tag::Context(4),
kind: ContainerKind::Array,
}) => {
let mut out = Vec::new();
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {
out.push(AccessControlTargetStruct::decode_from(r)?);
}
None => {
return Err(ClusterError::Tlv(
matter_codec::Error::UnclosedContainer,
))
}
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
f_targets = Some(Nullable::Value(out));
}
Some(Element::Scalar {
tag: Tag::Context(254),
value: Value::Uint(v),
}) => {
f_fabric_index = Some(
u8::try_from(v).map_err(|_| ClusterError::InvalidLength("FabricIndex"))?,
)
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(Self {
privilege: f_privilege.ok_or(ClusterError::MissingField("Privilege"))?,
auth_mode: f_auth_mode.ok_or(ClusterError::MissingField("AuthMode"))?,
subjects: f_subjects.ok_or(ClusterError::MissingField("Subjects"))?,
targets: f_targets.ok_or(ClusterError::MissingField("Targets"))?,
fabric_index: f_fabric_index.ok_or(ClusterError::MissingField("FabricIndex"))?,
})
}
pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {}
_ => {
return Err(ClusterError::UnexpectedType {
context: "AccessControlEntryStruct",
})
}
}
Self::decode_from(&mut r)
}
}
impl AccessControlExtensionStruct {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_data: Option<Vec<u8>> = None;
let mut f_fabric_index: Option<u8> = None;
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Bytes(v),
}) => f_data = Some(v),
Some(Element::Scalar {
tag: Tag::Context(254),
value: Value::Uint(v),
}) => {
f_fabric_index = Some(
u8::try_from(v).map_err(|_| ClusterError::InvalidLength("FabricIndex"))?,
)
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(Self {
data: f_data.ok_or(ClusterError::MissingField("Data"))?,
fabric_index: f_fabric_index.ok_or(ClusterError::MissingField("FabricIndex"))?,
})
}
pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {}
_ => {
return Err(ClusterError::UnexpectedType {
context: "AccessControlExtensionStruct",
})
}
}
Self::decode_from(&mut r)
}
#[allow(clippy::expect_used)] pub fn write_fields(&self, w: &mut TlvWriter<'_>) {
w.put_bytes(Tag::Context(1), &self.data)
.expect("infallible: vec writer");
w.put_uint(Tag::Context(254), u64::from(self.fabric_index))
.expect("infallible: vec writer");
}
#[must_use]
#[allow(clippy::expect_used)] pub fn encode(&self) -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
self.write_fields(&mut w);
w.end_container().expect("infallible: vec writer");
buf
}
}
impl AccessControlTargetStruct {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_cluster: Option<Nullable<u32>> = None;
let mut f_endpoint: Option<Nullable<u16>> = None;
let mut f_device_type: Option<Nullable<u32>> = None;
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
tag: Tag::Context(0),
value: Value::Null,
}) => f_cluster = Some(Nullable::Null),
Some(Element::Scalar {
tag: Tag::Context(0),
value: Value::Uint(v),
}) => {
f_cluster = Some(Nullable::Value(
u32::try_from(v).map_err(|_| ClusterError::InvalidLength("Cluster"))?,
))
}
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Null,
}) => f_endpoint = Some(Nullable::Null),
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Uint(v),
}) => {
f_endpoint = Some(Nullable::Value(
u16::try_from(v).map_err(|_| ClusterError::InvalidLength("Endpoint"))?,
))
}
Some(Element::Scalar {
tag: Tag::Context(2),
value: Value::Null,
}) => f_device_type = Some(Nullable::Null),
Some(Element::Scalar {
tag: Tag::Context(2),
value: Value::Uint(v),
}) => {
f_device_type = Some(Nullable::Value(
u32::try_from(v).map_err(|_| ClusterError::InvalidLength("DeviceType"))?,
))
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(Self {
cluster: f_cluster.ok_or(ClusterError::MissingField("Cluster"))?,
endpoint: f_endpoint.ok_or(ClusterError::MissingField("Endpoint"))?,
device_type: f_device_type.ok_or(ClusterError::MissingField("DeviceType"))?,
})
}
pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {}
_ => {
return Err(ClusterError::UnexpectedType {
context: "AccessControlTargetStruct",
})
}
}
Self::decode_from(&mut r)
}
#[allow(clippy::expect_used)] pub fn write_fields(&self, w: &mut TlvWriter<'_>) {
match &self.cluster {
Nullable::Null => w.put_null(Tag::Context(0)).expect("infallible: vec writer"),
Nullable::Value(cluster) => {
w.put_uint(Tag::Context(0), u64::from(*cluster))
.expect("infallible: vec writer");
}
}
match &self.endpoint {
Nullable::Null => w.put_null(Tag::Context(1)).expect("infallible: vec writer"),
Nullable::Value(endpoint) => {
w.put_uint(Tag::Context(1), u64::from(*endpoint))
.expect("infallible: vec writer");
}
}
match &self.device_type {
Nullable::Null => w.put_null(Tag::Context(2)).expect("infallible: vec writer"),
Nullable::Value(device_type) => {
w.put_uint(Tag::Context(2), u64::from(*device_type))
.expect("infallible: vec writer");
}
}
}
#[must_use]
#[allow(clippy::expect_used)] pub fn encode(&self) -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
self.write_fields(&mut w);
w.end_container().expect("infallible: vec writer");
buf
}
}
impl AccessRestrictionEntryStruct {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_endpoint: Option<u16> = None;
let mut f_cluster: Option<u32> = None;
let mut f_restrictions: Option<Vec<AccessRestrictionStruct>> = None;
let mut f_fabric_index: Option<u8> = None;
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
tag: Tag::Context(0),
value: Value::Uint(v),
}) => {
f_endpoint = Some(
u16::try_from(v).map_err(|_| ClusterError::InvalidLength("Endpoint"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Uint(v),
}) => {
f_cluster =
Some(u32::try_from(v).map_err(|_| ClusterError::InvalidLength("Cluster"))?)
}
Some(Element::ContainerStart {
tag: Tag::Context(2),
kind: ContainerKind::Array,
}) => {
let mut out = Vec::new();
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {
out.push(AccessRestrictionStruct::decode_from(r)?);
}
None => {
return Err(ClusterError::Tlv(
matter_codec::Error::UnclosedContainer,
))
}
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
f_restrictions = Some(out);
}
Some(Element::Scalar {
tag: Tag::Context(254),
value: Value::Uint(v),
}) => {
f_fabric_index = Some(
u8::try_from(v).map_err(|_| ClusterError::InvalidLength("FabricIndex"))?,
)
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(Self {
endpoint: f_endpoint.ok_or(ClusterError::MissingField("Endpoint"))?,
cluster: f_cluster.ok_or(ClusterError::MissingField("Cluster"))?,
restrictions: f_restrictions.ok_or(ClusterError::MissingField("Restrictions"))?,
fabric_index: f_fabric_index.ok_or(ClusterError::MissingField("FabricIndex"))?,
})
}
pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {}
_ => {
return Err(ClusterError::UnexpectedType {
context: "AccessRestrictionEntryStruct",
})
}
}
Self::decode_from(&mut r)
}
}
impl AccessRestrictionStruct {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_type: Option<AccessRestrictionTypeEnum> = None;
let mut f_id: Option<Nullable<u32>> = None;
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
tag: Tag::Context(0),
value: Value::Uint(v),
}) => {
f_type = Some(AccessRestrictionTypeEnum::from_raw(
u8::try_from(v).map_err(|_| ClusterError::InvalidLength("Type"))?,
))
}
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Null,
}) => f_id = Some(Nullable::Null),
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Uint(v),
}) => {
f_id = Some(Nullable::Value(
u32::try_from(v).map_err(|_| ClusterError::InvalidLength("Id"))?,
))
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(Self {
r#type: f_type.ok_or(ClusterError::MissingField("Type"))?,
id: f_id.ok_or(ClusterError::MissingField("Id"))?,
})
}
pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {}
_ => {
return Err(ClusterError::UnexpectedType {
context: "AccessRestrictionStruct",
})
}
}
Self::decode_from(&mut r)
}
#[allow(clippy::expect_used)] pub fn write_fields(&self, w: &mut TlvWriter<'_>) {
w.put_uint(Tag::Context(0), u64::from(self.r#type.to_raw()))
.expect("infallible: vec writer");
match &self.id {
Nullable::Null => w.put_null(Tag::Context(1)).expect("infallible: vec writer"),
Nullable::Value(id) => {
w.put_uint(Tag::Context(1), u64::from(*id))
.expect("infallible: vec writer");
}
}
}
#[must_use]
#[allow(clippy::expect_used)] pub fn encode(&self) -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
self.write_fields(&mut w);
w.end_container().expect("infallible: vec writer");
buf
}
}
impl CommissioningAccessRestrictionEntryStruct {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_endpoint: Option<u16> = None;
let mut f_cluster: Option<u32> = None;
let mut f_restrictions: Option<Vec<AccessRestrictionStruct>> = None;
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
tag: Tag::Context(0),
value: Value::Uint(v),
}) => {
f_endpoint = Some(
u16::try_from(v).map_err(|_| ClusterError::InvalidLength("Endpoint"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Uint(v),
}) => {
f_cluster =
Some(u32::try_from(v).map_err(|_| ClusterError::InvalidLength("Cluster"))?)
}
Some(Element::ContainerStart {
tag: Tag::Context(2),
kind: ContainerKind::Array,
}) => {
let mut out = Vec::new();
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {
out.push(AccessRestrictionStruct::decode_from(r)?);
}
None => {
return Err(ClusterError::Tlv(
matter_codec::Error::UnclosedContainer,
))
}
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
f_restrictions = Some(out);
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(Self {
endpoint: f_endpoint.ok_or(ClusterError::MissingField("Endpoint"))?,
cluster: f_cluster.ok_or(ClusterError::MissingField("Cluster"))?,
restrictions: f_restrictions.ok_or(ClusterError::MissingField("Restrictions"))?,
})
}
pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {}
_ => {
return Err(ClusterError::UnexpectedType {
context: "CommissioningAccessRestrictionEntryStruct",
})
}
}
Self::decode_from(&mut r)
}
#[allow(clippy::expect_used)] pub fn write_fields(&self, w: &mut TlvWriter<'_>) {
w.put_uint(Tag::Context(0), u64::from(self.endpoint))
.expect("infallible: vec writer");
w.put_uint(Tag::Context(1), u64::from(self.cluster))
.expect("infallible: vec writer");
w.start_array(Tag::Context(2))
.expect("infallible: vec writer");
for el in &self.restrictions {
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
el.write_fields(w);
w.end_container().expect("infallible: vec writer");
}
w.end_container().expect("infallible: vec writer");
}
#[must_use]
#[allow(clippy::expect_used)] pub fn encode(&self) -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
self.write_fields(&mut w);
w.end_container().expect("infallible: vec writer");
buf
}
}
pub fn decode_acl(tlv: &[u8]) -> Result<Vec<AccessControlEntryStruct>, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::ContainerStart {
kind: ContainerKind::Array,
..
}) => {}
_ => return Err(ClusterError::UnexpectedType { context: "Acl" }),
}
let r = &mut r;
let mut out = Vec::new();
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {
out.push(AccessControlEntryStruct::decode_from(r)?);
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(out)
}
pub fn decode_extension(tlv: &[u8]) -> Result<Vec<AccessControlExtensionStruct>, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::ContainerStart {
kind: ContainerKind::Array,
..
}) => {}
_ => {
return Err(ClusterError::UnexpectedType {
context: "Extension",
})
}
}
let r = &mut r;
let mut out = Vec::new();
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {
out.push(AccessControlExtensionStruct::decode_from(r)?);
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(out)
}
pub fn decode_subjects_per_access_control_entry(tlv: &[u8]) -> Result<u16, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(u16::try_from(v)
.map_err(|_| ClusterError::InvalidLength("SubjectsPerAccessControlEntry"))?),
_ => Err(ClusterError::UnexpectedType {
context: "SubjectsPerAccessControlEntry",
}),
}
}
pub fn decode_targets_per_access_control_entry(tlv: &[u8]) -> Result<u16, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(u16::try_from(v)
.map_err(|_| ClusterError::InvalidLength("TargetsPerAccessControlEntry"))?),
_ => Err(ClusterError::UnexpectedType {
context: "TargetsPerAccessControlEntry",
}),
}
}
pub fn decode_access_control_entries_per_fabric(tlv: &[u8]) -> Result<u16, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(u16::try_from(v)
.map_err(|_| ClusterError::InvalidLength("AccessControlEntriesPerFabric"))?),
_ => Err(ClusterError::UnexpectedType {
context: "AccessControlEntriesPerFabric",
}),
}
}
pub fn decode_commissioning_arl(
tlv: &[u8],
) -> Result<Vec<CommissioningAccessRestrictionEntryStruct>, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::ContainerStart {
kind: ContainerKind::Array,
..
}) => {}
_ => {
return Err(ClusterError::UnexpectedType {
context: "CommissioningArl",
})
}
}
let r = &mut r;
let mut out = Vec::new();
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {
out.push(CommissioningAccessRestrictionEntryStruct::decode_from(r)?);
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(out)
}
pub fn decode_arl(tlv: &[u8]) -> Result<Vec<AccessRestrictionEntryStruct>, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::ContainerStart {
kind: ContainerKind::Array,
..
}) => {}
_ => return Err(ClusterError::UnexpectedType { context: "Arl" }),
}
let r = &mut r;
let mut out = Vec::new();
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {
out.push(AccessRestrictionEntryStruct::decode_from(r)?);
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(out)
}
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_review_fabric_restrictions(
arl: &Vec<CommissioningAccessRestrictionEntryStruct>,
) -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
w.start_array(Tag::Context(0))
.expect("infallible: vec writer");
for el in arl.iter() {
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
el.write_fields(&mut w);
w.end_container().expect("infallible: vec writer");
}
w.end_container().expect("infallible: vec writer");
w.end_container().expect("infallible: vec writer");
buf
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct ReviewFabricRestrictionsResponse {
pub token: u64,
}
impl ReviewFabricRestrictionsResponse {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_token: Option<u64> = None;
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
tag: Tag::Context(0),
value: Value::Uint(v),
}) => {
f_token =
Some(u64::try_from(v).map_err(|_| ClusterError::InvalidLength("Token"))?)
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(Self {
token: f_token.ok_or(ClusterError::MissingField("Token"))?,
})
}
pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::ContainerStart {
kind: ContainerKind::Structure,
..
}) => {}
_ => {
return Err(ClusterError::UnexpectedType {
context: "ReviewFabricRestrictionsResponse",
})
}
}
Self::decode_from(&mut r)
}
}