From c378bd9a254745363ac67f2be8eb8719fa4979e4 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Mon, 4 Dec 2023 08:22:47 -0800 Subject: [PATCH] [meshcop] `MeshCoP::ChannelTlv` to utilize `Mle::ChannelTlvValue` (#9674) This commit introduces `IsValid()` and `SetChannelAndPage()` methods to `Mle::ChannelTlvValue`, enabling its use as value of `MeshCoP::ChannelTlv`. --- src/core/meshcop/dataset.cpp | 12 ++-- src/core/meshcop/dataset_manager_ftd.cpp | 17 +++--- src/core/meshcop/meshcop_tlvs.cpp | 50 +---------------- src/core/meshcop/meshcop_tlvs.hpp | 70 +++--------------------- src/core/thread/mle_tlvs.cpp | 43 +++++++++++++++ src/core/thread/mle_tlvs.hpp | 17 ++++++ 6 files changed, 86 insertions(+), 123 deletions(-) diff --git a/src/core/meshcop/dataset.cpp b/src/core/meshcop/dataset.cpp index 00c8d6d17..1692696fc 100644 --- a/src/core/meshcop/dataset.cpp +++ b/src/core/meshcop/dataset.cpp @@ -194,7 +194,7 @@ void Dataset::ConvertTo(Info &aDatasetInfo) const break; case Tlv::kChannel: - aDatasetInfo.SetChannel(As(cur)->GetChannel()); + aDatasetInfo.SetChannel(cur->ReadValueAs().GetChannel()); break; case Tlv::kChannelMask: @@ -304,10 +304,10 @@ Error Dataset::SetFrom(const Info &aDatasetInfo) if (aDatasetInfo.IsChannelPresent()) { - ChannelTlv tlv; - tlv.Init(); - tlv.SetChannel(aDatasetInfo.GetChannel()); - IgnoreError(WriteTlv(tlv)); + ChannelTlvValue channelValue; + + channelValue.SetChannelAndPage(aDatasetInfo.GetChannel()); + IgnoreError(Write(channelValue)); } if (aDatasetInfo.IsChannelMaskPresent()) @@ -527,7 +527,7 @@ Error Dataset::ApplyConfiguration(Instance &aInstance, bool *aIsNetworkKeyUpdate { case Tlv::kChannel: { - uint8_t channel = static_cast(As(cur)->GetChannel()); + uint8_t channel = static_cast(cur->ReadValueAs().GetChannel()); error = mac.SetPanChannel(channel); diff --git a/src/core/meshcop/dataset_manager_ftd.cpp b/src/core/meshcop/dataset_manager_ftd.cpp index 3eec1a8b6..e5423dc3c 100644 --- a/src/core/meshcop/dataset_manager_ftd.cpp +++ b/src/core/meshcop/dataset_manager_ftd.cpp @@ -82,7 +82,7 @@ Error DatasetManager::HandleSet(Coap::Message &aMessage, const Ip6::MessageInfo StateTlv::State state = StateTlv::kReject; Dataset dataset; Timestamp activeTimestamp; - ChannelTlv channel; + ChannelTlvValue channelValue; uint16_t sessionId; Ip6::NetworkPrefix meshLocalPrefix; NetworkKey networkKey; @@ -116,12 +116,11 @@ Error DatasetManager::HandleSet(Coap::Message &aMessage, const Ip6::MessageInfo VerifyOrExit(Timestamp::Compare(&activeTimestamp, mLocal.GetTimestamp()) > 0); } - // check channel - if (Tlv::FindTlv(aMessage, channel) == kErrorNone) + if (Tlv::Find(aMessage, channelValue) == kErrorNone) { - VerifyOrExit(channel.IsValid()); + VerifyOrExit(channelValue.IsValid()); - if (channel.GetChannel() != Get().GetPanChannel()) + if (channelValue.GetChannel() != Get().GetPanChannel()) { doesAffectConnectivity = true; } @@ -312,10 +311,10 @@ Error ActiveDatasetManager::GenerateLocal(void) if (!dataset.Contains()) { - ChannelTlv tlv; - tlv.Init(); - tlv.SetChannel(Get().GetPanChannel()); - IgnoreError(dataset.WriteTlv(tlv)); + ChannelTlvValue channelValue; + + channelValue.SetChannelAndPage(Get().GetPanChannel()); + IgnoreError(dataset.Write(channelValue)); } if (!dataset.Contains()) diff --git a/src/core/meshcop/meshcop_tlvs.cpp b/src/core/meshcop/meshcop_tlvs.cpp index 446846f45..573e6b095 100644 --- a/src/core/meshcop/meshcop_tlvs.cpp +++ b/src/core/meshcop/meshcop_tlvs.cpp @@ -65,9 +65,9 @@ bool Tlv::IsValid(const Tlv &aTlv) case Tlv::kMeshLocalPrefix: minLength = sizeof(MeshLocalPrefixTlv::ValueType); break; - case Tlv::kChannel: - isValid = As(aTlv).IsValid(); + VerifyOrExit(aTlv.GetLength() >= sizeof(ChannelTlvValue), isValid = false); + isValid = aTlv.ReadValueAs().IsValid(); break; case Tlv::kNetworkName: isValid = As(aTlv).IsValid(); @@ -90,6 +90,7 @@ bool Tlv::IsValid(const Tlv &aTlv) isValid = (aTlv.GetLength() >= minLength); } +exit: return isValid; } @@ -143,51 +144,6 @@ void SecurityPolicyTlv::SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy) aSecurityPolicy.GetFlags(mFlags, sizeof(mFlags)); } -bool ChannelTlv::IsValid(void) const -{ - bool ret = false; - - VerifyOrExit(GetLength() == sizeof(*this) - sizeof(Tlv)); - VerifyOrExit(mChannelPage < BitSizeOf(uint32_t)); - VerifyOrExit((1U << mChannelPage) & Radio::kSupportedChannelPages); - VerifyOrExit(Radio::kChannelMin <= GetChannel() && GetChannel() <= Radio::kChannelMax); - ret = true; - -exit: - return ret; -} - -void ChannelTlv::SetChannel(uint16_t aChannel) -{ - uint8_t channelPage = OT_RADIO_CHANNEL_PAGE_0; - -#if OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT - if ((OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN <= aChannel) && (aChannel <= OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX)) - { - channelPage = OT_RADIO_CHANNEL_PAGE_0; - } -#endif - -#if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT - if ((OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN <= aChannel) && (aChannel <= OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX)) - { - channelPage = OT_RADIO_CHANNEL_PAGE_2; - } -#endif - -#if OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT - if ((OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MIN == aChannel) || - ((OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MIN < aChannel) && - (aChannel <= OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MAX))) - { - channelPage = OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_PAGE; - } -#endif - - SetChannelPage(channelPage); - mChannel = BigEndian::HostSwap16(aChannel); -} - const char *StateTlv::StateToString(State aState) { static const char *const kStateStrings[] = { diff --git a/src/core/meshcop/meshcop_tlvs.hpp b/src/core/meshcop/meshcop_tlvs.hpp index c9c324e1b..b7b2af3fb 100644 --- a/src/core/meshcop/meshcop_tlvs.hpp +++ b/src/core/meshcop/meshcop_tlvs.hpp @@ -54,6 +54,7 @@ #include "net/ip6_address.hpp" #include "radio/radio.hpp" #include "thread/key_manager.hpp" +#include "thread/mle_tlvs.hpp" #include "thread/mle_types.hpp" namespace ot { @@ -245,75 +246,22 @@ typedef UintTlvInfo PeriodTlv; typedef UintTlvInfo ScanDurationTlv; /** - * Defines Commissioner ID TLV constants and type.s + * Defines Commissioner ID TLV constants and types. * */ typedef StringTlvInfo CommissionerIdTlv; /** - * Implements Channel TLV generation and parsing. + * Implements Channel TLV value format. * */ -OT_TOOL_PACKED_BEGIN -class ChannelTlv : public Tlv, public TlvInfo -{ -public: - /** - * Initializes the TLV. - * - */ - void Init(void) - { - SetType(kChannel); - SetLength(sizeof(*this) - sizeof(Tlv)); - } +typedef Mle::ChannelTlvValue ChannelTlvValue; - /** - * Indicates whether or not the TLV appears to be well-formed. - * - * @retval TRUE If the TLV appears to be well-formed. - * @retval FALSE If the TLV does not appear to be well-formed. - * - */ - bool IsValid(void) const; - - /** - * Returns the ChannelPage value. - * - * @returns The ChannelPage value. - * - */ - uint8_t GetChannelPage(void) const { return mChannelPage; } - - /** - * Sets the ChannelPage value. - * - * @param[in] aChannelPage The ChannelPage value. - * - */ - void SetChannelPage(uint8_t aChannelPage) { mChannelPage = aChannelPage; } - - /** - * Returns the Channel value. - * - * @returns The Channel value. - * - */ - uint16_t GetChannel(void) const { return BigEndian::HostSwap16(mChannel); } - - /** - * Sets the Channel value. - * Note: This method also sets the channel page according to the channel value. - * - * @param[in] aChannel The Channel value. - * - */ - void SetChannel(uint16_t aChannel); - -private: - uint8_t mChannelPage; - uint16_t mChannel; -} OT_TOOL_PACKED_END; +/** + * Defines Channel TLV constants and types. + * + */ +typedef SimpleTlvInfo ChannelTlv; /** * Defines PAN ID TLV constants and types. diff --git a/src/core/thread/mle_tlvs.cpp b/src/core/thread/mle_tlvs.cpp index 1908d61d4..f3081e18f 100644 --- a/src/core/thread/mle_tlvs.cpp +++ b/src/core/thread/mle_tlvs.cpp @@ -34,6 +34,8 @@ #include "mle_tlvs.hpp" #include "common/code_utils.hpp" +#include "common/numeric_limits.hpp" +#include "radio/radio.hpp" namespace ot { namespace Mle { @@ -94,5 +96,46 @@ void ConnectivityTlv::SetParentPriority(int8_t aParentPriority) mFlags = static_cast(Preference::To2BitUint(aParentPriority) << kFlagsParentPriorityOffset); } +void ChannelTlvValue::SetChannelAndPage(uint16_t aChannel) +{ + uint8_t channelPage = OT_RADIO_CHANNEL_PAGE_0; + +#if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT + if ((OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN <= aChannel) && (aChannel <= OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX)) + { + channelPage = OT_RADIO_CHANNEL_PAGE_2; + } +#endif + +#if OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT + if ((OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MIN == aChannel) || + ((OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MIN < aChannel) && + (aChannel <= OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MAX))) + { + channelPage = OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_PAGE; + } +#endif + + SetChannelPage(channelPage); + SetChannel(aChannel); +} + +bool ChannelTlvValue::IsValid(void) const +{ + bool isValid = false; + uint16_t channel; + + VerifyOrExit(mChannelPage < BitSizeOf(uint32_t)); + VerifyOrExit((1U << mChannelPage) & Radio::kSupportedChannelPages); + + channel = GetChannel(); + VerifyOrExit((Radio::kChannelMin <= channel) && (channel <= Radio::kChannelMax)); + + isValid = true; + +exit: + return isValid; +} + } // namespace Mle } // namespace ot diff --git a/src/core/thread/mle_tlvs.hpp b/src/core/thread/mle_tlvs.hpp index d4be8ff45..68f62a49f 100644 --- a/src/core/thread/mle_tlvs.hpp +++ b/src/core/thread/mle_tlvs.hpp @@ -1096,6 +1096,23 @@ public: */ void SetChannel(uint16_t aChannel) { mChannel = BigEndian::HostSwap16(aChannel); } + /** + * Sets the Channel and determines and sets the Channel Page from the given channel. + * + * @param[in] aChannel The Channel value. + * + */ + void SetChannelAndPage(uint16_t aChannel); + + /** + * Indicates whether or not the Channel and Channel Page values are valid. + * + * @retval TRUE If the Channel and Channel Page values are valid. + * @retval FALSE If the Channel and Channel Page values are not valid. + * + */ + bool IsValid(void) const; + private: uint8_t mChannelPage; uint16_t mChannel;