Merge pull request #13 from kedars/feature/data-model-updates

Support more common cluster attributes
This commit is contained in:
Kedar Sovani 2023-01-28 09:39:41 +05:30 committed by GitHub
commit 690e396914
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 127 additions and 113 deletions

View file

@ -35,6 +35,7 @@ fn main() {
pid: 0x8002, pid: 0x8002,
hw_ver: 2, hw_ver: 2,
sw_ver: 1, sw_ver: 1,
sw_ver_str: "1".to_string(),
serial_no: "aabbccdd".to_string(), serial_no: "aabbccdd".to_string(),
device_name: "OnOff Light".to_string(), device_name: "OnOff Light".to_string(),
}; };

View file

@ -28,6 +28,7 @@ enum Attributes {
ProductId = 4, ProductId = 4,
HwVer = 7, HwVer = 7,
SwVer = 9, SwVer = 9,
SwVerString = 0xa,
SerialNo = 0x0f, SerialNo = 0x0f,
} }
@ -37,64 +38,12 @@ pub struct BasicInfoConfig {
pub pid: u16, pub pid: u16,
pub hw_ver: u16, pub hw_ver: u16,
pub sw_ver: u32, pub sw_ver: u32,
pub sw_ver_str: String,
pub serial_no: String, pub serial_no: String,
/// Device name; up to 32 characters /// Device name; up to 32 characters
pub device_name: String, pub device_name: String,
} }
fn attr_dm_rev_new() -> Result<Attribute, Error> {
Attribute::new(
Attributes::DMRevision as u16,
AttrValue::Uint8(1),
Access::RV,
Quality::FIXED,
)
}
fn attr_vid_new(vid: u16) -> Result<Attribute, Error> {
Attribute::new(
Attributes::VendorId as u16,
AttrValue::Uint16(vid),
Access::RV,
Quality::FIXED,
)
}
fn attr_pid_new(pid: u16) -> Result<Attribute, Error> {
Attribute::new(
Attributes::ProductId as u16,
AttrValue::Uint16(pid),
Access::RV,
Quality::FIXED,
)
}
fn attr_hw_ver_new(hw_ver: u16) -> Result<Attribute, Error> {
Attribute::new(
Attributes::HwVer as u16,
AttrValue::Uint16(hw_ver),
Access::RV,
Quality::FIXED,
)
}
fn attr_sw_ver_new(sw_ver: u32) -> Result<Attribute, Error> {
Attribute::new(
Attributes::SwVer as u16,
AttrValue::Uint32(sw_ver),
Access::RV,
Quality::FIXED,
)
}
fn attr_serial_no_new(label: String) -> Result<Attribute, Error> {
Attribute::new(
Attributes::SerialNo as u16,
AttrValue::Utf8(label),
Access::RV,
Quality::FIXED,
)
}
pub struct BasicInfoCluster { pub struct BasicInfoCluster {
base: Cluster, base: Cluster,
} }
@ -104,14 +53,53 @@ impl BasicInfoCluster {
let mut cluster = Box::new(BasicInfoCluster { let mut cluster = Box::new(BasicInfoCluster {
base: Cluster::new(ID)?, base: Cluster::new(ID)?,
}); });
cluster.base.add_attribute(attr_dm_rev_new()?)?;
cluster.base.add_attribute(attr_vid_new(cfg.vid)?)?; let attrs = [
cluster.base.add_attribute(attr_pid_new(cfg.pid)?)?; Attribute::new(
cluster.base.add_attribute(attr_hw_ver_new(cfg.hw_ver)?)?; Attributes::DMRevision as u16,
cluster.base.add_attribute(attr_sw_ver_new(cfg.sw_ver)?)?; AttrValue::Uint8(1),
cluster Access::RV,
.base Quality::FIXED,
.add_attribute(attr_serial_no_new(cfg.serial_no)?)?; )?,
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::SwVerString as u16,
AttrValue::Utf8(cfg.sw_ver_str),
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) Ok(cluster)
} }
} }

View file

