openthread/ot/types/
operational_dataset.rsuse crate::prelude_internal::*;
use std::ops::Deref;
#[derive(Default, Clone)]
#[repr(transparent)]
pub struct OperationalDataset(pub otOperationalDataset);
impl_ot_castable!(OperationalDataset, otOperationalDataset);
impl OperationalDataset {
pub fn empty() -> OperationalDataset {
Self::default()
}
pub fn is_complete(&self) -> bool {
self.get_active_timestamp().is_some()
&& self.get_network_name().is_some()
&& self.get_network_key().is_some()
&& self.get_extended_pan_id().is_some()
&& self.get_mesh_local_prefix().is_some()
&& self.get_pan_id().is_some()
&& self.get_channel().is_some()
&& self.get_pskc().is_some()
&& self.get_security_policy().is_some()
&& self.get_channel_mask().is_some()
}
pub fn clear(&mut self) {
*self = Self::empty();
}
}
impl std::fmt::Debug for OperationalDataset {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut ds = f.debug_struct("OperationalDataset");
if let Some(x) = self.get_network_name() {
ds.field("network_name", &x);
}
if let Some(x) = self.get_extended_pan_id() {
ds.field("xpanid", &x);
}
if let Some(x) = self.get_network_key() {
ds.field("network_key", &x);
}
if let Some(x) = self.get_mesh_local_prefix() {
ds.field("mesh_local_prefix", &x);
}
if let Some(x) = self.get_pan_id() {
ds.field("panid", &x);
}
if let Some(x) = self.get_channel() {
ds.field("channel", &x);
}
if let Some(x) = self.get_channel_mask() {
ds.field("channel_mask", &x);
}
if let Some(x) = self.get_pskc() {
ds.field("pskc", &x);
}
if let Some(x) = self.get_security_policy() {
ds.field("security_policy", &x);
}
if let Some(x) = self.get_delay() {
ds.field("delay", &x);
}
if let Some(x) = self.get_active_timestamp() {
ds.field("active_timestamp", &x);
}
if let Some(x) = self.get_pending_timestamp() {
ds.field("pending_timestamp", &x);
}
ds.finish()
}
}
impl OperationalDataset {
pub fn get_channel(&self) -> Option<ChannelIndex> {
self.0.mComponents.mIsChannelPresent.then(|| self.0.mChannel.try_into().unwrap())
}
pub fn get_channel_mask(&self) -> Option<ChannelMask> {
self.0.mComponents.mIsChannelMaskPresent.then(|| self.0.mChannelMask.into())
}
pub fn get_delay(&self) -> Option<u32> {
self.0.mComponents.mIsDelayPresent.then_some(self.0.mDelay)
}
pub fn get_extended_pan_id(&self) -> Option<&ExtendedPanId> {
self.0
.mComponents
.mIsExtendedPanIdPresent
.then(|| ExtendedPanId::ref_from_ot_ref(&self.0.mExtendedPanId))
}
pub fn get_network_key(&self) -> Option<&NetworkKey> {
self.0
.mComponents
.mIsNetworkKeyPresent
.then(|| NetworkKey::ref_from_ot_ref(&self.0.mNetworkKey))
}
pub fn get_pskc(&self) -> Option<&Pskc> {
self.0.mComponents.mIsPskcPresent.then(|| Pskc::ref_from_ot_ref(&self.0.mPskc))
}
pub fn get_network_name(&self) -> Option<&NetworkName> {
self.0
.mComponents
.mIsNetworkNamePresent
.then(|| NetworkName::ref_from_ot_ref(&self.0.mNetworkName))
}
pub fn get_pan_id(&self) -> Option<PanId> {
self.0.mComponents.mIsPanIdPresent.then_some(self.0.mPanId)
}
pub fn get_active_timestamp(&self) -> Option<Timestamp> {
self.0.mComponents.mIsActiveTimestampPresent.then(|| self.0.mActiveTimestamp.into())
}
pub fn get_pending_timestamp(&self) -> Option<Timestamp> {
self.0.mComponents.mIsPendingTimestampPresent.then(|| self.0.mPendingTimestamp.into())
}
pub fn get_security_policy(&self) -> Option<&SecurityPolicy> {
self.0
.mComponents
.mIsSecurityPolicyPresent
.then(|| SecurityPolicy::ref_from_ot_ref(&self.0.mSecurityPolicy))
}
pub fn get_mesh_local_prefix(&self) -> Option<&MeshLocalPrefix> {
self.0
.mComponents
.mIsMeshLocalPrefixPresent
.then_some(&self.0.mMeshLocalPrefix)
.map(Into::into)
}
}
impl OperationalDataset {
pub fn set_channel(&mut self, opt: Option<ChannelIndex>) {
if let Some(x) = opt {
self.0.mChannel = x.into();
self.0.mComponents.mIsChannelPresent = true;
} else {
self.0.mComponents.mIsChannelPresent = false;
}
}
pub fn set_channel_mask(&mut self, opt: Option<ChannelMask>) {
if let Some(x) = opt {
self.0.mChannelMask = x.into();
self.0.mComponents.mIsChannelMaskPresent = true;
} else {
self.0.mComponents.mIsChannelMaskPresent = false;
}
}
pub fn set_delay(&mut self, opt: Option<u32>) {
if let Some(x) = opt {
self.0.mDelay = x;
self.0.mComponents.mIsDelayPresent = true;
} else {
self.0.mComponents.mIsDelayPresent = false;
}
}
pub fn set_extended_pan_id(&mut self, opt: Option<&ExtendedPanId>) {
if let Some(x) = opt {
self.0.mExtendedPanId = *x.as_ot_ref();
self.0.mComponents.mIsExtendedPanIdPresent = true;
} else {
self.0.mComponents.mIsExtendedPanIdPresent = false;
}
}
pub fn set_network_key(&mut self, opt: Option<&NetworkKey>) {
if let Some(x) = opt {
self.0.mNetworkKey = *x.as_ot_ref();
self.0.mComponents.mIsNetworkKeyPresent = true;
} else {
self.0.mComponents.mIsNetworkKeyPresent = false;
}
}
pub fn set_network_name(&mut self, opt: Option<&NetworkName>) {
if let Some(x) = opt {
self.0.mNetworkName = *x.as_ot_ref();
self.0.mComponents.mIsNetworkNamePresent = true;
} else {
self.0.mComponents.mIsNetworkNamePresent = false;
}
}
pub fn set_pan_id(&mut self, opt: Option<PanId>) {
if let Some(x) = opt {
self.0.mPanId = x;
self.0.mComponents.mIsPanIdPresent = true;
} else {
self.0.mComponents.mIsPanIdPresent = false;
}
}
pub fn set_active_timestamp(&mut self, opt: Option<Timestamp>) {
if let Some(x) = opt {
self.0.mActiveTimestamp = x.into();
self.0.mComponents.mIsActiveTimestampPresent = true;
} else {
self.0.mComponents.mIsActiveTimestampPresent = false;
}
}
pub fn set_pending_timestamp(&mut self, opt: Option<Timestamp>) {
if let Some(x) = opt {
self.0.mPendingTimestamp = x.into();
self.0.mComponents.mIsPendingTimestampPresent = true;
} else {
self.0.mComponents.mIsPendingTimestampPresent = false;
}
}
pub fn set_security_policy(&mut self, opt: Option<SecurityPolicy>) {
if let Some(x) = opt {
self.0.mSecurityPolicy = *x.as_ot_ref();
self.0.mComponents.mIsSecurityPolicyPresent = true;
} else {
self.0.mComponents.mIsSecurityPolicyPresent = false;
}
}
pub fn set_mesh_local_prefix(&mut self, opt: Option<&MeshLocalPrefix>) {
if let Some(x) = opt {
self.0.mMeshLocalPrefix = *x.as_ot_ref();
self.0.mComponents.mIsMeshLocalPrefixPresent = true;
} else {
self.0.mComponents.mIsMeshLocalPrefixPresent = false;
}
}
}
#[derive(Debug, Default, Clone)]
#[repr(transparent)]
pub struct OperationalDatasetTlvs(pub otOperationalDatasetTlvs);
impl_ot_castable!(OperationalDatasetTlvs, otOperationalDatasetTlvs);
impl OperationalDatasetTlvs {
pub fn try_to_dataset(&self) -> Result<OperationalDataset> {
let mut ret = OperationalDataset::default();
Error::from(unsafe { otDatasetParseTlvs(self.as_ot_ptr(), ret.as_ot_mut_ptr()) })
.into_result()?;
Ok(ret)
}
pub fn try_from_slice(slice: &[u8]) -> Result<Self, ot::WrongSize> {
let mut ret = Self::default();
let len = slice.len();
if len > OT_OPERATIONAL_DATASET_MAX_LENGTH as usize {
return Err(ot::WrongSize);
}
ret.0.mLength = len.try_into().unwrap();
ret.0.mTlvs[0..len].clone_from_slice(slice);
Ok(ret)
}
#[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> usize {
self.0.mLength as usize
}
pub fn as_slice(&self) -> &[u8] {
&self.0.mTlvs[0..self.len()]
}
pub fn to_vec(&self) -> Vec<u8> {
self.as_slice().to_vec()
}
}
impl Deref for OperationalDatasetTlvs {
type Target = [u8];
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}
impl<'a> TryFrom<&'a [u8]> for OperationalDatasetTlvs {
type Error = ot::WrongSize;
fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
OperationalDatasetTlvs::try_from_slice(value)
}
}
impl TryFrom<Vec<u8>> for OperationalDatasetTlvs {
type Error = ot::WrongSize;
fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
OperationalDatasetTlvs::try_from_slice(&value)
}
}
impl From<OperationalDatasetTlvs> for Vec<u8> {
fn from(value: OperationalDatasetTlvs) -> Self {
value.to_vec()
}
}
impl TryFrom<OperationalDatasetTlvs> for OperationalDataset {
type Error = ot::Error;
fn try_from(value: OperationalDatasetTlvs) -> Result<Self, Self::Error> {
value.try_to_dataset()
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_operational_dataset() {
let dataset_bytes = hex::decode("0e08000062cc8de70000000300001635060004001fffe0020830b02192978a444f0708fd70a9fb17d60000030d4e4553542d50414e2d3043454401020ced0410f73d3809ffd94b329fdab33ba781ba910c0402a0f778").unwrap();
let dataset_tlvs = OperationalDatasetTlvs::try_from_slice(&dataset_bytes).unwrap();
let dataset = dataset_tlvs.try_to_dataset().unwrap();
println!("dataset = {dataset:#?}");
}
}