diff --git a/src/core/meshcop/dataset.cpp b/src/core/meshcop/dataset.cpp index 6f8b05c2c..3605ea0ca 100644 --- a/src/core/meshcop/dataset.cpp +++ b/src/core/meshcop/dataset.cpp @@ -105,49 +105,49 @@ bool Dataset::Info::IsSubsetOf(const Info &aOther) const { bool isSubset = false; - if (IsNetworkKeyPresent()) + if (IsPresent()) { - VerifyOrExit(aOther.IsNetworkKeyPresent() && GetNetworkKey() == aOther.GetNetworkKey()); + VerifyOrExit(aOther.IsPresent() && Get() == aOther.Get()); } - if (IsNetworkNamePresent()) + if (IsPresent()) { - VerifyOrExit(aOther.IsNetworkNamePresent() && GetNetworkName() == aOther.GetNetworkName()); + VerifyOrExit(aOther.IsPresent() && Get() == aOther.Get()); } - if (IsExtendedPanIdPresent()) + if (IsPresent()) { - VerifyOrExit(aOther.IsExtendedPanIdPresent() && GetExtendedPanId() == aOther.GetExtendedPanId()); + VerifyOrExit(aOther.IsPresent() && Get() == aOther.Get()); } - if (IsMeshLocalPrefixPresent()) + if (IsPresent()) { - VerifyOrExit(aOther.IsMeshLocalPrefixPresent() && GetMeshLocalPrefix() == aOther.GetMeshLocalPrefix()); + VerifyOrExit(aOther.IsPresent() && Get() == aOther.Get()); } - if (IsPanIdPresent()) + if (IsPresent()) { - VerifyOrExit(aOther.IsPanIdPresent() && GetPanId() == aOther.GetPanId()); + VerifyOrExit(aOther.IsPresent() && Get() == aOther.Get()); } - if (IsChannelPresent()) + if (IsPresent()) { - VerifyOrExit(aOther.IsChannelPresent() && GetChannel() == aOther.GetChannel()); + VerifyOrExit(aOther.IsPresent() && Get() == aOther.Get()); } - if (IsPskcPresent()) + if (IsPresent()) { - VerifyOrExit(aOther.IsPskcPresent() && GetPskc() == aOther.GetPskc()); + VerifyOrExit(aOther.IsPresent() && Get() == aOther.Get()); } - if (IsSecurityPolicyPresent()) + if (IsPresent()) { - VerifyOrExit(aOther.IsSecurityPolicyPresent() && GetSecurityPolicy() == aOther.GetSecurityPolicy()); + VerifyOrExit(aOther.IsPresent() && Get() == aOther.Get()); } - if (IsChannelMaskPresent()) + if (IsPresent()) { - VerifyOrExit(aOther.IsChannelMaskPresent() && GetChannelMask() == aOther.GetChannelMask()); + VerifyOrExit(aOther.IsPresent() && Get() == aOther.Get()); } isSubset = true; @@ -191,11 +191,11 @@ void Dataset::ConvertTo(Info &aDatasetInfo) const switch (cur->GetType()) { case Tlv::kActiveTimestamp: - aDatasetInfo.SetActiveTimestamp(cur->ReadValueAs()); + aDatasetInfo.Set(cur->ReadValueAs()); break; case Tlv::kChannel: - aDatasetInfo.SetChannel(cur->ReadValueAs().GetChannel()); + aDatasetInfo.Set(cur->ReadValueAs().GetChannel()); break; case Tlv::kChannelMask: @@ -204,46 +204,46 @@ void Dataset::ConvertTo(Info &aDatasetInfo) const if (As(cur)->ReadChannelMask(mask) == kErrorNone) { - aDatasetInfo.SetChannelMask(mask); + aDatasetInfo.Set(mask); } break; } case Tlv::kDelayTimer: - aDatasetInfo.SetDelay(cur->ReadValueAs()); + aDatasetInfo.Set(cur->ReadValueAs()); break; case Tlv::kExtendedPanId: - aDatasetInfo.SetExtendedPanId(cur->ReadValueAs()); + aDatasetInfo.Set(cur->ReadValueAs()); break; case Tlv::kMeshLocalPrefix: - aDatasetInfo.SetMeshLocalPrefix(cur->ReadValueAs()); + aDatasetInfo.Set(cur->ReadValueAs()); break; case Tlv::kNetworkKey: - aDatasetInfo.SetNetworkKey(cur->ReadValueAs()); + aDatasetInfo.Set(cur->ReadValueAs()); break; case Tlv::kNetworkName: - aDatasetInfo.SetNetworkName(As(cur)->GetNetworkName()); + IgnoreError(aDatasetInfo.Update().Set(As(cur)->GetNetworkName())); break; case Tlv::kPanId: - aDatasetInfo.SetPanId(cur->ReadValueAs()); + aDatasetInfo.Set(cur->ReadValueAs()); break; case Tlv::kPendingTimestamp: - aDatasetInfo.SetPendingTimestamp(cur->ReadValueAs()); + aDatasetInfo.Set(cur->ReadValueAs()); break; case Tlv::kPskc: - aDatasetInfo.SetPskc(cur->ReadValueAs()); + aDatasetInfo.Set(cur->ReadValueAs()); break; case Tlv::kSecurityPolicy: - aDatasetInfo.SetSecurityPolicy(As(cur)->GetSecurityPolicy()); + aDatasetInfo.Set(As(cur)->GetSecurityPolicy()); break; default: @@ -282,81 +282,81 @@ Error Dataset::SetFrom(const Info &aDatasetInfo) { Error error = kErrorNone; - if (aDatasetInfo.IsActiveTimestampPresent()) + if (aDatasetInfo.IsPresent()) { Timestamp activeTimestamp; - aDatasetInfo.GetActiveTimestamp(activeTimestamp); + aDatasetInfo.Get(activeTimestamp); IgnoreError(Write(activeTimestamp)); } - if (aDatasetInfo.IsPendingTimestampPresent()) + if (aDatasetInfo.IsPresent()) { Timestamp pendingTimestamp; - aDatasetInfo.GetPendingTimestamp(pendingTimestamp); + aDatasetInfo.Get(pendingTimestamp); IgnoreError(Write(pendingTimestamp)); } - if (aDatasetInfo.IsDelayPresent()) + if (aDatasetInfo.IsPresent()) { - IgnoreError(Write(aDatasetInfo.GetDelay())); + IgnoreError(Write(aDatasetInfo.Get())); } - if (aDatasetInfo.IsChannelPresent()) + if (aDatasetInfo.IsPresent()) { ChannelTlvValue channelValue; - channelValue.SetChannelAndPage(aDatasetInfo.GetChannel()); + channelValue.SetChannelAndPage(aDatasetInfo.Get()); IgnoreError(Write(channelValue)); } - if (aDatasetInfo.IsChannelMaskPresent()) + if (aDatasetInfo.IsPresent()) { ChannelMaskTlv::Value value; - ChannelMaskTlv::PrepareValue(value, aDatasetInfo.GetChannelMask()); + ChannelMaskTlv::PrepareValue(value, aDatasetInfo.Get()); IgnoreError(WriteTlv(Tlv::kChannelMask, value.mData, value.mLength)); } - if (aDatasetInfo.IsExtendedPanIdPresent()) + if (aDatasetInfo.IsPresent()) { - IgnoreError(Write(aDatasetInfo.GetExtendedPanId())); + IgnoreError(Write(aDatasetInfo.Get())); } - if (aDatasetInfo.IsMeshLocalPrefixPresent()) + if (aDatasetInfo.IsPresent()) { - IgnoreError(Write(aDatasetInfo.GetMeshLocalPrefix())); + IgnoreError(Write(aDatasetInfo.Get())); } - if (aDatasetInfo.IsNetworkKeyPresent()) + if (aDatasetInfo.IsPresent()) { - IgnoreError(Write(aDatasetInfo.GetNetworkKey())); + IgnoreError(Write(aDatasetInfo.Get())); } - if (aDatasetInfo.IsNetworkNamePresent()) + if (aDatasetInfo.IsPresent()) { - NameData nameData = aDatasetInfo.GetNetworkName().GetAsData(); + NameData nameData = aDatasetInfo.Get().GetAsData(); IgnoreError(WriteTlv(Tlv::kNetworkName, nameData.GetBuffer(), nameData.GetLength())); } - if (aDatasetInfo.IsPanIdPresent()) + if (aDatasetInfo.IsPresent()) { - IgnoreError(Write(aDatasetInfo.GetPanId())); + IgnoreError(Write(aDatasetInfo.Get())); } - if (aDatasetInfo.IsPskcPresent()) + if (aDatasetInfo.IsPresent()) { - IgnoreError(Write(aDatasetInfo.GetPskc())); + IgnoreError(Write(aDatasetInfo.Get())); } - if (aDatasetInfo.IsSecurityPolicyPresent()) + if (aDatasetInfo.IsPresent()) { SecurityPolicyTlv tlv; tlv.Init(); - tlv.SetSecurityPolicy(aDatasetInfo.GetSecurityPolicy()); + tlv.SetSecurityPolicy(aDatasetInfo.Get()); IgnoreError(WriteTlv(tlv)); } diff --git a/src/core/meshcop/dataset.hpp b/src/core/meshcop/dataset.hpp index 38b2a0c1f..a552e00ba 100644 --- a/src/core/meshcop/dataset.hpp +++ b/src/core/meshcop/dataset.hpp @@ -81,108 +81,52 @@ public: */ typedef otOperationalDatasetTlvs Tlvs; + /** + * Represents a component in Dataset. + * + */ + enum Component : uint8_t + { + kActiveTimestamp, ///< Active Timestamp + kPendingTimestamp, ///< Pending Timestamp + kNetworkKey, ///< Network Key + kNetworkName, ///< Network Name + kExtendedPanId, ///< Extended PAN Identifier + kMeshLocalPrefix, ///< Mesh Local Prefix + kDelay, ///< Delay + kPanId, ///< PAN Identifier + kChannel, ///< Channel + kPskc, ///< PSKc + kSecurityPolicy, ///< Security Policy + kChannelMask, ///< Channel Mask + }; + + template struct TypeFor; ///< Specifies the associate type for a given `Component`. + + class Info; + /** * Represents presence of different components in Active or Pending Operational Dataset. * */ class Components : public otOperationalDatasetComponents, public Clearable { + friend class Info; + public: /** - * Indicates whether or not the Active Timestamp is present in the Dataset. + * Indicates whether or not the specified `kComponent` is present in the Dataset. * - * @returns TRUE if Active Timestamp is present, FALSE otherwise. + * @tparam kComponent The component to check. + * + * @retval TRUE The component is present in the Dataset. + * @retval FALSE The component is not present in the Dataset. * */ - bool IsActiveTimestampPresent(void) const { return mIsActiveTimestampPresent; } + template bool IsPresent(void) const; - /** - * Indicates whether or not the Pending Timestamp is present in the Dataset. - * - * @returns TRUE if Pending Timestamp is present, FALSE otherwise. - * - */ - bool IsPendingTimestampPresent(void) const { return mIsPendingTimestampPresent; } - - /** - * Indicates whether or not the Network Key is present in the Dataset. - * - * @returns TRUE if Network Key is present, FALSE otherwise. - * - */ - bool IsNetworkKeyPresent(void) const { return mIsNetworkKeyPresent; } - - /** - * Indicates whether or not the Network Name is present in the Dataset. - * - * @returns TRUE if Network Name is present, FALSE otherwise. - * - */ - bool IsNetworkNamePresent(void) const { return mIsNetworkNamePresent; } - - /** - * Indicates whether or not the Extended PAN ID is present in the Dataset. - * - * @returns TRUE if Extended PAN ID is present, FALSE otherwise. - * - */ - bool IsExtendedPanIdPresent(void) const { return mIsExtendedPanIdPresent; } - - /** - * Indicates whether or not the Mesh Local Prefix is present in the Dataset. - * - * @returns TRUE if Mesh Local Prefix is present, FALSE otherwise. - * - */ - bool IsMeshLocalPrefixPresent(void) const { return mIsMeshLocalPrefixPresent; } - - /** - * Indicates whether or not the Delay Timer is present in the Dataset. - * - * @returns TRUE if Delay Timer is present, FALSE otherwise. - * - */ - bool IsDelayPresent(void) const { return mIsDelayPresent; } - - /** - * Indicates whether or not the PAN ID is present in the Dataset. - * - * @returns TRUE if PAN ID is present, FALSE otherwise. - * - */ - bool IsPanIdPresent(void) const { return mIsPanIdPresent; } - - /** - * Indicates whether or not the Channel is present in the Dataset. - * - * @returns TRUE if Channel is present, FALSE otherwise. - * - */ - bool IsChannelPresent(void) const { return mIsChannelPresent; } - - /** - * Indicates whether or not the PSKc is present in the Dataset. - * - * @returns TRUE if PSKc is present, FALSE otherwise. - * - */ - bool IsPskcPresent(void) const { return mIsPskcPresent; } - - /** - * Indicates whether or not the Security Policy is present in the Dataset. - * - * @returns TRUE if Security Policy is present, FALSE otherwise. - * - */ - bool IsSecurityPolicyPresent(void) const { return mIsSecurityPolicyPresent; } - - /** - * Indicates whether or not the Channel Mask is present in the Dataset. - * - * @returns TRUE if Channel Mask is present, FALSE otherwise. - * - */ - bool IsChannelMaskPresent(void) const { return mIsChannelMaskPresent; } + private: + template void MarkAsPresent(void); }; /** @@ -193,389 +137,66 @@ public: { public: /** - * Indicates whether or not the Active Timestamp is present in the Dataset. + * Indicates whether or not the specified component is present in the Dataset. * - * @returns TRUE if Active Timestamp is present, FALSE otherwise. + * @tparam kComponent The component to check. + * + * @retval TRUE The component is present in the Dataset. + * @retval FALSE The component is not present in the Dataset. * */ - bool IsActiveTimestampPresent(void) const { return mComponents.mIsActiveTimestampPresent; } + template bool IsPresent(void) const { return GetComponents().IsPresent(); } /** - * Gets the Active Timestamp in the Dataset. + * Gets the specified component in the Dataset. * - * MUST be used when Active Timestamp component is present in the Dataset, otherwise its behavior is - * undefined. + * @tparam kComponent The component to check. * - * @param[out] aTimestamp A reference to output the Active Timestamp in the Dataset. + * MUST be used when component is present in the Dataset, otherwise its behavior is undefined. + * + * @returns The component value. * */ - void GetActiveTimestamp(Timestamp &aTimestamp) const { aTimestamp.SetFromTimestamp(mActiveTimestamp); } + template const typename TypeFor::Type &Get(void) const; /** - * Sets the Active Timestamp in the Dataset. + * Gets the specified component in the Dataset. * - * @param[in] aTimestamp A Timestamp value. + * @tparam kComponent The component to check. + * + * MUST be used when component is present in the Dataset, otherwise its behavior is undefined. + * + * @pram[out] aComponent A reference to output the component value. * */ - void SetActiveTimestamp(const Timestamp &aTimestamp) + template void Get(typename TypeFor::Type &aComponent) const; + + /** + * Sets the specified component in the Dataset. + * + * @tparam kComponent The component to set. + * + * @param[in] aComponent The component value. + * + */ + template void Set(const typename TypeFor::Type &aComponent) { - aTimestamp.ConvertTo(mActiveTimestamp); - mComponents.mIsActiveTimestampPresent = true; + GetComponents().MarkAsPresent(); + AsNonConst(Get()) = aComponent; } /** - * Indicates whether or not the Pending Timestamp is present in the Dataset. + * Returns a reference to the specified component in the Dataset to be updated by caller. * - * @returns TRUE if Pending Timestamp is present, FALSE otherwise. + * @tparam kComponent The component to set. + * + * @returns A reference to the component in the Dataset. * */ - bool IsPendingTimestampPresent(void) const { return mComponents.mIsPendingTimestampPresent; } - - /** - * Gets the Pending Timestamp in the Dataset. - * - * MUST be used when Pending Timestamp component is present in the Dataset, otherwise its behavior - * is undefined. - * - * @param[out] aTimestamp A reference to output the Pending Timestamp in the Dataset. - * - */ - void GetPendingTimestamp(Timestamp &aTimestamp) const { aTimestamp.SetFromTimestamp(mPendingTimestamp); } - - /** - * Sets the Pending Timestamp in the Dataset. - * - * @param[in] aTimestamp A Timestamp value. - * - */ - void SetPendingTimestamp(const Timestamp &aTimestamp) + template typename TypeFor::Type &Update(void) { - aTimestamp.ConvertTo(mPendingTimestamp); - mComponents.mIsPendingTimestampPresent = true; - } - - /** - * Indicates whether or not the Network Key is present in the Dataset. - * - * @returns TRUE if Network Key is present, FALSE otherwise. - * - */ - bool IsNetworkKeyPresent(void) const { return mComponents.mIsNetworkKeyPresent; } - - /** - * Gets the Network Key in the Dataset. - * - * MUST be used when Network Key component is present in the Dataset, otherwise its behavior - * is undefined. - * - * @returns The Network Key in the Dataset. - * - */ - const NetworkKey &GetNetworkKey(void) const { return AsCoreType(&mNetworkKey); } - - /** - * Sets the Network Key in the Dataset. - * - * @param[in] aNetworkKey A Network Key. - * - */ - void SetNetworkKey(const NetworkKey &aNetworkKey) - { - mNetworkKey = aNetworkKey; - mComponents.mIsNetworkKeyPresent = true; - } - - /** - * Returns a reference to the Network Key in the Dataset to be updated by caller. - * - * @returns A reference to the Network Key in the Dataset. - * - */ - NetworkKey &UpdateNetworkKey(void) - { - mComponents.mIsNetworkKeyPresent = true; - return AsCoreType(&mNetworkKey); - } - - /** - * Indicates whether or not the Network Name is present in the Dataset. - * - * @returns TRUE if Network Name is present, FALSE otherwise. - * - */ - bool IsNetworkNamePresent(void) const { return mComponents.mIsNetworkNamePresent; } - - /** - * Gets the Network Name in the Dataset. - * - * MUST be used when Network Name component is present in the Dataset, otherwise its behavior is - * undefined. - * - * @returns The Network Name in the Dataset. - * - */ - const NetworkName &GetNetworkName(void) const { return AsCoreType(&mNetworkName); } - - /** - * Sets the Network Name in the Dataset. - * - * @param[in] aNetworkNameData A Network Name Data. - * - */ - void SetNetworkName(const NameData &aNetworkNameData) - { - IgnoreError(AsCoreType(&mNetworkName).Set(aNetworkNameData)); - mComponents.mIsNetworkNamePresent = true; - } - - /** - * Indicates whether or not the Extended PAN ID is present in the Dataset. - * - * @returns TRUE if Extended PAN ID is present, FALSE otherwise. - * - */ - bool IsExtendedPanIdPresent(void) const { return mComponents.mIsExtendedPanIdPresent; } - - /** - * Gets the Extended PAN ID in the Dataset. - * - * MUST be used when Extended PAN ID component is present in the Dataset, otherwise its behavior is - * undefined. - * - * @returns The Extended PAN ID in the Dataset. - * - */ - const ExtendedPanId &GetExtendedPanId(void) const { return AsCoreType(&mExtendedPanId); } - - /** - * Sets the Extended PAN ID in the Dataset. - * - * @param[in] aExtendedPanId An Extended PAN ID. - * - */ - void SetExtendedPanId(const ExtendedPanId &aExtendedPanId) - { - mExtendedPanId = aExtendedPanId; - mComponents.mIsExtendedPanIdPresent = true; - } - - /** - * Indicates whether or not the Mesh Local Prefix is present in the Dataset. - * - * @returns TRUE if Mesh Local Prefix is present, FALSE otherwise. - * - */ - bool IsMeshLocalPrefixPresent(void) const { return mComponents.mIsMeshLocalPrefixPresent; } - - /** - * Gets the Mesh Local Prefix in the Dataset. - * - * MUST be used when Mesh Local Prefix component is present in the Dataset, otherwise its behavior - * is undefined. - * - * @returns The Mesh Local Prefix in the Dataset. - * - */ - const Ip6::NetworkPrefix &GetMeshLocalPrefix(void) const - { - return static_cast(mMeshLocalPrefix); - } - - /** - * Sets the Mesh Local Prefix in the Dataset. - * - * @param[in] aMeshLocalPrefix A Mesh Local Prefix. - * - */ - void SetMeshLocalPrefix(const Ip6::NetworkPrefix &aMeshLocalPrefix) - { - mMeshLocalPrefix = aMeshLocalPrefix; - mComponents.mIsMeshLocalPrefixPresent = true; - } - - /** - * Indicates whether or not the Delay Timer is present in the Dataset. - * - * @returns TRUE if Delay Timer is present, FALSE otherwise. - * - */ - bool IsDelayPresent(void) const { return mComponents.mIsDelayPresent; } - - /** - * Gets the Delay Timer in the Dataset. - * - * MUST be used when Delay Timer component is present in the Dataset, otherwise its behavior is - * undefined. - * - * @returns The Delay Timer in the Dataset. - * - */ - uint32_t GetDelay(void) const { return mDelay; } - - /** - * Sets the Delay Timer in the Dataset. - * - * @param[in] aDelay A Delay value. - * - */ - void SetDelay(uint32_t aDelay) - { - mDelay = aDelay; - mComponents.mIsDelayPresent = true; - } - - /** - * Indicates whether or not the PAN ID is present in the Dataset. - * - * @returns TRUE if PAN ID is present, FALSE otherwise. - * - */ - bool IsPanIdPresent(void) const { return mComponents.mIsPanIdPresent; } - - /** - * Gets the PAN ID in the Dataset. - * - * MUST be used when PAN ID component is present in the Dataset, otherwise its behavior is - * undefined. - * - * @returns The PAN ID in the Dataset. - * - */ - Mac::PanId GetPanId(void) const { return mPanId; } - - /** - * Sets the PAN ID in the Dataset. - * - * @param[in] aPanId A PAN ID. - * - */ - void SetPanId(Mac::PanId aPanId) - { - mPanId = aPanId; - mComponents.mIsPanIdPresent = true; - } - - /** - * Indicates whether or not the Channel is present in the Dataset. - * - * @returns TRUE if Channel is present, FALSE otherwise. - * - */ - bool IsChannelPresent(void) const { return mComponents.mIsChannelPresent; } - - /** - * Gets the Channel in the Dataset. - * - * MUST be used when Channel component is present in the Dataset, otherwise its behavior is - * undefined. - * - * @returns The Channel in the Dataset. - * - */ - uint16_t GetChannel(void) const { return mChannel; } - - /** - * Sets the Channel in the Dataset. - * - * @param[in] aChannel A Channel. - * - */ - void SetChannel(uint16_t aChannel) - { - mChannel = aChannel; - mComponents.mIsChannelPresent = true; - } - - /** - * Indicates whether or not the PSKc is present in the Dataset. - * - * @returns TRUE if PSKc is present, FALSE otherwise. - * - */ - bool IsPskcPresent(void) const { return mComponents.mIsPskcPresent; } - - /** - * Gets the PSKc in the Dataset. - * - * MUST be used when PSKc component is present in the Dataset, otherwise its behavior is undefined. - * - * @returns The PSKc in the Dataset. - * - */ - const Pskc &GetPskc(void) const { return AsCoreType(&mPskc); } - - /** - * Set the PSKc in the Dataset. - * - * @param[in] aPskc A PSKc value. - * - */ - void SetPskc(const Pskc &aPskc) - { - mPskc = aPskc; - mComponents.mIsPskcPresent = true; - } - - /** - * Indicates whether or not the Security Policy is present in the Dataset. - * - * @returns TRUE if Security Policy is present, FALSE otherwise. - * - */ - bool IsSecurityPolicyPresent(void) const { return mComponents.mIsSecurityPolicyPresent; } - - /** - * Gets the Security Policy in the Dataset. - * - * MUST be used when Security Policy component is present in the Dataset, otherwise its behavior is - * undefined. - * - * @returns The Security Policy in the Dataset. - * - */ - const SecurityPolicy &GetSecurityPolicy(void) const { return AsCoreType(&mSecurityPolicy); } - - /** - * Sets the Security Policy in the Dataset. - * - * @param[in] aSecurityPolicy A Security Policy to set in Dataset. - * - */ - void SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy) - { - mSecurityPolicy = aSecurityPolicy; - mComponents.mIsSecurityPolicyPresent = true; - } - - /** - * Indicates whether or not the Channel Mask is present in the Dataset. - * - * @returns TRUE if Channel Mask is present, FALSE otherwise. - * - */ - bool IsChannelMaskPresent(void) const { return mComponents.mIsChannelMaskPresent; } - - /** - * Gets the Channel Mask in the Dataset. - * - * MUST be used when Channel Mask component is present in the Dataset, otherwise its behavior is - * undefined. - * - * @returns The Channel Mask in the Dataset. - * - */ - otChannelMask GetChannelMask(void) const { return mChannelMask; } - - /** - * Sets the Channel Mask in the Dataset. - * - * @param[in] aChannelMask A Channel Mask value. - * - */ - void SetChannelMask(otChannelMask aChannelMask) - { - mChannelMask = aChannelMask; - mComponents.mIsChannelMaskPresent = true; + GetComponents().MarkAsPresent(); + return AsNonConst(Get()); } /** @@ -606,6 +227,10 @@ public: * */ bool IsSubsetOf(const Info &aOther) const; + + private: + Components &GetComponents(void) { return static_cast(mComponents); } + const Components &GetComponents(void) const { return static_cast(mComponents); } }; /** @@ -994,6 +619,121 @@ private: uint16_t mLength; ///< The number of valid bytes in @var mTlvs }; +//--------------------------------------------------------------------------------------------------------------------- +// Template specializations + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// `Dataset::Components::IsPresent()` and `Dataset::Components::MarkAsPresent()` + +#define DefineIsPresentAndMarkAsPresent(Component) \ + template <> inline bool Dataset::Components::IsPresent(void) const \ + { \ + return mIs##Component##Present; \ + } \ + \ + template <> inline void Dataset::Components::MarkAsPresent(void) \ + { \ + mIs##Component##Present = true; \ + } + +// clang-format off + +DefineIsPresentAndMarkAsPresent(ActiveTimestamp) +DefineIsPresentAndMarkAsPresent(PendingTimestamp) +DefineIsPresentAndMarkAsPresent(NetworkKey) +DefineIsPresentAndMarkAsPresent(NetworkName) +DefineIsPresentAndMarkAsPresent(ExtendedPanId) +DefineIsPresentAndMarkAsPresent(MeshLocalPrefix) +DefineIsPresentAndMarkAsPresent(Delay) +DefineIsPresentAndMarkAsPresent(PanId) +DefineIsPresentAndMarkAsPresent(Channel) +DefineIsPresentAndMarkAsPresent(Pskc) +DefineIsPresentAndMarkAsPresent(SecurityPolicy) +DefineIsPresentAndMarkAsPresent(ChannelMask) + +#undef DefineIsPresentAndMarkAsPresent + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// `Dataset::TypeFor<>` + +template <> struct Dataset::TypeFor { using Type = Timestamp; }; +template <> struct Dataset::TypeFor { using Type = Timestamp; }; +template <> struct Dataset::TypeFor { using Type = NetworkKey; }; +template <> struct Dataset::TypeFor { using Type = NetworkName; }; +template <> struct Dataset::TypeFor { using Type = ExtendedPanId; }; +template <> struct Dataset::TypeFor { using Type = Ip6::NetworkPrefix; }; +template <> struct Dataset::TypeFor { using Type = uint32_t; }; +template <> struct Dataset::TypeFor { using Type = Mac::PanId; }; +template <> struct Dataset::TypeFor { using Type = uint16_t; }; +template <> struct Dataset::TypeFor { using Type = Pskc; }; +template <> struct Dataset::TypeFor { using Type = SecurityPolicy; }; +template <> struct Dataset::TypeFor { using Type = uint32_t; }; + +// clang-format on + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Dataset::Info::Get<>() + +template <> inline const NetworkKey &Dataset::Info::Get(void) const +{ + return AsCoreType(&mNetworkKey); +} + +template <> inline const NetworkName &Dataset::Info::Get(void) const +{ + return AsCoreType(&mNetworkName); +} + +template <> inline const ExtendedPanId &Dataset::Info::Get(void) const +{ + return AsCoreType(&mExtendedPanId); +} + +template <> inline const Ip6::NetworkPrefix &Dataset::Info::Get(void) const +{ + return static_cast(mMeshLocalPrefix); +} + +template <> inline const uint32_t &Dataset::Info::Get(void) const { return mDelay; } + +template <> inline const Mac::PanId &Dataset::Info::Get(void) const { return mPanId; } + +template <> inline const uint16_t &Dataset::Info::Get(void) const { return mChannel; } + +template <> inline const Pskc &Dataset::Info::Get(void) const { return AsCoreType(&mPskc); } + +template <> inline const SecurityPolicy &Dataset::Info::Get(void) const +{ + return AsCoreType(&mSecurityPolicy); +} + +template <> inline const uint32_t &Dataset::Info::Get(void) const { return mChannelMask; } + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Active and Pending Timestamp + +template <> inline void Dataset::Info::Get(Timestamp &aTimestamp) const +{ + aTimestamp.SetFromTimestamp(mActiveTimestamp); +} + +template <> inline void Dataset::Info::Get(Timestamp &aTimestamp) const +{ + aTimestamp.SetFromTimestamp(mPendingTimestamp); +} + +template <> inline void Dataset::Info::Set(const Timestamp &aTimestamp) +{ + GetComponents().MarkAsPresent(); + aTimestamp.ConvertTo(mActiveTimestamp); +} + +template <> inline void Dataset::Info::Set(const Timestamp &aTimestamp) +{ + GetComponents().MarkAsPresent(); + aTimestamp.ConvertTo(mPendingTimestamp); +} + } // namespace MeshCoP DefineCoreType(otOperationalDatasetComponents, MeshCoP::Dataset::Components); diff --git a/src/core/meshcop/dataset_manager.cpp b/src/core/meshcop/dataset_manager.cpp index 48033acdf..7c3f80ac9 100644 --- a/src/core/meshcop/dataset_manager.cpp +++ b/src/core/meshcop/dataset_manager.cpp @@ -525,62 +525,62 @@ Error DatasetManager::SendGetRequest(const Dataset::Components &aDatasetComponen length = 0; - if (aDatasetComponents.IsActiveTimestampPresent()) + if (aDatasetComponents.IsPresent()) { datasetTlvs[length++] = Tlv::kActiveTimestamp; } - if (aDatasetComponents.IsPendingTimestampPresent()) + if (aDatasetComponents.IsPresent()) { datasetTlvs[length++] = Tlv::kPendingTimestamp; } - if (aDatasetComponents.IsNetworkKeyPresent()) + if (aDatasetComponents.IsPresent()) { datasetTlvs[length++] = Tlv::kNetworkKey; } - if (aDatasetComponents.IsNetworkNamePresent()) + if (aDatasetComponents.IsPresent()) { datasetTlvs[length++] = Tlv::kNetworkName; } - if (aDatasetComponents.IsExtendedPanIdPresent()) + if (aDatasetComponents.IsPresent()) { datasetTlvs[length++] = Tlv::kExtendedPanId; } - if (aDatasetComponents.IsMeshLocalPrefixPresent()) + if (aDatasetComponents.IsPresent()) { datasetTlvs[length++] = Tlv::kMeshLocalPrefix; } - if (aDatasetComponents.IsDelayPresent()) + if (aDatasetComponents.IsPresent()) { datasetTlvs[length++] = Tlv::kDelayTimer; } - if (aDatasetComponents.IsPanIdPresent()) + if (aDatasetComponents.IsPresent()) { datasetTlvs[length++] = Tlv::kPanId; } - if (aDatasetComponents.IsChannelPresent()) + if (aDatasetComponents.IsPresent()) { datasetTlvs[length++] = Tlv::kChannel; } - if (aDatasetComponents.IsPskcPresent()) + if (aDatasetComponents.IsPresent()) { datasetTlvs[length++] = Tlv::kPskc; } - if (aDatasetComponents.IsSecurityPolicyPresent()) + if (aDatasetComponents.IsPresent()) { datasetTlvs[length++] = Tlv::kSecurityPolicy; } - if (aDatasetComponents.IsChannelMaskPresent()) + if (aDatasetComponents.IsPresent()) { datasetTlvs[length++] = Tlv::kChannelMask; } @@ -638,8 +638,9 @@ bool ActiveDatasetManager::IsCommissioned(void) const SuccessOrExit(Read(datasetInfo)); - isValid = (datasetInfo.IsNetworkKeyPresent() && datasetInfo.IsNetworkNamePresent() && - datasetInfo.IsExtendedPanIdPresent() && datasetInfo.IsPanIdPresent() && datasetInfo.IsChannelPresent()); + isValid = (datasetInfo.IsPresent() && datasetInfo.IsPresent() && + datasetInfo.IsPresent() && datasetInfo.IsPresent() && + datasetInfo.IsPresent()); exit: return isValid; diff --git a/src/core/meshcop/dataset_updater.cpp b/src/core/meshcop/dataset_updater.cpp index c4b1145cf..4f55a3036 100644 --- a/src/core/meshcop/dataset_updater.cpp +++ b/src/core/meshcop/dataset_updater.cpp @@ -61,7 +61,7 @@ Error DatasetUpdater::RequestUpdate(const Dataset::Info &aDataset, UpdaterCallba VerifyOrExit(!Get().IsDisabled(), error = kErrorInvalidState); VerifyOrExit(mDataset == nullptr, error = kErrorBusy); - VerifyOrExit(!aDataset.IsActiveTimestampPresent() && !aDataset.IsPendingTimestampPresent(), + VerifyOrExit(!aDataset.IsPresent() && !aDataset.IsPresent(), error = kErrorInvalidArgs); message = Get().Allocate(Message::kTypeOther); @@ -119,7 +119,7 @@ void DatasetUpdater::PreparePendingDataset(void) IgnoreError(dataset.SetFrom(requestedDataset)); - if (!requestedDataset.IsDelayPresent()) + if (!requestedDataset.IsPresent()) { uint32_t delay = kDefaultDelay; @@ -190,8 +190,8 @@ void DatasetUpdater::HandleNotifierEvents(Events aEvents) Timestamp requestedDatasetTimestamp; Timestamp activeDatasetTimestamp; - requestedDataset.GetActiveTimestamp(requestedDatasetTimestamp); - dataset.GetActiveTimestamp(activeDatasetTimestamp); + requestedDataset.Get(requestedDatasetTimestamp); + dataset.Get(activeDatasetTimestamp); if (Timestamp::Compare(requestedDatasetTimestamp, activeDatasetTimestamp) <= 0) { Finish(kErrorAlready); diff --git a/src/core/meshcop/joiner.cpp b/src/core/meshcop/joiner.cpp index 4df5f96fc..f8fb30e0c 100644 --- a/src/core/meshcop/joiner.cpp +++ b/src/core/meshcop/joiner.cpp @@ -528,10 +528,10 @@ template <> void Joiner::HandleTmf(Coap::Message &aMessage, c datasetInfo.Clear(); - SuccessOrExit(error = Tlv::Find(aMessage, datasetInfo.UpdateNetworkKey())); + SuccessOrExit(error = Tlv::Find(aMessage, datasetInfo.Update())); - datasetInfo.SetChannel(Get().GetPanChannel()); - datasetInfo.SetPanId(Get().GetPanId()); + datasetInfo.Set(Get().GetPanChannel()); + datasetInfo.Set(Get().GetPanId()); IgnoreError(Get().Save(datasetInfo)); diff --git a/src/core/meshcop/tcat_agent.cpp b/src/core/meshcop/tcat_agent.cpp index f8e459642..325aa9a2c 100644 --- a/src/core/meshcop/tcat_agent.cpp +++ b/src/core/meshcop/tcat_agent.cpp @@ -224,14 +224,14 @@ bool TcatAgent::CheckCommandClassAuthorizationFlags(CommandClassFlags aCommissio if (datasetError == kErrorNone) { - if (datasetInfo.IsNetworkNamePresent() && mCommissionerHasNetworkName && - (datasetInfo.GetNetworkName() == mCommissionerNetworkName)) + if (datasetInfo.IsPresent() && mCommissionerHasNetworkName && + (datasetInfo.Get() == mCommissionerNetworkName)) { networkNamesMatch = true; } - if (datasetInfo.IsExtendedPanIdPresent() && mCommissionerHasExtendedPanId && - (datasetInfo.GetExtendedPanId() == mCommissionerExtendedPanId)) + if (datasetInfo.IsPresent() && mCommissionerHasExtendedPanId && + (datasetInfo.Get() == mCommissionerExtendedPanId)) { extendedPanIdsMatch = true; } @@ -487,7 +487,7 @@ Error TcatAgent::HandleStartThreadInterface(void) Dataset::Info datasetInfo; VerifyOrExit(Get().Read(datasetInfo) == kErrorNone, error = kErrorInvalidState); - VerifyOrExit(datasetInfo.IsNetworkKeyPresent(), error = kErrorInvalidState); + VerifyOrExit(datasetInfo.IsPresent(), error = kErrorInvalidState); #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE VerifyOrExit(!Get().IsEnabled(), error = kErrorInvalidState); diff --git a/src/core/utils/channel_manager.cpp b/src/core/utils/channel_manager.cpp index 788a077ca..e0b13e43a 100644 --- a/src/core/utils/channel_manager.cpp +++ b/src/core/utils/channel_manager.cpp @@ -162,8 +162,8 @@ void ChannelManager::StartDatasetUpdate(void) MeshCoP::Dataset::Info dataset; dataset.Clear(); - dataset.SetChannel(mChannel); - dataset.SetDelay(Time::SecToMsec(mDelay)); + dataset.Set(mChannel); + dataset.Set(Time::SecToMsec(mDelay)); switch (Get().RequestUpdate(dataset, HandleDatasetUpdateDone, this)) {