mirror of
https://github.com/espressif/openthread.git
synced 2026-08-05 18:37:45 +00:00
[mle] add Aloc16 helper class (#11818)
This commit introduces the `Mle::Aloc16` helper class to encapsulate constants and helper methods related to Anycast Locators (ALOC16). The new class provides static helpers for: - Checking if a given ALOC16 has a specific purpose (e.g., Service, DHCPv6 Agent, Commissioner, Primary BBR). - Converting between an ALOC16 and its related service, context, or session ID. All existing code is updated to use the new helper methods. This improves code readability and centralizes ALOC16 management.
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -58,8 +58,7 @@ void Agent::UpdateService(void)
|
||||
|
||||
if (IsAlocInUse())
|
||||
{
|
||||
uint8_t contextId = static_cast<uint8_t>(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<Mle::Mle>().GetMeshLocalPrefix(), aloc16);
|
||||
|
||||
@@ -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)
|
||||
|
||||
+170
-48
@@ -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<uint8_t>(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<uint8_t>(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<uint16_t>(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<uint16_t>((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<uint8_t>(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<uint8_t>(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<uint16_t>(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<uint16_t>((aSessionId & kAloc16CommissionerMask) + kAloc16CommissionerStart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives RLOC16 from a given Router ID.
|
||||
*
|
||||
|
||||
@@ -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<ServerTlv>(cur)->SetServer16(Mle::ServiceAlocFromId(aService.GetServiceId()));
|
||||
As<ServerTlv>(cur)->SetServer16(Mle::Aloc16::FromServiceId(aService.GetServiceId()));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -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<Mle::Mle>().GetLeaderRloc16();
|
||||
}
|
||||
else if (IsValueInRange(aAloc16, Mle::kAloc16DhcpAgentStart, Mle::kAloc16DhcpAgentEnd))
|
||||
else if (Mle::Aloc16::IsForDhcp6Agent(aAloc16))
|
||||
{
|
||||
uint8_t contextId = static_cast<uint8_t>(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<BackboneRouter::Leader>().HasPrimary(), error = kErrorDrop);
|
||||
aRloc16 = Get<BackboneRouter::Leader>().GetServer16();
|
||||
}
|
||||
#endif
|
||||
else if (IsValueInRange(aAloc16, Mle::kAloc16NeighborDiscoveryAgentStart, Mle::kAloc16NeighborDiscoveryAgentEnd))
|
||||
else if (Mle::Aloc16::IsForNdAgent(aAloc16))
|
||||
{
|
||||
uint8_t contextId = static_cast<uint8_t>(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)
|
||||
{
|
||||
|
||||
@@ -268,7 +268,7 @@ void Manager::HandleNotifierEvents(Events aEvents)
|
||||
|
||||
while (Get<Leader>().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<Leader>().GetNext(iterator, deviceRloc16, service) == kErrorNone)
|
||||
{
|
||||
uint16_t aloc16 = Mle::ServiceAlocFromId(service.mServiceId);
|
||||
uint16_t aloc16 = Mle::Aloc16::FromServiceId(service.mServiceId);
|
||||
|
||||
if (FindInServiceAlocs(aloc16) == nullptr)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user