Merge pull request #13 from kedars/feature/data-model-updates
Support more common cluster attributes
This commit is contained in:
commit
690e396914
9 changed files with 127 additions and 113 deletions
|
@ -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(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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(),
|
||||||
//! };
|
//! };
|
||||||
|
|
|
@ -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(),
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue