Control memory by removing implicit copy
This commit is contained in:
parent
2e0a09b532
commit
1c26df0712
19 changed files with 281 additions and 255 deletions
|
@ -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);
|
||||
|
|
|
@ -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()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(),
|
||||
))
|
||||
});
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -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()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)))
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)];
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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),
|
||||
];
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Add table
Reference in a new issue