Skip to content

Commit

Permalink
[message] track the MLE command type in Message (openthread#10809)
Browse files Browse the repository at this point in the history
This commit adds a new field, `mMleCommand`, to `Message::Metadata` to
track the MLE command type of the message. Helper methods, such as
`IsMleCommand()`, are added to `Message` to get/set/check the MLE
command type.

This replaces the previous model where `Message::SubType` was used to
track a subset of MLE commands. It helps simplify the code and allow
us to track all MLE commands.
  • Loading branch information
abtink authored Oct 11, 2024
1 parent 87474bd commit 5673039
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 162 deletions.
23 changes: 2 additions & 21 deletions src/core/common/message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,28 +318,9 @@ void Message::SetOffset(uint16_t aOffset)
GetMetadata().mOffset = aOffset;
}

bool Message::IsSubTypeMle(void) const
bool Message::IsMleCommand(Mle::Command aMleCommand) const
{
bool rval;

switch (GetMetadata().mSubType)
{
case kSubTypeMleGeneral:
case kSubTypeMleAnnounce:
case kSubTypeMleDiscoverRequest:
case kSubTypeMleDiscoverResponse:
case kSubTypeMleChildUpdateRequest:
case kSubTypeMleDataResponse:
case kSubTypeMleChildIdRequest:
rval = true;
break;

default:
rval = false;
break;
}

return rval;
return (GetSubType() == kSubTypeMle) && (GetMetadata().mMleCommand == aMleCommand);
}

Error Message::SetPriority(Priority aPriority)
Expand Down
58 changes: 42 additions & 16 deletions src/core/common/message.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ class Buffer : public otMessageBuffer, public LinkedListEntry<Buffer>
#endif
uint8_t mType : 3; // The message type.
uint8_t mSubType : 4; // The message sub type.
uint8_t mMleCommand; // The MLE command type (used when `mSubType is `Mle`).
uint8_t mChannel; // The message channel (used for MLE Announce).
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
uint8_t mTimeSyncSeq; // The time sync sequence.
Expand Down Expand Up @@ -289,18 +290,12 @@ class Message : public otMessage, public Buffer, public GetProvider<Message>
*/
enum SubType : uint8_t
{
kSubTypeNone = 0, ///< None
kSubTypeMleAnnounce = 1, ///< MLE Announce
kSubTypeMleDiscoverRequest = 2, ///< MLE Discover Request
kSubTypeMleDiscoverResponse = 3, ///< MLE Discover Response
kSubTypeJoinerEntrust = 4, ///< Joiner Entrust
kSubTypeMplRetransmission = 5, ///< MPL next retransmission message
kSubTypeMleGeneral = 6, ///< General MLE
kSubTypeJoinerFinalizeResponse = 7, ///< Joiner Finalize Response
kSubTypeMleChildUpdateRequest = 8, ///< MLE Child Update Request
kSubTypeMleDataResponse = 9, ///< MLE Data Response
kSubTypeMleChildIdRequest = 10, ///< MLE Child ID Request
kSubTypeMleDataRequest = 11, ///< MLE Data Request
kSubTypeNone = 0, ///< None
kSubTypeMle = 1, ///< MLE message
kSubTypeMplRetransmission = 2, ///< MPL next retransmission message
kSubTypeJoinerEntrust = 3, ///< Joiner Entrust
kSubTypeJoinerFinalizeResponse = 4, ///< Joiner Finalize Response

};

enum Priority : uint8_t
Expand Down Expand Up @@ -566,12 +561,43 @@ class Message : public otMessage, public Buffer, public GetProvider<Message>
void SetSubType(SubType aSubType) { GetMetadata().mSubType = aSubType; }

/**
* Returns whether or not the message is of MLE subtype.
* Indicates whether or not the message is of MLE sub type.
*
* @retval TRUE The message is of MLE sub type.
* @retval FALSE The message is not of MLE sub type.
*/
bool IsSubTypeMle(void) const { return (GetSubType() == kSubTypeMle); }

/**
* Indicates whether or not the message is a given MLE command.
*
* It checks `IsSubTypeMle()` and then if `GetMleCommand()` is the same as `aMleCommand`.
*
* @param[in] aMleCommand The MLE command type.
*
* @retval TRUE The message is an MLE command of @p aMleCommand type.
* @retval FALSE The message is not an MLE command of @p aMleCommand type.
*/
bool IsMleCommand(Mle::Command aMleCommand) const;

