diff --git a/src/core/backbone_router/bbr_local.cpp b/src/core/backbone_router/bbr_local.cpp index 84b18aefa..70ed0d7d8 100644 --- a/src/core/backbone_router/bbr_local.cpp +++ b/src/core/backbone_router/bbr_local.cpp @@ -57,7 +57,7 @@ Local::Local(Instance &aInstance) // Primary Backbone Router Aloc mBbrPrimaryAloc.InitAsThreadOriginMeshLocal(); - mBbrPrimaryAloc.GetAddress().GetIid().SetToLocator(Mle::kAloc16BackboneRouterPrimary); + mBbrPrimaryAloc.GetAddress().GetIid().SetToLocator(Mle::Aloc16::ForPrimaryBackboneRouter()); // All Network Backbone Routers Multicast Address. mAllNetworkBackboneRouters.Clear(); diff --git a/src/core/net/ip6_address.cpp b/src/core/net/ip6_address.cpp index e1c4dfe5c..3eb185f95 100644 --- a/src/core/net/ip6_address.cpp +++ b/src/core/net/ip6_address.cpp @@ -285,7 +285,7 @@ bool InterfaceIdentifier::IsAnycastServiceLocator(void) const { uint16_t locator = GetLocator(); - return (IsLocator() && (locator >= Mle::kAloc16ServiceStart) && (locator <= Mle::kAloc16ServiceEnd)); + return (IsLocator() && Mle::Aloc16::IsForService(locator)); } void InterfaceIdentifier::ApplyPrefix(const Prefix &aPrefix) diff --git a/src/core/net/nd_agent.cpp b/src/core/net/nd_agent.cpp index e709aaac1..81b8d023d 100644 --- a/src/core/net/nd_agent.cpp +++ b/src/core/net/nd_agent.cpp @@ -58,8 +58,7 @@ void Agent::UpdateService(void) if (IsAlocInUse()) { - uint8_t contextId = static_cast(mAloc.GetAddress().GetIid().GetLocator() - - Mle::kAloc16NeighborDiscoveryAgentStart + 1); + uint8_t contextId = Mle::Aloc16::ToNdAgentContextId(mAloc.GetAddress().GetIid().GetLocator()); bool found = false; iterator = NetworkData::kIteratorInit; @@ -104,7 +103,7 @@ void Agent::UpdateService(void) if (error == kErrorNone) { - uint16_t aloc16 = Mle::kAloc16NeighborDiscoveryAgentStart + lowpanContext.mContextId - 1; + uint16_t aloc16 = Mle::Aloc16::FromNdAgentContextId(lowpanContext.mContextId); mAloc.InitAsThreadOrigin(); mAloc.GetAddress().SetToAnycastLocator(Get().GetMeshLocalPrefix(), aloc16); diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index f154bc56c..41a53067e 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1031,16 +1031,19 @@ void Mle::GetLeaderRloc(Ip6::Address &aAddress) const aAddress.SetToRoutingLocator(mMeshLocalPrefix, GetLeaderRloc16()); } -void Mle::GetLeaderAloc(Ip6::Address &aAddress) const { aAddress.SetToAnycastLocator(mMeshLocalPrefix, kAloc16Leader); } +void Mle::GetLeaderAloc(Ip6::Address &aAddress) const +{ + aAddress.SetToAnycastLocator(mMeshLocalPrefix, Aloc16::ForLeader()); +} void Mle::GetCommissionerAloc(uint16_t aSessionId, Ip6::Address &aAddress) const { - aAddress.SetToAnycastLocator(mMeshLocalPrefix, CommissionerAloc16FromId(aSessionId)); + aAddress.SetToAnycastLocator(mMeshLocalPrefix, Aloc16::FromCommissionerSessionId(aSessionId)); } void Mle::GetServiceAloc(uint8_t aServiceId, Ip6::Address &aAddress) const { - aAddress.SetToAnycastLocator(mMeshLocalPrefix, ServiceAlocFromId(aServiceId)); + aAddress.SetToAnycastLocator(mMeshLocalPrefix, Aloc16::FromServiceId(aServiceId)); } const LeaderData &Mle::GetLeaderData(void) diff --git a/src/core/thread/mle_types.hpp b/src/core/thread/mle_types.hpp index 17fc5b4e4..eb207a371 100644 --- a/src/core/thread/mle_types.hpp +++ b/src/core/thread/mle_types.hpp @@ -50,6 +50,7 @@ #include "common/code_utils.hpp" #include "common/encoding.hpp" #include "common/equatable.hpp" +#include "common/num_utils.hpp" #include "common/numeric_limits.hpp" #include "common/offset_range.hpp" #include "common/string.hpp" @@ -168,20 +169,6 @@ enum RouterUpgradeReason : uint8_t kReasonBorderRouterRequest = 5, ///< Device is Border Router. }; -constexpr uint16_t kAloc16Leader = 0xfc00; -constexpr uint16_t kAloc16DhcpAgentStart = 0xfc01; -constexpr uint16_t kAloc16DhcpAgentEnd = 0xfc0f; -constexpr uint16_t kAloc16ServiceStart = 0xfc10; -constexpr uint16_t kAloc16ServiceEnd = 0xfc1f; -constexpr uint16_t kAloc16ReservedStart = 0xfc20; -constexpr uint16_t kAloc16ReservedEnd = 0xfc2f; -constexpr uint16_t kAloc16CommissionerStart = 0xfc30; -constexpr uint16_t kAloc16CommissionerEnd = 0xfc37; -constexpr uint16_t kAloc16BackboneRouterPrimary = 0xfc38; -constexpr uint16_t kAloc16CommissionerMask = 0x0007; -constexpr uint16_t kAloc16NeighborDiscoveryAgentStart = 0xfc40; -constexpr uint16_t kAloc16NeighborDiscoveryAgentEnd = 0xfc4e; - /** * Specifies the leader role start mode. * @@ -193,6 +180,174 @@ enum LeaderStartMode : uint8_t kRestoringLeaderRoleAfterReset, ///< Restoring leader role after reset. }; +/** + * Provides ALOC16 helper methods. + */ +class Aloc16 +{ +public: + /** + * Indicates whether or not a given ALOC16 is the leader ALOC16. + * + * @param[in] aAloc16 The ALOC16 to check. + * + * @retval TRUE The @p aAloc16 is the leader ALOC16. + * @retval FALSE The @p aAloc16 is not the leader ALOC16. + */ + static bool IsForLeader(uint16_t aAloc16) { return aAloc16 == kLeader; } + + /** + * Returns the leader ALOC16. + * + * @returns The leader ALOC16. + */ + static uint16_t ForLeader(void) { return kLeader; } + + /** + * Indicates whether or not a given ALOC16 is for a DHCP agent. + * + * @param[in] aAloc16 The ALOC16 to check. + * + * @retval TRUE The @p aAloc16 is for a DHCP agent. + * @retval FALSE The @p aAloc16 is not for a DHCP agent. + */ + static bool IsForDhcp6Agent(uint16_t aAloc16) { return IsValueInRange(aAloc16, kDhcpAgentStart, kDhcpAgentEnd); } + + /** + * Determines the Context ID associated with a DHCP agent ALOC16 + * + * @param[in] aAloc16 The DHCP agent ALOC16. + * + * @returns The Context ID corresponding to @p aAloc16. + */ + static uint8_t ToDhcpAgentContextId(uint16_t aAloc16) + { + return static_cast(aAloc16 - kDhcpAgentStart + 1); + } + + /** + * Determines the DHCP agent ALOC16 for a given Context ID. + * + * @param[in] aContextId The Context ID. + * + * @returns The DHCP agent ALOC16 corresponding @p aContextId. + */ + static uint16_t FromDhcpAgentContextId(uint8_t aContextId) { return (kDhcpAgentStart + aContextId - 1); } + + /** + * Indicates whether or not a given ALOC16 is for a Network Data service. + * + * @param[in] aAloc16 The ALOC16 to check. + * + * @retval TRUE The @p aAloc16 is for a Network Data service. + * @retval FALSE The @p aAloc16 is not for a Network Data service. + */ + static bool IsForService(uint16_t aAloc16) { return IsValueInRange(aAloc16, kServiceStart, kServiceEnd); } + + /** + * Determines the Service ID associated with a Service ALOC16. + * + * @param[in] aAloc16 The Service ALOC16. + * + * @returns The Service ID corresponding to @p aAloc16. + */ + static uint8_t ToServiceId(uint16_t aAloc16) { return static_cast(aAloc16 - kServiceStart); } + + /** + * Determines the Service ALOC16 for a given Service ID. + * + * @param[in] aServiceId The Service ID. + * + * @returns The Service ALOC16 corresponding @p aServiceId. + */ + static uint16_t FromServiceId(uint8_t aServiceId) { return static_cast(kServiceStart + aServiceId); } + + /** + * Indicates whether or not a given ALOC16 is for a Commissioner. + * + * @param[in] aAloc16 The ALOC16 to check. + * + * @retval TRUE The @p aAloc16 is for a Commissioner. + * @retval FALSE The @p aAloc16 is not for a Commissioner. + */ + static bool IsForCommissioner(uint16_t aAloc16) + { + return IsValueInRange(aAloc16, kCommissionerStart, kCommissionerEnd); + } + + /** + * Determines the Commissioner ALOC16 corresponding to a given Commissioner Session ID. + * + * @param[in] aSessionId The Commissioner Session ID. + * + * @returns The Commissioner ALOC16 corresponding to @p aSessionId. + */ + static uint16_t FromCommissionerSessionId(uint16_t aSessionId) + { + return static_cast((aSessionId & kCommissionerMask) + kCommissionerStart); + } + + /** + * Indicates whether or not a given ALOC16 is for the primary backbone router. + * + * @param[in] aAloc16 The ALOC16 to check. + * + * @retval TRUE The @p aAloc16 is for the primary backbone router. + * @retval FALSE The @p aAloc16 is not for the primary backbone router. + */ + static bool IsForPrimaryBackboneRouter(uint16_t aAloc16) { return aAloc16 == kPrimaryBackboneRouter; } + + /** + * Returns the primary backbone router ALOC16. + * + * @returns The primary backbone router ALOC16. + */ + static uint16_t ForPrimaryBackboneRouter(void) { return kPrimaryBackboneRouter; } + + /** + * Indicates whether or not a given ALOC16 is for a Neighbor Discovery agent. + * + * @param[in] aAloc16 The ALOC16 to check. + * + * @retval TRUE The @p aAloc16 is for a Neighbor Discovery agent. + * @retval FALSE The @p aAloc16 is not for a Neighbor Discovery agent. + */ + static bool IsForNdAgent(uint16_t aAloc16) { return IsValueInRange(aAloc16, kNdAgentStart, kNdAgentEnd); } + + /** + * Determines the Context ID associated with a Neighbor Discovery agent ALOC16 + * + * @param[in] aAloc16 The Neighbor Discovery agent ALOC16. + * + * @returns The Context ID corresponding to @p aAloc16. + */ + static uint8_t ToNdAgentContextId(uint16_t aAloc16) { return static_cast(aAloc16 - kNdAgentStart + 1); } + + /** + * Determines the Neighbor Discovery agent ALOC16 for a given Context ID. + * + * @param[in] aContextId The Context ID. + * + * @returns The Neighbor Discovery agent ALOC16 corresponding @p aContextId. + */ + static uint16_t FromNdAgentContextId(uint8_t aContextId) { return kNdAgentStart + aContextId - 1; } + +private: + // The range [0xfc20, 0xfc2f] is reserved for future use. + static constexpr uint16_t kLeader = 0xfc00; + static constexpr uint16_t kDhcpAgentStart = 0xfc01; + static constexpr uint16_t kDhcpAgentEnd = 0xfc0f; + static constexpr uint16_t kServiceStart = 0xfc10; + static constexpr uint16_t kServiceEnd = 0xfc1f; + static constexpr uint16_t kCommissionerStart = 0xfc30; + static constexpr uint16_t kCommissionerEnd = 0xfc37; + static constexpr uint16_t kPrimaryBackboneRouter = 0xfc38; + static constexpr uint16_t kNdAgentStart = 0xfc40; + static constexpr uint16_t kNdAgentEnd = 0xfc4e; + + static constexpr uint16_t kCommissionerMask = 0x0007; +}; + /** * Represents a MLE device mode. */ @@ -491,7 +646,7 @@ public: private: static uint8_t MaskFor(uint8_t aRouterId) { return (0x80 >> (aRouterId % 8)); } - uint8_t mRouterIdSet[BytesForBitSize(Mle::kMaxRouterId + 1)]; + uint8_t mRouterIdSet[BytesForBitSize(kMaxRouterId + 1)]; } OT_TOOL_PACKED_END; class TxChallenge; @@ -634,39 +789,6 @@ inline bool RouterIdMatch(uint16_t aRloc16A, uint16_t aRloc16B) return RouterIdFromRloc16(aRloc16A) == RouterIdFromRloc16(aRloc16B); } -/** - * Returns the Service ID corresponding to a Service ALOC16. - * - * @param[in] aAloc16 The Service ALOC16 value. - * - * @returns The Service ID corresponding to given ALOC16. - */ -inline uint8_t ServiceIdFromAloc(uint16_t aAloc16) { return static_cast(aAloc16 - kAloc16ServiceStart); } - -/** - * Returns the Service ALOC16 corresponding to a Service ID. - * - * @param[in] aServiceId The Service ID value. - * - * @returns The Service ALOC16 corresponding to given ID. - */ -inline uint16_t ServiceAlocFromId(uint8_t aServiceId) -{ - return static_cast(aServiceId + kAloc16ServiceStart); -} - -/** - * Returns the Commissioner Aloc corresponding to a Commissioner Session ID. - * - * @param[in] aSessionId The Commissioner Session ID value. - * - * @returns The Commissioner ALOC16 corresponding to given ID. - */ -inline uint16_t CommissionerAloc16FromId(uint16_t aSessionId) -{ - return static_cast((aSessionId & kAloc16CommissionerMask) + kAloc16CommissionerStart); -} - /** * Derives RLOC16 from a given Router ID. * diff --git a/src/core/thread/network_data.cpp b/src/core/thread/network_data.cpp index 9a4440ad0..66b2323dd 100644 --- a/src/core/thread/network_data.cpp +++ b/src/core/thread/network_data.cpp @@ -586,7 +586,7 @@ bool MutableNetworkData::RemoveTemporaryDataIn(PrefixTlv &aPrefix) { if ((entry->IsDhcp() || entry->IsConfigure()) && (context != nullptr)) { - entry->SetRloc(Mle::kAloc16DhcpAgentStart + context->GetContextId() - 1); + entry->SetRloc(Mle::Aloc16::FromDhcpAgentContextId(context->GetContextId())); } else { @@ -639,7 +639,7 @@ bool MutableNetworkData::RemoveTemporaryDataIn(ServiceTlv &aService) switch (cur->GetType()) { case NetworkDataTlv::kTypeServer: - As(cur)->SetServer16(Mle::ServiceAlocFromId(aService.GetServiceId())); + As(cur)->SetServer16(Mle::Aloc16::FromServiceId(aService.GetServiceId())); break; default: diff --git a/src/core/thread/network_data_leader_ftd.cpp b/src/core/thread/network_data_leader_ftd.cpp index 8ec6031f1..6d69e6276 100644 --- a/src/core/thread/network_data_leader_ftd.cpp +++ b/src/core/thread/network_data_leader_ftd.cpp @@ -105,34 +105,34 @@ Error Leader::AnycastLookup(uint16_t aAloc16, uint16_t &aRloc16) const aRloc16 = Mle::kInvalidRloc16; - if (aAloc16 == Mle::kAloc16Leader) + if (Mle::Aloc16::IsForLeader(aAloc16)) { aRloc16 = Get().GetLeaderRloc16(); } - else if (IsValueInRange(aAloc16, Mle::kAloc16DhcpAgentStart, Mle::kAloc16DhcpAgentEnd)) + else if (Mle::Aloc16::IsForDhcp6Agent(aAloc16)) { - uint8_t contextId = static_cast(aAloc16 - Mle::kAloc16DhcpAgentStart + 1); + uint8_t contextId = Mle::Aloc16::ToDhcpAgentContextId(aAloc16); error = LookupRouteForAgentAloc(contextId, IsEntryForDhcp6Agent, aRloc16); } - else if (IsValueInRange(aAloc16, Mle::kAloc16ServiceStart, Mle::kAloc16ServiceEnd)) + else if (Mle::Aloc16::IsForService(aAloc16)) { error = LookupRouteForServiceAloc(aAloc16, aRloc16); } - else if (IsValueInRange(aAloc16, Mle::kAloc16CommissionerStart, Mle::kAloc16CommissionerEnd)) + else if (Mle::Aloc16::IsForCommissioner(aAloc16)) { error = FindBorderAgentRloc(aRloc16); } #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) - else if (aAloc16 == Mle::kAloc16BackboneRouterPrimary) + else if (Mle::Aloc16::IsForPrimaryBackboneRouter(aAloc16)) { VerifyOrExit(Get().HasPrimary(), error = kErrorDrop); aRloc16 = Get().GetServer16(); } #endif - else if (IsValueInRange(aAloc16, Mle::kAloc16NeighborDiscoveryAgentStart, Mle::kAloc16NeighborDiscoveryAgentEnd)) + else if (Mle::Aloc16::IsForNdAgent(aAloc16)) { - uint8_t contextId = static_cast(aAloc16 - Mle::kAloc16NeighborDiscoveryAgentStart + 1); + uint8_t contextId = Mle::Aloc16::ToNdAgentContextId(aAloc16); error = LookupRouteForAgentAloc(contextId, IsEntryForNdAgent, aRloc16); } @@ -165,7 +165,7 @@ exit: Error Leader::LookupRouteForServiceAloc(uint16_t aAloc16, uint16_t &aRloc16) const { Error error = kErrorNoRoute; - const ServiceTlv *serviceTlv = FindServiceById(Mle::ServiceIdFromAloc(aAloc16)); + const ServiceTlv *serviceTlv = FindServiceById(Mle::Aloc16::ToServiceId(aAloc16)); if (serviceTlv != nullptr) { diff --git a/src/core/thread/network_data_service.cpp b/src/core/thread/network_data_service.cpp index 60cf5dce2..1dc903147 100644 --- a/src/core/thread/network_data_service.cpp +++ b/src/core/thread/network_data_service.cpp @@ -268,7 +268,7 @@ void Manager::HandleNotifierEvents(Events aEvents) while (Get().GetNext(iterator, deviceRloc16, service) == kErrorNone) { - if (service.mServiceId == Mle::ServiceIdFromAloc(serviceAloc.GetAloc16())) + if (service.mServiceId == Mle::Aloc16::ToServiceId(serviceAloc.GetAloc16())) { found = true; break; @@ -288,7 +288,7 @@ void Manager::HandleNotifierEvents(Events aEvents) while (Get().GetNext(iterator, deviceRloc16, service) == kErrorNone) { - uint16_t aloc16 = Mle::ServiceAlocFromId(service.mServiceId); + uint16_t aloc16 = Mle::Aloc16::FromServiceId(service.mServiceId); if (FindInServiceAlocs(aloc16) == nullptr) {