#![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 = 0x0046;
pub const CLUSTER_REVISION: u16 = 3;
pub mod command_id {
pub const REGISTER_CLIENT: u32 = 0x00;
pub const REGISTER_CLIENT_RESPONSE: u32 = 0x01;
pub const UNREGISTER_CLIENT: u32 = 0x02;
pub const STAY_ACTIVE_REQUEST: u32 = 0x03;
pub const STAY_ACTIVE_RESPONSE: u32 = 0x04;
}
pub mod attribute_id {
pub const IDLE_MODE_DURATION: u32 = 0x0000;
pub const ACTIVE_MODE_DURATION: u32 = 0x0001;
pub const ACTIVE_MODE_THRESHOLD: u32 = 0x0002;
pub const REGISTERED_CLIENTS: u32 = 0x0003;
pub const ICD_COUNTER: u32 = 0x0004;
pub const CLIENTS_SUPPORTED_PER_FABRIC: u32 = 0x0005;
pub const USER_ACTIVE_MODE_TRIGGER_HINT: u32 = 0x0006;
pub const USER_ACTIVE_MODE_TRIGGER_INSTRUCTION: u32 = 0x0007;
pub const OPERATING_MODE: u32 = 0x0008;
pub const MAXIMUM_CHECK_IN_BACKOFF: u32 = 0x0009;
}
bitflags::bitflags! {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct Feature: u32 {
const CIP = 1 << 0;
const UAT = 1 << 1;
const LITS = 1 << 2;
const DSLS = 1 << 3;
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ClientTypeEnum {
Permanent,
Ephemeral,
Unknown(u8),
}
impl ClientTypeEnum {
#[must_use]
pub fn from_raw(v: u8) -> Self {
match v {
0 => Self::Permanent,
1 => Self::Ephemeral,
other => Self::Unknown(other),
}
}
#[must_use]
pub fn to_raw(self) -> u8 {
match self {
Self::Permanent => 0,
Self::Ephemeral => 1,
Self::Unknown(v) => v,
}
}
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct MonitoringRegistrationStruct {
pub check_in_node_id: u64,
pub monitored_subject: u64,
pub client_type: ClientTypeEnum,
pub fabric_index: u8,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum OperatingModeEnum {
Sit,
Lit,
Unknown(u8),
}
impl OperatingModeEnum {
#[must_use]
pub fn from_raw(v: u8) -> Self {
match v {
0 => Self::Sit,
1 => Self::Lit,
other => Self::Unknown(other),
}
}
#[must_use]
pub fn to_raw(self) -> u8 {
match self {
Self::Sit => 0,
Self::Lit => 1,
Self::Unknown(v) => v,
}
}
}
bitflags::bitflags! {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct UserActiveModeTriggerBitmap: u32 {
const POWER_CYCLE = 1 << 0;
const SETTINGS_MENU = 1 << 1;
const CUSTOM_INSTRUCTION = 1 << 2;
const DEVICE_MANUAL = 1 << 3;
const ACTUATE_SENSOR = 1 << 4;
const ACTUATE_SENSOR_SECONDS = 1 << 5;
const ACTUATE_SENSOR_TIMES = 1 << 6;
const ACTUATE_SENSOR_LIGHTS_BLINK = 1 << 7;
const RESET_BUTTON = 1 << 8;
const RESET_BUTTON_LIGHTS_BLINK = 1 << 9;
const RESET_BUTTON_SECONDS = 1 << 10;
const RESET_BUTTON_TIMES = 1 << 11;
const SETUP_BUTTON = 1 << 12;
const SETUP_BUTTON_SECONDS = 1 << 13;
const SETUP_BUTTON_LIGHTS_BLINK = 1 << 14;
const SETUP_BUTTON_TIMES = 1 << 15;
const APP_DEFINED_BUTTON = 1 << 16;
}
}
impl MonitoringRegistrationStruct {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_check_in_node_id: Option<u64> = None;
let mut f_monitored_subject: Option<u64> = None;
let mut f_client_type: Option<ClientTypeEnum> = 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_check_in_node_id = Some(
u64::try_from(v)
.map_err(|_| ClusterError::InvalidLength("CheckInNodeId"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(2),
value: Value::Uint(v),
}) => {
f_monitored_subject = Some(
u64::try_from(v)
.map_err(|_| ClusterError::InvalidLength("MonitoredSubject"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(4),
value: Value::Uint(v),
}) => {
f_client_type = Some(ClientTypeEnum::from_raw(
u8::try_from(v).map_err(|_| ClusterError::InvalidLength("ClientType"))?,
))
}
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 {
check_in_node_id: f_check_in_node_id
.ok_or(ClusterError::MissingField("CheckInNodeId"))?,
monitored_subject: f_monitored_subject
.ok_or(ClusterError::MissingField("MonitoredSubject"))?,
client_type: f_client_type.ok_or(ClusterError::MissingField("ClientType"))?,
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: "MonitoringRegistrationStruct",
})
}
}
Self::decode_from(&mut r)
}
#[allow(clippy::expect_used)] pub fn write_fields(&self, w: &mut TlvWriter<'_>) {
w.put_uint(Tag::Context(1), u64::from(self.check_in_node_id))
.expect("infallible: vec writer");
w.put_uint(Tag::Context(2), u64::from(self.monitored_subject))
.expect("infallible: vec writer");
w.put_uint(Tag::Context(4), u64::from(self.client_type.to_raw()))
.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
}
}
pub fn decode_idle_mode_duration(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("IdleModeDuration"))?),
_ => Err(ClusterError::UnexpectedType {
context: "IdleModeDuration",
}),
}
}
pub fn decode_active_mode_duration(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("ActiveModeDuration"))?),
_ => Err(ClusterError::UnexpectedType {
context: "ActiveModeDuration",
}),
}
}
pub fn decode_active_mode_threshold(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("ActiveModeThreshold"))?),
_ => Err(ClusterError::UnexpectedType {
context: "ActiveModeThreshold",
}),
}
}
pub fn decode_registered_clients(
tlv: &[u8],
) -> Result<Vec<MonitoringRegistrationStruct>, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::ContainerStart {
kind: ContainerKind::Array,
..
}) => {}
_ => {
return Err(ClusterError::UnexpectedType {
context: "RegisteredClients",
})
}
}
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(MonitoringRegistrationStruct::decode_from(r)?);
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(out)
}
pub fn decode_icd_counter(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("IcdCounter"))?),
_ => Err(ClusterError::UnexpectedType {
context: "IcdCounter",
}),
}
}
pub fn decode_clients_supported_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("ClientsSupportedPerFabric"))?),
_ => Err(ClusterError::UnexpectedType {
context: "ClientsSupportedPerFabric",
}),
}
}
pub fn decode_user_active_mode_trigger_hint(
tlv: &[u8],
) -> Result<UserActiveModeTriggerBitmap, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(UserActiveModeTriggerBitmap::from_bits_retain(
u32::try_from(v)
.map_err(|_| ClusterError::InvalidLength("UserActiveModeTriggerHint"))?,
)),
_ => Err(ClusterError::UnexpectedType {
context: "UserActiveModeTriggerHint",
}),
}
}
pub fn decode_user_active_mode_trigger_instruction(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: "UserActiveModeTriggerInstruction",
}),
}
}
pub fn decode_operating_mode(tlv: &[u8]) -> Result<OperatingModeEnum, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(OperatingModeEnum::from_raw(
u8::try_from(v).map_err(|_| ClusterError::InvalidLength("OperatingMode"))?,
)),
_ => Err(ClusterError::UnexpectedType {
context: "OperatingMode",
}),
}
}
pub fn decode_maximum_check_in_backoff(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("MaximumCheckInBackoff"))?)
}
_ => Err(ClusterError::UnexpectedType {
context: "MaximumCheckInBackoff",
}),
}
}
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_register_client(
check_in_node_id: u64,
monitored_subject: u64,
key: &Vec<u8>,
verification_key: Option<Vec<u8>>,
client_type: ClientTypeEnum,
) -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
w.put_uint(Tag::Context(0), u64::from(check_in_node_id))
.expect("infallible: vec writer");
w.put_uint(Tag::Context(1), u64::from(monitored_subject))
.expect("infallible: vec writer");
w.put_bytes(Tag::Context(2), &key)
.expect("infallible: vec writer");
if let Some(verification_key) = verification_key {
w.put_bytes(Tag::Context(3), &verification_key)
.expect("infallible: vec writer");
}
w.put_uint(Tag::Context(4), u64::from(client_type.to_raw()))
.expect("infallible: vec writer");
w.end_container().expect("infallible: vec writer");
buf
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct RegisterClientResponse {
pub icd_counter: u32,
}
impl RegisterClientResponse {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_icd_counter: Option<u32> = None;
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
tag: Tag::Context(0),
value: Value::Uint(v),
}) => {
f_icd_counter = Some(
u32::try_from(v).map_err(|_| ClusterError::InvalidLength("IcdCounter"))?,
)
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(Self {
icd_counter: f_icd_counter.ok_or(ClusterError::MissingField("IcdCounter"))?,
})
}
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: "RegisterClientResponse",
})
}
}
Self::decode_from(&mut r)
}
}
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_unregister_client(
check_in_node_id: u64,
verification_key: Option<Vec<u8>>,
) -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
w.put_uint(Tag::Context(0), u64::from(check_in_node_id))
.expect("infallible: vec writer");
if let Some(verification_key) = verification_key {
w.put_bytes(Tag::Context(1), &verification_key)
.expect("infallible: vec writer");
}
w.end_container().expect("infallible: vec writer");
buf
}
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_stay_active_request(stay_active_duration: u32) -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
w.put_uint(Tag::Context(0), u64::from(stay_active_duration))
.expect("infallible: vec writer");
w.end_container().expect("infallible: vec writer");
buf
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct StayActiveResponse {
pub promised_active_duration: u32,
}
impl StayActiveResponse {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_promised_active_duration: Option<u32> = None;
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
tag: Tag::Context(0),
value: Value::Uint(v),
}) => {
f_promised_active_duration = Some(
u32::try_from(v)
.map_err(|_| ClusterError::InvalidLength("PromisedActiveDuration"))?,
)
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(Self {
promised_active_duration: f_promised_active_duration
.ok_or(ClusterError::MissingField("PromisedActiveDuration"))?,
})
}
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: "StayActiveResponse",
})
}
}
Self::decode_from(&mut r)
}
}