@ -151,7 +151,7 @@ impl AttrValue {
} }
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct Attribute { pub struct Attribute {
pub(super) id: u16, pub(super) id: u16,
pub(super) value: AttrValue, pub(super) value: AttrValue,

View file

@ -30,7 +30,7 @@ use std::fmt::{self, Debug};
use super::Encoder; use super::Encoder;
pub const ATTRS_PER_CLUSTER: usize = 8; pub const ATTRS_PER_CLUSTER: usize = 10;
pub const CMDS_PER_CLUSTER: usize = 8; pub const CMDS_PER_CLUSTER: usize = 8;
#[derive(FromPrimitive, Debug)] #[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> { pub fn add_attribute(&mut self, attr: Attribute) -> Result<(), Error> {
if self.attributes.len() < self.attributes.capacity() { if self.attributes.len() < self.attributes.capacity() {
self.attributes.push(attr); self.attributes.push(attr);

View file

@ -23,7 +23,7 @@ use crate::cert::Cert;
use crate::crypto::{self, CryptoKeyPair, KeyPair}; use crate::crypto::{self, CryptoKeyPair, KeyPair};
use crate::data_model::objects::*; use crate::data_model::objects::*;
use crate::data_model::sdm::dev_att; 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::command::CommandReq;
use crate::interaction_model::core::IMStatusCode; use crate::interaction_model::core::IMStatusCode;
use crate::interaction_model::messages::ib; use crate::interaction_model::messages::ib;
@ -125,8 +125,33 @@ impl NocCluster {
failsafe, failsafe,
base: Cluster::new(ID)?, base: Cluster::new(ID)?,
}); });
c.base.add_attribute(attr_currfabindex_new()?)?; let attrs = [
c.base.add_attribute(attr_fabrics_new()?)?; 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) Ok(c)
} }
@ -389,24 +414,6 @@ impl NocCluster {
} }
} }
fn attr_currfabindex_new() -> Result<Attribute, Error> {
Attribute::new(
Attributes::CurrentFabricIndex as u16,
AttrValue::Custom,
Access::RV,
Quality::NONE,
)
}
fn attr_fabrics_new() -> Result<Attribute, Error> {
Attribute::new(
Attributes::Fabrics as u16,
AttrValue::Custom,
Access::RV | Access::FAB_SCOPED,
Quality::NONE,
)
}
impl ClusterType for NocCluster { impl ClusterType for NocCluster {
fn base(&self) -> &Cluster { fn base(&self) -> &Cluster {
&self.base &self.base
@ -450,6 +457,10 @@ impl ClusterType for NocCluster {
}); });
let _ = tw.end_container(); 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"); error!("Attribute not supported: this shouldn't happen");
} }

View file

@ -48,9 +48,27 @@ impl DescriptorCluster {
data_model, data_model,
base: Cluster::new(ID)?, base: Cluster::new(ID)?,
}); });
c.base.add_attribute(attr_devtypelist_new()?)?; let attrs = [
c.base.add_attribute(attr_serverlist_new()?)?; Attribute::new(
c.base.add_attribute(attr_partslist_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) Ok(c)
} }
@ -133,29 +151,3 @@ impl ClusterType for DescriptorCluster {
} }
} }
} }
fn attr_devtypelist_new() -> Result<Attribute, Error> {
Attribute::new(
Attributes::DeviceTypeList as u16,
AttrValue::Custom,
Access::RV,
Quality::NONE,
)
}
fn attr_serverlist_new() -> Result<Attribute, Error> {
Attribute::new(
Attributes::ServerList as u16,
AttrValue::Custom,
Access::RV,
Quality::NONE,
)
}
fn attr_partslist_new() -> Result<Attribute, Error> {
Attribute::new(
Attributes::PartsList as u16,
AttrValue::Custom,
Access::RV,
Quality::NONE,
)
}

View file

@ -364,6 +364,17 @@ impl FabricMgr {
true 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 // Parameters to T are the Fabric and its Fabric Index
pub fn for_each<T>(&self, mut f: T) -> Result<(), Error> pub fn for_each<T>(&self, mut f: T) -> Result<(), Error>
where where

View file

@ -49,6 +49,7 @@
//! pid: 0xFFF1, //! pid: 0xFFF1,
//! hw_ver: 2, //! hw_ver: 2,
//! sw_ver: 1, //! sw_ver: 1,
//! sw_ver_str: "1".to_string(),
//! serial_no: "aabbcc".to_string(), //! serial_no: "aabbcc".to_string(),
//! device_name: "OnOff Light".to_string(), //! device_name: "OnOff Light".to_string(),
//! }; //! };

View file

@ -94,6 +94,7 @@ impl ImEngine {
pid: 11, pid: 11,
hw_ver: 12, hw_ver: 12,
sw_ver: 13, sw_ver: 13,
sw_ver_str: "13".to_string(),
serial_no: "aabbccdd".to_string(), serial_no: "aabbccdd".to_string(),
device_name: "Test Device".to_string(), device_name: "Test Device".to_string(),
}; };