From faf3c609463ea2e047c897355cfa30ae1abdc266 Mon Sep 17 00:00:00 2001 From: Kedar Sovani Date: Tue, 1 Aug 2023 11:49:01 +0530 Subject: [PATCH] Placeholder clusters that show in 'server-list' to make iOS happy --- rs-matter/src/data_model/root_endpoint.rs | 29 +++- .../data_model/sdm/ethernet_nw_diagnostics.rs | 146 ++++++++++++++++ .../src/data_model/sdm/general_diagnostics.rs | 157 +++++++++++++++++ .../data_model/sdm/group_key_management.rs | 164 ++++++++++++++++++ rs-matter/src/data_model/sdm/mod.rs | 3 + 5 files changed, 497 insertions(+), 2 deletions(-) create mode 100644 rs-matter/src/data_model/sdm/ethernet_nw_diagnostics.rs create mode 100644 rs-matter/src/data_model/sdm/general_diagnostics.rs create mode 100644 rs-matter/src/data_model/sdm/group_key_management.rs diff --git a/rs-matter/src/data_model/root_endpoint.rs b/rs-matter/src/data_model/root_endpoint.rs index 69df3bd..b39e12f 100644 --- a/rs-matter/src/data_model/root_endpoint.rs +++ b/rs-matter/src/data_model/root_endpoint.rs @@ -15,8 +15,12 @@ use super::{ sdm::{ admin_commissioning::{self, AdminCommCluster}, dev_att::DevAttDataFetcher, + ethernet_nw_diagnostics::{self, EthNwDiagCluster}, failsafe::FailSafe, general_commissioning::{self, GenCommCluster}, + general_diagnostics::{self, GenDiagCluster}, + group_key_management, + group_key_management::GrpKeyMgmtCluster, noc::{self, NocCluster}, nw_commissioning::{self, NwCommCluster}, }, @@ -33,10 +37,13 @@ pub type RootEndpointHandler<'a> = handler_chain_type!( NwCommCluster, AdminCommCluster<'a>, NocCluster<'a>, - AccessControlCluster<'a> + AccessControlCluster<'a>, + GenDiagCluster, + EthNwDiagCluster, + GrpKeyMgmtCluster ); -pub const CLUSTERS: [Cluster<'static>; 7] = [ +pub const CLUSTERS: [Cluster<'static>; 10] = [ descriptor::CLUSTER, cluster_basic_information::CLUSTER, general_commissioning::CLUSTER, @@ -44,6 +51,9 @@ pub const CLUSTERS: [Cluster<'static>; 7] = [ admin_commissioning::CLUSTER, noc::CLUSTER, access_control::CLUSTER, + general_diagnostics::CLUSTER, + ethernet_nw_diagnostics::CLUSTER, + group_key_management::CLUSTER, ]; pub const fn endpoint(id: EndptId) -> Endpoint<'static> { @@ -95,6 +105,21 @@ pub fn wrap<'a>( rand: Rand, ) -> RootEndpointHandler<'a> { EmptyHandler + .chain( + endpoint_id, + group_key_management::ID, + GrpKeyMgmtCluster::new(rand), + ) + .chain( + endpoint_id, + ethernet_nw_diagnostics::ID, + EthNwDiagCluster::new(rand), + ) + .chain( + endpoint_id, + general_diagnostics::ID, + GenDiagCluster::new(rand), + ) .chain( endpoint_id, access_control::ID, diff --git a/rs-matter/src/data_model/sdm/ethernet_nw_diagnostics.rs b/rs-matter/src/data_model/sdm/ethernet_nw_diagnostics.rs new file mode 100644 index 0000000..83ea376 --- /dev/null +++ b/rs-matter/src/data_model/sdm/ethernet_nw_diagnostics.rs @@ -0,0 +1,146 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use core::convert::TryInto; + +use crate::{ + attribute_enum, cmd_enter, command_enum, data_model::objects::AttrType, data_model::objects::*, + error::Error, tlv::TLVElement, transport::exchange::Exchange, utils::rand::Rand, +}; +use log::info; +use strum::{EnumDiscriminants, FromRepr}; + +pub const ID: u32 = 0x0037; + +#[derive(FromRepr, EnumDiscriminants)] +#[repr(u16)] +pub enum Attributes { + PacketRxCount(AttrType) = 0x02, + PacketTxCount(AttrType) = 0x03, +} + +attribute_enum!(Attributes); + +#[derive(FromRepr, EnumDiscriminants)] +#[repr(u32)] +pub enum Commands { + ResetCounts = 0x0, +} + +command_enum!(Commands); + +pub const CLUSTER: Cluster<'static> = Cluster { + id: ID as _, + feature_map: 0, + attributes: &[ + FEATURE_MAP, + ATTRIBUTE_LIST, + Attribute::new( + AttributesDiscriminants::PacketRxCount as u16, + Access::RV, + Quality::NONE, + ), + Attribute::new( + AttributesDiscriminants::PacketTxCount as u16, + Access::RV, + Quality::FIXED, + ), + ], + commands: &[CommandsDiscriminants::ResetCounts as _], +}; + +pub struct EthNwDiagCluster { + data_ver: Dataver, +} + +impl EthNwDiagCluster { + pub fn new(rand: Rand) -> Self { + Self { + data_ver: Dataver::new(rand), + } + } + + pub fn read(&self, attr: &AttrDetails, encoder: AttrDataEncoder) -> Result<(), Error> { + if let Some(writer) = encoder.with_dataver(self.data_ver.get())? { + if attr.is_system() { + CLUSTER.read(attr.attr_id, writer) + } else { + match attr.attr_id.try_into()? { + Attributes::PacketRxCount(codec) => codec.encode(writer, 1), + Attributes::PacketTxCount(codec) => codec.encode(writer, 1), + } + } + } else { + Ok(()) + } + } + + pub fn write(&self, _attr: &AttrDetails, data: AttrData) -> Result<(), Error> { + let _data = data.with_dataver(self.data_ver.get())?; + + self.data_ver.changed(); + + Ok(()) + } + + pub fn invoke( + &self, + _exchange: &Exchange, + cmd: &CmdDetails, + _data: &TLVElement, + _encoder: CmdDataEncoder, + ) -> Result<(), Error> { + match cmd.cmd_id.try_into()? { + Commands::ResetCounts => { + cmd_enter!("ResetCounts: Not yet supported"); + } + } + + self.data_ver.changed(); + + Ok(()) + } +} + +impl Handler for EthNwDiagCluster { + fn read(&self, attr: &AttrDetails, encoder: AttrDataEncoder) -> Result<(), Error> { + EthNwDiagCluster::read(self, attr, encoder) + } + + fn write(&self, attr: &AttrDetails, data: AttrData) -> Result<(), Error> { + EthNwDiagCluster::write(self, attr, data) + } + + fn invoke( + &self, + exchange: &Exchange, + cmd: &CmdDetails, + data: &TLVElement, + encoder: CmdDataEncoder, + ) -> Result<(), Error> { + EthNwDiagCluster::invoke(self, exchange, cmd, data, encoder) + } +} + +// TODO: Might be removed once the `on` member is externalized +impl NonBlockingHandler for EthNwDiagCluster {} + +impl ChangeNotifier<()> for EthNwDiagCluster { + fn consume_change(&mut self) -> Option<()> { + self.data_ver.consume_change(()) + } +} diff --git a/rs-matter/src/data_model/sdm/general_diagnostics.rs b/rs-matter/src/data_model/sdm/general_diagnostics.rs new file mode 100644 index 0000000..091c165 --- /dev/null +++ b/rs-matter/src/data_model/sdm/general_diagnostics.rs @@ -0,0 +1,157 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use core::convert::TryInto; + +use crate::{ + attribute_enum, cmd_enter, command_enum, + data_model::objects::AttrType, + data_model::objects::*, + error::{Error, ErrorCode}, + tlv::TLVElement, + transport::exchange::Exchange, + utils::rand::Rand, +}; +use log::info; +use strum::{EnumDiscriminants, FromRepr}; + +pub const ID: u32 = 0x0033; + +#[derive(FromRepr, EnumDiscriminants)] +#[repr(u16)] +pub enum Attributes { + NetworkInterfaces(()) = 0x00, + RebootCount(AttrType) = 0x01, + TestEventTriggersEnabled(AttrType) = 0x08, +} + +attribute_enum!(Attributes); + +#[derive(FromRepr, EnumDiscriminants)] +#[repr(u32)] +pub enum Commands { + TestEventTrigger = 0x0, +} + +command_enum!(Commands); + +pub const CLUSTER: Cluster<'static> = Cluster { + id: ID as _, + feature_map: 0, + attributes: &[ + FEATURE_MAP, + ATTRIBUTE_LIST, + Attribute::new( + AttributesDiscriminants::NetworkInterfaces as u16, + Access::RV, + Quality::NONE, + ), + Attribute::new( + AttributesDiscriminants::RebootCount as u16, + Access::RV, + Quality::PERSISTENT, + ), + Attribute::new( + AttributesDiscriminants::TestEventTriggersEnabled as u16, + Access::RV, + Quality::NONE, + ), + ], + commands: &[CommandsDiscriminants::TestEventTrigger as _], +}; + +pub struct GenDiagCluster { + data_ver: Dataver, +} + +impl GenDiagCluster { + pub fn new(rand: Rand) -> Self { + Self { + data_ver: Dataver::new(rand), + } + } + + pub fn read(&self, attr: &AttrDetails, encoder: AttrDataEncoder) -> Result<(), Error> { + if let Some(writer) = encoder.with_dataver(self.data_ver.get())? { + if attr.is_system() { + CLUSTER.read(attr.attr_id, writer) + } else { + match attr.attr_id.try_into()? { + Attributes::RebootCount(codec) => codec.encode(writer, 1), + _ => Err(ErrorCode::AttributeNotFound.into()), + } + } + } else { + Ok(()) + } + } + + pub fn write(&self, _attr: &AttrDetails, data: AttrData) -> Result<(), Error> { + let _data = data.with_dataver(self.data_ver.get())?; + + self.data_ver.changed(); + + Ok(()) + } + + pub fn invoke( + &self, + _exchange: &Exchange, + cmd: &CmdDetails, + _data: &TLVElement, + _encoder: CmdDataEncoder, + ) -> Result<(), Error> { + match cmd.cmd_id.try_into()? { + Commands::TestEventTrigger => { + cmd_enter!("TestEventTrigger: Not yet supported"); + } + } + + self.data_ver.changed(); + + Ok(()) + } +} + +impl Handler for GenDiagCluster { + fn read(&self, attr: &AttrDetails, encoder: AttrDataEncoder) -> Result<(), Error> { + GenDiagCluster::read(self, attr, encoder) + } + + fn write(&self, attr: &AttrDetails, data: AttrData) -> Result<(), Error> { + GenDiagCluster::write(self, attr, data) + } + + fn invoke( + &self, + exchange: &Exchange, + cmd: &CmdDetails, + data: &TLVElement, + encoder: CmdDataEncoder, + ) -> Result<(), Error> { + GenDiagCluster::invoke(self, exchange, cmd, data, encoder) + } +} + +// TODO: Might be removed once the `on` member is externalized +impl NonBlockingHandler for GenDiagCluster {} + +impl ChangeNotifier<()> for GenDiagCluster { + fn consume_change(&mut self) -> Option<()> { + self.data_ver.consume_change(()) + } +} diff --git a/rs-matter/src/data_model/sdm/group_key_management.rs b/rs-matter/src/data_model/sdm/group_key_management.rs new file mode 100644 index 0000000..64a9fd0 --- /dev/null +++ b/rs-matter/src/data_model/sdm/group_key_management.rs @@ -0,0 +1,164 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use core::convert::TryInto; + +use crate::{ + attribute_enum, cmd_enter, command_enum, + data_model::objects::AttrType, + data_model::objects::*, + error::{Error, ErrorCode}, + tlv::TLVElement, + transport::exchange::Exchange, + utils::rand::Rand, +}; +use log::info; +use strum::{EnumDiscriminants, FromRepr}; + +pub const ID: u32 = 0x003F; + +#[derive(FromRepr, EnumDiscriminants)] +#[repr(u16)] +pub enum Attributes { + GroupKeyMap(()) = 0x00, + GroupTable(()) = 0x01, + MaxGroupsPerFabric(AttrType) = 0x02, + MaxGroupKeysPerFabric(AttrType) = 0x03, +} + +attribute_enum!(Attributes); + +#[derive(FromRepr, EnumDiscriminants)] +#[repr(u32)] +pub enum Commands { + KeySetWrite = 0x0, +} + +command_enum!(Commands); + +pub const CLUSTER: Cluster<'static> = Cluster { + id: ID as _, + feature_map: 0, + attributes: &[ + FEATURE_MAP, + ATTRIBUTE_LIST, + Attribute::new( + AttributesDiscriminants::GroupKeyMap as u16, + Access::RWFVM, + Quality::PERSISTENT, + ), + Attribute::new( + AttributesDiscriminants::GroupTable as u16, + Access::RF, + Quality::NONE, + ), + Attribute::new( + AttributesDiscriminants::MaxGroupsPerFabric as u16, + Access::READ, + Quality::FIXED, + ), + Attribute::new( + AttributesDiscriminants::MaxGroupKeysPerFabric as u16, + Access::READ, + Quality::FIXED, + ), + ], + commands: &[CommandsDiscriminants::KeySetWrite as _], +}; + +pub struct GrpKeyMgmtCluster { + data_ver: Dataver, +} + +impl GrpKeyMgmtCluster { + pub fn new(rand: Rand) -> Self { + Self { + data_ver: Dataver::new(rand), + } + } + + pub fn read(&self, attr: &AttrDetails, encoder: AttrDataEncoder) -> Result<(), Error> { + if let Some(writer) = encoder.with_dataver(self.data_ver.get())? { + if attr.is_system() { + CLUSTER.read(attr.attr_id, writer) + } else { + match attr.attr_id.try_into()? { + Attributes::MaxGroupsPerFabric(codec) => codec.encode(writer, 1), + Attributes::MaxGroupKeysPerFabric(codec) => codec.encode(writer, 1), + _ => Err(ErrorCode::AttributeNotFound.into()), + } + } + } else { + Ok(()) + } + } + + pub fn write(&self, _attr: &AttrDetails, data: AttrData) -> Result<(), Error> { + let _data = data.with_dataver(self.data_ver.get())?; + + self.data_ver.changed(); + + Ok(()) + } + + pub fn invoke( + &self, + _exchange: &Exchange, + cmd: &CmdDetails, + _data: &TLVElement, + _encoder: CmdDataEncoder, + ) -> Result<(), Error> { + match cmd.cmd_id.try_into()? { + Commands::KeySetWrite => { + cmd_enter!("KeySetWrite: Not yet supported"); + } + } + + self.data_ver.changed(); + + Ok(()) + } +} + +impl Handler for GrpKeyMgmtCluster { + fn read(&self, attr: &AttrDetails, encoder: AttrDataEncoder) -> Result<(), Error> { + GrpKeyMgmtCluster::read(self, attr, encoder) + } + + fn write(&self, attr: &AttrDetails, data: AttrData) -> Result<(), Error> { + GrpKeyMgmtCluster::write(self, attr, data) + } + + fn invoke( + &self, + exchange: &Exchange, + cmd: &CmdDetails, + data: &TLVElement, + encoder: CmdDataEncoder, + ) -> Result<(), Error> { + GrpKeyMgmtCluster::invoke(self, exchange, cmd, data, encoder) + } +} + +// TODO: Might be removed once the `on` member is externalized +impl NonBlockingHandler for GrpKeyMgmtCluster {} + +impl ChangeNotifier<()> for GrpKeyMgmtCluster { + fn consume_change(&mut self) -> Option<()> { + self.data_ver.consume_change(()) + } +} diff --git a/rs-matter/src/data_model/sdm/mod.rs b/rs-matter/src/data_model/sdm/mod.rs index 1ce25ad..8a87277 100644 --- a/rs-matter/src/data_model/sdm/mod.rs +++ b/rs-matter/src/data_model/sdm/mod.rs @@ -17,7 +17,10 @@ pub mod admin_commissioning; pub mod dev_att; +pub mod ethernet_nw_diagnostics; pub mod failsafe; pub mod general_commissioning; +pub mod general_diagnostics; +pub mod group_key_management; pub mod noc; pub mod nw_commissioning;