/**
* Gets the MLE command type.
*
* Caller MUST ensure that message sub type is `kSubTypeMle` before calling this method. Otherwise the returned
* value is not meaningful.
*
* @returns The message's MLE command type.
*/
Mle::Command GetMleCommand(void) const { return static_cast<Mle::Command>(GetMetadata().mMleCommand); }

/**
* Set the MLE command type of message.
*
* Caller should also set the sub type to `kSubTypeMle`.
*
* @retval TRUE If message is of MLE subtype.
* @retval FALSE If message is not of MLE subtype.
* @param[in] aMleCommand The MLE command type.
*/
bool IsSubTypeMle(void) const;
void SetMleCommand(Mle::Command aMleCommand) { GetMetadata().mMleCommand = aMleCommand; }

/**
* Checks whether this multicast message may be looped back.
Expand Down
2 changes: 1 addition & 1 deletion src/core/thread/discover_scanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ Error DiscoverScanner::Discover(const Mac::ChannelMask &aScanChannels,
mScanChannels.Intersect(aScanChannels);
}

VerifyOrExit((message = Get<Mle>().NewMleMessage(Mle::kCommandDiscoveryRequest)) != nullptr, error = kErrorNoBufs);
VerifyOrExit((message = Get<Mle>().NewMleMessage(kCommandDiscoveryRequest)) != nullptr, error = kErrorNoBufs);
message->SetPanId(aPanId);

// Prepare sub-TLV MeshCoP Discovery Request.
Expand Down
62 changes: 29 additions & 33 deletions src/core/thread/mesh_forwarder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ Mac::TxFrame *MeshForwarder::HandleFrameRequest(Mac::TxFrames &aTxFrames)
switch (mSendMessage->GetType())
{
case Message::kTypeIp6:
if (mSendMessage->GetSubType() == Message::kSubTypeMleDiscoverRequest)
if (mSendMessage->IsMleCommand(Mle::kCommandDiscoveryRequest))
{
frame = Get<Mle::DiscoverScanner>().PrepareDiscoveryRequestFrame(*frame);
VerifyOrExit(frame != nullptr);
Expand All @@ -792,7 +792,7 @@ Mac::TxFrame *MeshForwarder::HandleFrameRequest(Mac::TxFrames &aTxFrames)
mMessageNextOffset =
PrepareDataFrame(*frame, *mSendMessage, mMacAddrs, mAddMeshHeader, mMeshSource, mMeshDest, addFragHeader);

if ((mSendMessage->GetSubType() == Message::kSubTypeMleChildIdRequest) && mSendMessage->IsLinkSecurityEnabled())
if (mSendMessage->IsMleCommand(Mle::kCommandChildIdRequest) && mSendMessage->IsLinkSecurityEnabled())
{
LogNote("Child ID Request requires fragmentation, aborting tx");
mMessageNextOffset = mSendMessage->GetLength();
Expand Down Expand Up @@ -856,7 +856,7 @@ void MeshForwarder::PrepareMacHeaders(Mac::TxFrame &aTxFrame, Mac::TxFrame::Info
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (Get<Mac::Mac>().IsCslEnabled() &&
!(aMessage != nullptr && aMessage->GetSubType() == Message::kSubTypeMleDiscoverRequest))
!(aMessage != nullptr && aMessage->IsMleCommand(Mle::kCommandDiscoveryRequest)))
{
aTxFrameInfo.mAppendCslIe = true;
aTxFrameInfo.mVersion = Mac::Frame::kVersion2015;
Expand Down Expand Up @@ -934,39 +934,40 @@ uint16_t MeshForwarder::PrepareDataFrame(Mac::TxFrame &aFrame,
{
frameInfo.mSecurityLevel = Mac::Frame::kSecurityEncMic32;

switch (aMessage.GetSubType())
if (aMessage.GetSubType() == Message::kSubTypeJoinerEntrust)
{
case Message::kSubTypeJoinerEntrust:
frameInfo.mKeyIdMode = Mac::Frame::kKeyIdMode0;
break;

case Message::kSubTypeMleAnnounce:
}
else if (aMessage.IsMleCommand(Mle::kCommandAnnounce))
{
frameInfo.mKeyIdMode = Mac::Frame::kKeyIdMode2;
break;

default:
}
else
{
frameInfo.mKeyIdMode = Mac::Frame::kKeyIdMode1;
break;
}
}

frameInfo.mPanIds.SetBothSourceDestination(Get<Mac::Mac>().GetPanId());

switch (aMessage.GetSubType())
if (aMessage.IsSubTypeMle())
{
case Message::kSubTypeMleAnnounce:
aFrame.SetChannel(aMessage.GetChannel());
aFrame.SetRxChannelAfterTxDone(Get<Mac::Mac>().GetPanChannel());
frameInfo.mPanIds.SetDestination(Mac::kPanIdBroadcast);
break;
switch (aMessage.GetMleCommand())
{
case Mle::kCommandAnnounce:
aFrame.SetChannel(aMessage.GetChannel());
aFrame.SetRxChannelAfterTxDone(Get<Mac::Mac>().GetPanChannel());
frameInfo.mPanIds.SetDestination(Mac::kPanIdBroadcast);
break;

case Message::kSubTypeMleDiscoverRequest:
case Message::kSubTypeMleDiscoverResponse:
frameInfo.mPanIds.SetDestination(aMessage.GetPanId());
break;
case Mle::kCommandDiscoveryRequest:
case Mle::kCommandDiscoveryResponse:
frameInfo.mPanIds.SetDestination(aMessage.GetPanId());
break;

default:
break;
default:
break;
}
}

frameInfo.mType = Mac::Frame::kTypeData;
Expand Down Expand Up @@ -1345,20 +1346,15 @@ void MeshForwarder::FinalizeMessageDirectTx(Message &aMessage, Error aError)
aMessage.GetTxSuccess() ? mIpCounters.mTxSuccess++ : mIpCounters.mTxFailure++;
}

switch (aMessage.GetSubType())
if (aMessage.IsMleCommand(Mle::kCommandDiscoveryRequest))
{
case Message::kSubTypeMleDiscoverRequest:
// Note that `HandleDiscoveryRequestFrameTxDone()` may update
// `aMessage` and mark it again for direct transmission.
Get<Mle::DiscoverScanner>().HandleDiscoveryRequestFrameTxDone(aMessage, aError);
break;

case Message::kSubTypeMleChildIdRequest:
}
else if (aMessage.IsMleCommand(Mle::kCommandChildIdRequest))
{
Get<Mle::Mle>().HandleChildIdRequestTxDone(aMessage);
break;

default:
break;
}

exit:
Expand Down
2 changes: 1 addition & 1 deletion src/core/thread/mesh_forwarder_ftd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ void MeshForwarder::RemoveDataResponseMessages(void)

for (Message &message : mSendQueue)
{
if (message.GetSubType() != Message::kSubTypeMleDataResponse)
if (!message.IsMleCommand(Mle::kCommandDataResponse))
{
continue;
}
Expand Down
51 changes: 8 additions & 43 deletions src/core/thread/mle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4354,7 +4354,7 @@ void Mle::DelayedSender::Send(TxMessage &aMessage, const Metadata &aMetadata)

aMetadata.RemoveFrom(aMessage);

if (aMessage.GetSubType() == Message::kSubTypeMleDataRequest)
if (aMessage.IsMleCommand(kCommandDataRequest))
{
SuccessOrExit(error = aMessage.AppendActiveAndPendingTimestampTlvs());
}
Expand All @@ -4381,26 +4381,23 @@ void Mle::DelayedSender::Send(TxMessage &aMessage, const Metadata &aMetadata)

void Mle::DelayedSender::RemoveDataResponseMessage(void)
{
RemoveMessage(Message::kSubTypeMleDataResponse, kTypeDataResponse, nullptr);
RemoveMessage(kCommandDataResponse, kTypeDataResponse, nullptr);
}

void Mle::DelayedSender::RemoveDataRequestMessage(const Ip6::Address &aDestination)
{
RemoveMessage(Message::kSubTypeMleDataRequest, kTypeDataRequest, &aDestination);
RemoveMessage(kCommandDataRequest, kTypeDataRequest, &aDestination);
}

void Mle::DelayedSender::RemoveMessage(Message::SubType aSubType,
MessageType aMessageType,
const Ip6::Address *aDestination)
void Mle::DelayedSender::RemoveMessage(Command aCommand, MessageType aMessageType, const Ip6::Address *aDestination)
{
for (Message &message : mQueue)
{
Metadata metadata;

metadata.ReadFrom(message);

if ((message.GetSubType() == aSubType) &&
((aDestination == nullptr) || (metadata.mDestination == *aDestination)))
if (message.IsMleCommand(aCommand) && ((aDestination == nullptr) || (metadata.mDestination == *aDestination)))
{
mQueue.DequeueAndFree(message);
Log(kMessageRemoveDelayed, aMessageType, metadata.mDestination);
Expand All @@ -4416,52 +4413,20 @@ Mle::TxMessage *Mle::NewMleMessage(Command aCommand)
Error error = kErrorNone;
TxMessage *message;
Message::Settings settings(Message::kNoLinkSecurity, Message::kPriorityNet);
Message::SubType subType;
uint8_t securitySuite;

message = static_cast<TxMessage *>(mSocket.NewMessage(0, settings));
VerifyOrExit(message != nullptr, error = kErrorNoBufs);

securitySuite = k154Security;
subType = Message::kSubTypeMleGeneral;

switch (aCommand)
if ((aCommand == kCommandDiscoveryRequest) || (aCommand == kCommandDiscoveryResponse))
{
case kCommandAnnounce:
subType = Message::kSubTypeMleAnnounce;
break;

case kCommandDiscoveryRequest:
subType = Message::kSubTypeMleDiscoverRequest;
securitySuite = kNoSecurity;
break;

case kCommandDiscoveryResponse:
subType = Message::kSubTypeMleDiscoverResponse;
securitySuite = kNoSecurity;
break;

case kCommandChildUpdateRequest:
subType = Message::kSubTypeMleChildUpdateRequest;
break;

case kCommandDataResponse:
subType = Message::kSubTypeMleDataResponse;
break;

case kCommandChildIdRequest:
subType = Message::kSubTypeMleChildIdRequest;
break;

case kCommandDataRequest:
subType = Message::kSubTypeMleDataRequest;
break;

default:
break;
}

message->SetSubType(subType);
message->SetSubType(Message::kSubTypeMle);
message->SetMleCommand(aCommand);

SuccessOrExit(error = message->Append(securitySuite));

Expand Down
28 changes: 1 addition & 27 deletions src/core/thread/mle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -792,32 +792,6 @@ class Mle : public InstanceLocator, private NonCopyable
//------------------------------------------------------------------------------------------------------------------
// Enumerations

enum Command : uint8_t
{
kCommandLinkRequest = 0,
kCommandLinkAccept = 1,
kCommandLinkAcceptAndRequest = 2,
kCommandLinkReject = 3,
kCommandAdvertisement = 4,
kCommandUpdate = 5,
kCommandUpdateRequest = 6,
kCommandDataRequest = 7,
kCommandDataResponse = 8,
kCommandParentRequest = 9,
kCommandParentResponse = 10,
kCommandChildIdRequest = 11,
kCommandChildIdResponse = 12,
kCommandChildUpdateRequest = 13,
kCommandChildUpdateResponse = 14,
kCommandAnnounce = 15,
kCommandDiscoveryRequest = 16,
kCommandDiscoveryResponse = 17,
kCommandLinkMetricsManagementRequest = 18,
kCommandLinkMetricsManagementResponse = 19,
kCommandLinkProbe = 20,
kCommandTimeSync = 99,
};

enum AttachMode : uint8_t
{
kAnyPartition, // Attach to any Thread partition.
Expand Down Expand Up @@ -1112,7 +1086,7 @@ class Mle : public InstanceLocator, private NonCopyable
};

void Send(TxMessage &aMessage, const Metadata &aMetadata);
void RemoveMessage(Message::SubType aSubType, MessageType aMessageType, const Ip6::Address *aDestination);
void RemoveMessage(Command aCommand, MessageType aMessageType, const Ip6::Address *aDestination);

using DelayTimer = TimerMilliIn<Mle, &Mle::HandleDelayedSenderTimer>;

Expand Down
Loading

0 comments on commit 5673039

Please sign in to comment.