#![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 = 0x0029;
pub const CLUSTER_REVISION: u16 = 1;
pub mod command_id {
pub const QUERY_IMAGE: u32 = 0x00;
pub const QUERY_IMAGE_RESPONSE: u32 = 0x01;
pub const APPLY_UPDATE_REQUEST: u32 = 0x02;
pub const APPLY_UPDATE_RESPONSE: u32 = 0x03;
pub const NOTIFY_UPDATE_APPLIED: u32 = 0x04;
}
pub mod attribute_id {}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ApplyUpdateActionEnum {
Proceed,
AwaitNextAction,
Discontinue,
Unknown(u8),
}
impl ApplyUpdateActionEnum {
#[must_use]
pub fn from_raw(v: u8) -> Self {
match v {
0 => Self::Proceed,
1 => Self::AwaitNextAction,
2 => Self::Discontinue,
other => Self::Unknown(other),
}
}
#[must_use]
pub fn to_raw(self) -> u8 {
match self {
Self::Proceed => 0,
Self::AwaitNextAction => 1,
Self::Discontinue => 2,
Self::Unknown(v) => v,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum DownloadProtocolEnum {
BdxSynchronous,
BdxAsynchronous,
Https,
VendorSpecific,
Unknown(u8),
}
impl DownloadProtocolEnum {
#[must_use]
pub fn from_raw(v: u8) -> Self {
match v {
0 => Self::BdxSynchronous,
1 => Self::BdxAsynchronous,
2 => Self::Https,
3 => Self::VendorSpecific,
other => Self::Unknown(other),
}
}
#[must_use]
pub fn to_raw(self) -> u8 {
match self {
Self::BdxSynchronous => 0,
Self::BdxAsynchronous => 1,
Self::Https => 2,
Self::VendorSpecific => 3,
Self::Unknown(v) => v,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum StatusEnum {
UpdateAvailable,
Busy,
NotAvailable,
DownloadProtocolNotSupported,
Unknown(u8),
}
impl StatusEnum {
#[must_use]
pub fn from_raw(v: u8) -> Self {
match v {
0 => Self::UpdateAvailable,
1 => Self::Busy,
2 => Self::NotAvailable,
3 => Self::DownloadProtocolNotSupported,
other => Self::Unknown(other),
}
}
#[must_use]
pub fn to_raw(self) -> u8 {
match self {
Self::UpdateAvailable => 0,
Self::Busy => 1,
Self::NotAvailable => 2,
Self::DownloadProtocolNotSupported => 3,
Self::Unknown(v) => v,
}
}
}
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_query_image(
vendor_id: u16,
product_id: u16,
software_version: u32,
protocols_supported: &Vec<DownloadProtocolEnum>,
hardware_version: Option<u16>,
location: Option<String>,
requestor_can_consent: Option<bool>,
metadata_for_provider: 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(vendor_id))
.expect("infallible: vec writer");
w.put_uint(Tag::Context(1), u64::from(product_id))
.expect("infallible: vec writer");
w.put_uint(Tag::Context(2), u64::from(software_version))
.expect("infallible: vec writer");
w.start_array(Tag::Context(3))
.expect("infallible: vec writer");
for el in protocols_supported.iter().copied() {
w.put_uint(Tag::Anonymous, u64::from(el.to_raw()))
.expect("infallible: vec writer");
}
w.end_container().expect("infallible: vec writer");
if let Some(hardware_version) = hardware_version {
w.put_uint(Tag::Context(4), u64::from(hardware_version))
.expect("infallible: vec writer");
}
if let Some(location) = location {
w.put_utf8(Tag::Context(5), &location)
.expect("infallible: vec writer");
}
if let Some(requestor_can_consent) = requestor_can_consent {
w.put_bool(Tag::Context(6), requestor_can_consent)
.expect("infallible: vec writer");
}
if let Some(metadata_for_provider) = metadata_for_provider {
w.put_bytes(Tag::Context(7), &metadata_for_provider)
.expect("infallible: vec writer");
}
w.end_container().expect("infallible: vec writer");
buf
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct QueryImageResponse {
pub status: StatusEnum,
pub delayed_action_time: Option<u32>,
pub image_uri: Option<String>,
pub software_version: Option<u32>,
pub software_version_string: Option<String>,
pub update_token: Option<Vec<u8>>,
pub user_consent_needed: Option<bool>,
pub metadata_for_requestor: Option<Vec<u8>>,
}
impl QueryImageResponse {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_status: Option<StatusEnum> = None;
let mut f_delayed_action_time: Option<u32> = None;
let mut f_image_uri: Option<String> = None;
let mut f_software_version: Option<u32> = None;
let mut f_software_version_string: Option<String> = None;
let mut f_update_token: Option<Vec<u8>> = None;
let mut f_user_consent_needed: Option<bool> = None;
let mut f_metadata_for_requestor: Option<Vec<u8>> = None;
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
tag: Tag::Context(0),
value: Value::Uint(v),
}) => {
f_status = Some(StatusEnum::from_raw(
u8::try_from(v).map_err(|_| ClusterError::InvalidLength("Status"))?,
))
}
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Uint(v),
}) => {
f_delayed_action_time = Some(
u32::try_from(v)
.map_err(|_| ClusterError::InvalidLength("DelayedActionTime"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(2),
value: Value::Utf8(v),
}) => f_image_uri = Some(v),
Some(Element::Scalar {
tag: Tag::Context(3),
value: Value::Uint(v),
}) => {
f_software_version = Some(
u32::try_from(v)
.map_err(|_| ClusterError::InvalidLength("SoftwareVersion"))?,
)
}
Some(Element::Scalar {
tag: Tag::Context(4),
value: Value::Utf8(v),
}) => f_software_version_string = Some(v),
Some(Element::Scalar {
tag: Tag::Context(5),
value: Value::Bytes(v),
}) => f_update_token = Some(v),
Some(Element::Scalar {
tag: Tag::Context(6),
value: Value::Bool(v),
}) => f_user_consent_needed = Some(v),
Some(Element::Scalar {
tag: Tag::Context(7),
value: Value::Bytes(v),
}) => f_metadata_for_requestor = Some(v),
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(Self {
status: f_status.ok_or(ClusterError::MissingField("Status"))?,
delayed_action_time: f_delayed_action_time,
image_uri: f_image_uri,
software_version: f_software_version,
software_version_string: f_software_version_string,
update_token: f_update_token,
user_consent_needed: f_user_consent_needed,
metadata_for_requestor: f_metadata_for_requestor,
})
}
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: "QueryImageResponse",
})
}
}
Self::decode_from(&mut r)
}
}
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_apply_update_request(update_token: &Vec<u8>, new_version: 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_bytes(Tag::Context(0), &update_token)
.expect("infallible: vec writer");
w.put_uint(Tag::Context(1), u64::from(new_version))
.expect("infallible: vec writer");
w.end_container().expect("infallible: vec writer");
buf
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct ApplyUpdateResponse {
pub action: ApplyUpdateActionEnum,
pub delayed_action_time: u32,
}
impl ApplyUpdateResponse {
pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
let mut f_action: Option<ApplyUpdateActionEnum> = None;
let mut f_delayed_action_time: Option<u32> = None;
loop {
match r.next()? {
Some(Element::ContainerEnd) => break,
Some(Element::Scalar {
tag: Tag::Context(0),
value: Value::Uint(v),
}) => {
f_action = Some(ApplyUpdateActionEnum::from_raw(
u8::try_from(v).map_err(|_| ClusterError::InvalidLength("Action"))?,
))
}
Some(Element::Scalar {
tag: Tag::Context(1),
value: Value::Uint(v),
}) => {
f_delayed_action_time = Some(
u32::try_from(v)
.map_err(|_| ClusterError::InvalidLength("DelayedActionTime"))?,
)
}
None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
Some(Element::ContainerStart { .. }) => r.skip_container()?,
Some(_) => {} }
}
Ok(Self {
action: f_action.ok_or(ClusterError::MissingField("Action"))?,
delayed_action_time: f_delayed_action_time
.ok_or(ClusterError::MissingField("DelayedActionTime"))?,
})
}
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: "ApplyUpdateResponse",
})
}
}
Self::decode_from(&mut r)
}
}
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_notify_update_applied(update_token: &Vec<u8>, software_version: 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_bytes(Tag::Context(0), &update_token)
.expect("infallible: vec writer");
w.put_uint(Tag::Context(1), u64::from(software_version))
.expect("infallible: vec writer");
w.end_container().expect("infallible: vec writer");
buf
}