mirror of
https://github.com/espressif/openthread.git
synced 2026-07-30 15:47:46 +00:00
[dataset] simplify IsSubsetOf() (#10292)
This commit adds a method `Dataset::IsSubsetOf()` to check whether one dataset is a subset of another. A dataset is considered a subset if all its TLVs, excluding Active/Pending Timestamp and Delay Timer TLVs, are present in the other dataset with exactly matching values. This new method simplifies `Dataset::Info::IsSubsetOf()`. The unit test `test_dataset` is updated to validate the `IsSubsetOf()()` method.
This commit is contained in:
@@ -103,57 +103,13 @@ exit:
|
||||
|
||||
bool Dataset::Info::IsSubsetOf(const Info &aOther) const
|
||||
{
|
||||
bool isSubset = false;
|
||||
Dataset dataset;
|
||||
Dataset other;
|
||||
|
||||
if (IsPresent<kNetworkKey>())
|
||||
{
|
||||
VerifyOrExit(aOther.IsPresent<kNetworkKey>() && Get<kNetworkKey>() == aOther.Get<kNetworkKey>());
|
||||
}
|
||||
dataset.SetFrom(*this);
|
||||
other.SetFrom(aOther);
|
||||
|
||||
if (IsPresent<kNetworkName>())
|
||||
{
|
||||
VerifyOrExit(aOther.IsPresent<kNetworkName>() && Get<kNetworkName>() == aOther.Get<kNetworkName>());
|
||||
}
|
||||
|
||||
if (IsPresent<kExtendedPanId>())
|
||||
{
|
||||
VerifyOrExit(aOther.IsPresent<kExtendedPanId>() && Get<kExtendedPanId>() == aOther.Get<kExtendedPanId>());
|
||||
}
|
||||
|
||||
if (IsPresent<kMeshLocalPrefix>())
|
||||
{
|
||||
VerifyOrExit(aOther.IsPresent<kMeshLocalPrefix>() && Get<kMeshLocalPrefix>() == aOther.Get<kMeshLocalPrefix>());
|
||||
}
|
||||
|
||||
if (IsPresent<kPanId>())
|
||||
{
|
||||
VerifyOrExit(aOther.IsPresent<kPanId>() && Get<kPanId>() == aOther.Get<kPanId>());
|
||||
}
|
||||
|
||||
if (IsPresent<kChannel>())
|
||||
{
|
||||
VerifyOrExit(aOther.IsPresent<kChannel>() && Get<kChannel>() == aOther.Get<kChannel>());
|
||||
}
|
||||
|
||||
if (IsPresent<kPskc>())
|
||||
{
|
||||
VerifyOrExit(aOther.IsPresent<kPskc>() && Get<kPskc>() == aOther.Get<kPskc>());
|
||||
}
|
||||
|
||||
if (IsPresent<kSecurityPolicy>())
|
||||
{
|
||||
VerifyOrExit(aOther.IsPresent<kSecurityPolicy>() && Get<kSecurityPolicy>() == aOther.Get<kSecurityPolicy>());
|
||||
}
|
||||
|
||||
if (IsPresent<kChannelMask>())
|
||||
{
|
||||
VerifyOrExit(aOther.IsPresent<kChannelMask>() && Get<kChannelMask>() == aOther.Get<kChannelMask>());
|
||||
}
|
||||
|
||||
isSubset = true;
|
||||
|
||||
exit:
|
||||
return isSubset;
|
||||
return dataset.IsSubsetOf(other);
|
||||
}
|
||||
|
||||
Dataset::Dataset(void)
|
||||
@@ -585,6 +541,31 @@ void Dataset::RemoveTlv(Tlv *aTlv)
|
||||
}
|
||||
}
|
||||
|
||||
bool Dataset::IsSubsetOf(const Dataset &aOther) const
|
||||
{
|
||||
bool isSubset = false;
|
||||
|
||||
for (const Tlv *tlv = GetTlvsStart(); tlv < GetTlvsEnd(); tlv = tlv->GetNext())
|
||||
{
|
||||
const Tlv *otherTlv;
|
||||
|
||||
if ((tlv->GetType() == Tlv::kActiveTimestamp) || (tlv->GetType() == Tlv::kPendingTimestamp) ||
|
||||
(tlv->GetType() == Tlv::kDelayTimer))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
otherTlv = aOther.FindTlv(tlv->GetType());
|
||||
VerifyOrExit(otherTlv != nullptr);
|
||||
VerifyOrExit(memcmp(tlv, otherTlv, tlv->GetSize()) == 0);
|
||||
}
|
||||
|
||||
isSubset = true;
|
||||
|
||||
exit:
|
||||
return isSubset;
|
||||
}
|
||||
|
||||
const char *Dataset::TypeToString(Type aType) { return (aType == kActive) ? "Active" : "Pending"; }
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
|
||||
@@ -220,7 +220,7 @@ public:
|
||||
*
|
||||
* @param[in] aOther The other Dataset to check against.
|
||||
*
|
||||
* @retval TRUE The current dataset is a subset of @p aOther.
|
||||
* @retval TRUE The current Dataset is a subset of @p aOther.
|
||||
* @retval FALSE The current Dataset is not a subset of @p aOther.
|
||||
*
|
||||
*/
|
||||
@@ -672,6 +672,20 @@ public:
|
||||
*/
|
||||
const Tlv *GetTlvsEnd(void) const { return reinterpret_cast<const Tlv *>(mTlvs + mLength); }
|
||||
|
||||
/**
|
||||
* Determines whether this Dataset is a subset of another Dataset.
|
||||
*
|
||||
* The Dataset is considered a subset if all of its TLVs, excluding Active/Pending Timestamp and Delay Timer TLVs,
|
||||
* are present in the @p aOther Dataset and the TLV values match exactly.
|
||||
*
|
||||
* @param[in] aOther The other Dataset to check against.
|
||||
*
|
||||
* @retval TRUE The current dataset is a subset of @p aOther.
|
||||
* @retval FALSE The current Dataset is not a subset of @p aOther.
|
||||
*
|
||||
*/
|
||||
bool IsSubsetOf(const Dataset &aOther) const;
|
||||
|
||||
/**
|
||||
* Converts a Dataset Type to a string.
|
||||
*
|
||||
|
||||
@@ -224,6 +224,41 @@ void TestDataset(void)
|
||||
VerifyOrQuit(memcmp(dataset.GetBytes() + sizeof(kTlvBytes), kTlvBytes, sizeof(kTlvBytes)) == 0);
|
||||
|
||||
VerifyOrQuit(dataset.ValidateTlvs() == kErrorParse);
|
||||
|
||||
// Validate `IsSubsetOf()`
|
||||
|
||||
SuccessOrQuit(dataset.SetFrom(kTlvBytes, sizeof(kTlvBytes)));
|
||||
|
||||
datasetInfo.Clear();
|
||||
datasetInfo.mComponents.mIsPanIdPresent = true;
|
||||
datasetInfo.mComponents.mIsNetworkKeyPresent = true;
|
||||
datasetInfo.mPanId = 0xface;
|
||||
datasetInfo.mNetworkKey = kNetworkKey;
|
||||
|
||||
dataset2.SetFrom(datasetInfo);
|
||||
|
||||
SuccessOrQuit(dataset2.ValidateTlvs());
|
||||
SuccessOrQuit(dataset.ValidateTlvs());
|
||||
|
||||
VerifyOrQuit(dataset2.IsSubsetOf(dataset));
|
||||
VerifyOrQuit(!dataset.IsSubsetOf(dataset2));
|
||||
|
||||
datasetInfo.mComponents.mIsActiveTimestampPresent = true;
|
||||
datasetInfo.mComponents.mIsPendingTimestampPresent = true;
|
||||
datasetInfo.mComponents.mIsDelayPresent = true;
|
||||
datasetInfo.mActiveTimestamp.mSeconds = 0xffff;
|
||||
datasetInfo.mPendingTimestamp.mSeconds = 0x1000;
|
||||
datasetInfo.mDelay = 5000;
|
||||
dataset2.SetFrom(datasetInfo);
|
||||
|
||||
VerifyOrQuit(dataset2.IsSubsetOf(dataset));
|
||||
VerifyOrQuit(!dataset.IsSubsetOf(dataset2));
|
||||
|
||||
datasetInfo.mPanId = 0xcafe;
|
||||
dataset2.SetFrom(datasetInfo);
|
||||
|
||||
VerifyOrQuit(!dataset2.IsSubsetOf(dataset));
|
||||
VerifyOrQuit(!dataset.IsSubsetOf(dataset2));
|
||||
}
|
||||
|
||||
} // namespace MeshCoP
|
||||
|
||||
Reference in New Issue
Block a user