Control memory by removing implicit copy

This commit is contained in:
ivmarkov 2023-05-28 11:04:46 +00:00
parent 1e6cd69de8
commit 357eb73c6f
19 changed files with 281 additions and 255 deletions

View file

@ -260,7 +260,7 @@ impl<'a> AccessReq<'a> {
} }
} }
#[derive(FromTLV, ToTLV, Copy, Clone, Debug, PartialEq)] #[derive(FromTLV, ToTLV, Clone, Debug, PartialEq)]
pub struct Target { pub struct Target {
cluster: Option<ClusterId>, cluster: Option<ClusterId>,
endpoint: Option<EndptId>, endpoint: Option<EndptId>,
@ -283,7 +283,7 @@ impl Target {
type Subjects = [Option<u64>; SUBJECTS_PER_ENTRY]; type Subjects = [Option<u64>; SUBJECTS_PER_ENTRY];
type Targets = [Option<Target>; TARGETS_PER_ENTRY]; type Targets = [Option<Target>; TARGETS_PER_ENTRY];
#[derive(ToTLV, FromTLV, Copy, Clone, Debug, PartialEq)] #[derive(ToTLV, FromTLV, Clone, Debug, PartialEq)]
#[tlvargs(start = 1)] #[tlvargs(start = 1)]
pub struct AclEntry { pub struct AclEntry {
privilege: Privilege, privilege: Privilege,
@ -463,7 +463,11 @@ impl AclMgr {
pub fn delete_for_fabric(&mut self, fab_idx: u8) -> Result<(), Error> { pub fn delete_for_fabric(&mut self, fab_idx: u8) -> Result<(), Error> {
for entry in &mut self.entries { 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; *entry = None;
self.changed = true; self.changed = true;
} }
@ -545,7 +549,11 @@ impl AclMgr {
for (curr_index, entry) in self for (curr_index, entry) in self
.entries .entries
.iter_mut() .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() .enumerate()
{ {
if curr_index == index as usize { if curr_index == index as usize {
@ -779,7 +787,7 @@ mod tests {
am.borrow_mut().add(new).unwrap(); am.borrow_mut().add(new).unwrap();
// Write on an RWVA without admin access - deny // 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); req.set_target_perms(Access::RWVA);
assert_eq!(req.allow(), false); assert_eq!(req.allow(), false);
@ -806,7 +814,7 @@ mod tests {
am.borrow_mut().erase_all().unwrap(); am.borrow_mut().erase_all().unwrap();
let path = GenericPath::new(Some(1), Some(1234), None); let path = GenericPath::new(Some(1), Some(1234), None);
let accessor2 = Accessor::new(2, AccessorSubjects::new(112233), AuthMode::Case, &am); 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); req2.set_target_perms(Access::RWVA);
let accessor3 = Accessor::new(3, AccessorSubjects::new(112233), AuthMode::Case, &am); let accessor3 = Accessor::new(3, AccessorSubjects::new(112233), AuthMode::Case, &am);
let mut req3 = AccessReq::new(&accessor3, path, Access::READ); let mut req3 = AccessReq::new(&accessor3, path, Access::READ);

View file

@ -39,7 +39,7 @@ use super::{AttrDetails, CmdDetails, Handler};
// the tw.rewind() in that case, if we add this support // the tw.rewind() in that case, if we add this support
pub type EncodeValueGen<'a> = &'a dyn Fn(TagType, &mut TLVWriter); pub type EncodeValueGen<'a> = &'a dyn Fn(TagType, &mut TLVWriter);
#[derive(Copy, Clone)] #[derive(Clone)]
/// A structure for encoding various types of values /// A structure for encoding various types of values
pub enum EncodeValue<'a> { pub enum EncodeValue<'a> {
/// This indicates a value that is dynamically generated. This variant /// This indicates a value that is dynamically generated. This variant
@ -66,13 +66,13 @@ impl<'a> EncodeValue<'a> {
impl<'a> PartialEq for EncodeValue<'a> { impl<'a> PartialEq for EncodeValue<'a> {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
match *self { match self {
EncodeValue::Closure(_) => { EncodeValue::Closure(_) => {
error!("PartialEq not yet supported"); error!("PartialEq not yet supported");
false false
} }
EncodeValue::Tlv(a) => { EncodeValue::Tlv(a) => {
if let EncodeValue::Tlv(b) = *other { if let EncodeValue::Tlv(b) = other {
a == b a == b
} else { } else {
false false
@ -89,7 +89,7 @@ impl<'a> PartialEq for EncodeValue<'a> {
impl<'a> Debug for EncodeValue<'a> { impl<'a> Debug for EncodeValue<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
match *self { match self {
EncodeValue::Closure(_) => write!(f, "Contains closure"), EncodeValue::Closure(_) => write!(f, "Contains closure"),
EncodeValue::Tlv(t) => write!(f, "{:?}", t), EncodeValue::Tlv(t) => write!(f, "{:?}", t),
EncodeValue::Value(_) => write!(f, "Contains EncodeValue"), EncodeValue::Value(_) => write!(f, "Contains EncodeValue"),
@ -113,7 +113,7 @@ impl<'a> ToTLV for EncodeValue<'a> {
impl<'a> FromTLV<'a> for EncodeValue<'a> { impl<'a> FromTLV<'a> for EncodeValue<'a> {
fn from_tlv(data: &TLVElement<'a>) -> Result<Self, Error> { fn from_tlv(data: &TLVElement<'a>) -> Result<Self, Error> {
Ok(EncodeValue::Tlv(*data)) Ok(EncodeValue::Tlv(data.clone()))
} }
} }

View file

@ -84,11 +84,11 @@ impl<'a> Iterable for Option<&'a TLVArray<'a, DataVersionFilter>> {
impl<'a> Iterable for &'a [DataVersionFilter] { impl<'a> Iterable for &'a [DataVersionFilter] {
type Item = DataVersionFilter; type Item = DataVersionFilter;
type Iterator<'i> = core::iter::Copied<core::slice::Iter<'i, DataVersionFilter>> where Self: 'i; type Iterator<'i> = core::iter::Cloned<core::slice::Iter<'i, DataVersionFilter>> where Self: 'i;
fn iter(&self) -> Self::Iterator<'_> { fn iter(&self) -> Self::Iterator<'_> {
let slice: &[DataVersionFilter] = self; let slice: &[DataVersionFilter] = self;
slice.iter().copied() slice.iter().cloned()
} }
} }
@ -127,11 +127,11 @@ impl<'a> Node<'a> {
's: 'm, 's: 'm,
{ {
self.read_attr_requests( self.read_attr_requests(
req.paths.iter().copied(), req.paths.iter().cloned(),
req.filters.as_slice(), req.filters.as_slice(),
req.fabric_filtered, req.fabric_filtered,
accessor, accessor,
Some(req.resume_path), Some(req.resume_path.clone()),
) )
} }
@ -163,11 +163,11 @@ impl<'a> Node<'a> {
's: 'm, 's: 'm,
{ {
self.read_attr_requests( self.read_attr_requests(
req.paths.iter().copied(), req.paths.iter().cloned(),
req.filters.as_slice(), req.filters.as_slice(),
req.fabric_filtered, req.fabric_filtered,
accessor, 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| { attr_requests.flat_map(move |path| {
if path.to_gp().is_wildcard() { if path.to_gp().is_wildcard() {
let dataver_filters = dataver_filters.clone(); let dataver_filters = dataver_filters.clone();
let from = from; let from = from.clone();
let iter = self let iter = self
.match_attributes(path.endpoint, path.cluster, path.attr) .match_attributes(path.endpoint, path.cluster, path.attr)
@ -302,7 +302,7 @@ impl<'a> Node<'a> {
dataver: attr_data.data_ver, dataver: attr_data.data_ver,
wildcard: true, 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, cmd_id: cmd,
wildcard: true, wildcard: true,
}, },
cmd_data.data.unwrap_tlv().unwrap(), cmd_data.data.clone().unwrap_tlv().unwrap(),
)) ))
}); });

View file

@ -205,7 +205,10 @@ impl<'a> GenCommCluster<'a> {
let status = if self let status = if self
.failsafe .failsafe
.borrow_mut() .borrow_mut()
.arm(p.expiry_len, transaction.session().get_session_mode()) .arm(
p.expiry_len,
transaction.session().get_session_mode().clone(),
)
.is_err() .is_err()
{ {
CommissioningError::ErrBusyWithOtherAdmin as u8 CommissioningError::ErrBusyWithOtherAdmin as u8
@ -271,7 +274,7 @@ impl<'a> GenCommCluster<'a> {
if self if self
.failsafe .failsafe
.borrow_mut() .borrow_mut()
.disarm(transaction.session().get_session_mode()) .disarm(transaction.session().get_session_mode().clone())
.is_err() .is_err()
{ {
status = CommissioningError::ErrInvalidAuth as u8; status = CommissioningError::ErrInvalidAuth as u8;

View file

@ -255,8 +255,8 @@ mod tests {
AclEntry::new(1, Privilege::VIEW, AuthMode::Case), AclEntry::new(1, Privilege::VIEW, AuthMode::Case),
AclEntry::new(2, Privilege::ADMIN, AuthMode::Case), AclEntry::new(2, Privilege::ADMIN, AuthMode::Case),
]; ];
for i in verifier { for i in &verifier {
acl_mgr.borrow_mut().add(i).unwrap(); acl_mgr.borrow_mut().add(i.clone()).unwrap();
} }
let mut acl = AccessControlCluster::new(&acl_mgr, dummy_rand); let mut acl = AccessControlCluster::new(&acl_mgr, dummy_rand);
@ -292,8 +292,8 @@ mod tests {
AclEntry::new(1, Privilege::VIEW, AuthMode::Case), AclEntry::new(1, Privilege::VIEW, AuthMode::Case),
AclEntry::new(2, Privilege::ADMIN, AuthMode::Case), AclEntry::new(2, Privilege::ADMIN, AuthMode::Case),
]; ];
for i in input { for i in &input {
acl_mgr.borrow_mut().add(i).unwrap(); acl_mgr.borrow_mut().add(i.clone()).unwrap();
} }
let mut acl = AccessControlCluster::new(&acl_mgr, dummy_rand); let mut acl = AccessControlCluster::new(&acl_mgr, dummy_rand);
// data is don't-care actually // data is don't-care actually
@ -303,7 +303,7 @@ mod tests {
let result = acl.write_acl_attr(&ListOperation::DeleteItem(0), &data, 1); let result = acl.write_acl_attr(&ListOperation::DeleteItem(0), &data, 1);
assert!(result.is_ok()); 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 // Also validate in the acl_mgr that the entries are in the right order
let mut index = 0; let mut index = 0;
acl_mgr acl_mgr

View file

@ -23,7 +23,7 @@ use crate::{
// A generic path with endpoint, clusters, and a leaf // A generic path with endpoint, clusters, and a leaf
// The leaf could be command, attribute, event // 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")] #[tlvargs(datatype = "list")]
pub struct GenericPath { pub struct GenericPath {
pub endpoint: Option<EndptId>, pub endpoint: Option<EndptId>,
@ -106,16 +106,6 @@ pub mod msg {
self.attr_requests = Some(TLVArray::new(requests)); self.attr_requests = Some(TLVArray::new(requests));
self 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)] #[derive(Debug, FromTLV, ToTLV)]
@ -268,7 +258,7 @@ pub mod ib {
use super::GenericPath; use super::GenericPath;
// Command Response // Command Response
#[derive(Clone, Copy, FromTLV, ToTLV, Debug)] #[derive(Clone, FromTLV, ToTLV, Debug)]
#[tlvargs(lifetime = "'a")] #[tlvargs(lifetime = "'a")]
pub enum InvResp<'a> { pub enum InvResp<'a> {
Cmd(CmdData<'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 { pub struct CmdStatus {
path: CmdPath, path: CmdPath,
status: Status, status: Status,
@ -319,7 +309,7 @@ pub mod ib {
} }
} }
#[derive(Debug, Clone, Copy, FromTLV, ToTLV)] #[derive(Debug, Clone, FromTLV, ToTLV)]
#[tlvargs(lifetime = "'a")] #[tlvargs(lifetime = "'a")]
pub struct CmdData<'a> { pub struct CmdData<'a> {
pub path: CmdPath, pub path: CmdPath,
@ -338,7 +328,7 @@ pub mod ib {
} }
// Status // Status
#[derive(Debug, Clone, Copy, PartialEq, FromTLV, ToTLV)] #[derive(Debug, Clone, PartialEq, FromTLV, ToTLV)]
pub struct Status { pub struct Status {
pub status: IMStatusCode, pub status: IMStatusCode,
pub cluster_status: u16, pub cluster_status: u16,
@ -354,7 +344,7 @@ pub mod ib {
} }
// Attribute Response // Attribute Response
#[derive(Clone, Copy, FromTLV, ToTLV, PartialEq, Debug)] #[derive(Clone, FromTLV, ToTLV, PartialEq, Debug)]
#[tlvargs(lifetime = "'a")] #[tlvargs(lifetime = "'a")]
pub enum AttrResp<'a> { pub enum AttrResp<'a> {
Status(AttrStatus), Status(AttrStatus),
@ -390,7 +380,7 @@ pub mod ib {
} }
// Attribute Data // Attribute Data
#[derive(Clone, Copy, PartialEq, FromTLV, ToTLV, Debug)] #[derive(Clone, PartialEq, FromTLV, ToTLV, Debug)]
#[tlvargs(lifetime = "'a")] #[tlvargs(lifetime = "'a")]
pub struct AttrData<'a> { pub struct AttrData<'a> {
pub data_ver: Option<u32>, pub data_ver: Option<u32>,
@ -458,7 +448,7 @@ pub mod ib {
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, FromTLV, ToTLV)] #[derive(Debug, Clone, PartialEq, FromTLV, ToTLV)]
pub struct AttrStatus { pub struct AttrStatus {
path: AttrPath, path: AttrPath,
status: Status, status: Status,
@ -474,7 +464,7 @@ pub mod ib {
} }
// Attribute Path // Attribute Path
#[derive(Default, Clone, Copy, Debug, PartialEq, FromTLV, ToTLV)] #[derive(Default, Clone, Debug, PartialEq, FromTLV, ToTLV)]
#[tlvargs(datatype = "list")] #[tlvargs(datatype = "list")]
pub struct AttrPath { pub struct AttrPath {
pub tag_compression: Option<bool>, pub tag_compression: Option<bool>,
@ -501,7 +491,7 @@ pub mod ib {
} }
// Command Path // Command Path
#[derive(Default, Debug, Copy, Clone, PartialEq)] #[derive(Default, Debug, Clone, PartialEq)]
pub struct CmdPath { pub struct CmdPath {
pub path: GenericPath, 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 struct ClusterPath {
pub node: Option<u64>, pub node: Option<u64>,
pub endpoint: EndptId, pub endpoint: EndptId,
pub cluster: ClusterId, pub cluster: ClusterId,
} }
#[derive(FromTLV, ToTLV, Copy, Clone, Debug)] #[derive(FromTLV, ToTLV, Clone, Debug)]
pub struct DataVersionFilter { pub struct DataVersionFilter {
pub path: ClusterPath, pub path: ClusterPath,
pub data_ver: u32, pub data_ver: u32,
} }
#[derive(FromTLV, ToTLV, Copy, Clone, Debug)] #[derive(FromTLV, ToTLV, Clone, Debug)]
#[tlvargs(datatype = "list")] #[tlvargs(datatype = "list")]
pub struct EventPath { pub struct EventPath {
pub node: Option<u64>, pub node: Option<u64>,
@ -580,7 +570,7 @@ pub mod ib {
pub is_urgent: Option<bool>, pub is_urgent: Option<bool>,
} }
#[derive(FromTLV, ToTLV, Copy, Clone, Debug)] #[derive(FromTLV, ToTLV, Clone, Debug)]
pub struct EventFilter { pub struct EventFilter {
pub node: Option<u64>, pub node: Option<u64>,
pub event_min: Option<u64>, pub event_min: Option<u64>,

View file

@ -234,15 +234,15 @@ pub mod builtin {
use crate::transport::udp::UdpListener; use crate::transport::udp::UdpListener;
use crate::utils::select::EitherUnwrap; use crate::utils::select::EitherUnwrap;
const IP_BROADCAST_ADDRS: [SocketAddr; 2] = [ const IP_BROADCAST_ADDRS: [(IpAddr, u16); 2] = [
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(224, 0, 0, 251)), 5353), (IpAddr::V4(Ipv4Addr::new(224, 0, 0, 251)), 5353),
SocketAddr::new( (
IpAddr::V6(Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 0x00fb)), IpAddr::V6(Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 0x00fb)),
5353, 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( pub fn create_record(
id: u16, id: u16,
@ -429,7 +429,8 @@ pub mod builtin {
async fn bind(&self) -> Result<(), Error> { async fn bind(&self) -> Result<(), Error> {
if self.udp.borrow().is_none() { 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(()) Ok(())
@ -575,8 +576,8 @@ pub mod builtin {
let udp = self.0.udp.borrow(); let udp = self.0.udp.borrow();
let udp = udp.as_ref().unwrap(); let udp = udp.as_ref().unwrap();
for addr in IP_BROADCAST_ADDRS { for (addr, port) in IP_BROADCAST_ADDRS {
udp.send(addr, &entry.record).await?; udp.send(SocketAddr::new(addr, port), &entry.record).await?;
} }
index += 1; index += 1;

View file

@ -33,14 +33,7 @@ impl<'a> TLVList<'a> {
} }
} }
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct Pointer<'a> {
buf: &'a [u8],
current: usize,
left: usize,
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum ElementType<'a> { pub enum ElementType<'a> {
S8(i8), S8(i8),
S16(i16), S16(i16),
@ -63,9 +56,9 @@ pub enum ElementType<'a> {
Str32l, Str32l,
Str64l, Str64l,
Null, Null,
Struct(Pointer<'a>), Struct(&'a [u8]),
Array(Pointer<'a>), Array(&'a [u8]),
List(Pointer<'a>), List(&'a [u8]),
EndCnt, EndCnt,
Last, Last,
} }
@ -204,44 +197,11 @@ static VALUE_EXTRACTOR: [ExtractValue; MAX_VALUE_INDEX] = [
// Null 20 // Null 20
{ |_t| (0, ElementType::Null) }, { |_t| (0, ElementType::Null) },
// Struct 21 // Struct 21
{ { |t| (0, ElementType::Struct(&t.buf[t.current..])) },
|t| {
(
0,
ElementType::Struct(Pointer {
buf: t.buf,
current: t.current,
left: t.left,
}),
)
}
},
// Array 22 // Array 22
{ { |t| (0, ElementType::Array(&t.buf[t.current..])) },
|t| {
(
0,
ElementType::Array(Pointer {
buf: t.buf,
current: t.current,
left: t.left,
}),
)
}
},
// List 23 // List 23
{ { |t| (0, ElementType::List(&t.buf[t.current..])) },
|t| {
(
0,
ElementType::List(Pointer {
buf: t.buf,
current: t.current,
left: t.left,
}),
)
}
},
// EndCnt 24 // EndCnt 24
{ |_t| (0, ElementType::EndCnt) }, { |_t| (0, ElementType::EndCnt) },
]; ];
@ -282,7 +242,7 @@ fn read_length_value<'a>(
// The current offset is the string size // The current offset is the string size
let length: usize = LittleEndian::read_uint(&t.buf[t.current..], size_of_length_field) as usize; 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 // 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 // Return Error
Err(ErrorCode::NoSpace.into()) Err(ErrorCode::NoSpace.into())
} else { } else {
@ -294,7 +254,7 @@ fn read_length_value<'a>(
} }
} }
#[derive(Debug, Copy, Clone)] #[derive(Debug, Clone)]
pub struct TLVElement<'a> { pub struct TLVElement<'a> {
tag_type: TagType, tag_type: TagType,
element_type: ElementType<'a>, element_type: ElementType<'a>,
@ -303,11 +263,11 @@ pub struct TLVElement<'a> {
impl<'a> PartialEq for TLVElement<'a> { impl<'a> PartialEq for TLVElement<'a> {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
match self.element_type { match self.element_type {
ElementType::Struct(a) | ElementType::Array(a) | ElementType::List(a) => { ElementType::Struct(buf) | ElementType::Array(buf) | ElementType::List(buf) => {
let mut our_iter = TLVListIterator::from_pointer(a); let mut our_iter = TLVListIterator::from_buf(buf);
let mut their = match other.element_type { let mut their = match other.element_type {
ElementType::Struct(b) | ElementType::Array(b) | ElementType::List(b) => { ElementType::Struct(buf) | ElementType::Array(buf) | ElementType::List(buf) => {
TLVListIterator::from_pointer(b) TLVListIterator::from_buf(buf)
} }
_ => { _ => {
// If we are a container, the other must be a container, else this is a mismatch // 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; nest_level -= 1;
} else { } else {
if is_container(ours.element_type) { if is_container(&ours.element_type) {
nest_level += 1; nest_level += 1;
// Only compare the discriminants in case of array/list/structures, // Only compare the discriminants in case of array/list/structures,
// instead of actual element values. Those will be subsets within this same // 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> { impl<'a> TLVElement<'a> {
pub fn enter(&self) -> Option<TLVContainerIterator<'a>> { pub fn enter(&self) -> Option<TLVContainerIterator<'a>> {
let ptr = match self.element_type { let buf = match self.element_type {
ElementType::Struct(a) | ElementType::Array(a) | ElementType::List(a) => a, ElementType::Struct(buf) | ElementType::Array(buf) | ElementType::List(buf) => buf,
_ => return None, _ => return None,
}; };
let list_iter = TLVListIterator { let list_iter = TLVListIterator { buf, current: 0 };
buf: ptr.buf,
current: ptr.current,
left: ptr.left,
};
Some(TLVContainerIterator { Some(TLVContainerIterator {
list_iter, list_iter,
prev_container: false, prev_container: false,
@ -465,23 +421,23 @@ impl<'a> TLVElement<'a> {
} }
} }
pub fn confirm_struct(&self) -> Result<TLVElement<'a>, Error> { pub fn confirm_struct(&self) -> Result<&TLVElement<'a>, Error> {
match self.element_type { match self.element_type {
ElementType::Struct(_) => Ok(*self), ElementType::Struct(_) => Ok(self),
_ => Err(ErrorCode::TLVTypeMismatch.into()), _ => Err(ErrorCode::TLVTypeMismatch.into()),
} }
} }
pub fn confirm_array(&self) -> Result<TLVElement<'a>, Error> { pub fn confirm_array(&self) -> Result<&TLVElement<'a>, Error> {
match self.element_type { match self.element_type {
ElementType::Array(_) => Ok(*self), ElementType::Array(_) => Ok(self),
_ => Err(ErrorCode::TLVTypeMismatch.into()), _ => Err(ErrorCode::TLVTypeMismatch.into()),
} }
} }
pub fn confirm_list(&self) -> Result<TLVElement<'a>, Error> { pub fn confirm_list(&self) -> Result<&TLVElement<'a>, Error> {
match self.element_type { match self.element_type {
ElementType::List(_) => Ok(*self), ElementType::List(_) => Ok(self),
_ => Err(ErrorCode::TLVTypeMismatch.into()), _ => Err(ErrorCode::TLVTypeMismatch.into()),
} }
} }
@ -511,8 +467,8 @@ impl<'a> TLVElement<'a> {
false false
} }
pub fn get_element_type(&self) -> ElementType { pub fn get_element_type(&self) -> &ElementType {
self.element_type &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 // 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> { pub struct TLVListIterator<'a> {
buf: &'a [u8], buf: &'a [u8],
current: usize, current: usize,
left: usize,
} }
impl<'a> TLVListIterator<'a> { impl<'a> TLVListIterator<'a> {
fn from_pointer(p: Pointer<'a>) -> Self { fn from_buf(buf: &'a [u8]) -> Self {
Self { Self { buf, current: 0 }
buf: p.buf,
current: p.current,
left: p.left,
}
} }
fn advance(&mut self, len: usize) { fn advance(&mut self, len: usize) {
self.current += len; self.current += len;
self.left -= len;
} }
// Caller should ensure they are reading the _right_ tag at the _right_ place // Caller should ensure they are reading the _right_ tag at the _right_ place
@ -573,7 +523,7 @@ impl<'a> TLVListIterator<'a> {
return None; return None;
} }
let tag_size = TAG_SIZE_MAP[tag_type as usize]; 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; return None;
} }
let tag = (TAG_EXTRACTOR[tag_type as usize])(self); let tag = (TAG_EXTRACTOR[tag_type as usize])(self);
@ -586,7 +536,7 @@ impl<'a> TLVListIterator<'a> {
return None; return None;
} }
let mut size = VALUE_SIZE_MAP[element_type as usize]; let mut size = VALUE_SIZE_MAP[element_type as usize];
if size > self.left { if size > self.buf.len() - self.current {
error!( error!(
"Invalid value found: {} self {:?} size {}", "Invalid value found: {} self {:?} size {}",
element_type, self, size element_type, self, size
@ -609,7 +559,7 @@ impl<'a> Iterator for TLVListIterator<'a> {
type Item = TLVElement<'a>; type Item = TLVElement<'a>;
/* Code for going to the next Element */ /* Code for going to the next Element */
fn next(&mut self) -> Option<TLVElement<'a>> { fn next(&mut self) -> Option<TLVElement<'a>> {
if self.left < 1 { if self.buf.len() - self.current < 1 {
return None; return None;
} }
/* Read Control */ /* Read Control */
@ -635,13 +585,12 @@ impl<'a> TLVList<'a> {
pub fn iter(&self) -> TLVListIterator<'a> { pub fn iter(&self) -> TLVListIterator<'a> {
TLVListIterator { TLVListIterator {
current: 0, current: 0,
left: self.buf.len(),
buf: self.buf, buf: self.buf,
} }
} }
} }
fn is_container(element_type: ElementType) -> bool { fn is_container(element_type: &ElementType) -> bool {
matches!( matches!(
element_type, element_type,
ElementType::Struct(_) | ElementType::Array(_) | ElementType::List(_) ElementType::Struct(_) | ElementType::Array(_) | ElementType::List(_)
@ -680,7 +629,7 @@ impl<'a> TLVContainerIterator<'a> {
nest_level -= 1; nest_level -= 1;
} }
_ => { _ => {
if is_container(element.element_type) { if is_container(&element.element_type) {
nest_level += 1; nest_level += 1;
} }
} }
@ -711,7 +660,7 @@ impl<'a> Iterator for TLVContainerIterator<'a> {
return None; return None;
} }
self.prev_container = is_container(element.element_type); self.prev_container = is_container(&element.element_type);
Some(element) Some(element)
} }
} }
@ -724,19 +673,25 @@ pub fn get_root_node(b: &[u8]) -> Result<TLVElement, Error> {
} }
pub fn get_root_node_struct(b: &[u8]) -> Result<TLVElement, Error> { pub fn get_root_node_struct(b: &[u8]) -> Result<TLVElement, Error> {
TLVList::new(b) let root = TLVList::new(b)
.iter() .iter()
.next() .next()
.ok_or(ErrorCode::InvalidData)? .ok_or(ErrorCode::InvalidData)?;
.confirm_struct()
root.confirm_struct()?;
Ok(root)
} }
pub fn get_root_node_list(b: &[u8]) -> Result<TLVElement, Error> { pub fn get_root_node_list(b: &[u8]) -> Result<TLVElement, Error> {
TLVList::new(b) let root = TLVList::new(b)
.iter() .iter()
.next() .next()
.ok_or(ErrorCode::InvalidData)? .ok_or(ErrorCode::InvalidData)?;
.confirm_list()
root.confirm_list()?;
Ok(root)
} }
pub fn print_tlv_list(b: &[u8]) { pub fn print_tlv_list(b: &[u8]) {
@ -798,8 +753,7 @@ mod tests {
use log::info; use log::info;
use super::{ use super::{
get_root_node_list, get_root_node_struct, ElementType, Pointer, TLVElement, TLVList, get_root_node_list, get_root_node_struct, ElementType, TLVElement, TLVList, TagType,
TagType,
}; };
use crate::error::ErrorCode; use crate::error::ErrorCode;
@ -859,11 +813,7 @@ mod tests {
tlv_iter.next(), tlv_iter.next(),
Some(TLVElement { Some(TLVElement {
tag_type: TagType::Context(0), tag_type: TagType::Context(0),
element_type: ElementType::Array(Pointer { element_type: ElementType::Array(&[]),
buf: &[21, 54, 0],
current: 3,
left: 0
}),
}) })
); );
} }
@ -1123,7 +1073,8 @@ mod tests {
// This is an array of CommandDataIB, but we'll only use the first element // 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_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!( assert_eq!(
cmd_path.find_tag(0).unwrap(), cmd_path.find_tag(0).unwrap(),
TLVElement { TLVElement {
@ -1188,11 +1139,7 @@ mod tests {
0x35, 0x1, 0x18, 0x18, 0x18, 0x18, 0x35, 0x1, 0x18, 0x18, 0x18, 0x18,
]; ];
let dummy_pointer = Pointer { let dummy_pointer = &b[1..];
buf: &b,
current: 1,
left: 21,
};
// These are the decoded elements that we expect from this input // These are the decoded elements that we expect from this input
let verify_matrix: [(TagType, ElementType); 13] = [ let verify_matrix: [(TagType, ElementType); 13] = [
(TagType::Anonymous, ElementType::Struct(dummy_pointer)), (TagType::Anonymous, ElementType::Struct(dummy_pointer)),

View file

@ -298,7 +298,7 @@ impl<T: ToTLV> ToTLV for Nullable<T> {
} }
} }
#[derive(Copy, Clone)] #[derive(Clone)]
pub enum TLVArray<'a, T> { pub enum TLVArray<'a, T> {
// This is used for the to-tlv path // This is used for the to-tlv path
Slice(&'a [T]), Slice(&'a [T]),
@ -317,7 +317,7 @@ impl<'a, T: ToTLV> TLVArray<'a, T> {
} }
pub fn iter(&self) -> TLVArrayIter<'a, T> { pub fn iter(&self) -> TLVArrayIter<'a, T> {
match *self { match self {
Self::Slice(s) => TLVArrayIter::Slice(s.iter()), Self::Slice(s) => TLVArrayIter::Slice(s.iter()),
Self::Ptr(p) => TLVArrayIter::Ptr(p.enter()), 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> { impl<'a, T> FromTLV<'a> for TLVArray<'a, T> {
fn from_tlv(t: &TLVElement<'a>) -> Result<Self, Error> { fn from_tlv(t: &TLVElement<'a>) -> Result<Self, Error> {
t.confirm_array()?; t.confirm_array()?;
Ok(Self::Ptr(*t)) Ok(Self::Ptr(t.clone()))
} }
} }

View file

@ -41,7 +41,7 @@ impl RetransEntry {
} }
} }
#[derive(Debug, Copy, Clone)] #[derive(Debug, Clone)]
pub struct AckEntry { pub struct AckEntry {
// The msg counter that we should acknowledge // The msg counter that we should acknowledge
msg_ctr: u32, msg_ctr: u32,
@ -92,7 +92,7 @@ impl ReliableMessage {
// Check any pending acknowledgements / retransmissions and take action // Check any pending acknowledgements / retransmissions and take action
pub fn is_ack_ready(&self, epoch: Epoch) -> bool { pub fn is_ack_ready(&self, epoch: Epoch) -> bool {
// Acknowledgements // Acknowledgements
if let Some(ack_entry) = self.ack { if let Some(ack_entry) = &self.ack {
ack_entry.has_timed_out(epoch) ack_entry.has_timed_out(epoch)
} else { } else {
false false
@ -107,7 +107,7 @@ impl ReliableMessage {
// Check if any acknowledgements are pending for this exchange, // Check if any acknowledgements are pending for this exchange,
// if so, piggy back in the encoded header here // 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 // Ack Entry exists, set ACK bit and remove from table
proto_tx.proto.set_ack(ack_entry.get_msg_ctr()); proto_tx.proto.set_ack(ack_entry.get_msg_ctr());
self.ack = None; self.ack = None;

View file

@ -37,7 +37,7 @@ pub type NocCatIds = [u32; MAX_CAT_IDS_PER_NOC];
const MATTER_AES128_KEY_SIZE: usize = 16; const MATTER_AES128_KEY_SIZE: usize = 16;
#[derive(Debug, Default, Copy, Clone, PartialEq)] #[derive(Debug, Default, Clone, PartialEq)]
pub struct CaseDetails { pub struct CaseDetails {
pub fab_idx: u8, pub fab_idx: u8,
pub cat_ids: NocCatIds, pub cat_ids: NocCatIds,
@ -52,7 +52,7 @@ impl CaseDetails {
} }
} }
#[derive(Debug, PartialEq, Copy, Clone, Default)] #[derive(Debug, PartialEq, Clone, Default)]
pub enum SessionMode { pub enum SessionMode {
// The Case session will capture the local fabric index // The Case session will capture the local fabric index
Case(CaseDetails), Case(CaseDetails),
@ -149,7 +149,7 @@ impl Session {
peer_sess_id: clone_from.peer_sess_id, peer_sess_id: clone_from.peer_sess_id,
msg_ctr: Self::rand_msg_ctr(rand), msg_ctr: Self::rand_msg_ctr(rand),
rx_ctr_state: RxCtrState::new(0), rx_ctr_state: RxCtrState::new(0),
mode: clone_from.mode, mode: clone_from.mode.clone(),
data: None, data: None,
last_use: epoch(), last_use: epoch(),
} }
@ -207,14 +207,14 @@ impl Session {
} }
pub fn get_local_fabric_idx(&self) -> Option<u8> { pub fn get_local_fabric_idx(&self) -> Option<u8> {
match self.mode { match &self.mode {
SessionMode::Case(a) => Some(a.fab_idx), SessionMode::Case(a) => Some(a.fab_idx),
_ => None, _ => None,
} }
} }
pub fn get_session_mode(&self) -> SessionMode { pub fn get_session_mode(&self) -> &SessionMode {
self.mode &self.mode
} }
pub fn get_msg_ctr(&mut self) -> u32 { pub fn get_msg_ctr(&mut self) -> u32 {
@ -454,7 +454,7 @@ impl SessionMgr {
Some(self.get_session_handle(index)) Some(self.get_session_handle(index))
} }
fn get_or_add( pub fn get_or_add(
&mut self, &mut self,
sess_id: u16, sess_id: u16,
peer_addr: Address, peer_addr: Address,

View file

@ -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 // 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() { for inv_response in received.attr_reports.as_ref().unwrap().iter() {
println!("Validating index {}", index); println!("Validating index {}", index);
match expected[index] { match &expected[index] {
AttrResp::Data(e_d) => match inv_response { AttrResp::Data(e_d) => match inv_response {
AttrResp::Data(d) => { AttrResp::Data(d) => {
// We don't match the data-version // 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"); 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); println!("Index {} success", index);
index += 1; index += 1;

View file

@ -30,15 +30,15 @@ pub enum ExpectedInvResp {
pub fn assert_inv_response(resp: &msg::InvResp, expected: &[ExpectedInvResp]) { pub fn assert_inv_response(resp: &msg::InvResp, expected: &[ExpectedInvResp]) {
let mut index = 0; 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); println!("Validating index {}", index);
match expected[index] { match &expected[index] {
ExpectedInvResp::Cmd(e_c, e_d) => match inv_response { ExpectedInvResp::Cmd(e_c, e_d) => match inv_response {
InvResp::Cmd(c) => { InvResp::Cmd(c) => {
assert_eq!(e_c, c.path); assert_eq!(e_c, &c.path);
match c.data { match c.data {
EncodeValue::Tlv(t) => { 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"), _ => panic!("Incorrect CmdDataType"),
} }
@ -49,7 +49,7 @@ pub fn assert_inv_response(resp: &msg::InvResp, expected: &[ExpectedInvResp]) {
}, },
ExpectedInvResp::Status(e_status) => match inv_response { ExpectedInvResp::Status(e_status) => match inv_response {
InvResp::Status(status) => { InvResp::Status(status) => {
assert_eq!(e_status, status); assert_eq!(e_status, &status);
} }
_ => { _ => {
panic!("Invalid response, expected InvResponse::Status"); panic!("Invalid response, expected InvResponse::Status");
@ -64,7 +64,7 @@ pub fn assert_inv_response(resp: &msg::InvResp, expected: &[ExpectedInvResp]) {
#[macro_export] #[macro_export]
macro_rules! cmd_data { macro_rules! cmd_data {
($path:ident, $data:literal) => { ($path:expr, $data:literal) => {
CmdData::new($path, EncodeValue::Value(&($data as u32))) CmdData::new($path, EncodeValue::Value(&($data as u32)))
}; };
} }

View file

@ -429,7 +429,7 @@ fn write_with_runtime_acl_add() {
peer, peer,
None, None,
// write to echo-cluster attribute, write to acl attribute, write to echo-cluster attribute // 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(&ep0_att, IMStatusCode::UnsupportedAccess, 0),
AttrStatus::new(&acl_att, IMStatusCode::Success, 0), AttrStatus::new(&acl_att, IMStatusCode::Success, 0),
@ -597,7 +597,7 @@ fn test_write_data_ver() {
let input_correct_dataver = &[AttrData::new( let input_correct_dataver = &[AttrData::new(
Some(initial_data_ver), Some(initial_data_ver),
AttrPath::new(&ep0_attwrite), AttrPath::new(&ep0_attwrite),
attr_data1, attr_data1.clone(),
)]; )];
im.handle_write_reqs( im.handle_write_reqs(
peer, peer,

View file

@ -59,7 +59,11 @@ fn attr_list_ops() {
let mut att_path = AttrPath::new(&att_data); let mut att_path = AttrPath::new(&att_data);
// Test 1: Add Operation - add val0 // 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)]; let expected = &[AttrStatus::new(&att_data, IMStatusCode::Success, 0)];
ImEngine::new_with_write_reqs(&matter(&mut DummyMdns), input, expected); 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 // 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)]; let expected = &[AttrStatus::new(&att_data, IMStatusCode::Success, 0)];
ImEngine::new_with_write_reqs(&matter(&mut DummyMdns), input, expected); 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 // Test 3: Edit Operation - edit val1 to val0
att_path.list_index = Some(Nullable::NotNull(1)); 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)]; let expected = &[AttrStatus::new(&att_data, IMStatusCode::Success, 0)];
ImEngine::new_with_write_reqs(&matter(&mut DummyMdns), input, expected); 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 // Test 4: Delete Operation - delete index 0
att_path.list_index = Some(Nullable::NotNull(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)]; let expected = &[AttrStatus::new(&att_data, IMStatusCode::Success, 0)];
ImEngine::new_with_write_reqs(&matter(&mut DummyMdns), input, expected); ImEngine::new_with_write_reqs(&matter(&mut DummyMdns), input, expected);
@ -105,7 +117,7 @@ fn attr_list_ops() {
att_path.list_index = None; att_path.list_index = None;
let input = &[AttrData::new( let input = &[AttrData::new(
None, None,
att_path, att_path.clone(),
EncodeValue::Value(&overwrite_val), EncodeValue::Value(&overwrite_val),
)]; )];
let expected = &[AttrStatus::new(&att_data, IMStatusCode::Success, 0)]; let expected = &[AttrStatus::new(&att_data, IMStatusCode::Success, 0)];

View file

@ -218,7 +218,7 @@ fn test_read_wc_endpoint_wc_attribute() {
Some(echo_cluster::ID), Some(echo_cluster::ID),
Some(GlobalElements::AttributeList as u32), Some(GlobalElements::AttributeList as u32),
), ),
attr_list_tlv.get_element_type() attr_list_tlv.get_element_type().clone()
), ),
attr_data_path!( attr_data_path!(
GenericPath::new( GenericPath::new(
@ -258,7 +258,7 @@ fn test_read_wc_endpoint_wc_attribute() {
Some(echo_cluster::ID), Some(echo_cluster::ID),
Some(GlobalElements::AttributeList as u32), Some(GlobalElements::AttributeList as u32),
), ),
attr_list_tlv.get_element_type() attr_list_tlv.get_element_type().clone()
), ),
attr_data_path!( attr_data_path!(
GenericPath::new( GenericPath::new(

View file

@ -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 = 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 invalid_command_wc_endpoint = CmdPath::new(None, Some(echo_cluster::ID), Some(0x1234));
let input = &[ let input = &[
cmd_data!(invalid_endpoint, 5), cmd_data!(invalid_endpoint.clone(), 5),
cmd_data!(invalid_cluster, 5), cmd_data!(invalid_cluster.clone(), 5),
cmd_data!(invalid_cluster_wc_endpoint, 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), cmd_data!(invalid_command_wc_endpoint, 5),
]; ];

View file

@ -77,163 +77,228 @@ fn wildcard_read_resp(part: u8) -> Vec<AttrResp<'static>> {
// For brevity, we only check the AttrPath, not the actual 'data' // For brevity, we only check the AttrPath, not the actual 'data'
let dont_care = ElementType::U8(0); let dont_care = ElementType::U8(0);
let part1 = vec![ let part1 = vec![
attr_data!(0, 29, GlobalElements::FeatureMap, dont_care), attr_data!(0, 29, GlobalElements::FeatureMap, dont_care.clone()),
attr_data!(0, 29, GlobalElements::AttributeList, dont_care), attr_data!(0, 29, GlobalElements::AttributeList, dont_care.clone()),
attr_data!(0, 29, descriptor::Attributes::DeviceTypeList, dont_care), attr_data!(
attr_data!(0, 29, descriptor::Attributes::ServerList, dont_care), 0,
attr_data!(0, 29, descriptor::Attributes::PartsList, dont_care), 29,
attr_data!(0, 29, descriptor::Attributes::ClientList, dont_care), descriptor::Attributes::DeviceTypeList,
attr_data!(0, 40, GlobalElements::FeatureMap, dont_care), dont_care.clone()
attr_data!(0, 40, GlobalElements::AttributeList, dont_care), ),
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!( attr_data!(
0, 0,
40, 40,
basic_info::AttributesDiscriminants::DMRevision, basic_info::AttributesDiscriminants::DMRevision,
dont_care dont_care.clone()
), ),
attr_data!( attr_data!(
0, 0,
40, 40,
basic_info::AttributesDiscriminants::VendorId, basic_info::AttributesDiscriminants::VendorId,
dont_care dont_care.clone()
), ),
attr_data!( attr_data!(
0, 0,
40, 40,
basic_info::AttributesDiscriminants::ProductId, 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!( attr_data!(
0, 0,
40, 40,
basic_info::AttributesDiscriminants::SwVerString, basic_info::AttributesDiscriminants::SwVerString,
dont_care dont_care.clone()
), ),
attr_data!( attr_data!(
0, 0,
40, 40,
basic_info::AttributesDiscriminants::SerialNo, basic_info::AttributesDiscriminants::SerialNo,
dont_care dont_care.clone()
), ),
attr_data!(0, 48, GlobalElements::FeatureMap, dont_care), attr_data!(0, 48, GlobalElements::FeatureMap, dont_care.clone()),
attr_data!(0, 48, GlobalElements::AttributeList, dont_care), attr_data!(0, 48, GlobalElements::AttributeList, dont_care.clone()),
attr_data!( attr_data!(
0, 0,
48, 48,
gen_comm::AttributesDiscriminants::BreadCrumb, gen_comm::AttributesDiscriminants::BreadCrumb,
dont_care dont_care.clone()
), ),
attr_data!( attr_data!(
0, 0,
48, 48,
gen_comm::AttributesDiscriminants::RegConfig, gen_comm::AttributesDiscriminants::RegConfig,
dont_care dont_care.clone()
), ),
attr_data!( attr_data!(
0, 0,
48, 48,
gen_comm::AttributesDiscriminants::LocationCapability, gen_comm::AttributesDiscriminants::LocationCapability,
dont_care dont_care.clone()
), ),
attr_data!( attr_data!(
0, 0,
48, 48,
gen_comm::AttributesDiscriminants::BasicCommissioningInfo, gen_comm::AttributesDiscriminants::BasicCommissioningInfo,
dont_care dont_care.clone()
), ),
attr_data!(0, 49, GlobalElements::FeatureMap, dont_care), attr_data!(0, 49, GlobalElements::FeatureMap, dont_care.clone()),
attr_data!(0, 49, GlobalElements::AttributeList, dont_care), attr_data!(0, 49, GlobalElements::AttributeList, dont_care.clone()),
attr_data!(0, 60, GlobalElements::FeatureMap, dont_care), attr_data!(0, 60, GlobalElements::FeatureMap, dont_care.clone()),
attr_data!(0, 60, GlobalElements::AttributeList, dont_care), attr_data!(0, 60, GlobalElements::AttributeList, dont_care.clone()),
attr_data!( attr_data!(
0, 0,
60, 60,
adm_comm::AttributesDiscriminants::WindowStatus, adm_comm::AttributesDiscriminants::WindowStatus,
dont_care dont_care.clone()
), ),
attr_data!( attr_data!(
0, 0,
60, 60,
adm_comm::AttributesDiscriminants::AdminFabricIndex, adm_comm::AttributesDiscriminants::AdminFabricIndex,
dont_care dont_care.clone()
), ),
attr_data!( attr_data!(
0, 0,
60, 60,
adm_comm::AttributesDiscriminants::AdminVendorId, adm_comm::AttributesDiscriminants::AdminVendorId,
dont_care dont_care.clone()
), ),
attr_data!(0, 62, GlobalElements::FeatureMap, dont_care), attr_data!(0, 62, GlobalElements::FeatureMap, dont_care.clone()),
attr_data!(0, 62, GlobalElements::AttributeList, dont_care), attr_data!(0, 62, GlobalElements::AttributeList, dont_care.clone()),
attr_data!( attr_data!(
0, 0,
62, 62,
noc::AttributesDiscriminants::CurrentFabricIndex, 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!( attr_data!(
0, 0,
62, 62,
noc::AttributesDiscriminants::SupportedFabrics, noc::AttributesDiscriminants::SupportedFabrics,
dont_care dont_care.clone()
), ),
attr_data!( attr_data!(
0, 0,
62, 62,
noc::AttributesDiscriminants::CommissionedFabrics, 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!( attr_data!(
0, 0,
31, 31,
acl::AttributesDiscriminants::SubjectsPerEntry, acl::AttributesDiscriminants::SubjectsPerEntry,
dont_care dont_care.clone()
), ),
attr_data!( attr_data!(
0, 0,
31, 31,
acl::AttributesDiscriminants::TargetsPerEntry, acl::AttributesDiscriminants::TargetsPerEntry,
dont_care dont_care.clone()
), ),
attr_data!( attr_data!(
0, 0,
31, 31,
acl::AttributesDiscriminants::EntriesPerFabric, 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!( attr_data!(
0, 0,
echo::ID, echo::ID,
echo::AttributesDiscriminants::AttCustom, 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![ let part2 = vec![
attr_data!(1, 29, descriptor::Attributes::ServerList, dont_care), attr_data!(1, 29, descriptor::Attributes::ServerList, dont_care.clone()),
attr_data!(1, 29, descriptor::Attributes::PartsList, dont_care), attr_data!(1, 29, descriptor::Attributes::PartsList, dont_care.clone()),
attr_data!(1, 29, descriptor::Attributes::ClientList, dont_care), attr_data!(1, 29, descriptor::Attributes::ClientList, dont_care.clone()),
attr_data!(1, 6, GlobalElements::FeatureMap, dont_care), attr_data!(1, 6, GlobalElements::FeatureMap, dont_care.clone()),
attr_data!(1, 6, GlobalElements::AttributeList, dont_care), attr_data!(1, 6, GlobalElements::AttributeList, dont_care.clone()),
attr_data!(1, 6, onoff::AttributesDiscriminants::OnOff, dont_care), attr_data!(
attr_data!(1, echo::ID, GlobalElements::FeatureMap, dont_care), 1,
attr_data!(1, echo::ID, GlobalElements::AttributeList, dont_care), 6,
attr_data!(1, echo::ID, echo::AttributesDiscriminants::Att1, dont_care), onoff::AttributesDiscriminants::OnOff,
attr_data!(1, echo::ID, echo::AttributesDiscriminants::Att2, dont_care), 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!( attr_data!(
1, 1,
echo::ID, echo::ID,

View file

@ -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 t_iter = t.#datatype ()?.enter().ok_or_else(|| #krate::error::Error::new(#krate::error::ErrorCode::Invalid))?;
let mut item = t_iter.next(); 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; let backup = item;
item = t_iter.next(); item = t_iter.next();
#types::from_tlv(&backup.unwrap()) #types::from_tlv(&backup.unwrap())