From 357eb73c6fb3256039716868ce1a9e3fbec015c5 Mon Sep 17 00:00:00 2001 From: ivmarkov Date: Sun, 28 May 2023 11:04:46 +0000 Subject: [PATCH] Control memory by removing implicit copy --- matter/src/acl.rs | 20 +- matter/src/data_model/objects/encoder.rs | 10 +- matter/src/data_model/objects/node.rs | 18 +- .../data_model/sdm/general_commissioning.rs | 7 +- .../data_model/system_model/access_control.rs | 10 +- matter/src/interaction_model/messages.rs | 38 ++-- matter/src/mdns.rs | 15 +- matter/src/tlv/parser.rs | 155 +++++---------- matter/src/tlv/traits.rs | 6 +- matter/src/transport/mrp.rs | 6 +- matter/src/transport/session.rs | 14 +- matter/tests/common/attributes.rs | 4 +- matter/tests/common/commands.rs | 12 +- matter/tests/data_model/acl_and_dataver.rs | 4 +- matter/tests/data_model/attribute_lists.rs | 22 ++- matter/tests/data_model/attributes.rs | 4 +- matter/tests/data_model/commands.rs | 6 +- matter/tests/data_model/long_reads.rs | 183 ++++++++++++------ matter_macro_derive/src/lib.rs | 2 +- 19 files changed, 281 insertions(+), 255 deletions(-) diff --git a/matter/src/acl.rs b/matter/src/acl.rs index 8bd8b70..15e4def 100644 --- a/matter/src/acl.rs +++ b/matter/src/acl.rs @@ -260,7 +260,7 @@ impl<'a> AccessReq<'a> { } } -#[derive(FromTLV, ToTLV, Copy, Clone, Debug, PartialEq)] +#[derive(FromTLV, ToTLV, Clone, Debug, PartialEq)] pub struct Target { cluster: Option, endpoint: Option, @@ -283,7 +283,7 @@ impl Target { type Subjects = [Option; SUBJECTS_PER_ENTRY]; type Targets = [Option; TARGETS_PER_ENTRY]; -#[derive(ToTLV, FromTLV, Copy, Clone, Debug, PartialEq)] +#[derive(ToTLV, FromTLV, Clone, Debug, PartialEq)] #[tlvargs(start = 1)] pub struct AclEntry { privilege: Privilege, @@ -463,7 +463,11 @@ impl AclMgr { pub fn delete_for_fabric(&mut self, fab_idx: u8) -> Result<(), Error> { for entry in &mut self.entries { - if entry.map(|e| e.fab_idx == Some(fab_idx)).unwrap_or(false) { + if entry + .as_ref() + .map(|e| e.fab_idx == Some(fab_idx)) + .unwrap_or(false) + { *entry = None; self.changed = true; } @@ -545,7 +549,11 @@ impl AclMgr { for (curr_index, entry) in self .entries .iter_mut() - .filter(|e| e.filter(|e1| e1.fab_idx == Some(fab_idx)).is_some()) + .filter(|e| { + e.as_ref() + .filter(|e1| e1.fab_idx == Some(fab_idx)) + .is_some() + }) .enumerate() { if curr_index == index as usize { @@ -779,7 +787,7 @@ mod tests { am.borrow_mut().add(new).unwrap(); // Write on an RWVA without admin access - deny - let mut req = AccessReq::new(&accessor, path, Access::WRITE); + let mut req = AccessReq::new(&accessor, path.clone(), Access::WRITE); req.set_target_perms(Access::RWVA); assert_eq!(req.allow(), false); @@ -806,7 +814,7 @@ mod tests { am.borrow_mut().erase_all().unwrap(); let path = GenericPath::new(Some(1), Some(1234), None); let accessor2 = Accessor::new(2, AccessorSubjects::new(112233), AuthMode::Case, &am); - let mut req2 = AccessReq::new(&accessor2, path, Access::READ); + let mut req2 = AccessReq::new(&accessor2, path.clone(), Access::READ); req2.set_target_perms(Access::RWVA); let accessor3 = Accessor::new(3, AccessorSubjects::new(112233), AuthMode::Case, &am); let mut req3 = AccessReq::new(&accessor3, path, Access::READ); diff --git a/matter/src/data_model/objects/encoder.rs b/matter/src/data_model/objects/encoder.rs index e97eea0..70e0db7 100644 --- a/matter/src/data_model/objects/encoder.rs +++ b/matter/src/data_model/objects/encoder.rs @@ -39,7 +39,7 @@ use super::{AttrDetails, CmdDetails, Handler}; // the tw.rewind() in that case, if we add this support pub type EncodeValueGen<'a> = &'a dyn Fn(TagType, &mut TLVWriter); -#[derive(Copy, Clone)] +#[derive(Clone)] /// A structure for encoding various types of values pub enum EncodeValue<'a> { /// This indicates a value that is dynamically generated. This variant @@ -66,13 +66,13 @@ impl<'a> EncodeValue<'a> { impl<'a> PartialEq for EncodeValue<'a> { fn eq(&self, other: &Self) -> bool { - match *self { + match self { EncodeValue::Closure(_) => { error!("PartialEq not yet supported"); false } EncodeValue::Tlv(a) => { - if let EncodeValue::Tlv(b) = *other { + if let EncodeValue::Tlv(b) = other { a == b } else { false @@ -89,7 +89,7 @@ impl<'a> PartialEq for EncodeValue<'a> { impl<'a> Debug for EncodeValue<'a> { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { - match *self { + match self { EncodeValue::Closure(_) => write!(f, "Contains closure"), EncodeValue::Tlv(t) => write!(f, "{:?}", t), EncodeValue::Value(_) => write!(f, "Contains EncodeValue"), @@ -113,7 +113,7 @@ impl<'a> ToTLV for EncodeValue<'a> { impl<'a> FromTLV<'a> for EncodeValue<'a> { fn from_tlv(data: &TLVElement<'a>) -> Result { - Ok(EncodeValue::Tlv(*data)) + Ok(EncodeValue::Tlv(data.clone())) } } diff --git a/matter/src/data_model/objects/node.rs b/matter/src/data_model/objects/node.rs index 3ee3af2..41720b6 100644 --- a/matter/src/data_model/objects/node.rs +++ b/matter/src/data_model/objects/node.rs @@ -84,11 +84,11 @@ impl<'a> Iterable for Option<&'a TLVArray<'a, DataVersionFilter>> { impl<'a> Iterable for &'a [DataVersionFilter] { type Item = DataVersionFilter; - type Iterator<'i> = core::iter::Copied> where Self: 'i; + type Iterator<'i> = core::iter::Cloned> where Self: 'i; fn iter(&self) -> Self::Iterator<'_> { let slice: &[DataVersionFilter] = self; - slice.iter().copied() + slice.iter().cloned() } } @@ -127,11 +127,11 @@ impl<'a> Node<'a> { 's: 'm, { self.read_attr_requests( - req.paths.iter().copied(), + req.paths.iter().cloned(), req.filters.as_slice(), req.fabric_filtered, accessor, - Some(req.resume_path), + Some(req.resume_path.clone()), ) } @@ -163,11 +163,11 @@ impl<'a> Node<'a> { 's: 'm, { self.read_attr_requests( - req.paths.iter().copied(), + req.paths.iter().cloned(), req.filters.as_slice(), req.fabric_filtered, accessor, - Some(req.resume_path.unwrap()), + Some(req.resume_path.clone().unwrap()), ) } @@ -187,7 +187,7 @@ impl<'a> Node<'a> { attr_requests.flat_map(move |path| { if path.to_gp().is_wildcard() { let dataver_filters = dataver_filters.clone(); - let from = from; + let from = from.clone(); let iter = self .match_attributes(path.endpoint, path.cluster, path.attr) @@ -302,7 +302,7 @@ impl<'a> Node<'a> { dataver: attr_data.data_ver, wildcard: true, }, - attr_data.data.unwrap_tlv().unwrap(), + attr_data.data.clone().unwrap_tlv().unwrap(), )) }); @@ -367,7 +367,7 @@ impl<'a> Node<'a> { cmd_id: cmd, wildcard: true, }, - cmd_data.data.unwrap_tlv().unwrap(), + cmd_data.data.clone().unwrap_tlv().unwrap(), )) }); diff --git a/matter/src/data_model/sdm/general_commissioning.rs b/matter/src/data_model/sdm/general_commissioning.rs index b0cdff1..78c3bef 100644 --- a/matter/src/data_model/sdm/general_commissioning.rs +++ b/matter/src/data_model/sdm/general_commissioning.rs @@ -205,7 +205,10 @@ impl<'a> GenCommCluster<'a> { let status = if self .failsafe .borrow_mut() - .arm(p.expiry_len, transaction.session().get_session_mode()) + .arm( + p.expiry_len, + transaction.session().get_session_mode().clone(), + ) .is_err() { CommissioningError::ErrBusyWithOtherAdmin as u8 @@ -271,7 +274,7 @@ impl<'a> GenCommCluster<'a> { if self .failsafe .borrow_mut() - .disarm(transaction.session().get_session_mode()) + .disarm(transaction.session().get_session_mode().clone()) .is_err() { status = CommissioningError::ErrInvalidAuth as u8; diff --git a/matter/src/data_model/system_model/access_control.rs b/matter/src/data_model/system_model/access_control.rs index c57c0df..17c88e3 100644 --- a/matter/src/data_model/system_model/access_control.rs +++ b/matter/src/data_model/system_model/access_control.rs @@ -255,8 +255,8 @@ mod tests { AclEntry::new(1, Privilege::VIEW, AuthMode::Case), AclEntry::new(2, Privilege::ADMIN, AuthMode::Case), ]; - for i in verifier { - acl_mgr.borrow_mut().add(i).unwrap(); + for i in &verifier { + acl_mgr.borrow_mut().add(i.clone()).unwrap(); } let mut acl = AccessControlCluster::new(&acl_mgr, dummy_rand); @@ -292,8 +292,8 @@ mod tests { AclEntry::new(1, Privilege::VIEW, AuthMode::Case), AclEntry::new(2, Privilege::ADMIN, AuthMode::Case), ]; - for i in input { - acl_mgr.borrow_mut().add(i).unwrap(); + for i in &input { + acl_mgr.borrow_mut().add(i.clone()).unwrap(); } let mut acl = AccessControlCluster::new(&acl_mgr, dummy_rand); // data is don't-care actually @@ -303,7 +303,7 @@ mod tests { let result = acl.write_acl_attr(&ListOperation::DeleteItem(0), &data, 1); assert!(result.is_ok()); - let verifier = [input[0], input[2]]; + let verifier = [input[0].clone(), input[2].clone()]; // Also validate in the acl_mgr that the entries are in the right order let mut index = 0; acl_mgr diff --git a/matter/src/interaction_model/messages.rs b/matter/src/interaction_model/messages.rs index bfd8a8b..0cf859a 100644 --- a/matter/src/interaction_model/messages.rs +++ b/matter/src/interaction_model/messages.rs @@ -23,7 +23,7 @@ use crate::{ // A generic path with endpoint, clusters, and a leaf // The leaf could be command, attribute, event -#[derive(Default, Clone, Copy, Debug, PartialEq, FromTLV, ToTLV)] +#[derive(Default, Clone, Debug, PartialEq, FromTLV, ToTLV)] #[tlvargs(datatype = "list")] pub struct GenericPath { pub endpoint: Option, @@ -106,16 +106,6 @@ pub mod msg { self.attr_requests = Some(TLVArray::new(requests)); self } - - pub fn to_read_req(&self) -> ReadReq<'a> { - ReadReq { - attr_requests: self.attr_requests, - event_requests: self.event_requests, - event_filters: self.event_filters, - fabric_filtered: self.fabric_filtered, - dataver_filters: self.dataver_filters, - } - } } #[derive(Debug, FromTLV, ToTLV)] @@ -268,7 +258,7 @@ pub mod ib { use super::GenericPath; // Command Response - #[derive(Clone, Copy, FromTLV, ToTLV, Debug)] + #[derive(Clone, FromTLV, ToTLV, Debug)] #[tlvargs(lifetime = "'a")] pub enum InvResp<'a> { Cmd(CmdData<'a>), @@ -301,7 +291,7 @@ pub mod ib { } } - #[derive(FromTLV, ToTLV, Copy, Clone, PartialEq, Debug)] + #[derive(FromTLV, ToTLV, Clone, PartialEq, Debug)] pub struct CmdStatus { path: CmdPath, status: Status, @@ -319,7 +309,7 @@ pub mod ib { } } - #[derive(Debug, Clone, Copy, FromTLV, ToTLV)] + #[derive(Debug, Clone, FromTLV, ToTLV)] #[tlvargs(lifetime = "'a")] pub struct CmdData<'a> { pub path: CmdPath, @@ -338,7 +328,7 @@ pub mod ib { } // Status - #[derive(Debug, Clone, Copy, PartialEq, FromTLV, ToTLV)] + #[derive(Debug, Clone, PartialEq, FromTLV, ToTLV)] pub struct Status { pub status: IMStatusCode, pub cluster_status: u16, @@ -354,7 +344,7 @@ pub mod ib { } // Attribute Response - #[derive(Clone, Copy, FromTLV, ToTLV, PartialEq, Debug)] + #[derive(Clone, FromTLV, ToTLV, PartialEq, Debug)] #[tlvargs(lifetime = "'a")] pub enum AttrResp<'a> { Status(AttrStatus), @@ -390,7 +380,7 @@ pub mod ib { } // Attribute Data - #[derive(Clone, Copy, PartialEq, FromTLV, ToTLV, Debug)] + #[derive(Clone, PartialEq, FromTLV, ToTLV, Debug)] #[tlvargs(lifetime = "'a")] pub struct AttrData<'a> { pub data_ver: Option, @@ -458,7 +448,7 @@ pub mod ib { } } - #[derive(Debug, Clone, Copy, PartialEq, FromTLV, ToTLV)] + #[derive(Debug, Clone, PartialEq, FromTLV, ToTLV)] pub struct AttrStatus { path: AttrPath, status: Status, @@ -474,7 +464,7 @@ pub mod ib { } // Attribute Path - #[derive(Default, Clone, Copy, Debug, PartialEq, FromTLV, ToTLV)] + #[derive(Default, Clone, Debug, PartialEq, FromTLV, ToTLV)] #[tlvargs(datatype = "list")] pub struct AttrPath { pub tag_compression: Option, @@ -501,7 +491,7 @@ pub mod ib { } // Command Path - #[derive(Default, Debug, Copy, Clone, PartialEq)] + #[derive(Default, Debug, Clone, PartialEq)] pub struct CmdPath { pub path: GenericPath, } @@ -557,20 +547,20 @@ pub mod ib { } } - #[derive(FromTLV, ToTLV, Copy, Clone, Debug)] + #[derive(FromTLV, ToTLV, Clone, Debug)] pub struct ClusterPath { pub node: Option, pub endpoint: EndptId, pub cluster: ClusterId, } - #[derive(FromTLV, ToTLV, Copy, Clone, Debug)] + #[derive(FromTLV, ToTLV, Clone, Debug)] pub struct DataVersionFilter { pub path: ClusterPath, pub data_ver: u32, } - #[derive(FromTLV, ToTLV, Copy, Clone, Debug)] + #[derive(FromTLV, ToTLV, Clone, Debug)] #[tlvargs(datatype = "list")] pub struct EventPath { pub node: Option, @@ -580,7 +570,7 @@ pub mod ib { pub is_urgent: Option, } - #[derive(FromTLV, ToTLV, Copy, Clone, Debug)] + #[derive(FromTLV, ToTLV, Clone, Debug)] pub struct EventFilter { pub node: Option, pub event_min: Option, diff --git a/matter/src/mdns.rs b/matter/src/mdns.rs index a187683..80333b1 100644 --- a/matter/src/mdns.rs +++ b/matter/src/mdns.rs @@ -234,15 +234,15 @@ pub mod builtin { use crate::transport::udp::UdpListener; use crate::utils::select::EitherUnwrap; - const IP_BROADCAST_ADDRS: [SocketAddr; 2] = [ - SocketAddr::new(IpAddr::V4(Ipv4Addr::new(224, 0, 0, 251)), 5353), - SocketAddr::new( + const IP_BROADCAST_ADDRS: [(IpAddr, u16); 2] = [ + (IpAddr::V4(Ipv4Addr::new(224, 0, 0, 251)), 5353), + ( IpAddr::V6(Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 0x00fb)), 5353, ), ]; - const IP_BIND_ADDR: SocketAddr = SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), 5353); + const IP_BIND_ADDR: (IpAddr, u16) = (IpAddr::V6(Ipv6Addr::UNSPECIFIED), 5353); pub fn create_record( id: u16, @@ -429,7 +429,8 @@ pub mod builtin { async fn bind(&self) -> Result<(), Error> { if self.udp.borrow().is_none() { - *self.udp.borrow_mut() = Some(UdpListener::new(IP_BIND_ADDR).await?); + *self.udp.borrow_mut() = + Some(UdpListener::new(SocketAddr::new(IP_BIND_ADDR.0, IP_BIND_ADDR.1)).await?); } Ok(()) @@ -575,8 +576,8 @@ pub mod builtin { let udp = self.0.udp.borrow(); let udp = udp.as_ref().unwrap(); - for addr in IP_BROADCAST_ADDRS { - udp.send(addr, &entry.record).await?; + for (addr, port) in IP_BROADCAST_ADDRS { + udp.send(SocketAddr::new(addr, port), &entry.record).await?; } index += 1; diff --git a/matter/src/tlv/parser.rs b/matter/src/tlv/parser.rs index 0c179e2..8bfdd28 100644 --- a/matter/src/tlv/parser.rs +++ b/matter/src/tlv/parser.rs @@ -33,14 +33,7 @@ impl<'a> TLVList<'a> { } } -#[derive(Debug, Copy, Clone, PartialEq)] -pub struct Pointer<'a> { - buf: &'a [u8], - current: usize, - left: usize, -} - -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq)] pub enum ElementType<'a> { S8(i8), S16(i16), @@ -63,9 +56,9 @@ pub enum ElementType<'a> { Str32l, Str64l, Null, - Struct(Pointer<'a>), - Array(Pointer<'a>), - List(Pointer<'a>), + Struct(&'a [u8]), + Array(&'a [u8]), + List(&'a [u8]), EndCnt, Last, } @@ -204,44 +197,11 @@ static VALUE_EXTRACTOR: [ExtractValue; MAX_VALUE_INDEX] = [ // Null 20 { |_t| (0, ElementType::Null) }, // Struct 21 - { - |t| { - ( - 0, - ElementType::Struct(Pointer { - buf: t.buf, - current: t.current, - left: t.left, - }), - ) - } - }, + { |t| (0, ElementType::Struct(&t.buf[t.current..])) }, // Array 22 - { - |t| { - ( - 0, - ElementType::Array(Pointer { - buf: t.buf, - current: t.current, - left: t.left, - }), - ) - } - }, + { |t| (0, ElementType::Array(&t.buf[t.current..])) }, // List 23 - { - |t| { - ( - 0, - ElementType::List(Pointer { - buf: t.buf, - current: t.current, - left: t.left, - }), - ) - } - }, + { |t| (0, ElementType::List(&t.buf[t.current..])) }, // EndCnt 24 { |_t| (0, ElementType::EndCnt) }, ]; @@ -282,7 +242,7 @@ fn read_length_value<'a>( // The current offset is the string size let length: usize = LittleEndian::read_uint(&t.buf[t.current..], size_of_length_field) as usize; // We'll consume the current offset (len) + the entire string - if length + size_of_length_field > t.left { + if length + size_of_length_field > t.buf.len() - t.current { // Return Error Err(ErrorCode::NoSpace.into()) } else { @@ -294,7 +254,7 @@ fn read_length_value<'a>( } } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Clone)] pub struct TLVElement<'a> { tag_type: TagType, element_type: ElementType<'a>, @@ -303,11 +263,11 @@ pub struct TLVElement<'a> { impl<'a> PartialEq for TLVElement<'a> { fn eq(&self, other: &Self) -> bool { match self.element_type { - ElementType::Struct(a) | ElementType::Array(a) | ElementType::List(a) => { - let mut our_iter = TLVListIterator::from_pointer(a); + ElementType::Struct(buf) | ElementType::Array(buf) | ElementType::List(buf) => { + let mut our_iter = TLVListIterator::from_buf(buf); let mut their = match other.element_type { - ElementType::Struct(b) | ElementType::Array(b) | ElementType::List(b) => { - TLVListIterator::from_pointer(b) + ElementType::Struct(buf) | ElementType::Array(buf) | ElementType::List(buf) => { + TLVListIterator::from_buf(buf) } _ => { // If we are a container, the other must be a container, else this is a mismatch @@ -336,7 +296,7 @@ impl<'a> PartialEq for TLVElement<'a> { } nest_level -= 1; } else { - if is_container(ours.element_type) { + if is_container(&ours.element_type) { nest_level += 1; // Only compare the discriminants in case of array/list/structures, // instead of actual element values. Those will be subsets within this same @@ -364,15 +324,11 @@ impl<'a> PartialEq for TLVElement<'a> { impl<'a> TLVElement<'a> { pub fn enter(&self) -> Option> { - let ptr = match self.element_type { - ElementType::Struct(a) | ElementType::Array(a) | ElementType::List(a) => a, + let buf = match self.element_type { + ElementType::Struct(buf) | ElementType::Array(buf) | ElementType::List(buf) => buf, _ => return None, }; - let list_iter = TLVListIterator { - buf: ptr.buf, - current: ptr.current, - left: ptr.left, - }; + let list_iter = TLVListIterator { buf, current: 0 }; Some(TLVContainerIterator { list_iter, prev_container: false, @@ -465,23 +421,23 @@ impl<'a> TLVElement<'a> { } } - pub fn confirm_struct(&self) -> Result, Error> { + pub fn confirm_struct(&self) -> Result<&TLVElement<'a>, Error> { match self.element_type { - ElementType::Struct(_) => Ok(*self), + ElementType::Struct(_) => Ok(self), _ => Err(ErrorCode::TLVTypeMismatch.into()), } } - pub fn confirm_array(&self) -> Result, Error> { + pub fn confirm_array(&self) -> Result<&TLVElement<'a>, Error> { match self.element_type { - ElementType::Array(_) => Ok(*self), + ElementType::Array(_) => Ok(self), _ => Err(ErrorCode::TLVTypeMismatch.into()), } } - pub fn confirm_list(&self) -> Result, Error> { + pub fn confirm_list(&self) -> Result<&TLVElement<'a>, Error> { match self.element_type { - ElementType::List(_) => Ok(*self), + ElementType::List(_) => Ok(self), _ => Err(ErrorCode::TLVTypeMismatch.into()), } } @@ -511,8 +467,8 @@ impl<'a> TLVElement<'a> { false } - pub fn get_element_type(&self) -> ElementType { - self.element_type + pub fn get_element_type(&self) -> &ElementType { + &self.element_type } } @@ -546,25 +502,19 @@ impl<'a> fmt::Display for TLVElement<'a> { } // This is a TLV List iterator, it only iterates over the individual TLVs in a TLV list -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub struct TLVListIterator<'a> { buf: &'a [u8], current: usize, - left: usize, } impl<'a> TLVListIterator<'a> { - fn from_pointer(p: Pointer<'a>) -> Self { - Self { - buf: p.buf, - current: p.current, - left: p.left, - } + fn from_buf(buf: &'a [u8]) -> Self { + Self { buf, current: 0 } } fn advance(&mut self, len: usize) { self.current += len; - self.left -= len; } // Caller should ensure they are reading the _right_ tag at the _right_ place @@ -573,7 +523,7 @@ impl<'a> TLVListIterator<'a> { return None; } let tag_size = TAG_SIZE_MAP[tag_type as usize]; - if tag_size > self.left { + if tag_size > self.buf.len() - self.current { return None; } let tag = (TAG_EXTRACTOR[tag_type as usize])(self); @@ -586,7 +536,7 @@ impl<'a> TLVListIterator<'a> { return None; } let mut size = VALUE_SIZE_MAP[element_type as usize]; - if size > self.left { + if size > self.buf.len() - self.current { error!( "Invalid value found: {} self {:?} size {}", element_type, self, size @@ -609,7 +559,7 @@ impl<'a> Iterator for TLVListIterator<'a> { type Item = TLVElement<'a>; /* Code for going to the next Element */ fn next(&mut self) -> Option> { - if self.left < 1 { + if self.buf.len() - self.current < 1 { return None; } /* Read Control */ @@ -635,13 +585,12 @@ impl<'a> TLVList<'a> { pub fn iter(&self) -> TLVListIterator<'a> { TLVListIterator { current: 0, - left: self.buf.len(), buf: self.buf, } } } -fn is_container(element_type: ElementType) -> bool { +fn is_container(element_type: &ElementType) -> bool { matches!( element_type, ElementType::Struct(_) | ElementType::Array(_) | ElementType::List(_) @@ -680,7 +629,7 @@ impl<'a> TLVContainerIterator<'a> { nest_level -= 1; } _ => { - if is_container(element.element_type) { + if is_container(&element.element_type) { nest_level += 1; } } @@ -711,7 +660,7 @@ impl<'a> Iterator for TLVContainerIterator<'a> { return None; } - self.prev_container = is_container(element.element_type); + self.prev_container = is_container(&element.element_type); Some(element) } } @@ -724,19 +673,25 @@ pub fn get_root_node(b: &[u8]) -> Result { } pub fn get_root_node_struct(b: &[u8]) -> Result { - TLVList::new(b) + let root = TLVList::new(b) .iter() .next() - .ok_or(ErrorCode::InvalidData)? - .confirm_struct() + .ok_or(ErrorCode::InvalidData)?; + + root.confirm_struct()?; + + Ok(root) } pub fn get_root_node_list(b: &[u8]) -> Result { - TLVList::new(b) + let root = TLVList::new(b) .iter() .next() - .ok_or(ErrorCode::InvalidData)? - .confirm_list() + .ok_or(ErrorCode::InvalidData)?; + + root.confirm_list()?; + + Ok(root) } pub fn print_tlv_list(b: &[u8]) { @@ -798,8 +753,7 @@ mod tests { use log::info; use super::{ - get_root_node_list, get_root_node_struct, ElementType, Pointer, TLVElement, TLVList, - TagType, + get_root_node_list, get_root_node_struct, ElementType, TLVElement, TLVList, TagType, }; use crate::error::ErrorCode; @@ -859,11 +813,7 @@ mod tests { tlv_iter.next(), Some(TLVElement { tag_type: TagType::Context(0), - element_type: ElementType::Array(Pointer { - buf: &[21, 54, 0], - current: 3, - left: 0 - }), + element_type: ElementType::Array(&[]), }) ); } @@ -1123,7 +1073,8 @@ mod tests { // This is an array of CommandDataIB, but we'll only use the first element let cmd_data_ib = cmd_list_iter.next().unwrap(); - let cmd_path = cmd_data_ib.find_tag(0).unwrap().confirm_list().unwrap(); + let cmd_path = cmd_data_ib.find_tag(0).unwrap(); + let cmd_path = cmd_path.confirm_list().unwrap(); assert_eq!( cmd_path.find_tag(0).unwrap(), TLVElement { @@ -1188,11 +1139,7 @@ mod tests { 0x35, 0x1, 0x18, 0x18, 0x18, 0x18, ]; - let dummy_pointer = Pointer { - buf: &b, - current: 1, - left: 21, - }; + let dummy_pointer = &b[1..]; // These are the decoded elements that we expect from this input let verify_matrix: [(TagType, ElementType); 13] = [ (TagType::Anonymous, ElementType::Struct(dummy_pointer)), diff --git a/matter/src/tlv/traits.rs b/matter/src/tlv/traits.rs index 28c236b..9a8edcd 100644 --- a/matter/src/tlv/traits.rs +++ b/matter/src/tlv/traits.rs @@ -298,7 +298,7 @@ impl ToTLV for Nullable { } } -#[derive(Copy, Clone)] +#[derive(Clone)] pub enum TLVArray<'a, T> { // This is used for the to-tlv path Slice(&'a [T]), @@ -317,7 +317,7 @@ impl<'a, T: ToTLV> TLVArray<'a, T> { } pub fn iter(&self) -> TLVArrayIter<'a, T> { - match *self { + match self { Self::Slice(s) => TLVArrayIter::Slice(s.iter()), Self::Ptr(p) => TLVArrayIter::Ptr(p.enter()), } @@ -401,7 +401,7 @@ impl<'a, T: FromTLV<'a> + Clone + ToTLV> ToTLV for TLVArray<'a, T> { impl<'a, T> FromTLV<'a> for TLVArray<'a, T> { fn from_tlv(t: &TLVElement<'a>) -> Result { t.confirm_array()?; - Ok(Self::Ptr(*t)) + Ok(Self::Ptr(t.clone())) } } diff --git a/matter/src/transport/mrp.rs b/matter/src/transport/mrp.rs index 2d046bf..d981591 100644 --- a/matter/src/transport/mrp.rs +++ b/matter/src/transport/mrp.rs @@ -41,7 +41,7 @@ impl RetransEntry { } } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Clone)] pub struct AckEntry { // The msg counter that we should acknowledge msg_ctr: u32, @@ -92,7 +92,7 @@ impl ReliableMessage { // Check any pending acknowledgements / retransmissions and take action pub fn is_ack_ready(&self, epoch: Epoch) -> bool { // Acknowledgements - if let Some(ack_entry) = self.ack { + if let Some(ack_entry) = &self.ack { ack_entry.has_timed_out(epoch) } else { false @@ -107,7 +107,7 @@ impl ReliableMessage { // Check if any acknowledgements are pending for this exchange, // if so, piggy back in the encoded header here - if let Some(ack_entry) = self.ack { + if let Some(ack_entry) = &self.ack { // Ack Entry exists, set ACK bit and remove from table proto_tx.proto.set_ack(ack_entry.get_msg_ctr()); self.ack = None; diff --git a/matter/src/transport/session.rs b/matter/src/transport/session.rs index 1e3a1d4..1c2e936 100644 --- a/matter/src/transport/session.rs +++ b/matter/src/transport/session.rs @@ -37,7 +37,7 @@ pub type NocCatIds = [u32; MAX_CAT_IDS_PER_NOC]; const MATTER_AES128_KEY_SIZE: usize = 16; -#[derive(Debug, Default, Copy, Clone, PartialEq)] +#[derive(Debug, Default, Clone, PartialEq)] pub struct CaseDetails { pub fab_idx: u8, pub cat_ids: NocCatIds, @@ -52,7 +52,7 @@ impl CaseDetails { } } -#[derive(Debug, PartialEq, Copy, Clone, Default)] +#[derive(Debug, PartialEq, Clone, Default)] pub enum SessionMode { // The Case session will capture the local fabric index Case(CaseDetails), @@ -149,7 +149,7 @@ impl Session { peer_sess_id: clone_from.peer_sess_id, msg_ctr: Self::rand_msg_ctr(rand), rx_ctr_state: RxCtrState::new(0), - mode: clone_from.mode, + mode: clone_from.mode.clone(), data: None, last_use: epoch(), } @@ -207,14 +207,14 @@ impl Session { } pub fn get_local_fabric_idx(&self) -> Option { - match self.mode { + match &self.mode { SessionMode::Case(a) => Some(a.fab_idx), _ => None, } } - pub fn get_session_mode(&self) -> SessionMode { - self.mode + pub fn get_session_mode(&self) -> &SessionMode { + &self.mode } pub fn get_msg_ctr(&mut self) -> u32 { @@ -454,7 +454,7 @@ impl SessionMgr { Some(self.get_session_handle(index)) } - fn get_or_add( + pub fn get_or_add( &mut self, sess_id: u16, peer_addr: Address, diff --git a/matter/tests/common/attributes.rs b/matter/tests/common/attributes.rs index 2ff95eb..3a4f5e7 100644 --- a/matter/tests/common/attributes.rs +++ b/matter/tests/common/attributes.rs @@ -28,7 +28,7 @@ pub fn __assert_attr_report(received: &ReportDataMsg, expected: &[AttrResp], ski // We can't use assert_eq because it will also try to match data-version for inv_response in received.attr_reports.as_ref().unwrap().iter() { println!("Validating index {}", index); - match expected[index] { + match &expected[index] { AttrResp::Data(e_d) => match inv_response { AttrResp::Data(d) => { // We don't match the data-version @@ -41,7 +41,7 @@ pub fn __assert_attr_report(received: &ReportDataMsg, expected: &[AttrResp], ski panic!("Invalid response, expected AttrRespIn::Data"); } }, - AttrResp::Status(s) => assert_eq!(AttrResp::Status(s), inv_response), + AttrResp::Status(s) => assert_eq!(AttrResp::Status(s.clone()), inv_response), } println!("Index {} success", index); index += 1; diff --git a/matter/tests/common/commands.rs b/matter/tests/common/commands.rs index 419b6ac..d1e0402 100644 --- a/matter/tests/common/commands.rs +++ b/matter/tests/common/commands.rs @@ -30,15 +30,15 @@ pub enum ExpectedInvResp { pub fn assert_inv_response(resp: &msg::InvResp, expected: &[ExpectedInvResp]) { let mut index = 0; - for inv_response in resp.inv_responses.unwrap().iter() { + for inv_response in resp.inv_responses.as_ref().unwrap().iter() { println!("Validating index {}", index); - match expected[index] { + match &expected[index] { ExpectedInvResp::Cmd(e_c, e_d) => match inv_response { InvResp::Cmd(c) => { - assert_eq!(e_c, c.path); + assert_eq!(e_c, &c.path); match c.data { EncodeValue::Tlv(t) => { - assert_eq!(e_d, t.find_tag(0).unwrap().u8().unwrap()) + assert_eq!(*e_d, t.find_tag(0).unwrap().u8().unwrap()) } _ => panic!("Incorrect CmdDataType"), } @@ -49,7 +49,7 @@ pub fn assert_inv_response(resp: &msg::InvResp, expected: &[ExpectedInvResp]) { }, ExpectedInvResp::Status(e_status) => match inv_response { InvResp::Status(status) => { - assert_eq!(e_status, status); + assert_eq!(e_status, &status); } _ => { panic!("Invalid response, expected InvResponse::Status"); @@ -64,7 +64,7 @@ pub fn assert_inv_response(resp: &msg::InvResp, expected: &[ExpectedInvResp]) { #[macro_export] macro_rules! cmd_data { - ($path:ident, $data:literal) => { + ($path:expr, $data:literal) => { CmdData::new($path, EncodeValue::Value(&($data as u32))) }; } diff --git a/matter/tests/data_model/acl_and_dataver.rs b/matter/tests/data_model/acl_and_dataver.rs index 81f220a..ebb831c 100644 --- a/matter/tests/data_model/acl_and_dataver.rs +++ b/matter/tests/data_model/acl_and_dataver.rs @@ -429,7 +429,7 @@ fn write_with_runtime_acl_add() { peer, None, // write to echo-cluster attribute, write to acl attribute, write to echo-cluster attribute - &[input0, acl_input, input0], + &[input0.clone(), acl_input, input0], &[ AttrStatus::new(&ep0_att, IMStatusCode::UnsupportedAccess, 0), AttrStatus::new(&acl_att, IMStatusCode::Success, 0), @@ -597,7 +597,7 @@ fn test_write_data_ver() { let input_correct_dataver = &[AttrData::new( Some(initial_data_ver), AttrPath::new(&ep0_attwrite), - attr_data1, + attr_data1.clone(), )]; im.handle_write_reqs( peer, diff --git a/matter/tests/data_model/attribute_lists.rs b/matter/tests/data_model/attribute_lists.rs index aaa2b63..636c9c0 100644 --- a/matter/tests/data_model/attribute_lists.rs +++ b/matter/tests/data_model/attribute_lists.rs @@ -59,7 +59,11 @@ fn attr_list_ops() { let mut att_path = AttrPath::new(&att_data); // Test 1: Add Operation - add val0 - let input = &[AttrData::new(None, att_path, EncodeValue::Value(&val0))]; + let input = &[AttrData::new( + None, + att_path.clone(), + EncodeValue::Value(&val0), + )]; let expected = &[AttrStatus::new(&att_data, IMStatusCode::Success, 0)]; ImEngine::new_with_write_reqs(&matter(&mut DummyMdns), input, expected); @@ -69,7 +73,11 @@ fn attr_list_ops() { } // Test 2: Another Add Operation - add val1 - let input = &[AttrData::new(None, att_path, EncodeValue::Value(&val1))]; + let input = &[AttrData::new( + None, + att_path.clone(), + EncodeValue::Value(&val1), + )]; let expected = &[AttrStatus::new(&att_data, IMStatusCode::Success, 0)]; ImEngine::new_with_write_reqs(&matter(&mut DummyMdns), input, expected); @@ -80,7 +88,11 @@ fn attr_list_ops() { // Test 3: Edit Operation - edit val1 to val0 att_path.list_index = Some(Nullable::NotNull(1)); - let input = &[AttrData::new(None, att_path, EncodeValue::Value(&val0))]; + let input = &[AttrData::new( + None, + att_path.clone(), + EncodeValue::Value(&val0), + )]; let expected = &[AttrStatus::new(&att_data, IMStatusCode::Success, 0)]; ImEngine::new_with_write_reqs(&matter(&mut DummyMdns), input, expected); @@ -91,7 +103,7 @@ fn attr_list_ops() { // Test 4: Delete Operation - delete index 0 att_path.list_index = Some(Nullable::NotNull(0)); - let input = &[AttrData::new(None, att_path, delete_item)]; + let input = &[AttrData::new(None, att_path.clone(), delete_item)]; let expected = &[AttrStatus::new(&att_data, IMStatusCode::Success, 0)]; ImEngine::new_with_write_reqs(&matter(&mut DummyMdns), input, expected); @@ -105,7 +117,7 @@ fn attr_list_ops() { att_path.list_index = None; let input = &[AttrData::new( None, - att_path, + att_path.clone(), EncodeValue::Value(&overwrite_val), )]; let expected = &[AttrStatus::new(&att_data, IMStatusCode::Success, 0)]; diff --git a/matter/tests/data_model/attributes.rs b/matter/tests/data_model/attributes.rs index 6d1072c..7d18526 100644 --- a/matter/tests/data_model/attributes.rs +++ b/matter/tests/data_model/attributes.rs @@ -218,7 +218,7 @@ fn test_read_wc_endpoint_wc_attribute() { Some(echo_cluster::ID), Some(GlobalElements::AttributeList as u32), ), - attr_list_tlv.get_element_type() + attr_list_tlv.get_element_type().clone() ), attr_data_path!( GenericPath::new( @@ -258,7 +258,7 @@ fn test_read_wc_endpoint_wc_attribute() { Some(echo_cluster::ID), Some(GlobalElements::AttributeList as u32), ), - attr_list_tlv.get_element_type() + attr_list_tlv.get_element_type().clone() ), attr_data_path!( GenericPath::new( diff --git a/matter/tests/data_model/commands.rs b/matter/tests/data_model/commands.rs index a232f26..0d9c0c3 100644 --- a/matter/tests/data_model/commands.rs +++ b/matter/tests/data_model/commands.rs @@ -75,10 +75,10 @@ fn test_invoke_cmds_unsupported_fields() { let invalid_command = CmdPath::new(Some(0), Some(echo_cluster::ID), Some(0x1234)); let invalid_command_wc_endpoint = CmdPath::new(None, Some(echo_cluster::ID), Some(0x1234)); let input = &[ - cmd_data!(invalid_endpoint, 5), - cmd_data!(invalid_cluster, 5), + cmd_data!(invalid_endpoint.clone(), 5), + cmd_data!(invalid_cluster.clone(), 5), cmd_data!(invalid_cluster_wc_endpoint, 5), - cmd_data!(invalid_command, 5), + cmd_data!(invalid_command.clone(), 5), cmd_data!(invalid_command_wc_endpoint, 5), ]; diff --git a/matter/tests/data_model/long_reads.rs b/matter/tests/data_model/long_reads.rs index a396cc0..21c2559 100644 --- a/matter/tests/data_model/long_reads.rs +++ b/matter/tests/data_model/long_reads.rs @@ -77,163 +77,228 @@ fn wildcard_read_resp(part: u8) -> Vec> { // For brevity, we only check the AttrPath, not the actual 'data' let dont_care = ElementType::U8(0); let part1 = vec![ - attr_data!(0, 29, GlobalElements::FeatureMap, dont_care), - attr_data!(0, 29, GlobalElements::AttributeList, dont_care), - attr_data!(0, 29, descriptor::Attributes::DeviceTypeList, dont_care), - attr_data!(0, 29, descriptor::Attributes::ServerList, dont_care), - attr_data!(0, 29, descriptor::Attributes::PartsList, dont_care), - attr_data!(0, 29, descriptor::Attributes::ClientList, dont_care), - attr_data!(0, 40, GlobalElements::FeatureMap, dont_care), - attr_data!(0, 40, GlobalElements::AttributeList, dont_care), + attr_data!(0, 29, GlobalElements::FeatureMap, dont_care.clone()), + attr_data!(0, 29, GlobalElements::AttributeList, dont_care.clone()), + attr_data!( + 0, + 29, + descriptor::Attributes::DeviceTypeList, + dont_care.clone() + ), + attr_data!(0, 29, descriptor::Attributes::ServerList, dont_care.clone()), + attr_data!(0, 29, descriptor::Attributes::PartsList, dont_care.clone()), + attr_data!(0, 29, descriptor::Attributes::ClientList, dont_care.clone()), + attr_data!(0, 40, GlobalElements::FeatureMap, dont_care.clone()), + attr_data!(0, 40, GlobalElements::AttributeList, dont_care.clone()), attr_data!( 0, 40, basic_info::AttributesDiscriminants::DMRevision, - dont_care + dont_care.clone() ), attr_data!( 0, 40, basic_info::AttributesDiscriminants::VendorId, - dont_care + dont_care.clone() ), attr_data!( 0, 40, basic_info::AttributesDiscriminants::ProductId, - dont_care + dont_care.clone() + ), + attr_data!( + 0, + 40, + basic_info::AttributesDiscriminants::HwVer, + dont_care.clone() + ), + attr_data!( + 0, + 40, + basic_info::AttributesDiscriminants::SwVer, + dont_care.clone() ), - attr_data!(0, 40, basic_info::AttributesDiscriminants::HwVer, dont_care), - attr_data!(0, 40, basic_info::AttributesDiscriminants::SwVer, dont_care), attr_data!( 0, 40, basic_info::AttributesDiscriminants::SwVerString, - dont_care + dont_care.clone() ), attr_data!( 0, 40, basic_info::AttributesDiscriminants::SerialNo, - dont_care + dont_care.clone() ), - attr_data!(0, 48, GlobalElements::FeatureMap, dont_care), - attr_data!(0, 48, GlobalElements::AttributeList, dont_care), + attr_data!(0, 48, GlobalElements::FeatureMap, dont_care.clone()), + attr_data!(0, 48, GlobalElements::AttributeList, dont_care.clone()), attr_data!( 0, 48, gen_comm::AttributesDiscriminants::BreadCrumb, - dont_care + dont_care.clone() ), attr_data!( 0, 48, gen_comm::AttributesDiscriminants::RegConfig, - dont_care + dont_care.clone() ), attr_data!( 0, 48, gen_comm::AttributesDiscriminants::LocationCapability, - dont_care + dont_care.clone() ), attr_data!( 0, 48, gen_comm::AttributesDiscriminants::BasicCommissioningInfo, - dont_care + dont_care.clone() ), - attr_data!(0, 49, GlobalElements::FeatureMap, dont_care), - attr_data!(0, 49, GlobalElements::AttributeList, dont_care), - attr_data!(0, 60, GlobalElements::FeatureMap, dont_care), - attr_data!(0, 60, GlobalElements::AttributeList, dont_care), + attr_data!(0, 49, GlobalElements::FeatureMap, dont_care.clone()), + attr_data!(0, 49, GlobalElements::AttributeList, dont_care.clone()), + attr_data!(0, 60, GlobalElements::FeatureMap, dont_care.clone()), + attr_data!(0, 60, GlobalElements::AttributeList, dont_care.clone()), attr_data!( 0, 60, adm_comm::AttributesDiscriminants::WindowStatus, - dont_care + dont_care.clone() ), attr_data!( 0, 60, adm_comm::AttributesDiscriminants::AdminFabricIndex, - dont_care + dont_care.clone() ), attr_data!( 0, 60, adm_comm::AttributesDiscriminants::AdminVendorId, - dont_care + dont_care.clone() ), - attr_data!(0, 62, GlobalElements::FeatureMap, dont_care), - attr_data!(0, 62, GlobalElements::AttributeList, dont_care), + attr_data!(0, 62, GlobalElements::FeatureMap, dont_care.clone()), + attr_data!(0, 62, GlobalElements::AttributeList, dont_care.clone()), attr_data!( 0, 62, noc::AttributesDiscriminants::CurrentFabricIndex, - dont_care + dont_care.clone() + ), + attr_data!( + 0, + 62, + noc::AttributesDiscriminants::Fabrics, + dont_care.clone() ), - attr_data!(0, 62, noc::AttributesDiscriminants::Fabrics, dont_care), attr_data!( 0, 62, noc::AttributesDiscriminants::SupportedFabrics, - dont_care + dont_care.clone() ), attr_data!( 0, 62, noc::AttributesDiscriminants::CommissionedFabrics, - dont_care + dont_care.clone() + ), + attr_data!(0, 31, GlobalElements::FeatureMap, dont_care.clone()), + attr_data!(0, 31, GlobalElements::AttributeList, dont_care.clone()), + attr_data!(0, 31, acl::AttributesDiscriminants::Acl, dont_care.clone()), + attr_data!( + 0, + 31, + acl::AttributesDiscriminants::Extension, + dont_care.clone() ), - attr_data!(0, 31, GlobalElements::FeatureMap, dont_care), - attr_data!(0, 31, GlobalElements::AttributeList, dont_care), - attr_data!(0, 31, acl::AttributesDiscriminants::Acl, dont_care), - attr_data!(0, 31, acl::AttributesDiscriminants::Extension, dont_care), attr_data!( 0, 31, acl::AttributesDiscriminants::SubjectsPerEntry, - dont_care + dont_care.clone() ), attr_data!( 0, 31, acl::AttributesDiscriminants::TargetsPerEntry, - dont_care + dont_care.clone() ), attr_data!( 0, 31, acl::AttributesDiscriminants::EntriesPerFabric, - dont_care + dont_care.clone() + ), + attr_data!(0, echo::ID, GlobalElements::FeatureMap, dont_care.clone()), + attr_data!( + 0, + echo::ID, + GlobalElements::AttributeList, + dont_care.clone() + ), + attr_data!( + 0, + echo::ID, + echo::AttributesDiscriminants::Att1, + dont_care.clone() + ), + attr_data!( + 0, + echo::ID, + echo::AttributesDiscriminants::Att2, + dont_care.clone() ), - attr_data!(0, echo::ID, GlobalElements::FeatureMap, dont_care), - attr_data!(0, echo::ID, GlobalElements::AttributeList, dont_care), - attr_data!(0, echo::ID, echo::AttributesDiscriminants::Att1, dont_care), - attr_data!(0, echo::ID, echo::AttributesDiscriminants::Att2, dont_care), attr_data!( 0, echo::ID, echo::AttributesDiscriminants::AttCustom, - dont_care + dont_care.clone() + ), + attr_data!(1, 29, GlobalElements::FeatureMap, dont_care.clone()), + attr_data!(1, 29, GlobalElements::AttributeList, dont_care.clone()), + attr_data!( + 1, + 29, + descriptor::Attributes::DeviceTypeList, + dont_care.clone() ), - attr_data!(1, 29, GlobalElements::FeatureMap, dont_care), - attr_data!(1, 29, GlobalElements::AttributeList, dont_care), - attr_data!(1, 29, descriptor::Attributes::DeviceTypeList, dont_care), ]; let part2 = vec![ - attr_data!(1, 29, descriptor::Attributes::ServerList, dont_care), - attr_data!(1, 29, descriptor::Attributes::PartsList, dont_care), - attr_data!(1, 29, descriptor::Attributes::ClientList, dont_care), - attr_data!(1, 6, GlobalElements::FeatureMap, dont_care), - attr_data!(1, 6, GlobalElements::AttributeList, dont_care), - attr_data!(1, 6, onoff::AttributesDiscriminants::OnOff, dont_care), - attr_data!(1, echo::ID, GlobalElements::FeatureMap, dont_care), - attr_data!(1, echo::ID, GlobalElements::AttributeList, dont_care), - attr_data!(1, echo::ID, echo::AttributesDiscriminants::Att1, dont_care), - attr_data!(1, echo::ID, echo::AttributesDiscriminants::Att2, dont_care), + attr_data!(1, 29, descriptor::Attributes::ServerList, dont_care.clone()), + attr_data!(1, 29, descriptor::Attributes::PartsList, dont_care.clone()), + attr_data!(1, 29, descriptor::Attributes::ClientList, dont_care.clone()), + attr_data!(1, 6, GlobalElements::FeatureMap, dont_care.clone()), + attr_data!(1, 6, GlobalElements::AttributeList, dont_care.clone()), + attr_data!( + 1, + 6, + onoff::AttributesDiscriminants::OnOff, + dont_care.clone() + ), + attr_data!(1, echo::ID, GlobalElements::FeatureMap, dont_care.clone()), + attr_data!( + 1, + echo::ID, + GlobalElements::AttributeList, + dont_care.clone() + ), + attr_data!( + 1, + echo::ID, + echo::AttributesDiscriminants::Att1, + dont_care.clone() + ), + attr_data!( + 1, + echo::ID, + echo::AttributesDiscriminants::Att2, + dont_care.clone() + ), attr_data!( 1, echo::ID, diff --git a/matter_macro_derive/src/lib.rs b/matter_macro_derive/src/lib.rs index c63eddc..619bf3b 100644 --- a/matter_macro_derive/src/lib.rs +++ b/matter_macro_derive/src/lib.rs @@ -323,7 +323,7 @@ fn gen_fromtlv_for_struct( let mut t_iter = t.#datatype ()?.enter().ok_or_else(|| #krate::error::Error::new(#krate::error::ErrorCode::Invalid))?; let mut item = t_iter.next(); #( - let #idents = if Some(true) == item.map(|x| x.check_ctx_tag(#tags)) { + let #idents = if Some(true) == item.as_ref().map(|x| x.check_ctx_tag(#tags)) { let backup = item; item = t_iter.next(); #types::from_tlv(&backup.unwrap())