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 {
|
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);
|
||||||
|
|
|
@ -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()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(),
|
||||||
))
|
))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)),
|
||||||
|
|
|
@ -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()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)];
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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())
|
||||||
|
|
Loading…
Add table
Reference in a new issue