[mle] simplify ThreadStatusTlv handling (#11782)

The Status TLV is used in several TMF messages (Address Solicit, DUA
Registration, MLR), and the meaning of its value is
context-dependent.

This commit refactors the TLV definitions by moving the status enums
from the generic `ThreadStatusTlv` class into the modules where they
are used.

The main changes are:
- The Address Solicit status is split into two more specific enums:
  - `RouterUpgradeReason` for Address Solicit requests.
  - `AddrSolicitResponse` for Address Solicit responses.
- `MlrStatus` and `DuaStatus` enums are moved to `mlr` and `dua`
  modules respectively.
- `ThreadStatusTlv` is simplified to a `typedef`.

This change improves code clarity, modularity, and type safety by
ensuring that status codes are defined and used within their proper
context.
This commit is contained in:
Abtin Keshavarzian
2025-08-06 19:02:01 -07:00
committed by GitHub
parent 8dadae2ea1
commit 7ab5c5c042
13 changed files with 163 additions and 157 deletions
+2 -2
View File
@@ -146,10 +146,10 @@ void otBackboneRouterConfigNextDuaRegistrationResponse(otInstance
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
void otBackboneRouterConfigNextMulticastListenerRegistrationResponse(otInstance *aInstance, uint8_t aStatus)
{
OT_ASSERT(aStatus <= ThreadStatusTlv::kMlrStatusMax);
OT_ASSERT(aStatus <= kMlrStatusMax);
AsCoreType(aInstance).Get<BackboneRouter::Manager>().ConfigNextMulticastListenerRegistrationResponse(
static_cast<ThreadStatusTlv::MlrStatus>(aStatus));
static_cast<MlrStatus>(aStatus));
}
void otBackboneRouterMulticastListenerClear(otInstance *aInstance)
+1 -1
View File
@@ -176,7 +176,7 @@ exit:
otError otThreadBecomeRouter(otInstance *aInstance)
{
return AsCoreType(aInstance).Get<Mle::Mle>().BecomeRouter(ThreadStatusTlv::kHaveChildIdRequest);
return AsCoreType(aInstance).Get<Mle::Mle>().BecomeRouter(Mle::kReasonHaveChildIdRequest);
}
otError otThreadBecomeLeader(otInstance *aInstance)
+39 -39
View File
@@ -55,10 +55,10 @@ Manager::Manager(Instance &aInstance)
, mBackboneTmfAgent(aInstance)
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
, mDuaResponseStatus(ThreadStatusTlv::kDuaSuccess)
, mDuaResponseStatus(kDuaSuccess)
#endif
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
, mMlrResponseStatus(ThreadStatusTlv::kMlrSuccess)
, mMlrResponseStatus(kMlrSuccess)
#endif
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
, mDuaResponseIsSpecified(false)
@@ -133,10 +133,10 @@ exit:
void Manager::HandleMulticastListenerRegistration(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
Error error = kErrorNone;
bool isPrimary = Get<Local>().IsPrimary();
ThreadStatusTlv::MlrStatus status = ThreadStatusTlv::kMlrSuccess;
Config config;
Error error = kErrorNone;
bool isPrimary = Get<Local>().IsPrimary();
MlrStatus status = kMlrSuccess;
Config config;
OffsetRange offsetRange;
Ip6::Address address;
@@ -160,7 +160,7 @@ void Manager::HandleMulticastListenerRegistration(const Coap::Message &aMessage,
}
#endif
VerifyOrExit(isPrimary, status = ThreadStatusTlv::kMlrBbrNotPrimary);
VerifyOrExit(isPrimary, status = kMlrBbrNotPrimary);
// TODO: (MLR) send configured MLR response for Reference Device
@@ -170,7 +170,7 @@ void Manager::HandleMulticastListenerRegistration(const Coap::Message &aMessage,
VerifyOrExit((Get<NetworkData::Leader>().FindCommissioningSessionId(localSessionId) == kErrorNone) &&
(localSessionId == commissionerSessionId),
status = ThreadStatusTlv::kMlrGeneralFailure);
status = kMlrGeneralFailure);
hasCommissionerSessionIdTlv = true;
}
@@ -179,9 +179,9 @@ void Manager::HandleMulticastListenerRegistration(const Coap::Message &aMessage,
VerifyOrExit(Tlv::FindTlvValueOffsetRange(aMessage, Ip6AddressesTlv::kIp6Addresses, offsetRange) == kErrorNone,
error = kErrorParse);
VerifyOrExit(offsetRange.GetLength() % sizeof(Ip6::Address) == 0, status = ThreadStatusTlv::kMlrGeneralFailure);
VerifyOrExit(offsetRange.GetLength() % sizeof(Ip6::Address) == 0, status = kMlrGeneralFailure);
VerifyOrExit(offsetRange.GetLength() / sizeof(Ip6::Address) <= Ip6AddressesTlv::kMaxAddresses,
status = ThreadStatusTlv::kMlrGeneralFailure);
status = kMlrGeneralFailure);
if (!processTimeoutTlv)
{
@@ -191,7 +191,7 @@ void Manager::HandleMulticastListenerRegistration(const Coap::Message &aMessage,
}
else
{
VerifyOrExit(timeout < NumericLimits<uint32_t>::kMax, status = ThreadStatusTlv::kMlrNoPersistent);
VerifyOrExit(timeout < NumericLimits<uint32_t>::kMax, status = kMlrNoPersistent);
if (timeout != 0)
{
@@ -230,15 +230,15 @@ void Manager::HandleMulticastListenerRegistration(const Coap::Message &aMessage,
failed = false;
break;
case kErrorInvalidArgs:
if (status == ThreadStatusTlv::kMlrSuccess)
if (status == kMlrSuccess)
{
status = ThreadStatusTlv::kMlrInvalid;
status = kMlrInvalid;
}
break;
case kErrorNoBufs:
if (status == ThreadStatusTlv::kMlrSuccess)
if (status == kMlrSuccess)
{
status = ThreadStatusTlv::kMlrNoResources;
status = kMlrNoResources;
}
break;
default:
@@ -270,11 +270,11 @@ exit:
}
}
void Manager::SendMulticastListenerRegistrationResponse(const Coap::Message &aMessage,
const Ip6::MessageInfo &aMessageInfo,
ThreadStatusTlv::MlrStatus aStatus,
Ip6::Address *aFailedAddresses,
uint8_t aFailedAddressNum)
void Manager::SendMulticastListenerRegistrationResponse(const Coap::Message &aMessage,
const Ip6::MessageInfo &aMessageInfo,
MlrStatus aStatus,
Ip6::Address *aFailedAddresses,
uint8_t aFailedAddressNum)
{
Error error = kErrorNone;
Coap::Message *message;
@@ -355,13 +355,13 @@ exit:
void Manager::HandleDuaRegistration(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
Error error = kErrorNone;
ThreadStatusTlv::DuaStatus status = ThreadStatusTlv::kDuaSuccess;
bool isPrimary = Get<Local>().IsPrimary();
uint32_t lastTransactionTime;
bool hasLastTransactionTime;
Ip6::Address target;
Ip6::InterfaceIdentifier meshLocalIid;
Error error = kErrorNone;
DuaStatus status = kDuaSuccess;
bool isPrimary = Get<Local>().IsPrimary();
uint32_t lastTransactionTime;
bool hasLastTransactionTime;
Ip6::Address target;
Ip6::InterfaceIdentifier meshLocalIid;
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
Coap::Code duaRespCoapCode = Coap::kCodeEmpty;
#endif
@@ -382,15 +382,15 @@ void Manager::HandleDuaRegistration(const Coap::Message &aMessage, const Ip6::Me
}
else
{
status = static_cast<ThreadStatusTlv::DuaStatus>(mDuaResponseStatus);
status = static_cast<DuaStatus>(mDuaResponseStatus);
}
ExitNow();
}
#endif
VerifyOrExit(isPrimary, status = ThreadStatusTlv::kDuaNotPrimary);
VerifyOrExit(Get<Leader>().HasDomainPrefix(), status = ThreadStatusTlv::kDuaGeneralFailure);
VerifyOrExit(Get<Leader>().IsDomainUnicast(target), status = ThreadStatusTlv::kDuaInvalid);
VerifyOrExit(isPrimary, status = kDuaNotPrimary);
VerifyOrExit(Get<Leader>().HasDomainPrefix(), status = kDuaGeneralFailure);
VerifyOrExit(Get<Leader>().IsDomainUnicast(target), status = kDuaInvalid);
hasLastTransactionTime = (Tlv::Find<ThreadLastTransactionTimeTlv>(aMessage, lastTransactionTime) == kErrorNone);
@@ -402,13 +402,13 @@ void Manager::HandleDuaRegistration(const Coap::Message &aMessage, const Ip6::Me
// DUA.req packet according to Thread Spec. 5.23.3.6.2
break;
case kErrorDuplicated:
status = ThreadStatusTlv::kDuaDuplicate;
status = kDuaDuplicate;
break;
case kErrorNoBufs:
status = ThreadStatusTlv::kDuaNoResources;
status = kDuaNoResources;
break;
default:
status = ThreadStatusTlv::kDuaGeneralFailure;
status = kDuaGeneralFailure;
break;
}
@@ -430,10 +430,10 @@ exit:
}
}
void Manager::SendDuaRegistrationResponse(const Coap::Message &aMessage,
const Ip6::MessageInfo &aMessageInfo,
const Ip6::Address &aTarget,
ThreadStatusTlv::DuaStatus aStatus)
void Manager::SendDuaRegistrationResponse(const Coap::Message &aMessage,
const Ip6::MessageInfo &aMessageInfo,
const Ip6::Address &aTarget,
DuaStatus aStatus)
{
Error error = kErrorNone;
Coap::Message *message;
@@ -472,7 +472,7 @@ void Manager::ConfigNextDuaRegistrationResponse(const Ip6::InterfaceIdentifier *
#endif
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
void Manager::ConfigNextMulticastListenerRegistrationResponse(ThreadStatusTlv::MlrStatus aStatus)
void Manager::ConfigNextMulticastListenerRegistrationResponse(MlrStatus aStatus)
{
mMlrResponseIsSpecified = true;
mMlrResponseStatus = aStatus;
+12 -11
View File
@@ -48,6 +48,7 @@
#include "common/locator.hpp"
#include "common/non_copyable.hpp"
#include "net/netif.hpp"
#include "thread/dua_manager.hpp"
#include "thread/network_data.hpp"
#include "thread/tmf.hpp"
@@ -103,7 +104,7 @@ public:
*
* @param[in] aStatus The status to respond.
*/
void ConfigNextMulticastListenerRegistrationResponse(ThreadStatusTlv::MlrStatus aStatus);
void ConfigNextMulticastListenerRegistrationResponse(MlrStatus aStatus);
#endif
#endif
@@ -170,11 +171,11 @@ private:
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
void HandleMulticastListenerRegistration(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
void SendMulticastListenerRegistrationResponse(const Coap::Message &aMessage,
const Ip6::MessageInfo &aMessageInfo,
ThreadStatusTlv::MlrStatus aStatus,
Ip6::Address *aFailedAddresses,
uint8_t aFailedAddressNum);
void SendMulticastListenerRegistrationResponse(const Coap::Message &aMessage,
const Ip6::MessageInfo &aMessageInfo,
MlrStatus aStatus,
Ip6::Address *aFailedAddresses,
uint8_t aFailedAddressNum);
void SendBackboneMulticastListenerRegistration(const Ip6::Address *aAddresses,
uint8_t aAddressNum,
uint32_t aTimeout);
@@ -199,10 +200,10 @@ private:
void HandleProactiveBackboneNotification(const Ip6::Address &aDua,
const Ip6::InterfaceIdentifier &aMeshLocalIid,
uint32_t aTimeSinceLastTransaction);
void SendDuaRegistrationResponse(const Coap::Message &aMessage,
const Ip6::MessageInfo &aMessageInfo,
const Ip6::Address &aTarget,
ThreadStatusTlv::DuaStatus aStatus);
void SendDuaRegistrationResponse(const Coap::Message &aMessage,
const Ip6::MessageInfo &aMessageInfo,
const Ip6::Address &aTarget,
DuaStatus aStatus);
#endif
void HandleNotifierEvents(Events aEvents);
@@ -229,7 +230,7 @@ private:
uint8_t mDuaResponseStatus;
#endif
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
ThreadStatusTlv::MlrStatus mMlrResponseStatus;
MlrStatus mMlrResponseStatus;
#endif
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
bool mDuaResponseIsSpecified : 1;
+19 -21
View File
@@ -612,7 +612,7 @@ Error DuaManager::ProcessDuaResponse(Coap::Message &aMessage)
if (aMessage.GetCode() >= Coap::kCodeBadRequest)
{
status = ThreadStatusTlv::kDuaGeneralFailure;
status = kDuaGeneralFailure;
target = mRegisteringDua;
}
else
@@ -626,29 +626,29 @@ Error DuaManager::ProcessDuaResponse(Coap::Message &aMessage)
#if OPENTHREAD_CONFIG_DUA_ENABLE
if (Get<ThreadNetif>().HasUnicastAddress(target))
{
switch (static_cast<ThreadStatusTlv::DuaStatus>(status))
switch (static_cast<DuaStatus>(status))
{
case ThreadStatusTlv::kDuaSuccess:
case kDuaSuccess:
mLastRegistrationTime = TimerMilli::GetNow();
mDuaState = kRegistered;
break;
case ThreadStatusTlv::kDuaReRegister:
case kDuaReRegister:
if (Get<ThreadNetif>().HasUnicastAddress(GetDomainUnicastAddress()))
{
RemoveDomainUnicastAddress();
AddDomainUnicastAddress();
}
break;
case ThreadStatusTlv::kDuaInvalid:
case kDuaInvalid:
// Domain Prefix might be invalid.
RemoveDomainUnicastAddress();
break;
case ThreadStatusTlv::kDuaDuplicate:
case kDuaDuplicate:
NotifyDuplicateDomainUnicastAddress();
break;
case ThreadStatusTlv::kDuaNoResources:
case ThreadStatusTlv::kDuaNotPrimary:
case ThreadStatusTlv::kDuaGeneralFailure:
case kDuaNoResources:
case kDuaNotPrimary:
case kDuaGeneralFailure:
UpdateReregistrationDelay();
break;
}
@@ -675,34 +675,34 @@ Error DuaManager::ProcessDuaResponse(Coap::Message &aMessage)
switch (status)
{
case ThreadStatusTlv::kDuaSuccess:
case kDuaSuccess:
// Mark as Registered
if (mChildDuaMask.Has(childIndex))
{
mChildDuaRegisteredMask.Add(childIndex);
}
break;
case ThreadStatusTlv::kDuaReRegister:
case kDuaReRegister:
// Parent stops registering for the Child's DUA until next Child Update Request
mChildDuaMask.Remove(childIndex);
mChildDuaRegisteredMask.Remove(childIndex);
break;
case ThreadStatusTlv::kDuaInvalid:
case ThreadStatusTlv::kDuaDuplicate:
case kDuaInvalid:
case kDuaDuplicate:
IgnoreError(child->RemoveIp6Address(target));
mChildDuaMask.Remove(childIndex);
mChildDuaRegisteredMask.Remove(childIndex);
break;
case ThreadStatusTlv::kDuaNoResources:
case ThreadStatusTlv::kDuaNotPrimary:
case ThreadStatusTlv::kDuaGeneralFailure:
case kDuaNoResources:
case kDuaNotPrimary:
case kDuaGeneralFailure:
UpdateReregistrationDelay();
break;
}
if (status != ThreadStatusTlv::kDuaSuccess)
if (status != kDuaSuccess)
{
SendAddressNotification(target, static_cast<ThreadStatusTlv::DuaStatus>(status), *child);
SendAddressNotification(target, static_cast<DuaStatus>(status), *child);
}
}
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE
@@ -713,9 +713,7 @@ exit:
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE
void DuaManager::SendAddressNotification(Ip6::Address &aAddress,
ThreadStatusTlv::DuaStatus aStatus,
const Child &aChild)
void DuaManager::SendAddressNotification(Ip6::Address &aAddress, DuaStatus aStatus, const Child &aChild)
{
Coap::Message *message = nullptr;
Tmf::MessageInfo messageInfo(GetInstance());
+15 -1
View File
@@ -75,6 +75,20 @@ namespace ot {
* @}
*/
/**
* Domain Unicast Address (DUA) Registration Status values
*/
enum DuaStatus : uint8_t
{
kDuaSuccess = 0, ///< Successful registration.
kDuaReRegister = 1, ///< Registration was accepted but immediate reregistration is required to solve.
kDuaInvalid = 2, ///< Registration rejected (Fatal): Target EID is not a valid DUA.
kDuaDuplicate = 3, ///< Registration rejected (Fatal): DUA is already in use by another device.
kDuaNoResources = 4, ///< Registration rejected (Non-fatal): Backbone Router Resource shortage.
kDuaNotPrimary = 5, ///< Registration rejected (Non-fatal): Backbone Router is not primary at this moment.
kDuaGeneralFailure = 6, ///< Registration failure (Non-fatal): Reason(s) not further specified.
};
/**
* Implements managing DUA.
*/
@@ -196,7 +210,7 @@ private:
#endif
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE
void SendAddressNotification(Ip6::Address &aAddress, ThreadStatusTlv::DuaStatus aStatus, const Child &aChild);
void SendAddressNotification(Ip6::Address &aAddress, DuaStatus aStatus, const Child &aChild);
#endif
void HandleNotifierEvents(Events aEvents);
+11 -4
View File
@@ -783,13 +783,13 @@ public:
/**
* Generates an Address Solicit request for a Router ID.
*
* @param[in] aStatus The reason for requesting a Router ID.
* @param[in] aReason The reason for requesting a Router ID.
*
* @retval kErrorNone Successfully generated an Address Solicit message.
* @retval kErrorNotCapable Device is not capable of becoming a router
* @retval kErrorInvalidState Thread is not enabled
*/
Error BecomeRouter(ThreadStatusTlv::Status aStatus);
Error BecomeRouter(RouterUpgradeReason aReason);
/**
* Specifies the leader weight check behavior used in `BecomeLeader()`.
@@ -1372,6 +1372,13 @@ private:
kDoNotSendChildUpdateToParent,
};
enum AddrSolicitResponse : uint8_t // Used in `SendAddressSolicitResponse`
{
kAddrSolicitSuccess = 0,
kAddrSolicitNoAddressAvailable = 1,
kAddrSolicitUnrecognizedReason = 6,
};
enum MessageAction : uint8_t
{
kMessageSend,
@@ -2173,9 +2180,9 @@ private:
Error ReadAndProcessRouteTlvOnFtdChild(RxInfo &aRxInfo, uint8_t aParentId);
void StopAdvertiseTrickleTimer(void);
uint32_t DetermineAdvertiseIntervalMax(void) const;
Error SendAddressSolicit(ThreadStatusTlv::Status aStatus);
Error SendAddressSolicit(RouterUpgradeReason aReason);
void SendAddressSolicitResponse(const Coap::Message &aRequest,
ThreadStatusTlv::Status aResponseStatus,
AddrSolicitResponse aResponseStatus,
const Router *aRouter,
const Ip6::MessageInfo &aMessageInfo);
void SendAddressRelease(void);
+24 -24
View File
@@ -185,7 +185,7 @@ void Mle::SetDeviceProperties(const DeviceProperties &aDeviceProperties)
}
#endif
Error Mle::BecomeRouter(ThreadStatusTlv::Status aStatus)
Error Mle::BecomeRouter(RouterUpgradeReason aReason)
{
Error error = kErrorNone;
@@ -211,7 +211,7 @@ Error Mle::BecomeRouter(ThreadStatusTlv::Status aStatus)
Get<MeshForwarder>().SetRxOnWhenIdle(true);
mRouterRoleTransition.StopTimeout();
error = SendAddressSolicit(aStatus);
error = SendAddressSolicit(aReason);
exit:
return error;
@@ -321,7 +321,7 @@ void Mle::HandleChildStart(AttachMode aMode)
case kSamePartition:
if (HasChildren())
{
IgnoreError(BecomeRouter(ThreadStatusTlv::kHaveChildIdRequest));
IgnoreError(BecomeRouter(kReasonHaveChildIdRequest));
}
break;
@@ -354,7 +354,7 @@ void Mle::HandleChildStart(AttachMode aMode)
case kBetterPartition:
if (HasChildren() && mPreviousPartitionIdRouter != mLeaderData.GetPartitionId())
{
IgnoreError(BecomeRouter(ThreadStatusTlv::kParentPartitionChange));
IgnoreError(BecomeRouter(kReasonParentPartitionChange));
}
break;
@@ -1542,7 +1542,7 @@ void Mle::HandleTimeTick(void)
{
if (mRouterTable.GetActiveRouterCount() < mRouterUpgradeThreshold && HasNeighborWithGoodLinkQuality())
{
IgnoreError(BecomeRouter(ThreadStatusTlv::kTooFewRouters));
IgnoreError(BecomeRouter(kReasonTooFewRouters));
}
else
{
@@ -2171,7 +2171,7 @@ void Mle::HandleChildIdRequest(RxInfo &aRxInfo)
{
case kRoleChild:
child->SetState(Neighbor::kStateChildIdRequest);
IgnoreError(BecomeRouter(ThreadStatusTlv::kHaveChildIdRequest));
IgnoreError(BecomeRouter(kReasonHaveChildIdRequest));
break;
case kRoleRouter:
@@ -3251,7 +3251,7 @@ void Mle::SetRouterId(uint8_t aRouterId)
mPreviousRouterId = mRouterId;
}
Error Mle::SendAddressSolicit(ThreadStatusTlv::Status aStatus)
Error Mle::SendAddressSolicit(RouterUpgradeReason aReason)
{
Error error = kErrorNone;
Tmf::MessageInfo messageInfo(GetInstance());
@@ -3269,7 +3269,7 @@ Error Mle::SendAddressSolicit(ThreadStatusTlv::Status aStatus)
SuccessOrExit(error = Tlv::Append<ThreadRloc16Tlv>(*message, Rloc16FromRouterId(mPreviousRouterId)));
}
SuccessOrExit(error = Tlv::Append<ThreadStatusTlv>(*message, aStatus));
SuccessOrExit(error = Tlv::Append<ThreadStatusTlv>(*message, aReason));
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
SuccessOrExit(error = Tlv::Append<XtalAccuracyTlv>(*message, otPlatTimeGetXtalAccuracy()));
@@ -3337,7 +3337,7 @@ void Mle::HandleAddressSolicitResponse(Coap::Message *aMessage, const Ip6::Messa
SuccessOrExit(Tlv::Find<ThreadStatusTlv>(*aMessage, status));
if (status != ThreadStatusTlv::kSuccess)
if (status != kAddrSolicitSuccess)
{
mAddressSolicitRejected = true;
@@ -3459,12 +3459,12 @@ exit:
template <> void Mle::HandleTmf<kUriAddressSolicit>(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
Error error = kErrorNone;
ThreadStatusTlv::Status responseStatus = ThreadStatusTlv::kNoAddressAvailable;
Router *router = nullptr;
Mac::ExtAddress extAddress;
uint16_t rloc16;
uint8_t status;
Error error = kErrorNone;
AddrSolicitResponse responseStatus = kAddrSolicitNoAddressAvailable;
Router *router = nullptr;
Mac::ExtAddress extAddress;
uint16_t rloc16;
uint8_t status;
VerifyOrExit(mRole == kRoleLeader, error = kErrorInvalidState);
@@ -3499,21 +3499,21 @@ template <> void Mle::HandleTmf<kUriAddressSolicit>(Coap::Message &aMessage, con
if (router != nullptr)
{
responseStatus = ThreadStatusTlv::kSuccess;
responseStatus = kAddrSolicitSuccess;
ExitNow();
}
switch (status)
{
case ThreadStatusTlv::kTooFewRouters:
case kReasonTooFewRouters:
VerifyOrExit(mRouterTable.GetActiveRouterCount() < mRouterUpgradeThreshold);
break;
case ThreadStatusTlv::kHaveChildIdRequest:
case ThreadStatusTlv::kParentPartitionChange:
case kReasonHaveChildIdRequest:
case kReasonParentPartitionChange:
break;
case ThreadStatusTlv::kBorderRouterRequest:
case kReasonBorderRouterRequest:
if ((mRouterTable.GetActiveRouterCount() >= mRouterUpgradeThreshold) &&
(Get<NetworkData::Leader>().CountBorderRouters(NetworkData::kRouterRoleOnly) >=
kRouterUpgradeBorderRouterRequestThreshold))
@@ -3525,7 +3525,7 @@ template <> void Mle::HandleTmf<kUriAddressSolicit>(Coap::Message &aMessage, con
break;
default:
responseStatus = ThreadStatusTlv::kUnrecognizedStatus;
responseStatus = kAddrSolicitUnrecognizedReason;
ExitNow();
}
@@ -3546,7 +3546,7 @@ template <> void Mle::HandleTmf<kUriAddressSolicit>(Coap::Message &aMessage, con
}
router->SetExtAddress(extAddress);
responseStatus = ThreadStatusTlv::kSuccess;
responseStatus = kAddrSolicitSuccess;
exit:
if (error == kErrorNone)
@@ -3556,7 +3556,7 @@ exit:
}
void Mle::SendAddressSolicitResponse(const Coap::Message &aRequest,
ThreadStatusTlv::Status aResponseStatus,
AddrSolicitResponse aResponseStatus,
const Router *aRouter,
const Ip6::MessageInfo &aMessageInfo)
{
@@ -3591,7 +3591,7 @@ void Mle::SendAddressSolicitResponse(const Coap::Message &aRequest,
// association with the promoted router's new RLOC16 upon
// receiving its Link Advertisement.
if ((aResponseStatus == ThreadStatusTlv::kSuccess) && (aRouter != nullptr))
if ((aResponseStatus == kAddrSolicitSuccess) && (aRouter != nullptr))
{
uint16_t oldRloc16;
+13
View File
@@ -155,6 +155,19 @@ enum Command : uint8_t
kCommandTimeSync = 99, ///< Time Sync command
};
/**
* Represents the reason to attempt to upgrade to router role (used in `BecomeRouter()`).
*
* The enumeration values correspond to the status values in `ThreadStatusTlv` in a TMF Address Solicit Request message.
*/
enum RouterUpgradeReason : uint8_t
{
kReasonTooFewRouters = 2, ///< Too few routers.
kReasonHaveChildIdRequest = 3, ///< Have pending Child ID Request.
kReasonParentPartitionChange = 4, ///< Parent Partition change.
kReasonBorderRouterRequest = 5, ///< Device is Border Router.
};
constexpr uint16_t kAloc16Leader = 0xfc00;
constexpr uint16_t kAloc16DhcpAgentStart = 0xfc01;
constexpr uint16_t kAloc16DhcpAgentEnd = 0xfc0f;
+5 -5
View File
@@ -444,9 +444,9 @@ void MlrManager::HandleMlrResponse(Coap::Message *aMessage, const Ip6::MessageIn
error = ParseMlrResponse(aResult, aMessage, status, failedAddresses);
FinishMlr(error == kErrorNone && status == ThreadStatusTlv::kMlrSuccess, failedAddresses);
FinishMlr(error == kErrorNone && status == kMlrSuccess, failedAddresses);
if (error == kErrorNone && status == ThreadStatusTlv::kMlrSuccess)
if (error == kErrorNone && status == kMlrSuccess)
{
// keep sending until all multicast addresses are registered.
ScheduleSend(0);
@@ -477,7 +477,7 @@ Error MlrManager::ParseMlrResponse(Error aResult,
Error error;
OffsetRange offsetRange;
aStatus = ThreadStatusTlv::kMlrGeneralFailure;
aStatus = kMlrGeneralFailure;
VerifyOrExit(aResult == kErrorNone && aMessage != nullptr, error = kErrorParse);
VerifyOrExit(aMessage->GetCode() == Coap::kCodeChanged, error = kErrorParse);
@@ -497,7 +497,7 @@ Error MlrManager::ParseMlrResponse(Error aResult,
}
}
VerifyOrExit(aFailedAddresses.IsEmpty() || aStatus != ThreadStatusTlv::kMlrSuccess, error = kErrorParse);
VerifyOrExit(aFailedAddresses.IsEmpty() || aStatus != kMlrSuccess, error = kErrorParse);
exit:
LogMlrResponse(aResult, error, aStatus, aFailedAddresses);
@@ -697,7 +697,7 @@ void MlrManager::LogMlrResponse(Error aResult, Error aError, uint8_t aStatus, co
OT_UNUSED_VARIABLE(aFailedAddresses);
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)
if (aResult == kErrorNone && aError == kErrorNone && aStatus == ThreadStatusTlv::kMlrSuccess)
if (aResult == kErrorNone && aError == kErrorNone && aStatus == kMlrSuccess)
{
LogInfo("Receive MLR.rsp OK");
}
+18 -3
View File
@@ -36,8 +36,6 @@
#include "openthread-core-config.h"
#if OPENTHREAD_CONFIG_MLR_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE)
namespace ot {
/**
@@ -46,6 +44,8 @@ namespace ot {
* @{
*/
#if OPENTHREAD_CONFIG_MLR_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE)
/**
* Multicast Listener Registration state for multicast addresses.
*/
@@ -56,7 +56,22 @@ enum MlrState : uint8_t
kMlrStateRegistered, ///< The multicast address is registered.
};
#endif // OPENTHREAD_CONFIG_MLR_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE)
/**
* Multicast Listener Registration (MLR) Status values.
*/
enum MlrStatus
{
kMlrSuccess = 0, ///< Successful (de)registration of all IPv6 addresses.
kMlrInvalid = 2, ///< Invalid IPv6 address(es) in request.
kMlrNoPersistent = 3, ///< This device does not support persistent registrations.
kMlrNoResources = 4, ///< BBR resource shortage.
kMlrBbrNotPrimary = 5, ///< BBR is not Primary at this moment.
kMlrGeneralFailure = 6, ///< Reason(s) for failure are not further specified.
kMlrStatusMax = 6, ///< Max MLR status.
};
} // namespace ot
#endif // OPENTHREAD_CONFIG_MLR_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE)
#endif // MLR_TYPES_HPP_
+1 -1
View File
@@ -361,7 +361,7 @@ void Notifier::HandleTimeTick(void)
{
LogInfo("Requesting router role as BR");
mDidRequestRouterRoleUpgrade = true;
IgnoreError(Get<Mle::Mle>().BecomeRouter(ThreadStatusTlv::kBorderRouterRequest));
IgnoreError(Get<Mle::Mle>().BecomeRouter(Mle::kReasonBorderRouterRequest));
}
}
exit:
+3 -45
View File
@@ -131,52 +131,10 @@ typedef UintTlvInfo<ThreadTlv::kCommissionerSessionId, uint16_t> ThreadCommissio
/**
* Defines Status TLV constants and types.
*
* The definition of Status values in this TLV depends on the TMF message in which it is used.
*/
class ThreadStatusTlv : public UintTlvInfo<ThreadTlv::kStatus, uint8_t>
{
public:
/**
* Status values.
*/
enum Status : uint8_t
{
kSuccess = 0, ///< Success.
kNoAddressAvailable = 1, ///< No address available.
kTooFewRouters = 2, ///< Address Solicit due to too few routers.
kHaveChildIdRequest = 3, ///< Address Solicit due to child ID request.
kParentPartitionChange = 4, ///< Address Solicit due to parent partition change
kBorderRouterRequest = 5, ///< Address Solicit from Border Router request.
kUnrecognizedStatus = 6, ///< The requested status is unrecognized or not meaningful in a request.
};
/**
* Multicast Listener Registration (MLR) Status values
*/
enum MlrStatus
{
kMlrSuccess = 0, ///< Successful (de)registration of all IPv6 addresses.
kMlrInvalid = 2, ///< Invalid IPv6 address(es) in request.
kMlrNoPersistent = 3, ///< This device does not support persistent registrations.
kMlrNoResources = 4, ///< BBR resource shortage.
kMlrBbrNotPrimary = 5, ///< BBR is not Primary at this moment.
kMlrGeneralFailure = 6, ///< Reason(s) for failure are not further specified.
kMlrStatusMax = 6, ///< Max MLR status.
};
/**
* Domain Unicast Address (DUA) Registration Status values
*/
enum DuaStatus : uint8_t
{
kDuaSuccess = 0, ///< Successful registration.
kDuaReRegister = 1, ///< Registration was accepted but immediate reregistration is required to solve.
kDuaInvalid = 2, ///< Registration rejected (Fatal): Target EID is not a valid DUA.
kDuaDuplicate = 3, ///< Registration rejected (Fatal): DUA is already in use by another device.
kDuaNoResources = 4, ///< Registration rejected (Non-fatal): Backbone Router Resource shortage.
kDuaNotPrimary = 5, ///< Registration rejected (Non-fatal): Backbone Router is not primary at this moment.
kDuaGeneralFailure = 6, ///< Registration failure (Non-fatal): Reason(s) not further specified.
};
};
typedef UintTlvInfo<ThreadTlv::kStatus, uint8_t> ThreadStatusTlv;
/**
* Implements Router Mask TLV generation and parsing.