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 {
cluster: Option<ClusterId>,
endpoint: Option<EndptId>,
@ -283,7 +283,7 @@ impl Target {
type Subjects = [Option<u64>; SUBJECTS_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)]
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);

View file

@ -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<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] {
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<'_> {
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(),
))
});

View file

@ -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;

View file

@ -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

View file

@ -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<EndptId>,
@ -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<u32>,
@ -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<bool>,
@ -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<u64>,
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<u64>,
@ -580,7 +570,7 @@ pub mod ib {
pub is_urgent: Option<bool>,
}
#[derive(FromTLV, ToTLV, Copy, Clone, Debug)]
#[derive(FromTLV, ToTLV, Clone, Debug)]
pub struct EventFilter {
pub node: Option<u64>,
pub event_min: Option<u64>,

View file

@ -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;

View file

@ -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<TLVContainerIterator<'a>> {
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<TLVElement<'a>, 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<TLVElement<'a>, 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<TLVElement<'a>, 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<TLVElement<'a>> {
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<TLVElement, Error> {
}
pub fn get_root_node_struct(b: &[u8]) -> Result<TLVElement, Error> {
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<TLVElement, Error> {
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)),

View file

@ -298,7 +298,7 @@ impl<T: ToTLV> ToTLV for Nullable<T> {
}
}
#[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<Self, Error> {
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 {
// 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;

View file

@ -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<u8> {
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,

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
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;

View file

@ -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)))
};
}

View file

@ -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,

View file

@ -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)];

View file

@ -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(

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_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),
];

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'
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,

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 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())