Implemented the Clippy recommendations

This commit is contained in:
Marcel 2023-01-10 08:53:04 +01:00
parent a4915bb0d6
commit b477a871e9
46 changed files with 240 additions and 247 deletions

View file

@ -15,7 +15,6 @@
* limitations under the License. * limitations under the License.
*/ */
use std::{ use std::{
mem::MaybeUninit, mem::MaybeUninit,
ops::{Deref, DerefMut}, ops::{Deref, DerefMut},
@ -115,7 +114,7 @@ impl<T: SlabPool> Slab<T> {
})) }))
} }
pub fn new(new_object: T::SlabType) -> Option<BoxSlab<T>> { pub fn try_new(new_object: T::SlabType) -> Option<BoxSlab<T>> {
let slab = T::get_slab(); let slab = T::get_slab();
let mut inner = slab.0.lock().unwrap(); let mut inner = slab.0.lock().unwrap();
if let Some(index) = inner.map.first_false_index() { if let Some(index) = inner.map.first_false_index() {
@ -180,14 +179,14 @@ mod tests {
#[test] #[test]
fn simple_alloc_free() { fn simple_alloc_free() {
{ {
let a = Slab::<TestSlab>::new(Test { val: Arc::new(10) }).unwrap(); let a = Slab::<TestSlab>::try_new(Test { val: Arc::new(10) }).unwrap();
assert_eq!(*a.val.deref(), 10); assert_eq!(*a.val.deref(), 10);
let inner = TestSlab::get_slab().0.lock().unwrap(); let inner = TestSlab::get_slab().0.lock().unwrap();
assert_eq!(inner.map.is_empty(), false); assert!(!inner.map.is_empty());
} }
// Validates that the 'Drop' got executed // Validates that the 'Drop' got executed
let inner = TestSlab::get_slab().0.lock().unwrap(); let inner = TestSlab::get_slab().0.lock().unwrap();
assert_eq!(inner.map.is_empty(), true); assert!(inner.map.is_empty());
println!("Box Size {}", std::mem::size_of::<Box<Test>>()); println!("Box Size {}", std::mem::size_of::<Box<Test>>());
println!("BoxSlab Size {}", std::mem::size_of::<BoxSlab<TestSlab>>()); println!("BoxSlab Size {}", std::mem::size_of::<BoxSlab<TestSlab>>());
} }
@ -195,25 +194,22 @@ mod tests {
#[test] #[test]
fn alloc_full_block() { fn alloc_full_block() {
{ {
let a = Slab::<TestSlab>::new(Test { val: Arc::new(10) }).unwrap(); let a = Slab::<TestSlab>::try_new(Test { val: Arc::new(10) }).unwrap();
let b = Slab::<TestSlab>::new(Test { val: Arc::new(11) }).unwrap(); let b = Slab::<TestSlab>::try_new(Test { val: Arc::new(11) }).unwrap();
let c = Slab::<TestSlab>::new(Test { val: Arc::new(12) }).unwrap(); let c = Slab::<TestSlab>::try_new(Test { val: Arc::new(12) }).unwrap();
// Test that at overflow, we return None // Test that at overflow, we return None
assert_eq!( assert!(Slab::<TestSlab>::try_new(Test { val: Arc::new(13) }).is_none(),);
Slab::<TestSlab>::new(Test { val: Arc::new(13) }).is_none(),
true
);
assert_eq!(*b.val.deref(), 11); assert_eq!(*b.val.deref(), 11);
{ {
let inner = TestSlab::get_slab().0.lock().unwrap(); let inner = TestSlab::get_slab().0.lock().unwrap();
// Test that the bitmap is marked as full // Test that the bitmap is marked as full
assert_eq!(inner.map.is_full(), true); assert!(inner.map.is_full());
} }
// Purposefully drop, to test that new allocation is possible // Purposefully drop, to test that new allocation is possible
std::mem::drop(b); std::mem::drop(b);
let d = Slab::<TestSlab>::new(Test { val: Arc::new(21) }).unwrap(); let d = Slab::<TestSlab>::try_new(Test { val: Arc::new(21) }).unwrap();
assert_eq!(*d.val.deref(), 21); assert_eq!(*d.val.deref(), 21);
// Ensure older allocations are still valid // Ensure older allocations are still valid
@ -223,16 +219,16 @@ mod tests {
// Validates that the 'Drop' got executed - test that the bitmap is empty // Validates that the 'Drop' got executed - test that the bitmap is empty
let inner = TestSlab::get_slab().0.lock().unwrap(); let inner = TestSlab::get_slab().0.lock().unwrap();
assert_eq!(inner.map.is_empty(), true); assert!(inner.map.is_empty());
} }
#[test] #[test]
fn test_drop_logic() { fn test_drop_logic() {
let root = Arc::new(10); let root = Arc::new(10);
{ {
let _a = Slab::<TestSlab>::new(Test { val: root.clone() }).unwrap(); let _a = Slab::<TestSlab>::try_new(Test { val: root.clone() }).unwrap();
let _b = Slab::<TestSlab>::new(Test { val: root.clone() }).unwrap(); let _b = Slab::<TestSlab>::try_new(Test { val: root.clone() }).unwrap();
let _c = Slab::<TestSlab>::new(Test { val: root.clone() }).unwrap(); let _c = Slab::<TestSlab>::try_new(Test { val: root.clone() }).unwrap();
assert_eq!(Arc::strong_count(&root), 4); assert_eq!(Arc::strong_count(&root), 4);
} }
// Test that Drop was correctly called on all the members of the pool // Test that Drop was correctly called on all the members of the pool

View file

@ -40,7 +40,7 @@ fn main() {
}; };
let dev_att = Box::new(dev_att::HardCodedDevAtt::new()); let dev_att = Box::new(dev_att::HardCodedDevAtt::new());
let mut matter = core::Matter::new(dev_info, dev_att, comm_data).unwrap(); let mut matter = core::Matter::new(&dev_info, dev_att, &comm_data).unwrap();
let dm = matter.get_data_model(); let dm = matter.get_data_model();
{ {
let mut node = dm.node.write().unwrap(); let mut node = dm.node.write().unwrap();

View file

@ -487,6 +487,7 @@ impl std::fmt::Display for AclMgr {
} }
#[cfg(test)] #[cfg(test)]
#[allow(clippy::bool_assert_comparison)]
mod tests { mod tests {
use crate::{ use crate::{
data_model::objects::{Access, Privilege}, data_model::objects::{Access, Privilege},

View file

@ -18,6 +18,7 @@
use super::{CertConsumer, MAX_DEPTH}; use super::{CertConsumer, MAX_DEPTH};
use crate::error::Error; use crate::error::Error;
use chrono::{TimeZone, Utc}; use chrono::{TimeZone, Utc};
use log::warn;
#[derive(Debug)] #[derive(Debug)]
pub struct ASN1Writer<'a> { pub struct ASN1Writer<'a> {
@ -255,10 +256,22 @@ impl<'a> CertConsumer for ASN1Writer<'a> {
} }
fn utctime(&mut self, _tag: &str, epoch: u32) -> Result<(), Error> { fn utctime(&mut self, _tag: &str, epoch: u32) -> Result<(), Error> {
let mut matter_epoch = Utc.ymd(2000, 1, 1).and_hms(0, 0, 0).timestamp(); let mut matter_epoch = Utc
.with_ymd_and_hms(2000, 1, 1, 0, 0, 0)
.unwrap()
.timestamp();
matter_epoch += epoch as i64; matter_epoch += epoch as i64;
let dt = Utc.timestamp(matter_epoch, 0); let dt = match Utc.timestamp_opt(matter_epoch, 0) {
chrono::LocalResult::None => return Err(Error::InvalidTime),
chrono::LocalResult::Single(s) => s,
chrono::LocalResult::Ambiguous(_, a) => {
warn!("Ambiguous time for epoch {epoch}; returning latest timestamp: {a}");
a
}
};
let time_str = format!("{}Z", dt.format("%y%m%d%H%M%S")); let time_str = format!("{}Z", dt.format("%y%m%d%H%M%S"));
self.write_str(0x17, time_str.as_bytes()) self.write_str(0x17, time_str.as_bytes())
} }

View file

@ -348,20 +348,17 @@ impl DistNames {
w.start_seq(tag)?; w.start_seq(tag)?;
for (id, value) in &self.dn { for (id, value) in &self.dn {
if let Ok(tag) = num::FromPrimitive::from_u8(*id).ok_or(Error::InvalidData) { if let Ok(tag) = num::FromPrimitive::from_u8(*id).ok_or(Error::InvalidData) {
match tag { if let DnTags::NocCat = tag {
DnTags::NocCat => { w.start_set("")?;
w.start_set("")?; w.start_seq("")?;
w.start_seq("")?; w.oid("Chip NOC CAT Id:", &OID_MATTER_NOC_CAT_ID)?;
w.oid("Chip NOC CAT Id:", &OID_MATTER_NOC_CAT_ID)?; w.utf8str("", format!("{:08X}", value).as_str())?;
w.utf8str("", format!("{:08X}", value).as_str())?; w.end_seq()?;
w.end_seq()?; w.end_set()?;
w.end_set()?; } else {
} let index: usize = (*id as usize) - (DnTags::NodeId as usize);
_ => { let this = &dn_encoding[index];
let index: usize = (*id as usize) - (DnTags::NodeId as usize); encode_u64_dn(*value, this.0, this.1, w)?;
let this = &dn_encoding[index];
encode_u64_dn(*value, this.0, this.1, w)?;
}
} }
} else { } else {
error!("Non Matter DNs are not yet supported {}", id); error!("Non Matter DNs are not yet supported {}", id);
@ -452,7 +449,7 @@ impl Cert {
pub fn as_asn1(&self, buf: &mut [u8]) -> Result<usize, Error> { pub fn as_asn1(&self, buf: &mut [u8]) -> Result<usize, Error> {
let mut w = ASN1Writer::new(buf); let mut w = ASN1Writer::new(buf);
let _ = self.encode(&mut w)?; self.encode(&mut w)?;
Ok(w.as_slice().len()) Ok(w.as_slice().len())
} }
@ -657,7 +654,7 @@ mod tests {
for input in test_input.iter() { for input in test_input.iter() {
println!("Testing next input..."); println!("Testing next input...");
let root = tlv::get_root_node(*input).unwrap(); let root = tlv::get_root_node(input).unwrap();
let cert = Cert::from_tlv(&root).unwrap(); let cert = Cert::from_tlv(&root).unwrap();
let mut buf = [0u8; 1024]; let mut buf = [0u8; 1024];
let buf_len = buf.len(); let buf_len = buf.len();

View file

@ -18,6 +18,7 @@
use super::{CertConsumer, MAX_DEPTH}; use super::{CertConsumer, MAX_DEPTH};
use crate::error::Error; use crate::error::Error;
use chrono::{TimeZone, Utc}; use chrono::{TimeZone, Utc};
use log::warn;
use std::fmt; use std::fmt;
pub struct CertPrinter<'a, 'b> { pub struct CertPrinter<'a, 'b> {
@ -118,15 +119,23 @@ impl<'a, 'b> CertConsumer for CertPrinter<'a, 'b> {
Ok(()) Ok(())
} }
fn utctime(&mut self, tag: &str, epoch: u32) -> Result<(), Error> { fn utctime(&mut self, tag: &str, epoch: u32) -> Result<(), Error> {
let mut matter_epoch = Utc.ymd(2000, 1, 1).and_hms(0, 0, 0).timestamp(); let mut matter_epoch = Utc
.with_ymd_and_hms(2000, 1, 1, 0, 0, 0)
.unwrap()
.timestamp();
matter_epoch += epoch as i64; matter_epoch += epoch as i64;
let _ = writeln!(
self.f, let dt = match Utc.timestamp_opt(matter_epoch, 0) {
"{} {} {}", chrono::LocalResult::None => return Err(Error::InvalidTime),
SPACE[self.level], chrono::LocalResult::Single(s) => s,
tag, chrono::LocalResult::Ambiguous(_, a) => {
Utc.timestamp(matter_epoch, 0) warn!("Ambiguous time for epoch {epoch}; returning latest timestamp: {a}");
); a
}
};
let _ = writeln!(self.f, "{} {} {}", SPACE[self.level], tag, dt);
Ok(()) Ok(())
} }
} }

View file

@ -57,9 +57,9 @@ impl Matter {
/// requires a set of device attestation certificates and keys. It is the responsibility of /// requires a set of device attestation certificates and keys. It is the responsibility of
/// this object to return the device attestation details when queried upon. /// this object to return the device attestation details when queried upon.
pub fn new( pub fn new(
dev_det: BasicInfoConfig, dev_det: &BasicInfoConfig,
dev_att: Box<dyn DevAttDataFetcher>, dev_att: Box<dyn DevAttDataFetcher>,
dev_comm: CommissioningData, dev_comm: &CommissioningData,
) -> Result<Box<Matter>, Error> { ) -> Result<Box<Matter>, Error> {
let mdns = Mdns::get()?; let mdns = Mdns::get()?;
mdns.set_values(dev_det.vid, dev_det.pid, dev_comm.discriminator); mdns.set_values(dev_det.vid, dev_det.pid, dev_comm.discriminator);

View file

@ -74,7 +74,7 @@ pub struct BasicInfoCluster {
} }
impl BasicInfoCluster { impl BasicInfoCluster {
pub fn new(cfg: BasicInfoConfig) -> Result<Box<Self>, Error> { pub fn new(cfg: &BasicInfoConfig) -> Result<Box<Self>, Error> {
let mut cluster = Box::new(BasicInfoCluster { let mut cluster = Box::new(BasicInfoCluster {
base: Cluster::new(ID)?, base: Cluster::new(ID)?,
}); });

View file

@ -50,7 +50,7 @@ pub struct DataModel {
impl DataModel { impl DataModel {
pub fn new( pub fn new(
dev_details: BasicInfoConfig, dev_details: &BasicInfoConfig,
dev_att: Box<dyn DevAttDataFetcher>, dev_att: Box<dyn DevAttDataFetcher>,
fabric_mgr: Arc<FabricMgr>, fabric_mgr: Arc<FabricMgr>,
acl_mgr: Arc<AclMgr>, acl_mgr: Arc<AclMgr>,
@ -171,7 +171,7 @@ impl DataModel {
// Set the cluster's data version // Set the cluster's data version
attr_encoder.set_data_ver(cluster_data_ver); attr_encoder.set_data_ver(cluster_data_ver);
let mut access_req = AccessReq::new(accessor, path, Access::READ); let mut access_req = AccessReq::new(accessor, path, Access::READ);
Cluster::read_attribute(c, &mut access_req, attr_encoder, &attr_details); Cluster::read_attribute(c, &mut access_req, attr_encoder, attr_details);
Ok(()) Ok(())
}); });
if let Err(e) = result { if let Err(e) = result {

View file

@ -34,7 +34,7 @@ type WriteNode<'a> = RwLockWriteGuard<'a, Box<Node>>;
pub fn device_type_add_root_node( pub fn device_type_add_root_node(
node: &mut WriteNode, node: &mut WriteNode,
dev_info: BasicInfoConfig, dev_info: &BasicInfoConfig,
dev_att: Box<dyn DevAttDataFetcher>, dev_att: Box<dyn DevAttDataFetcher>,
fabric_mgr: Arc<FabricMgr>, fabric_mgr: Arc<FabricMgr>,
acl_mgr: Arc<AclMgr>, acl_mgr: Arc<AclMgr>,

View file

@ -203,6 +203,7 @@ impl std::fmt::Display for Attribute {
} }
#[cfg(test)] #[cfg(test)]
#[allow(clippy::bool_assert_comparison)]
mod tests { mod tests {
use super::Access; use super::Access;
use crate::data_model::objects::Privilege; use crate::data_model::objects::Privilege;

View file

@ -291,7 +291,6 @@ impl Cluster {
a.set_value(value) a.set_value(value)
.map(|_| { .map(|_| {
self.cluster_changed(); self.cluster_changed();
()
}) })
.map_err(|_| IMStatusCode::UnsupportedWrite) .map_err(|_| IMStatusCode::UnsupportedWrite)
} else { } else {
@ -303,7 +302,6 @@ impl Cluster {
let a = self.get_attribute_mut(attr_id)?; let a = self.get_attribute_mut(attr_id)?;
a.set_value(value).map(|_| { a.set_value(value).map(|_| {
self.cluster_changed(); self.cluster_changed();
()
}) })
} }

View file

@ -95,7 +95,7 @@ impl<'a> ToTLV for EncodeValue<'a> {
(f)(tag_type, tw); (f)(tag_type, tw);
Ok(()) Ok(())
} }
EncodeValue::Tlv(_) => (panic!("This looks invalid")), EncodeValue::Tlv(_) => panic!("This looks invalid"),
EncodeValue::Value(v) => v.to_tlv(tw, tag_type), EncodeValue::Value(v) => v.to_tlv(tw, tag_type),
} }
} }

View file

@ -25,6 +25,8 @@ pub struct Endpoint {
clusters: Vec<Box<dyn ClusterType>>, clusters: Vec<Box<dyn ClusterType>>,
} }
pub type BoxedClusters = [Box<dyn ClusterType>];
impl Endpoint { impl Endpoint {
pub fn new() -> Result<Box<Endpoint>, Error> { pub fn new() -> Result<Box<Endpoint>, Error> {
Ok(Box::new(Endpoint { Ok(Box::new(Endpoint {
@ -63,7 +65,7 @@ impl Endpoint {
pub fn get_wildcard_clusters( pub fn get_wildcard_clusters(
&self, &self,
cluster: Option<u32>, cluster: Option<u32>,
) -> Result<(&[Box<dyn ClusterType>], bool), IMStatusCode> { ) -> Result<(&BoxedClusters, bool), IMStatusCode> {
if let Some(c) = cluster { if let Some(c) = cluster {
if let Some(i) = self.get_cluster_index(c) { if let Some(i) = self.get_cluster_index(c) {
Ok((&self.clusters[i..i + 1], false)) Ok((&self.clusters[i..i + 1], false))
@ -79,7 +81,7 @@ impl Endpoint {
pub fn get_wildcard_clusters_mut( pub fn get_wildcard_clusters_mut(
&mut self, &mut self,
cluster: Option<u32>, cluster: Option<u32>,
) -> Result<(&mut [Box<dyn ClusterType>], bool), IMStatusCode> { ) -> Result<(&mut BoxedClusters, bool), IMStatusCode> {
if let Some(c) = cluster { if let Some(c) = cluster {
if let Some(i) = self.get_cluster_index(c) { if let Some(i) = self.get_cluster_index(c) {
Ok((&mut self.clusters[i..i + 1], false)) Ok((&mut self.clusters[i..i + 1], false))

View file

@ -29,6 +29,8 @@ pub trait ChangeConsumer {
pub const ENDPTS_PER_ACC: usize = 3; pub const ENDPTS_PER_ACC: usize = 3;
pub type BoxedEndpoints = [Option<Box<Endpoint>>];
#[derive(Default)] #[derive(Default)]
pub struct Node { pub struct Node {
endpoints: [Option<Box<Endpoint>>; ENDPTS_PER_ACC], endpoints: [Option<Box<Endpoint>>; ENDPTS_PER_ACC],
@ -49,7 +51,7 @@ impl std::fmt::Display for Node {
impl Node { impl Node {
pub fn new() -> Result<Box<Node>, Error> { pub fn new() -> Result<Box<Node>, Error> {
let node = Box::new(Node::default()); let node = Box::default();
Ok(node) Ok(node)
} }
@ -121,7 +123,7 @@ impl Node {
pub fn get_wildcard_endpoints( pub fn get_wildcard_endpoints(
&self, &self,
endpoint: Option<u16>, endpoint: Option<u16>,
) -> Result<(&[Option<Box<Endpoint>>], usize, bool), IMStatusCode> { ) -> Result<(&BoxedEndpoints, usize, bool), IMStatusCode> {
if let Some(e) = endpoint { if let Some(e) = endpoint {
let e = e as usize; let e = e as usize;
if self.endpoints.len() <= e || self.endpoints[e].is_none() { if self.endpoints.len() <= e || self.endpoints[e].is_none() {
@ -137,7 +139,7 @@ impl Node {
pub fn get_wildcard_endpoints_mut( pub fn get_wildcard_endpoints_mut(
&mut self, &mut self,
endpoint: Option<u16>, endpoint: Option<u16>,
) -> Result<(&mut [Option<Box<Endpoint>>], usize, bool), IMStatusCode> { ) -> Result<(&mut BoxedEndpoints, usize, bool), IMStatusCode> {
if let Some(e) = endpoint { if let Some(e) = endpoint {
let e = e as usize; let e = e as usize;
if self.endpoints.len() <= e || self.endpoints[e].is_none() { if self.endpoints.len() <= e || self.endpoints[e].is_none() {

View file

@ -58,6 +58,7 @@ impl FromTLV<'_> for Privilege {
} }
impl ToTLV for Privilege { impl ToTLV for Privilege {
#[allow(clippy::bool_to_int_with_if)]
fn to_tlv( fn to_tlv(
&self, &self,
tw: &mut crate::tlv::TLVWriter, tw: &mut crate::tlv::TLVWriter,

View file

@ -21,6 +21,7 @@ use std::sync::RwLock;
#[derive(PartialEq)] #[derive(PartialEq)]
#[allow(dead_code)] #[allow(dead_code)]
#[allow(clippy::enum_variant_names)]
enum NocState { enum NocState {
NocNotRecvd, NocNotRecvd,
// This is the local fabric index // This is the local fabric index

View file

@ -129,7 +129,7 @@ impl NocCluster {
} }
fn add_acl(&self, fab_idx: u8, admin_subject: u64) -> Result<(), Error> { fn add_acl(&self, fab_idx: u8, admin_subject: u64) -> Result<(), Error> {
let mut acl = AclEntry::new(fab_idx as u8, Privilege::ADMIN, AuthMode::Case); let mut acl = AclEntry::new(fab_idx, Privilege::ADMIN, AuthMode::Case);
acl.add_subject(admin_subject)?; acl.add_subject(admin_subject)?;
self.acl_mgr.add(acl) self.acl_mgr.add(acl)
} }
@ -154,7 +154,7 @@ impl NocCluster {
let noc_value = Cert::new(r.noc_value.0).map_err(|_| NocStatus::InvalidNOC)?; let noc_value = Cert::new(r.noc_value.0).map_err(|_| NocStatus::InvalidNOC)?;
info!("Received NOC as: {}", noc_value); info!("Received NOC as: {}", noc_value);
let icac_value = if r.icac_value.0.len() != 0 { let icac_value = if !r.icac_value.0.is_empty() {
let cert = Cert::new(r.icac_value.0).map_err(|_| NocStatus::InvalidNOC)?; let cert = Cert::new(r.icac_value.0).map_err(|_| NocStatus::InvalidNOC)?;
info!("Received ICAC as: {}", cert); info!("Received ICAC as: {}", cert);
Some(cert) Some(cert)
@ -176,7 +176,7 @@ impl NocCluster {
.add(fabric) .add(fabric)
.map_err(|_| NocStatus::TableFull)?; .map_err(|_| NocStatus::TableFull)?;
if self.add_acl(fab_idx as u8, r.case_admin_subject).is_err() { if self.add_acl(fab_idx, r.case_admin_subject).is_err() {
error!("Failed to add ACL, what to do?"); error!("Failed to add ACL, what to do?");
} }

View file

@ -63,7 +63,7 @@ impl AccessControlCluster {
/// Care about fabric-scoped behaviour is taken /// Care about fabric-scoped behaviour is taken
fn write_acl_attr( fn write_acl_attr(
&mut self, &mut self,
op: ListOperation, op: &ListOperation,
data: &TLVElement, data: &TLVElement,
fab_idx: u8, fab_idx: u8,
) -> Result<(), IMStatusCode> { ) -> Result<(), IMStatusCode> {
@ -77,12 +77,12 @@ impl AccessControlCluster {
acl_entry.fab_idx = Some(fab_idx); acl_entry.fab_idx = Some(fab_idx);
if let ListOperation::EditItem(index) = op { if let ListOperation::EditItem(index) = op {
self.acl_mgr.edit(index as u8, fab_idx, acl_entry) self.acl_mgr.edit(*index as u8, fab_idx, acl_entry)
} else { } else {
self.acl_mgr.add(acl_entry) self.acl_mgr.add(acl_entry)
} }
} }
ListOperation::DeleteItem(index) => self.acl_mgr.delete(index as u8, fab_idx), ListOperation::DeleteItem(index) => self.acl_mgr.delete(*index as u8, fab_idx),
ListOperation::DeleteList => self.acl_mgr.delete_for_fabric(fab_idx), ListOperation::DeleteList => self.acl_mgr.delete_for_fabric(fab_idx),
}; };
match result { match result {
@ -128,14 +128,13 @@ impl ClusterType for AccessControlCluster {
attr: &AttrDetails, attr: &AttrDetails,
data: &TLVElement, data: &TLVElement,
) -> Result<(), IMStatusCode> { ) -> Result<(), IMStatusCode> {
let result = match num::FromPrimitive::from_u16(attr.attr_id) { let result = if let Some(Attributes::Acl) = num::FromPrimitive::from_u16(attr.attr_id) {
Some(Attributes::Acl) => attr_list_write(attr, data, |op, data| { attr_list_write(attr, data, |op, data| {
self.write_acl_attr(op, data, attr.fab_idx) self.write_acl_attr(&op, data, attr.fab_idx)
}), })
_ => { } else {
error!("Attribute not yet supported: this shouldn't happen"); error!("Attribute not yet supported: this shouldn't happen");
Err(IMStatusCode::NotFound) Err(IMStatusCode::NotFound)
}
}; };
if result.is_ok() { if result.is_ok() {
self.base.cluster_changed(); self.base.cluster_changed();
@ -223,7 +222,7 @@ mod tests {
// Test, ACL has fabric index 2, but the accessing fabric is 1 // Test, ACL has fabric index 2, but the accessing fabric is 1
// the fabric index in the TLV should be ignored and the ACL should be created with entry 1 // the fabric index in the TLV should be ignored and the ACL should be created with entry 1
let result = acl.write_acl_attr(ListOperation::AddItem, &data, 1); let result = acl.write_acl_attr(&ListOperation::AddItem, &data, 1);
assert_eq!(result, Ok(())); assert_eq!(result, Ok(()));
let verifier = AclEntry::new(1, Privilege::VIEW, AuthMode::Case); let verifier = AclEntry::new(1, Privilege::VIEW, AuthMode::Case);
@ -259,7 +258,7 @@ mod tests {
let data = get_root_node_struct(writebuf.as_borrow_slice()).unwrap(); let data = get_root_node_struct(writebuf.as_borrow_slice()).unwrap();
// Test, Edit Fabric 2's index 1 - with accessing fabring as 2 - allow // Test, Edit Fabric 2's index 1 - with accessing fabring as 2 - allow
let result = acl.write_acl_attr(ListOperation::EditItem(1), &data, 2); let result = acl.write_acl_attr(&ListOperation::EditItem(1), &data, 2);
// Fabric 2's index 1, is actually our index 2, update the verifier // Fabric 2's index 1, is actually our index 2, update the verifier
verifier[2] = new; verifier[2] = new;
assert_eq!(result, Ok(())); assert_eq!(result, Ok(()));
@ -292,7 +291,7 @@ mod tests {
let data = TLVElement::new(TagType::Anonymous, ElementType::True); let data = TLVElement::new(TagType::Anonymous, ElementType::True);
// Test , Delete Fabric 1's index 0 // Test , Delete Fabric 1's index 0
let result = acl.write_acl_attr(ListOperation::DeleteItem(0), &data, 1); let result = acl.write_acl_attr(&ListOperation::DeleteItem(0), &data, 1);
assert_eq!(result, Ok(())); assert_eq!(result, Ok(()));
let verifier = [input[0], input[2]]; let verifier = [input[0], input[2]];
@ -323,7 +322,7 @@ mod tests {
for i in input { for i in input {
acl_mgr.add(i).unwrap(); acl_mgr.add(i).unwrap();
} }
let acl = AccessControlCluster::new(acl_mgr.clone()).unwrap(); let acl = AccessControlCluster::new(acl_mgr).unwrap();
// Test 1, all 3 entries are read in the response without fabric filtering // Test 1, all 3 entries are read in the response without fabric filtering
{ {
let mut tw = TLVWriter::new(&mut writebuf); let mut tw = TLVWriter::new(&mut writebuf);

View file

@ -27,6 +27,7 @@ use log::error;
pub const ID: u32 = 0x001D; pub const ID: u32 = 0x001D;
#[derive(FromPrimitive)] #[derive(FromPrimitive)]
#[allow(clippy::enum_variant_names)]
enum Attributes { enum Attributes {
DeviceTypeList = 0, DeviceTypeList = 0,
ServerList = 1, ServerList = 1,

View file

@ -57,6 +57,7 @@ pub enum Error {
InvalidAuthKey, InvalidAuthKey,
InvalidSignature, InvalidSignature,
InvalidState, InvalidState,
InvalidTime,
RwLock, RwLock,
TLVNotFound, TLVNotFound,
TLVTypeMismatch, TLVTypeMismatch,
@ -118,7 +119,7 @@ impl From<TryRecvError> for Error {
} }
} }
impl<'a> fmt::Display for Error { impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self) write!(f, "{:?}", self)
} }

View file

@ -228,7 +228,7 @@ impl Fabric {
let mut icac = Vec::new(); let mut icac = Vec::new();
psm.get_kv_slice(fb_key!(index, ST_ICA), &mut icac)?; psm.get_kv_slice(fb_key!(index, ST_ICA), &mut icac)?;
let icac = if icac.len() != 0 { let icac = if !icac.is_empty() {
Some(Cert::new(icac.as_slice())?) Some(Cert::new(icac.as_slice())?)
} else { } else {
None None

View file

@ -51,7 +51,7 @@ impl InteractionModel {
rx_buf: &[u8], rx_buf: &[u8],
proto_tx: &mut Packet, proto_tx: &mut Packet,
) -> Result<ResponseRequired, Error> { ) -> Result<ResponseRequired, Error> {
if InteractionModel::req_timeout_handled(trans, proto_tx)? == true { if InteractionModel::req_timeout_handled(trans, proto_tx)? {
return Ok(ResponseRequired::Yes); return Ok(ResponseRequired::Yes);
} }
@ -61,7 +61,7 @@ impl InteractionModel {
let inv_req = InvReq::from_tlv(&root)?; let inv_req = InvReq::from_tlv(&root)?;
let timed_tx = trans.get_timeout().map(|_| true); let timed_tx = trans.get_timeout().map(|_| true);
let timed_request = inv_req.timed_request.filter(|a| *a == true); let timed_request = inv_req.timed_request.filter(|a| *a);
// Either both should be None, or both should be Some(true) // Either both should be None, or both should be Some(true)
if timed_tx != timed_request { if timed_tx != timed_request {
InteractionModel::create_status_response(proto_tx, IMStatusCode::TimedRequestMisMatch)?; InteractionModel::create_status_response(proto_tx, IMStatusCode::TimedRequestMisMatch)?;

View file

@ -179,7 +179,7 @@ impl proto_demux::HandleProto for InteractionModel {
} }
fn get_proto_id(&self) -> usize { fn get_proto_id(&self) -> usize {
PROTO_ID_INTERACTION_MODEL as usize PROTO_ID_INTERACTION_MODEL
} }
} }

View file

@ -348,22 +348,20 @@ pub mod ib {
} else { } else {
f(ListOperation::EditItem(index), data) f(ListOperation::EditItem(index), data)
} }
} else { } else if data.confirm_array().is_ok() {
if data.confirm_array().is_ok() { // If data is list, this is either Delete List or OverWrite List operation
// If data is list, this is either Delete List or OverWrite List operation // in either case, we have to first delete the whole list
// in either case, we have to first delete the whole list f(ListOperation::DeleteList, data)?;
f(ListOperation::DeleteList, data)?; // Now the data must be a list, that should be added item by item
// Now the data must be a list, that should be added item by item
let container = data.enter().ok_or(Error::Invalid)?; let container = data.enter().ok_or(Error::Invalid)?;
for d in container { for d in container {
f(ListOperation::AddItem, &d)?; f(ListOperation::AddItem, &d)?;
}
Ok(())
} else {
// If data is not a list, this must be an add operation
f(ListOperation::AddItem, data)
} }
Ok(())
} else {
// If data is not a list, this must be an add operation
f(ListOperation::AddItem, data)
} }
} }

View file

@ -32,7 +32,7 @@ impl InteractionModel {
rx_buf: &[u8], rx_buf: &[u8],
proto_tx: &mut Packet, proto_tx: &mut Packet,
) -> Result<ResponseRequired, Error> { ) -> Result<ResponseRequired, Error> {
if InteractionModel::req_timeout_handled(trans, proto_tx)? == true { if InteractionModel::req_timeout_handled(trans, proto_tx)? {
return Ok(ResponseRequired::Yes); return Ok(ResponseRequired::Yes);
} }
proto_tx.set_proto_opcode(OpCode::WriteResponse as u8); proto_tx.set_proto_opcode(OpCode::WriteResponse as u8);

View file

@ -15,7 +15,6 @@
* limitations under the License. * limitations under the License.
*/ */
//! Native Rust Implementation of Matter (Smart-Home) //! Native Rust Implementation of Matter (Smart-Home)
//! //!
//! This crate implements the Matter specification that can be run on embedded devices //! This crate implements the Matter specification that can be run on embedded devices
@ -56,7 +55,7 @@
//! //!
//! /// Get the Matter Object //! /// Get the Matter Object
//! /// The dev_att is an object that implements the DevAttDataFetcher trait. //! /// The dev_att is an object that implements the DevAttDataFetcher trait.
//! let mut matter = Matter::new(dev_info, dev_att, comm_data).unwrap(); //! let mut matter = Matter::new(&dev_info, dev_att, &comm_data).unwrap();
//! let dm = matter.get_data_model(); //! let dm = matter.get_data_model();
//! { //! {
//! let mut node = dm.node.write().unwrap(); //! let mut node = dm.node.write().unwrap();

View file

@ -44,6 +44,7 @@ const SHORT_DISCRIMINATOR_SHIFT: u16 = 8;
static mut G_MDNS: Option<Arc<Mdns>> = None; static mut G_MDNS: Option<Arc<Mdns>> = None;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
#[derive(Clone, Copy)]
pub enum ServiceMode { pub enum ServiceMode {
Commissioned, Commissioned,
Commissionable, Commissionable,

View file

@ -143,6 +143,6 @@ impl proto_demux::HandleProto for SecureChannel {
} }
fn get_proto_id(&self) -> usize { fn get_proto_id(&self) -> usize {
PROTO_ID_SECURE_CHANNEL as usize PROTO_ID_SECURE_CHANNEL
} }
} }

View file

@ -219,7 +219,7 @@ impl PAKE {
let local_sessid = ctx.exch_ctx.sess.reserve_new_sess_id(); let local_sessid = ctx.exch_ctx.sess.reserve_new_sess_id();
let spake2p_data: u32 = ((local_sessid as u32) << 16) | a.initiator_ssid as u32; let spake2p_data: u32 = ((local_sessid as u32) << 16) | a.initiator_ssid as u32;
let mut spake2p = Box::new(Spake2P::new()); let mut spake2p = Box::new(Spake2P::new());
spake2p.set_app_data(spake2p_data as u32); spake2p.set_app_data(spake2p_data);
// Generate response // Generate response
let mut tw = TLVWriter::new(ctx.tx.get_writebuf()?); let mut tw = TLVWriter::new(ctx.tx.get_writebuf()?);

View file

@ -88,7 +88,7 @@ static TAG_EXTRACTOR: [ExtractTag; 8] = [
// ImplPrf32 5 // ImplPrf32 5
|t| TagType::ImplPrf32(LittleEndian::read_u32(&t.buf[t.current..])), |t| TagType::ImplPrf32(LittleEndian::read_u32(&t.buf[t.current..])),
// FullQual48 6 // FullQual48 6
|t| TagType::FullQual48(LittleEndian::read_u48(&t.buf[t.current..]) as u64), |t| TagType::FullQual48(LittleEndian::read_u48(&t.buf[t.current..])),
// FullQual64 7 // FullQual64 7
|t| TagType::FullQual64(LittleEndian::read_u64(&t.buf[t.current..])), |t| TagType::FullQual64(LittleEndian::read_u64(&t.buf[t.current..])),
]; ];
@ -330,32 +330,28 @@ impl<'a> PartialEq for TLVElement<'a> {
let ours = ours.unwrap(); let ours = ours.unwrap();
let theirs = theirs.unwrap(); let theirs = theirs.unwrap();
match ours.element_type { if let ElementType::EndCnt = ours.element_type {
ElementType::EndCnt => { if nest_level == 0 {
if nest_level == 0 { break;
break;
} else {
nest_level -= 1;
}
} }
_ => { nest_level -= 1;
if is_container(ours.element_type) { } else {
nest_level += 1; if is_container(ours.element_type) {
// Only compare the discriminants in case of array/list/structures, nest_level += 1;
// instead of actual element values. Those will be subsets within this same // Only compare the discriminants in case of array/list/structures,
// list that will get validated anyway // instead of actual element values. Those will be subsets within this same
if std::mem::discriminant(&ours.element_type) // list that will get validated anyway
!= std::mem::discriminant(&theirs.element_type) if std::mem::discriminant(&ours.element_type)
{ != std::mem::discriminant(&theirs.element_type)
return false; {
}
} else if ours.element_type != theirs.element_type {
return false; return false;
} }
} else if ours.element_type != theirs.element_type {
return false;
}
if ours.tag_type != theirs.tag_type { if ours.tag_type != theirs.tag_type {
return false; return false;
}
} }
} }
} }
@ -668,9 +664,8 @@ impl<'a> TLVContainerIterator<'a> {
} }
_ => return Some(last_elem), _ => return Some(last_elem),
} }
} else {
nest_level -= 1;
} }
nest_level -= 1;
} }
_ => { _ => {
if is_container(element.element_type) { if is_container(element.element_type) {

View file

@ -88,7 +88,7 @@ macro_rules! totlv_for {
}; };
} }
impl<'a, T: ToTLV, const N: usize> ToTLV for [T; N] { impl<T: ToTLV, const N: usize> ToTLV for [T; N] {
fn to_tlv(&self, tw: &mut TLVWriter, tag: TagType) -> Result<(), Error> { fn to_tlv(&self, tw: &mut TLVWriter, tag: TagType) -> Result<(), Error> {
tw.start_array(tag)?; tw.start_array(tag)?;
for i in self { for i in self {
@ -201,7 +201,7 @@ impl<'a, T: FromTLV<'a>> FromTLV<'a> for Option<T> {
impl<T: ToTLV> ToTLV for Option<T> { impl<T: ToTLV> ToTLV for Option<T> {
fn to_tlv(&self, tw: &mut TLVWriter, tag: TagType) -> Result<(), Error> { fn to_tlv(&self, tw: &mut TLVWriter, tag: TagType) -> Result<(), Error> {
match self { match self {
Some(s) => (s.to_tlv(tw, tag)), Some(s) => s.to_tlv(tw, tag),
None => Ok(()), None => Ok(()),
} }
} }
@ -311,12 +311,10 @@ impl<'a, T: ToTLV> TLVArray<'a, T> {
impl<'a, T: ToTLV + FromTLV<'a> + Copy> TLVArray<'a, T> { impl<'a, T: ToTLV + FromTLV<'a> + Copy> TLVArray<'a, T> {
pub fn get_index(&self, index: usize) -> T { pub fn get_index(&self, index: usize) -> T {
let mut curr = 0; for (curr, element) in self.iter().enumerate() {
for element in self.iter() {
if curr == index { if curr == index {
return element; return element;
} }
curr += 1;
} }
panic!("Out of bounds"); panic!("Out of bounds");
} }
@ -350,7 +348,7 @@ where
{ {
fn eq(&self, other: &&[T]) -> bool { fn eq(&self, other: &&[T]) -> bool {
let mut iter1 = self.iter(); let mut iter1 = self.iter();
let mut iter2 = other.into_iter(); let mut iter2 = other.iter();
loop { loop {
match (iter1.next(), iter2.next()) { match (iter1.next(), iter2.next()) {
(None, None) => return true, (None, None) => return true,
@ -392,7 +390,7 @@ impl<'a, T: Debug + ToTLV + FromTLV<'a> + Copy> Debug for TLVArray<'a, T> {
for i in self.iter() { for i in self.iter() {
writeln!(f, "{:?}", i)?; writeln!(f, "{:?}", i)?;
} }
writeln!(f, "") writeln!(f)
} }
} }

View file

@ -74,8 +74,8 @@ impl<'a, 'b> TLVWriter<'a, 'b> {
TagType::CommonPrf32(v) => (3, v as u64), TagType::CommonPrf32(v) => (3, v as u64),
TagType::ImplPrf16(v) => (4, v as u64), TagType::ImplPrf16(v) => (4, v as u64),
TagType::ImplPrf32(v) => (5, v as u64), TagType::ImplPrf32(v) => (5, v as u64),
TagType::FullQual48(v) => (6, v as u64), TagType::FullQual48(v) => (6, v),
TagType::FullQual64(v) => (7, v as u64), TagType::FullQual64(v) => (7, v),
}; };
self.buf self.buf
.le_u8(((tag_id) << TAG_SHIFT_BITS) | (val_type as u8))?; .le_u8(((tag_id) << TAG_SHIFT_BITS) | (val_type as u8))?;
@ -269,13 +269,11 @@ mod tests {
tw.u8(TagType::Anonymous, 12).unwrap(); tw.u8(TagType::Anonymous, 12).unwrap();
tw.u8(TagType::Context(1), 13).unwrap(); tw.u8(TagType::Context(1), 13).unwrap();
match tw.u16(TagType::Anonymous, 12) { if tw.u16(TagType::Anonymous, 12).is_ok() {
Ok(_) => panic!("This should have returned error"), panic!("This should have returned error")
_ => (),
} }
match tw.u16(TagType::Context(2), 13) { if tw.u16(TagType::Context(2), 13).is_ok() {
Ok(_) => panic!("This should have returned error"), panic!("This should have returned error")
_ => (),
} }
assert_eq!(buf, [4, 12, 36, 1, 13, 4]); assert_eq!(buf, [4, 12, 36, 1, 13, 4]);
} }

View file

@ -123,10 +123,7 @@ impl Exchange {
} }
pub fn is_data_none(&self) -> bool { pub fn is_data_none(&self) -> bool {
match self.data { matches!(self.data, DataOption::None)
DataOption::None => true,
_ => false,
}
} }
pub fn set_data_boxed(&mut self, data: Box<dyn Any>) { pub fn set_data_boxed(&mut self, data: Box<dyn Any>) {
@ -147,12 +144,11 @@ impl Exchange {
pub fn take_data_boxed<T: Any>(&mut self) -> Option<Box<T>> { pub fn take_data_boxed<T: Any>(&mut self) -> Option<Box<T>> {
let old = std::mem::replace(&mut self.data, DataOption::None); let old = std::mem::replace(&mut self.data, DataOption::None);
match old { if let DataOption::Boxed(d) = old {
DataOption::Boxed(d) => d.downcast::<T>().ok(), d.downcast::<T>().ok()
_ => { } else {
self.data = old; self.data = old;
None None
}
} }
} }
@ -293,15 +289,14 @@ impl ExchangeMgr {
// Get the session // Get the session
let (mut proto_rx, index) = self.sess_mgr.recv()?; let (mut proto_rx, index) = self.sess_mgr.recv()?;
let index = match index { let index = if let Some(s) = index {
Some(s) => s, s
None => { } else {
// The sessions were full, evict one session, and re-perform post-recv // The sessions were full, evict one session, and re-perform post-recv
let evict_index = self.sess_mgr.get_lru(); let evict_index = self.sess_mgr.get_lru();
self.evict_session(evict_index)?; self.evict_session(evict_index)?;
info!("Reattempting session creation"); info!("Reattempting session creation");
self.sess_mgr.post_recv(&proto_rx)?.ok_or(Error::Invalid)? self.sess_mgr.post_recv(&proto_rx)?.ok_or(Error::Invalid)?
}
}; };
let mut session = self.sess_mgr.get_session_handle(index); let mut session = self.sess_mgr.get_session_handle(index);
@ -352,7 +347,7 @@ impl ExchangeMgr {
} }
} }
for (exch_id, _) in to_purge.iter() { for (exch_id, _) in to_purge.iter() {
self.exchanges.remove(&*exch_id); self.exchanges.remove(exch_id);
} }
} }
@ -370,7 +365,7 @@ impl ExchangeMgr {
// As per the spec, we need to send a CLOSE here // As per the spec, we need to send a CLOSE here
let mut session = self.sess_mgr.get_session_handle(index); let mut session = self.sess_mgr.get_session_handle(index);
let mut tx = Slab::<PacketPool>::new(Packet::new_tx()?).ok_or(Error::NoSpace)?; let mut tx = Slab::<PacketPool>::try_new(Packet::new_tx()?).ok_or(Error::NoSpace)?;
secure_channel::common::create_sc_status_report( secure_channel::common::create_sc_status_report(
&mut tx, &mut tx,
secure_channel::common::SCStatusCodes::CloseSession, secure_channel::common::SCStatusCodes::CloseSession,
@ -408,13 +403,13 @@ impl ExchangeMgr {
Ok(()) Ok(())
} }
pub fn add_session(&mut self, clone_data: CloneData) -> Result<SessionHandle, Error> { pub fn add_session(&mut self, clone_data: &CloneData) -> Result<SessionHandle, Error> {
let sess_idx = match self.sess_mgr.clone_session(&clone_data) { let sess_idx = match self.sess_mgr.clone_session(clone_data) {
Ok(idx) => idx, Ok(idx) => idx,
Err(Error::NoSpace) => { Err(Error::NoSpace) => {
let evict_index = self.sess_mgr.get_lru(); let evict_index = self.sess_mgr.get_lru();
self.evict_session(evict_index)?; self.evict_session(evict_index)?;
self.sess_mgr.clone_session(&clone_data)? self.sess_mgr.clone_session(clone_data)?
} }
Err(e) => { Err(e) => {
return Err(e); return Err(e);
@ -437,6 +432,7 @@ impl fmt::Display for ExchangeMgr {
} }
#[cfg(test)] #[cfg(test)]
#[allow(clippy::bool_assert_comparison)]
mod tests { mod tests {
use crate::{ use crate::{
@ -496,8 +492,8 @@ mod tests {
let mut peer_sess_id = 100; let mut peer_sess_id = 100;
for _ in 1..count { for _ in 1..count {
let clone_data = get_clone_data(peer_sess_id, local_sess_id); let clone_data = get_clone_data(peer_sess_id, local_sess_id);
match mgr.add_session(clone_data) { match mgr.add_session(&clone_data) {
Ok(s) => (assert_eq!(peer_sess_id, s.get_peer_sess_id())), Ok(s) => assert_eq!(peer_sess_id, s.get_peer_sess_id()),
Err(Error::NoSpace) => break, Err(Error::NoSpace) => break,
_ => { _ => {
panic!("Couldn't, create session"); panic!("Couldn't, create session");
@ -558,7 +554,7 @@ mod tests {
for i in 1..(MAX_SESSIONS + 1) { for i in 1..(MAX_SESSIONS + 1) {
// Now purposefully overflow the sessions by adding another session // Now purposefully overflow the sessions by adding another session
let session = mgr let session = mgr
.add_session(get_clone_data(new_peer_sess_id, new_local_sess_id)) .add_session(&get_clone_data(new_peer_sess_id, new_local_sess_id))
.unwrap(); .unwrap();
assert_eq!(session.get_peer_sess_id(), new_peer_sess_id); assert_eq!(session.get_peer_sess_id(), new_peer_sess_id);

View file

@ -118,7 +118,7 @@ impl Mgr {
// If a new session was created, add it // If a new session was created, add it
let _ = self let _ = self
.exch_mgr .exch_mgr
.add_session(clone_data) .add_session(&clone_data)
.map_err(|e| error!("Error adding new session {:?}", e)); .map_err(|e| error!("Error adding new session {:?}", e));
} }
_ => { _ => {
@ -170,6 +170,6 @@ impl Mgr {
} }
fn new_tx() -> Result<BoxSlab<PacketPool>, Error> { fn new_tx() -> Result<BoxSlab<PacketPool>, Error> {
Slab::<PacketPool>::new(Packet::new_tx()?).ok_or(Error::PacketPoolExhaust) Slab::<PacketPool>::try_new(Packet::new_tx()?).ok_or(Error::PacketPoolExhaust)
} }
} }

View file

@ -15,7 +15,6 @@
* limitations under the License. * limitations under the License.
*/ */
pub mod exchange; pub mod exchange;
pub mod mgr; pub mod mgr;
pub mod mrp; pub mod mrp;

View file

@ -138,8 +138,8 @@ impl<'a> Packet<'a> {
pub fn as_borrow_slice(&mut self) -> &mut [u8] { pub fn as_borrow_slice(&mut self) -> &mut [u8] {
match &mut self.data { match &mut self.data {
Direction::Rx(pb, _) => (pb.as_borrow_slice()), Direction::Rx(pb, _) => pb.as_borrow_slice(),
Direction::Tx(wb) => (wb.as_mut_slice()), Direction::Tx(wb) => wb.as_mut_slice(),
} }
} }

View file

@ -15,7 +15,6 @@
* limitations under the License. * limitations under the License.
*/ */
use std::sync::Once; use std::sync::Once;
use async_channel::{bounded, Receiver, Sender}; use async_channel::{bounded, Receiver, Sender};

View file

@ -466,7 +466,8 @@ impl SessionMgr {
} }
pub fn recv(&mut self) -> Result<(BoxSlab<PacketPool>, Option<usize>), Error> { pub fn recv(&mut self) -> Result<(BoxSlab<PacketPool>, Option<usize>), Error> {
let mut rx = Slab::<PacketPool>::new(Packet::new_rx()?).ok_or(Error::PacketPoolExhaust)?; let mut rx =
Slab::<PacketPool>::try_new(Packet::new_rx()?).ok_or(Error::PacketPoolExhaust)?;
let network = self.network.as_ref().ok_or(Error::NoNetworkInterface)?; let network = self.network.as_ref().ok_or(Error::NoNetworkInterface)?;

View file

@ -117,22 +117,19 @@ mod tests {
assert_eq!(buf.le_u8().unwrap(), 0x01); assert_eq!(buf.le_u8().unwrap(), 0x01);
match buf.le_u16() { if buf.le_u16().is_ok() {
Ok(_) => panic!("This should have returned error"), panic!("This should have returned error")
Err(_) => (),
} }
match buf.le_u32() { if buf.le_u32().is_ok() {
Ok(_) => panic!("This should have returned error"), panic!("This should have returned error")
Err(_) => (),
} }
// Now consume the leftover byte // Now consume the leftover byte
assert_eq!(buf.le_u8().unwrap(), 65); assert_eq!(buf.le_u8().unwrap(), 65);
match buf.le_u8() { if buf.le_u8().is_ok() {
Ok(_) => panic!("This should have returned error"), panic!("This should have returned error")
Err(_) => (),
} }
assert_eq!(buf.as_slice(), []); assert_eq!(buf.as_slice(), []);
} }
@ -161,9 +158,8 @@ mod tests {
assert_eq!(buf.le_u8().unwrap(), 0x01); assert_eq!(buf.le_u8().unwrap(), 0x01);
assert_eq!(buf.le_u16().unwrap(), 65); assert_eq!(buf.le_u16().unwrap(), 65);
assert_eq!(buf.le_u32().unwrap(), 0xcafebabe); assert_eq!(buf.le_u32().unwrap(), 0xcafebabe);
match buf.tail(5) { if buf.tail(5).is_ok() {
Ok(_) => panic!("This should have returned error"), panic!("This should have returned error")
Err(_) => (),
} }
assert_eq!(buf.tail(2).unwrap(), [0xc, 0xd]); assert_eq!(buf.tail(2).unwrap(), [0xc, 0xd]);
} }

View file

@ -199,24 +199,20 @@ mod tests {
buf.le_u64(0xcafebabecafebabe).unwrap(); buf.le_u64(0xcafebabecafebabe).unwrap();
// Now the buffer is fully filled up, so no further puts will happen // Now the buffer is fully filled up, so no further puts will happen
match buf.le_u8(1) { if buf.le_u8(1).is_ok() {
Ok(_) => panic!("Should return error"), panic!("Should return error")
_ => (),
} }
match buf.le_u16(65) { if buf.le_u16(65).is_ok() {
Ok(_) => panic!("Should return error"), panic!("Should return error")
_ => (),
} }
match buf.le_u32(0xcafebabe) { if buf.le_u32(0xcafebabe).is_ok() {
Ok(_) => panic!("Should return error"), panic!("Should return error")
_ => (),
} }
match buf.le_u64(0xcafebabecafebabe) { if buf.le_u64(0xcafebabecafebabe).is_ok() {
Ok(_) => panic!("Should return error"), panic!("Should return error")
_ => (),
} }
} }
@ -267,9 +263,8 @@ mod tests {
buf.le_u16(65).unwrap(); buf.le_u16(65).unwrap();
let new_slice: [u8; 5] = [0xaa, 0xbb, 0xcc, 0xdd, 0xee]; let new_slice: [u8; 5] = [0xaa, 0xbb, 0xcc, 0xdd, 0xee];
match buf.copy_from_slice(&new_slice) { if buf.copy_from_slice(&new_slice).is_ok() {
Ok(_) => panic!("This should have returned error"), panic!("This should have returned error")
Err(_) => (),
} }
} }
@ -296,9 +291,8 @@ mod tests {
buf.le_u16(65).unwrap(); buf.le_u16(65).unwrap();
let new_slice: [u8; 6] = [0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]; let new_slice: [u8; 6] = [0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff];
match buf.prepend(&new_slice) { if buf.prepend(&new_slice).is_ok() {
Ok(_) => panic!("Prepend should return error"), panic!("Prepend should return error")
Err(_) => (),
} }
} }

View file

@ -121,7 +121,7 @@ impl ClusterType for EchoCluster {
) -> Result<(), IMStatusCode> { ) -> Result<(), IMStatusCode> {
match num::FromPrimitive::from_u16(attr.attr_id) { match num::FromPrimitive::from_u16(attr.attr_id) {
Some(Attributes::AttWriteList) => { Some(Attributes::AttWriteList) => {
attr_list_write(attr, data, |op, data| self.write_attr_list(op, data)) attr_list_write(attr, data, |op, data| self.write_attr_list(&op, data))
} }
_ => self.base.write_attribute_from_tlv(attr.attr_id, data), _ => self.base.write_attribute_from_tlv(attr.attr_id, data),
} }
@ -132,7 +132,7 @@ impl ClusterType for EchoCluster {
.cmd .cmd
.path .path
.leaf .leaf
.map(|c| num::FromPrimitive::from_u32(c)) .map(num::FromPrimitive::from_u32)
.ok_or(IMStatusCode::UnsupportedCommand)? .ok_or(IMStatusCode::UnsupportedCommand)?
.ok_or(IMStatusCode::UnsupportedCommand)?; .ok_or(IMStatusCode::UnsupportedCommand)?;
match cmd { match cmd {
@ -206,7 +206,7 @@ impl EchoCluster {
fn write_attr_list( fn write_attr_list(
&mut self, &mut self,
op: ListOperation, op: &ListOperation,
data: &TLVElement, data: &TLVElement,
) -> Result<(), IMStatusCode> { ) -> Result<(), IMStatusCode> {
let tc_handle = TestChecker::get().unwrap(); let tc_handle = TestChecker::get().unwrap();
@ -224,16 +224,16 @@ impl EchoCluster {
} }
ListOperation::EditItem(index) => { ListOperation::EditItem(index) => {
let data = data.u16().map_err(|_| IMStatusCode::Failure)?; let data = data.u16().map_err(|_| IMStatusCode::Failure)?;
if tc.write_list[index as usize].is_some() { if tc.write_list[*index as usize].is_some() {
tc.write_list[index as usize] = Some(data); tc.write_list[*index as usize] = Some(data);
Ok(()) Ok(())
} else { } else {
Err(IMStatusCode::InvalidAction) Err(IMStatusCode::InvalidAction)
} }
} }
ListOperation::DeleteItem(index) => { ListOperation::DeleteItem(index) => {
if tc.write_list[index as usize].is_some() { if tc.write_list[*index as usize].is_some() {
tc.write_list[index as usize] = None; tc.write_list[*index as usize] = None;
Ok(()) Ok(())
} else { } else {
Err(IMStatusCode::InvalidAction) Err(IMStatusCode::InvalidAction)

View file

@ -102,7 +102,7 @@ impl ImEngine {
// Only allow the standard peer node id of the IM Engine // Only allow the standard peer node id of the IM Engine
default_acl.add_subject(IM_ENGINE_PEER_ID).unwrap(); default_acl.add_subject(IM_ENGINE_PEER_ID).unwrap();
acl_mgr.add(default_acl).unwrap(); acl_mgr.add(default_acl).unwrap();
let dm = DataModel::new(dev_det, dev_att, fabric_mgr.clone(), acl_mgr.clone()).unwrap(); let dm = DataModel::new(&dev_det, dev_att, fabric_mgr, acl_mgr.clone()).unwrap();
{ {
let mut d = dm.node.write().unwrap(); let mut d = dm.node.write().unwrap();
@ -127,7 +127,7 @@ impl ImEngine {
pub fn process<'a>(&mut self, input: &ImInput, data_out: &'a mut [u8]) -> (u8, &'a mut [u8]) { pub fn process<'a>(&mut self, input: &ImInput, data_out: &'a mut [u8]) -> (u8, &'a mut [u8]) {
let mut new_exch = Exchange::new(1, 0, exchange::Role::Responder); let mut new_exch = Exchange::new(1, 0, exchange::Role::Responder);
// Choose whether to use a new exchange, or use the one from the ImEngine configuration // Choose whether to use a new exchange, or use the one from the ImEngine configuration
let mut exch = self.exch.as_mut().unwrap_or_else(|| &mut new_exch); let exch = self.exch.as_mut().unwrap_or(&mut new_exch);
let mut sess_mgr: SessionMgr = Default::default(); let mut sess_mgr: SessionMgr = Default::default();
@ -144,12 +144,9 @@ impl ImEngine {
); );
let sess_idx = sess_mgr.clone_session(&clone_data).unwrap(); let sess_idx = sess_mgr.clone_session(&clone_data).unwrap();
let sess = sess_mgr.get_session_handle(sess_idx); let sess = sess_mgr.get_session_handle(sess_idx);
let exch_ctx = ExchangeCtx { let exch_ctx = ExchangeCtx { exch, sess };
exch: &mut exch, let mut rx = Slab::<PacketPool>::try_new(Packet::new_rx().unwrap()).unwrap();
sess, let tx = Slab::<PacketPool>::try_new(Packet::new_tx().unwrap()).unwrap();
};
let mut rx = Slab::<PacketPool>::new(Packet::new_rx().unwrap()).unwrap();
let tx = Slab::<PacketPool>::new(Packet::new_tx().unwrap()).unwrap();
// Create fake rx packet // Create fake rx packet
rx.set_proto_id(0x01); rx.set_proto_id(0x01);
rx.set_proto_opcode(input.action as u8); rx.set_proto_opcode(input.action as u8);

View file

@ -83,7 +83,7 @@ enum WriteResponse<'a> {
// Helper for handling Write Attribute sequences // Helper for handling Write Attribute sequences
fn handle_timed_write_reqs( fn handle_timed_write_reqs(
input: &[AttrData], input: &[AttrData],
expected: WriteResponse, expected: &WriteResponse,
timeout: u16, timeout: u16,
delay: u16, delay: u16,
) -> DataModel { ) -> DataModel {
@ -159,10 +159,10 @@ fn test_timed_write_fail_and_success() {
]; ];
// Test with incorrect handling // Test with incorrect handling
handle_timed_write_reqs(input, WriteResponse::TransactionError, 400, 500); handle_timed_write_reqs(input, &WriteResponse::TransactionError, 400, 500);
// Test with correct handling // Test with correct handling
let dm = handle_timed_write_reqs(input, WriteResponse::TransactionSuccess(expected), 400, 0); let dm = handle_timed_write_reqs(input, &WriteResponse::TransactionSuccess(expected), 400, 0);
assert_eq!( assert_eq!(
AttrValue::Uint16(val0), AttrValue::Uint16(val0),
dm.read_attribute_raw( dm.read_attribute_raw(
@ -190,7 +190,7 @@ enum TimedInvResponse<'a> {
// Helper for handling Invoke Command sequences // Helper for handling Invoke Command sequences
fn handle_timed_commands( fn handle_timed_commands(
input: &[CmdData], input: &[CmdData],
expected: TimedInvResponse, expected: &TimedInvResponse,
timeout: u16, timeout: u16,
delay: u16, delay: u16,
set_timed_request: bool, set_timed_request: bool,
@ -222,7 +222,7 @@ fn handle_timed_commands(
Some(OpCode::StatusResponse) Some(OpCode::StatusResponse)
); );
let status_resp = StatusResp::from_tlv(&root).unwrap(); let status_resp = StatusResp::from_tlv(&root).unwrap();
assert_eq!(status_resp.status, e); assert_eq!(status_resp.status, *e);
} }
} }
dm dm
@ -237,7 +237,7 @@ fn test_timed_cmd_success() {
let expected = &[echo_resp!(0, 10), echo_resp!(1, 30)]; let expected = &[echo_resp!(0, 10), echo_resp!(1, 30)];
handle_timed_commands( handle_timed_commands(
input, input,
TimedInvResponse::TransactionSuccess(expected), &TimedInvResponse::TransactionSuccess(expected),
400, 400,
0, 0,
true, true,
@ -252,7 +252,7 @@ fn test_timed_cmd_timeout() {
let input = &[echo_req!(0, 5), echo_req!(1, 10)]; let input = &[echo_req!(0, 5), echo_req!(1, 10)];
handle_timed_commands( handle_timed_commands(
input, input,
TimedInvResponse::TransactionError(IMStatusCode::Timeout), &TimedInvResponse::TransactionError(IMStatusCode::Timeout),
400, 400,
500, 500,
true, true,
@ -267,7 +267,7 @@ fn test_timed_cmd_timedout_mismatch() {
let input = &[echo_req!(0, 5), echo_req!(1, 10)]; let input = &[echo_req!(0, 5), echo_req!(1, 10)];
handle_timed_commands( handle_timed_commands(
input, input,
TimedInvResponse::TransactionError(IMStatusCode::TimedRequestMisMatch), &TimedInvResponse::TransactionError(IMStatusCode::TimedRequestMisMatch),
400, 400,
0, 0,
false, false,
@ -276,7 +276,7 @@ fn test_timed_cmd_timedout_mismatch() {
let input = &[echo_req!(0, 5), echo_req!(1, 10)]; let input = &[echo_req!(0, 5), echo_req!(1, 10)];
handle_timed_commands( handle_timed_commands(
input, input,
TimedInvResponse::TransactionError(IMStatusCode::TimedRequestMisMatch), &TimedInvResponse::TransactionError(IMStatusCode::TimedRequestMisMatch),
0, 0,
0, 0,
true, true,

View file

@ -136,8 +136,8 @@ fn handle_data(action: OpCode, data_in: &[u8], data_out: &mut [u8]) -> (DataMode
exch: &mut exch, exch: &mut exch,
sess, sess,
}; };
let mut rx = Slab::<PacketPool>::new(Packet::new_rx().unwrap()).unwrap(); let mut rx = Slab::<PacketPool>::try_new(Packet::new_rx().unwrap()).unwrap();
let tx = Slab::<PacketPool>::new(Packet::new_tx().unwrap()).unwrap(); let tx = Slab::<PacketPool>::try_new(Packet::new_tx().unwrap()).unwrap();
// Create fake rx packet // Create fake rx packet
rx.set_proto_id(0x01); rx.set_proto_id(0x01);
rx.set_proto_opcode(action as u8); rx.set_proto_opcode(action as u8);

View file

@ -47,7 +47,7 @@ impl Default for TlvArgs {
fn parse_tlvargs(ast: &DeriveInput) -> TlvArgs { fn parse_tlvargs(ast: &DeriveInput) -> TlvArgs {
let mut tlvargs: TlvArgs = Default::default(); let mut tlvargs: TlvArgs = Default::default();
if ast.attrs.len() > 0 { if !ast.attrs.is_empty() {
if let List(MetaList { if let List(MetaList {
path, path,
paren_token: _, paren_token: _,
@ -87,7 +87,7 @@ fn parse_tlvargs(ast: &DeriveInput) -> TlvArgs {
} }
fn parse_tag_val(field: &syn::Field) -> Option<u8> { fn parse_tag_val(field: &syn::Field) -> Option<u8> {
if field.attrs.len() > 0 { if !field.attrs.is_empty() {
if let List(MetaList { if let List(MetaList {
path, path,
paren_token: _, paren_token: _,
@ -110,8 +110,8 @@ fn parse_tag_val(field: &syn::Field) -> Option<u8> {
fn gen_totlv_for_struct( fn gen_totlv_for_struct(
fields: &syn::FieldsNamed, fields: &syn::FieldsNamed,
struct_name: &proc_macro2::Ident, struct_name: &proc_macro2::Ident,
tlvargs: TlvArgs, tlvargs: &TlvArgs,
generics: syn::Generics, generics: &syn::Generics,
) -> TokenStream { ) -> TokenStream {
let mut tag_start = tlvargs.start; let mut tag_start = tlvargs.start;
let datatype = format_ident!("start_{}", tlvargs.datatype); let datatype = format_ident!("start_{}", tlvargs.datatype);
@ -127,7 +127,7 @@ fn gen_totlv_for_struct(
// keys.push(quote! { #literal_key_str }); // keys.push(quote! { #literal_key_str });
idents.push(&field.ident); idents.push(&field.ident);
// types.push(type_name.to_token_stream()); // types.push(type_name.to_token_stream());
if let Some(a) = parse_tag_val(&field) { if let Some(a) = parse_tag_val(field) {
tags.push(a); tags.push(a);
} else { } else {
tags.push(tag_start); tags.push(tag_start);
@ -152,10 +152,10 @@ fn gen_totlv_for_struct(
/// Generate a ToTlv implementation for an enum /// Generate a ToTlv implementation for an enum
fn gen_totlv_for_enum( fn gen_totlv_for_enum(
data_enum: syn::DataEnum, data_enum: &syn::DataEnum,
enum_name: &proc_macro2::Ident, enum_name: &proc_macro2::Ident,
tlvargs: TlvArgs, tlvargs: &TlvArgs,
generics: syn::Generics, generics: &syn::Generics,
) -> TokenStream { ) -> TokenStream {
let mut tag_start = tlvargs.start; let mut tag_start = tlvargs.start;
@ -232,9 +232,9 @@ pub fn derive_totlv(item: TokenStream) -> TokenStream {
.. ..
}) = ast.data }) = ast.data
{ {
gen_totlv_for_struct(fields, name, tlvargs, generics) gen_totlv_for_struct(fields, name, &tlvargs, &generics)
} else if let syn::Data::Enum(data_enum) = ast.data { } else if let syn::Data::Enum(data_enum) = ast.data {
gen_totlv_for_enum(data_enum, name, tlvargs, generics) gen_totlv_for_enum(&data_enum, name, &tlvargs, &generics)
} else { } else {
panic!( panic!(
"Derive ToTLV - Only supported Struct for now {:?}", "Derive ToTLV - Only supported Struct for now {:?}",
@ -248,7 +248,7 @@ fn gen_fromtlv_for_struct(
fields: &syn::FieldsNamed, fields: &syn::FieldsNamed,
struct_name: &proc_macro2::Ident, struct_name: &proc_macro2::Ident,
tlvargs: TlvArgs, tlvargs: TlvArgs,
generics: syn::Generics, generics: &syn::Generics,
) -> TokenStream { ) -> TokenStream {
let mut tag_start = tlvargs.start; let mut tag_start = tlvargs.start;
let lifetime = tlvargs.lifetime; let lifetime = tlvargs.lifetime;
@ -260,7 +260,7 @@ fn gen_fromtlv_for_struct(
for field in fields.named.iter() { for field in fields.named.iter() {
let type_name = &field.ty; let type_name = &field.ty;
if let Some(a) = parse_tag_val(&field) { if let Some(a) = parse_tag_val(field) {
// TODO: The current limitation with this is that a hard-coded integer // TODO: The current limitation with this is that a hard-coded integer
// value has to be mentioned in the tagval attribute. This is because // value has to be mentioned in the tagval attribute. This is because
// our tags vector is for integers, and pushing an 'identifier' on it // our tags vector is for integers, and pushing an 'identifier' on it
@ -330,10 +330,10 @@ fn gen_fromtlv_for_struct(
/// Generate a FromTlv implementation for an enum /// Generate a FromTlv implementation for an enum
fn gen_fromtlv_for_enum( fn gen_fromtlv_for_enum(
data_enum: syn::DataEnum, data_enum: &syn::DataEnum,
enum_name: &proc_macro2::Ident, enum_name: &proc_macro2::Ident,
tlvargs: TlvArgs, tlvargs: TlvArgs,
generics: syn::Generics, generics: &syn::Generics,
) -> TokenStream { ) -> TokenStream {
let mut tag_start = tlvargs.start; let mut tag_start = tlvargs.start;
let lifetime = tlvargs.lifetime; let lifetime = tlvargs.lifetime;
@ -422,9 +422,9 @@ pub fn derive_fromtlv(item: TokenStream) -> TokenStream {
.. ..
}) = ast.data }) = ast.data
{ {
gen_fromtlv_for_struct(fields, name, tlvargs, generics) gen_fromtlv_for_struct(fields, name, tlvargs, &generics)
} else if let syn::Data::Enum(data_enum) = ast.data { } else if let syn::Data::Enum(data_enum) = ast.data {
gen_fromtlv_for_enum(data_enum, name, tlvargs, generics) gen_fromtlv_for_enum(&data_enum, name, tlvargs, &generics)
} else { } else {
panic!( panic!(
"Derive FromTLV - Only supported Struct for now {:?}", "Derive FromTLV - Only supported Struct for now {:?}",