From fb82caf391c4643b71f758659c177efa29d1faad Mon Sep 17 00:00:00 2001 From: Kedar Sovani Date: Fri, 13 Jan 2023 11:05:24 +0530 Subject: [PATCH 1/3] data_model: provide an API for adding attributes in bulk --- .../data_model/cluster_basic_information.rs | 102 +++++++----------- matter/src/data_model/objects/attribute.rs | 2 +- matter/src/data_model/objects/cluster.rs | 11 +- .../src/data_model/system_model/descriptor.rs | 50 ++++----- 4 files changed, 73 insertions(+), 92 deletions(-) diff --git a/matter/src/data_model/cluster_basic_information.rs b/matter/src/data_model/cluster_basic_information.rs index eedd826..61eecef 100644 --- a/matter/src/data_model/cluster_basic_information.rs +++ b/matter/src/data_model/cluster_basic_information.rs @@ -42,59 +42,6 @@ pub struct BasicInfoConfig { pub device_name: String, } -fn attr_dm_rev_new() -> Result { - Attribute::new( - Attributes::DMRevision as u16, - AttrValue::Uint8(1), - Access::RV, - Quality::FIXED, - ) -} - -fn attr_vid_new(vid: u16) -> Result { - Attribute::new( - Attributes::VendorId as u16, - AttrValue::Uint16(vid), - Access::RV, - Quality::FIXED, - ) -} - -fn attr_pid_new(pid: u16) -> Result { - Attribute::new( - Attributes::ProductId as u16, - AttrValue::Uint16(pid), - Access::RV, - Quality::FIXED, - ) -} - -fn attr_hw_ver_new(hw_ver: u16) -> Result { - Attribute::new( - Attributes::HwVer as u16, - AttrValue::Uint16(hw_ver), - Access::RV, - Quality::FIXED, - ) -} - -fn attr_sw_ver_new(sw_ver: u32) -> Result { - Attribute::new( - Attributes::SwVer as u16, - AttrValue::Uint32(sw_ver), - Access::RV, - Quality::FIXED, - ) -} - -fn attr_serial_no_new(label: String) -> Result { - Attribute::new( - Attributes::SerialNo as u16, - AttrValue::Utf8(label), - Access::RV, - Quality::FIXED, - ) -} pub struct BasicInfoCluster { base: Cluster, } @@ -104,14 +51,47 @@ impl BasicInfoCluster { let mut cluster = Box::new(BasicInfoCluster { base: Cluster::new(ID)?, }); - cluster.base.add_attribute(attr_dm_rev_new()?)?; - cluster.base.add_attribute(attr_vid_new(cfg.vid)?)?; - cluster.base.add_attribute(attr_pid_new(cfg.pid)?)?; - cluster.base.add_attribute(attr_hw_ver_new(cfg.hw_ver)?)?; - cluster.base.add_attribute(attr_sw_ver_new(cfg.sw_ver)?)?; - cluster - .base - .add_attribute(attr_serial_no_new(cfg.serial_no)?)?; + + let attrs = [ + Attribute::new( + Attributes::DMRevision as u16, + AttrValue::Uint8(1), + Access::RV, + Quality::FIXED, + )?, + Attribute::new( + Attributes::VendorId as u16, + AttrValue::Uint16(cfg.vid), + Access::RV, + Quality::FIXED, + )?, + Attribute::new( + Attributes::ProductId as u16, + AttrValue::Uint16(cfg.pid), + Access::RV, + Quality::FIXED, + )?, + Attribute::new( + Attributes::HwVer as u16, + AttrValue::Uint16(cfg.hw_ver), + Access::RV, + Quality::FIXED, + )?, + Attribute::new( + Attributes::SwVer as u16, + AttrValue::Uint32(cfg.sw_ver), + Access::RV, + Quality::FIXED, + )?, + Attribute::new( + Attributes::SerialNo as u16, + AttrValue::Utf8(cfg.serial_no), + Access::RV, + Quality::FIXED, + )?, + ]; + cluster.base.add_attributes(&attrs[..])?; + Ok(cluster) } } diff --git a/matter/src/data_model/objects/attribute.rs b/matter/src/data_model/objects/attribute.rs index 0ffbc73..0f897e1 100644 --- a/matter/src/data_model/objects/attribute.rs +++ b/matter/src/data_model/objects/attribute.rs @@ -151,7 +151,7 @@ impl AttrValue { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Attribute { pub(super) id: u16, pub(super) value: AttrValue, diff --git a/matter/src/data_model/objects/cluster.rs b/matter/src/data_model/objects/cluster.rs index d279363..68a4860 100644 --- a/matter/src/data_model/objects/cluster.rs +++ b/matter/src/data_model/objects/cluster.rs @@ -30,7 +30,7 @@ use std::fmt::{self, Debug}; use super::Encoder; -pub const ATTRS_PER_CLUSTER: usize = 8; +pub const ATTRS_PER_CLUSTER: usize = 10; pub const CMDS_PER_CLUSTER: usize = 8; #[derive(FromPrimitive, Debug)] @@ -132,6 +132,15 @@ impl Cluster { )?) } + pub fn add_attributes(&mut self, attrs: &[Attribute]) -> Result<(), Error> { + if self.attributes.len() + attrs.len() <= self.attributes.capacity() { + self.attributes.extend_from_slice(attrs); + Ok(()) + } else { + Err(Error::NoSpace) + } + } + pub fn add_attribute(&mut self, attr: Attribute) -> Result<(), Error> { if self.attributes.len() < self.attributes.capacity() { self.attributes.push(attr); diff --git a/matter/src/data_model/system_model/descriptor.rs b/matter/src/data_model/system_model/descriptor.rs index 29fb15b..377b950 100644 --- a/matter/src/data_model/system_model/descriptor.rs +++ b/matter/src/data_model/system_model/descriptor.rs @@ -48,9 +48,27 @@ impl DescriptorCluster { data_model, base: Cluster::new(ID)?, }); - c.base.add_attribute(attr_devtypelist_new()?)?; - c.base.add_attribute(attr_serverlist_new()?)?; - c.base.add_attribute(attr_partslist_new()?)?; + let attrs = [ + Attribute::new( + Attributes::DeviceTypeList as u16, + AttrValue::Custom, + Access::RV, + Quality::NONE, + )?, + Attribute::new( + Attributes::ServerList as u16, + AttrValue::Custom, + Access::RV, + Quality::NONE, + )?, + Attribute::new( + Attributes::PartsList as u16, + AttrValue::Custom, + Access::RV, + Quality::NONE, + )?, + ]; + c.base.add_attributes(&attrs[..])?; Ok(c) } @@ -133,29 +151,3 @@ impl ClusterType for DescriptorCluster { } } } - -fn attr_devtypelist_new() -> Result { - Attribute::new( - Attributes::DeviceTypeList as u16, - AttrValue::Custom, - Access::RV, - Quality::NONE, - ) -} -fn attr_serverlist_new() -> Result { - Attribute::new( - Attributes::ServerList as u16, - AttrValue::Custom, - Access::RV, - Quality::NONE, - ) -} - -fn attr_partslist_new() -> Result { - Attribute::new( - Attributes::PartsList as u16, - AttrValue::Custom, - Access::RV, - Quality::NONE, - ) -} From a3b24c91fc0b51fe7add01b462799c5f623e5a67 Mon Sep 17 00:00:00 2001 From: Kedar Sovani Date: Fri, 13 Jan 2023 11:11:23 +0530 Subject: [PATCH 2/3] basic_info: Add Software Version String support --- examples/onoff_light/src/main.rs | 1 + matter/src/data_model/cluster_basic_information.rs | 8 ++++++++ matter/src/lib.rs | 1 + matter/tests/common/im_engine.rs | 1 + 4 files changed, 11 insertions(+) diff --git a/examples/onoff_light/src/main.rs b/examples/onoff_light/src/main.rs index ff86b68..2d64027 100644 --- a/examples/onoff_light/src/main.rs +++ b/examples/onoff_light/src/main.rs @@ -35,6 +35,7 @@ fn main() { pid: 0x8002, hw_ver: 2, sw_ver: 1, + sw_ver_str: "1".to_string(), serial_no: "aabbccdd".to_string(), device_name: "OnOff Light".to_string(), }; diff --git a/matter/src/data_model/cluster_basic_information.rs b/matter/src/data_model/cluster_basic_information.rs index 61eecef..3026138 100644 --- a/matter/src/data_model/cluster_basic_information.rs +++ b/matter/src/data_model/cluster_basic_information.rs @@ -28,6 +28,7 @@ enum Attributes { ProductId = 4, HwVer = 7, SwVer = 9, + SwVerString = 0xa, SerialNo = 0x0f, } @@ -37,6 +38,7 @@ pub struct BasicInfoConfig { pub pid: u16, pub hw_ver: u16, pub sw_ver: u32, + pub sw_ver_str: String, pub serial_no: String, /// Device name; up to 32 characters pub device_name: String, @@ -83,6 +85,12 @@ impl BasicInfoCluster { Access::RV, Quality::FIXED, )?, + Attribute::new( + Attributes::SwVerString as u16, + AttrValue::Utf8(cfg.sw_ver_str), + Access::RV, + Quality::FIXED, + )?, Attribute::new( Attributes::SerialNo as u16, AttrValue::Utf8(cfg.serial_no), diff --git a/matter/src/lib.rs b/matter/src/lib.rs index 4ca7e5a..f276961 100644 --- a/matter/src/lib.rs +++ b/matter/src/lib.rs @@ -49,6 +49,7 @@ //! pid: 0xFFF1, //! hw_ver: 2, //! sw_ver: 1, +//! sw_ver_str: "1".to_string(), //! serial_no: "aabbcc".to_string(), //! device_name: "OnOff Light".to_string(), //! }; diff --git a/matter/tests/common/im_engine.rs b/matter/tests/common/im_engine.rs index 2ee55c8..561c014 100644 --- a/matter/tests/common/im_engine.rs +++ b/matter/tests/common/im_engine.rs @@ -94,6 +94,7 @@ impl ImEngine { pid: 11, hw_ver: 12, sw_ver: 13, + sw_ver_str: "13".to_string(), serial_no: "aabbccdd".to_string(), device_name: "Test Device".to_string(), }; From 6fa4554d6d42c2bf8b3d951c1a2d596efea6260b Mon Sep 17 00:00:00 2001 From: Kedar Sovani Date: Fri, 20 Jan 2023 06:36:01 +0530 Subject: [PATCH 3/3] NOC: Add support for 2 attributes --- matter/src/data_model/sdm/noc.rs | 53 +++++++++++++++++++------------- matter/src/fabric.rs | 11 +++++++ 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/matter/src/data_model/sdm/noc.rs b/matter/src/data_model/sdm/noc.rs index c15f607..2d3beeb 100644 --- a/matter/src/data_model/sdm/noc.rs +++ b/matter/src/data_model/sdm/noc.rs @@ -23,7 +23,7 @@ use crate::cert::Cert; use crate::crypto::{self, CryptoKeyPair, KeyPair}; use crate::data_model::objects::*; use crate::data_model::sdm::dev_att; -use crate::fabric::{Fabric, FabricMgr}; +use crate::fabric::{Fabric, FabricMgr, MAX_SUPPORTED_FABRICS}; use crate::interaction_model::command::CommandReq; use crate::interaction_model::core::IMStatusCode; use crate::interaction_model::messages::ib; @@ -125,8 +125,33 @@ impl NocCluster { failsafe, base: Cluster::new(ID)?, }); - c.base.add_attribute(attr_currfabindex_new()?)?; - c.base.add_attribute(attr_fabrics_new()?)?; + let attrs = [ + Attribute::new( + Attributes::CurrentFabricIndex as u16, + AttrValue::Custom, + Access::RV, + Quality::NONE, + )?, + Attribute::new( + Attributes::Fabrics as u16, + AttrValue::Custom, + Access::RV | Access::FAB_SCOPED, + Quality::NONE, + )?, + Attribute::new( + Attributes::SupportedFabrics as u16, + AttrValue::Uint8(MAX_SUPPORTED_FABRICS as u8), + Access::RV, + Quality::FIXED, + )?, + Attribute::new( + Attributes::CommissionedFabrics as u16, + AttrValue::Custom, + Access::RV, + Quality::NONE, + )?, + ]; + c.base.add_attributes(&attrs[..])?; Ok(c) } @@ -389,24 +414,6 @@ impl NocCluster { } } -fn attr_currfabindex_new() -> Result { - Attribute::new( - Attributes::CurrentFabricIndex as u16, - AttrValue::Custom, - Access::RV, - Quality::NONE, - ) -} - -fn attr_fabrics_new() -> Result { - Attribute::new( - Attributes::Fabrics as u16, - AttrValue::Custom, - Access::RV | Access::FAB_SCOPED, - Quality::NONE, - ) -} - impl ClusterType for NocCluster { fn base(&self) -> &Cluster { &self.base @@ -450,6 +457,10 @@ impl ClusterType for NocCluster { }); let _ = tw.end_container(); })), + Some(Attributes::CommissionedFabrics) => { + let count = self.fabric_mgr.used_count() as u8; + encoder.encode(EncodeValue::Value(&count)) + } _ => { error!("Attribute not supported: this shouldn't happen"); } diff --git a/matter/src/fabric.rs b/matter/src/fabric.rs index bb729ae..c5a2ce6 100644 --- a/matter/src/fabric.rs +++ b/matter/src/fabric.rs @@ -364,6 +364,17 @@ impl FabricMgr { true } + pub fn used_count(&self) -> usize { + let mgr = self.inner.read().unwrap(); + let mut count = 0; + for i in 1..MAX_SUPPORTED_FABRICS { + if mgr.fabrics[i].is_some() { + count += 1; + } + } + count + } + // Parameters to T are the Fabric and its Fabric Index pub fn for_each(&self, mut f: T) -> Result<(), Error> where