#![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 = 0x0028;
pub const CLUSTER_REVISION: u16 = 5;
pub mod command_id {}
pub mod attribute_id {
pub const DATA_MODEL_REVISION: u32 = 0x0000;
pub const VENDOR_NAME: u32 = 0x0001;
pub const VENDOR_ID: u32 = 0x0002;
pub const PRODUCT_NAME: u32 = 0x0003;
pub const PRODUCT_ID: u32 = 0x0004;
pub const NODE_LABEL: u32 = 0x0005;
pub const LOCATION: u32 = 0x0006;
pub const HARDWARE_VERSION: u32 = 0x0007;
pub const HARDWARE_VERSION_STRING: u32 = 0x0008;
pub const SOFTWARE_VERSION: u32 = 0x0009;
pub const SOFTWARE_VERSION_STRING: u32 = 0x000A;
pub const MANUFACTURING_DATE: u32 = 0x000B;
pub const PART_NUMBER: u32 = 0x000C;
pub const PRODUCT_URL: u32 = 0x000D;
pub const PRODUCT_LABEL: u32 = 0x000E;
pub const SERIAL_NUMBER: u32 = 0x000F;
pub const LOCAL_CONFIG_DISABLED: u32 = 0x0010;
pub const REACHABLE: u32 = 0x0011;
pub const UNIQUE_ID: u32 = 0x0012;
pub const CAPABILITY_MINIMA: u32 = 0x0013;
pub const PRODUCT_APPEARANCE: u32 = 0x0014;
pub const SPECIFICATION_VERSION: u32 = 0x0015;
pub const MAX_PATHS_PER_INVOKE: u32 = 0x0016;
pub const CONFIGURATION_VERSION: u32 = 0x0018;
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct CapabilityMinimaStruct {
pub case_sessions_per_fabric: u16,
pub subscriptions_per_fabric: u16,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ColorEnum {
Black,
Navy,
Green,
Teal,
Maroon,
Purple,
Olive,
Gray,
Blue,
Lime,
Aqua,
Red,
Fuchsia,
Yellow,
White,
Nickel,
Chrome,
Brass,
Copper,
Silver,
Gold,
Unknown(u8),
}
impl ColorEnum {
#[must_use]
pub fn from_raw(v: u8) -> Self {
match v {
0 => Self::Black,
1 => Self::Navy,
2 => Self::Green,
3 => Self::Teal,
4 => Self::Maroon,
5 => Self::Purple,
6 => Self::Olive,
7 => Self::Gray,
8 => Self::Blue,
9 => Self::Lime,
10 => Self::Aqua,
11 => Self::Red,
12 => Self::Fuchsia,
13 => Self::Yellow,
14 => Self::White,
15 => Self::Nickel,
16 => Self::Chrome,
17 => Self::Brass,
18 => Self::Copper,
19 => Self::Silver,
20 => Self::Gold,
other => Self::Unknown(other),
}
}
#[must_use]
pub fn to_raw(self) -> u8 {
match self {
Self::Black => 0,
Self::Navy => 1,
Self::Green => 2,
Self::Teal => 3,
Self::Maroon => 4,
Self::Purple => 5,
Self::Olive => 6,
Self::Gray => 7,
Self::Blue => 8,
Self::Lime => 9,
Self::Aqua => 10,
Self::Red => 11,
Self::Fuchsia => 12,
Self::Yellow => 13,
Self::White => 14,
Self::Nickel => 15,
Self::Chrome => 16,
Self::Brass => 17,
Self::Copper => 18,
Self::Silver => 19,
Self::Gold => 20,
Self::Unknown(v) => v,
}
}
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct ProductAppearanceStruct {
pub finish: ProductFinishEnum,
pub primary_color: Nullable<ColorEnum>,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ProductFinishEnum {
Other,
Matte,
Satin,
Polished,
Rugged,
Fabric,
Unknown(u8),
}
impl ProductFinishEnum {
#[must_use]
pub fn from_raw(v: u8) -> Self {
match v {
0 => Self::Other,
1 => Self::Matte,
2 => Self::Satin,
3 => Self::Polished,
4 => Self::Rugged,
5 => Self::Fabric,
other => Self::Unknown(other),
}
}
#[must_use]
pub fn to_raw(self) -> u8 {
match self {
Self::Other => 0,
Self::Matte => 1,
Self::Satin => 2,
Self::Polished => 3,
Self::Rugged => 4,
Self::Fabric => 5,
Self::Unknown(v) => v,
}
}
}
impl CapabilityMinimaStruct {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_case_sessions_per_fabric: Option<u16> = None;
let mut f_subscriptions_per_fabric: Option<u16> = None;
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
tag: Tag::Context(0),
value: Value::Uint(v),
}) => {
f_case_sessions_per_fabric = Some(
u16::try_from(v)
.map_err(|_| ClusterError::InvalidLength("CaseSessionsPerFabric"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Uint(v),
}) => {
f_subscriptions_per_fabric = Some(
u16::try_from(v)
.map_err(|_| ClusterError::InvalidLength("SubscriptionsPerFabric"))?,
)
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(Self {
case_sessions_per_fabric: f_case_sessions_per_fabric
.ok_or(ClusterError::MissingField("CaseSessionsPerFabric"))?,
subscriptions_per_fabric: f_subscriptions_per_fabric
.ok_or(ClusterError::MissingField("SubscriptionsPerFabric"))?,
})
}
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: "CapabilityMinimaStruct",
})
}
}
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.case_sessions_per_fabric))
.expect("infallible: vec writer");
w.put_uint(Tag::Context(1), u64::from(self.subscriptions_per_fabric))
.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 ProductAppearanceStruct {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_finish: Option<ProductFinishEnum> = None;
let mut f_primary_color: Option<Nullable<ColorEnum>> = None;
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
tag: Tag::Context(0),
value: Value::Uint(v),
}) => {
f_finish = Some(ProductFinishEnum::from_raw(
u8::try_from(v).map_err(|_| ClusterError::InvalidLength("Finish"))?,
))
}
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Null,
}) => f_primary_color = Some(Nullable::Null),
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Uint(v),
}) => {
f_primary_color = Some(Nullable::Value(ColorEnum::from_raw(
u8::try_from(v).map_err(|_| ClusterError::InvalidLength("PrimaryColor"))?,
)))
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(Self {
finish: f_finish.ok_or(ClusterError::MissingField("Finish"))?,
primary_color: f_primary_color.ok_or(ClusterError::MissingField("PrimaryColor"))?,
})
}
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: "ProductAppearanceStruct",
})
}
}
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.finish.to_raw()))
.expect("infallible: vec writer");
match &self.primary_color {
Nullable::Null => w.put_null(Tag::Context(1)).expect("infallible: vec writer"),
Nullable::Value(primary_color) => {
w.put_uint(Tag::Context(1), u64::from((*primary_color).to_raw()))
.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_data_model_revision(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("DataModelRevision"))?),
_ => Err(ClusterError::UnexpectedType {
context: "DataModelRevision",
}),
}
}
pub fn decode_vendor_name(tlv: &[u8]) -> Result<String, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Utf8(v),
..
}) => Ok(v),
_ => Err(ClusterError::UnexpectedType {
context: "VendorName",
}),
}
}
pub fn decode_vendor_id(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("VendorId"))?),
_ => Err(ClusterError::UnexpectedType {
context: "VendorId",
}),
}
}
pub fn decode_product_name(tlv: &[u8]) -> Result<String, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Utf8(v),
..
}) => Ok(v),
_ => Err(ClusterError::UnexpectedType {
context: "ProductName",
}),
}
}
pub fn decode_product_id(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("ProductId"))?),
_ => Err(ClusterError::UnexpectedType {
context: "ProductId",
}),
}
}
pub fn decode_node_label(tlv: &[u8]) -> Result<String, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Utf8(v),
..
}) => Ok(v),
_ => Err(ClusterError::UnexpectedType {
context: "NodeLabel",
}),
}
}
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_node_label(value: &String) -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.put_utf8(Tag::Anonymous, &value)
.expect("infallible: vec writer");
buf
}
pub fn decode_location(tlv: &[u8]) -> Result<String, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Utf8(v),
..
}) => Ok(v),
_ => Err(ClusterError::UnexpectedType {
context: "Location",
}),
}
}
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_location(value: &String) -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.put_utf8(Tag::Anonymous, &value)
.expect("infallible: vec writer");
buf
}
pub fn decode_hardware_version(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("HardwareVersion"))?),
_ => Err(ClusterError::UnexpectedType {
context: "HardwareVersion",
}),
}
}
pub fn decode_hardware_version_string(tlv: &[u8]) -> Result<String, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Utf8(v),
..
}) => Ok(v),
_ => Err(ClusterError::UnexpectedType {
context: "HardwareVersionString",
}),
}
}
pub fn decode_software_version(tlv: &[u8]) -> Result<u32, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(u32::try_from(v).map_err(|_| ClusterError::InvalidLength("SoftwareVersion"))?),
_ => Err(ClusterError::UnexpectedType {
context: "SoftwareVersion",
}),
}
}
pub fn decode_software_version_string(tlv: &[u8]) -> Result<String, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Utf8(v),
..
}) => Ok(v),
_ => Err(ClusterError::UnexpectedType {
context: "SoftwareVersionString",
}),
}
}
pub fn decode_manufacturing_date(tlv: &[u8]) -> Result<String, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Utf8(v),
..
}) => Ok(v),
_ => Err(ClusterError::UnexpectedType {
context: "ManufacturingDate",
}),
}
}
pub fn decode_part_number(tlv: &[u8]) -> Result<String, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Utf8(v),
..
}) => Ok(v),
_ => Err(ClusterError::UnexpectedType {
context: "PartNumber",
}),
}
}
pub fn decode_product_url(tlv: &[u8]) -> Result<String, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Utf8(v),
..
}) => Ok(v),
_ => Err(ClusterError::UnexpectedType {
context: "ProductUrl",
}),
}
}
pub fn decode_product_label(tlv: &[u8]) -> Result<String, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Utf8(v),
..
}) => Ok(v),
_ => Err(ClusterError::UnexpectedType {
context: "ProductLabel",
}),
}
}
pub fn decode_serial_number(tlv: &[u8]) -> Result<String, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Utf8(v),
..
}) => Ok(v),
_ => Err(ClusterError::UnexpectedType {
context: "SerialNumber",
}),
}
}
pub fn decode_local_config_disabled(tlv: &[u8]) -> Result<bool, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Bool(v),
..
}) => Ok(v),
_ => Err(ClusterError::UnexpectedType {
context: "LocalConfigDisabled",
}),
}
}
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_local_config_disabled(value: bool) -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.put_bool(Tag::Anonymous, value)
.expect("infallible: vec writer");
buf
}
pub fn decode_reachable(tlv: &[u8]) -> Result<bool, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Bool(v),
..
}) => Ok(v),
_ => Err(ClusterError::UnexpectedType {
context: "Reachable",
}),
}
}
pub fn decode_unique_id(tlv: &[u8]) -> Result<String, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Utf8(v),
..
}) => Ok(v),
_ => Err(ClusterError::UnexpectedType {
context: "UniqueId",
}),
}
}
pub fn decode_capability_minima(tlv: &[u8]) -> Result<CapabilityMinimaStruct, ClusterError> {
CapabilityMinimaStruct::decode(tlv)
}
pub fn decode_product_appearance(tlv: &[u8]) -> Result<ProductAppearanceStruct, ClusterError> {
ProductAppearanceStruct::decode(tlv)
}
pub fn decode_specification_version(tlv: &[u8]) -> Result<u32, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(u32::try_from(v).map_err(|_| ClusterError::InvalidLength("SpecificationVersion"))?),
_ => Err(ClusterError::UnexpectedType {
context: "SpecificationVersion",
}),
}
}
pub fn decode_max_paths_per_invoke(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("MaxPathsPerInvoke"))?),
_ => Err(ClusterError::UnexpectedType {
context: "MaxPathsPerInvoke",
}),
}
}
pub fn decode_configuration_version(tlv: &[u8]) -> Result<u32, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(u32::try_from(v).map_err(|_| ClusterError::InvalidLength("ConfigurationVersion"))?),
_ => Err(ClusterError::UnexpectedType {
context: "ConfigurationVersion",
}),
}
}