[mle] add Tx/RxMessage providing Append/Read{Tlv} methods (#7689)

This commit adds new `Mle::TxMessage` and `Mle::RxMessage` classes
(as sub-classes of `Message`). `TxMessage` represents an MLE message
to be sent out providing `Append{Some}Tlv()` methods and `RxMessage`
represent a received MLE message providing helper methods `Read
{Some}Tlv()`.
This commit is contained in:
Abtin Keshavarzian
2022-05-17 11:25:41 -07:00
committed by GitHub
parent 3f47516ce8
commit cb41668c0c
5 changed files with 737 additions and 714 deletions
+2 -2
View File
@@ -67,7 +67,7 @@ Error DiscoverScanner::Discover(const Mac::ChannelMask &aScanChannels,
void * aContext)
{
Error error = kErrorNone;
Message * message = nullptr;
Mle::TxMessage * message = nullptr;
Tlv tlv;
Ip6::Address destination;
MeshCoP::DiscoveryRequestTlv discoveryRequest;
@@ -136,7 +136,7 @@ Error DiscoverScanner::Discover(const Mac::ChannelMask &aScanChannels,
destination.SetToLinkLocalAllRoutersMulticast();
SuccessOrExit(error = Get<Mle>().SendMessage(*message, destination));
SuccessOrExit(error = message->SendTo(destination));
if ((aPanId == Mac::kPanIdBroadcast) && (Get<Mac::Mac>().GetPanId() == Mac::kPanIdBroadcast))
{
+177 -175
View File
@@ -1031,15 +1031,15 @@ const LeaderData &Mle::GetLeaderData(void)
return mLeaderData;
}
Message *Mle::NewMleMessage(Command aCommand)
Mle::TxMessage *Mle::NewMleMessage(Command aCommand)
{
Error error = kErrorNone;
Message * message;
TxMessage * message;
Message::Settings settings(Message::kNoLinkSecurity, Message::kPriorityNet);
Message::SubType subType;
uint8_t securitySuite;
message = mSocket.NewMessage(0, settings);
message = static_cast<TxMessage *>(mSocket.NewMessage(0, settings));
VerifyOrExit(message != nullptr, error = kErrorNoBufs);
securitySuite = k154Security;
@@ -1090,7 +1090,7 @@ Message *Mle::NewMleMessage(Command aCommand)
SecurityHeader securityHeader;
// The other fields in security header are updated in the
// message in `SendMessage()` before message is sent.
// message in `TxMessage::SendTo()` before message is sent.
securityHeader.InitSecurityControl();
SuccessOrExit(error = message->Append(securityHeader));
@@ -1103,48 +1103,48 @@ exit:
return message;
}
Error Mle::AppendSourceAddress(Message &aMessage) const
Error Mle::TxMessage::AppendSourceAddressTlv(void)
{
return Tlv::Append<SourceAddressTlv>(aMessage, GetRloc16());
return Tlv::Append<SourceAddressTlv>(*this, Get<Mle>().GetRloc16());
}
Error Mle::AppendStatus(Message &aMessage, StatusTlv::Status aStatus)
Error Mle::TxMessage::AppendStatusTlv(StatusTlv::Status aStatus)
{
return Tlv::Append<StatusTlv>(aMessage, aStatus);
return Tlv::Append<StatusTlv>(*this, aStatus);
}
Error Mle::AppendMode(Message &aMessage, DeviceMode aMode)
Error Mle::TxMessage::AppendModeTlv(DeviceMode aMode)
{
return Tlv::Append<ModeTlv>(aMessage, aMode.Get());
return Tlv::Append<ModeTlv>(*this, aMode.Get());
}
Error Mle::AppendTimeout(Message &aMessage, uint32_t aTimeout)
Error Mle::TxMessage::AppendTimeoutTlv(uint32_t aTimeout)
{
return Tlv::Append<TimeoutTlv>(aMessage, aTimeout);
return Tlv::Append<TimeoutTlv>(*this, aTimeout);
}
Error Mle::AppendChallenge(Message &aMessage, const Challenge &aChallenge)
Error Mle::TxMessage::AppendChallengeTlv(const Challenge &aChallenge)
{
return Tlv::Append<ChallengeTlv>(aMessage, aChallenge.mBuffer, aChallenge.mLength);
return Tlv::Append<ChallengeTlv>(*this, aChallenge.mBuffer, aChallenge.mLength);
}
Error Mle::AppendChallenge(Message &aMessage, const uint8_t *aChallenge, uint8_t aChallengeLength)
Error Mle::TxMessage::AppendChallengeTlv(const uint8_t *aChallenge, uint8_t aChallengeLength)
{
return Tlv::Append<ChallengeTlv>(aMessage, aChallenge, aChallengeLength);
return Tlv::Append<ChallengeTlv>(*this, aChallenge, aChallengeLength);
}
Error Mle::AppendResponse(Message &aMessage, const Challenge &aResponse)
Error Mle::TxMessage::AppendResponseTlv(const Challenge &aResponse)
{
return Tlv::Append<ResponseTlv>(aMessage, aResponse.mBuffer, aResponse.mLength);
return Tlv::Append<ResponseTlv>(*this, aResponse.mBuffer, aResponse.mLength);
}
Error Mle::ReadChallengeOrResponse(const Message &aMessage, uint8_t aTlvType, Challenge &aBuffer)
Error Mle::RxMessage::ReadChallengeOrResponse(uint8_t aTlvType, Challenge &aBuffer) const
{
Error error;
uint16_t offset;
uint16_t length;
SuccessOrExit(error = Tlv::FindTlvValueOffset(aMessage, aTlvType, offset, length));
SuccessOrExit(error = Tlv::FindTlvValueOffset(*this, aTlvType, offset, length));
VerifyOrExit(length >= kMinChallengeSize, error = kErrorParse);
if (length > kMaxChallengeSize)
@@ -1152,24 +1152,24 @@ Error Mle::ReadChallengeOrResponse(const Message &aMessage, uint8_t aTlvType, Ch
length = kMaxChallengeSize;
}
aMessage.ReadBytes(offset, aBuffer.mBuffer, length);
ReadBytes(offset, aBuffer.mBuffer, length);
aBuffer.mLength = static_cast<uint8_t>(length);
exit:
return error;
}
Error Mle::ReadChallenge(const Message &aMessage, Challenge &aChallenge)
Error Mle::RxMessage::ReadChallengeTlv(Challenge &aChallenge) const
{
return ReadChallengeOrResponse(aMessage, Tlv::kChallenge, aChallenge);
return ReadChallengeOrResponse(Tlv::kChallenge, aChallenge);
}
Error Mle::ReadResponse(const Message &aMessage, Challenge &aResponse)
Error Mle::RxMessage::ReadResponseTlv(Challenge &aResponse) const
{
return ReadChallengeOrResponse(aMessage, Tlv::kResponse, aResponse);
return ReadChallengeOrResponse(Tlv::kResponse, aResponse);
}
Error Mle::AppendLinkFrameCounter(Message &aMessage)
Error Mle::TxMessage::AppendLinkFrameCounterTlv(void)
{
uint32_t counter;
@@ -1184,21 +1184,21 @@ Error Mle::AppendLinkFrameCounter(Message &aMessage)
Get<KeyManager>().SetAllMacFrameCounters(counter);
#endif
return Tlv::Append<LinkFrameCounterTlv>(aMessage, counter);
return Tlv::Append<LinkFrameCounterTlv>(*this, counter);
}
Error Mle::AppendMleFrameCounter(Message &aMessage)
Error Mle::TxMessage::AppendMleFrameCounterTlv(void)
{
return Tlv::Append<MleFrameCounterTlv>(aMessage, Get<KeyManager>().GetMleFrameCounter());
return Tlv::Append<MleFrameCounterTlv>(*this, Get<KeyManager>().GetMleFrameCounter());
}
Error Mle::ReadFrameCounters(const Message &aMessage, uint32_t &aLinkFrameCounter, uint32_t &aMleFrameCounter) const
Error Mle::RxMessage::ReadFrameCounterTlvs(uint32_t &aLinkFrameCounter, uint32_t &aMleFrameCounter) const
{
Error error;
SuccessOrExit(error = Tlv::Find<LinkFrameCounterTlv>(aMessage, aLinkFrameCounter));
SuccessOrExit(error = Tlv::Find<LinkFrameCounterTlv>(*this, aLinkFrameCounter));
switch (Tlv::Find<MleFrameCounterTlv>(aMessage, aMleFrameCounter))
switch (Tlv::Find<MleFrameCounterTlv>(*this, aMleFrameCounter))
{
case kErrorNone:
break;
@@ -1214,30 +1214,30 @@ exit:
return error;
}
Error Mle::AppendAddress16(Message &aMessage, uint16_t aRloc16)
Error Mle::TxMessage::AppendAddress16Tlv(uint16_t aRloc16)
{
return Tlv::Append<Address16Tlv>(aMessage, aRloc16);
return Tlv::Append<Address16Tlv>(*this, aRloc16);
}
Error Mle::AppendLeaderData(Message &aMessage)
Error Mle::TxMessage::AppendLeaderDataTlv(void)
{
LeaderDataTlv leaderDataTlv;
mLeaderData.SetDataVersion(Get<NetworkData::Leader>().GetVersion(NetworkData::kFullSet));
mLeaderData.SetStableDataVersion(Get<NetworkData::Leader>().GetVersion(NetworkData::kStableSubset));
Get<Mle>().mLeaderData.SetDataVersion(Get<NetworkData::Leader>().GetVersion(NetworkData::kFullSet));
Get<Mle>().mLeaderData.SetStableDataVersion(Get<NetworkData::Leader>().GetVersion(NetworkData::kStableSubset));
leaderDataTlv.Init();
leaderDataTlv.Set(mLeaderData);
leaderDataTlv.Set(Get<Mle>().mLeaderData);
return leaderDataTlv.AppendTo(aMessage);
return leaderDataTlv.AppendTo(*this);
}
Error Mle::ReadLeaderData(const Message &aMessage, LeaderData &aLeaderData)
Error Mle::RxMessage::ReadLeaderDataTlv(LeaderData &aLeaderData) const
{
Error error;
LeaderDataTlv leaderDataTlv;
SuccessOrExit(error = Tlv::FindTlv(aMessage, leaderDataTlv));
SuccessOrExit(error = Tlv::FindTlv(*this, leaderDataTlv));
VerifyOrExit(leaderDataTlv.IsValid(), error = kErrorParse);
leaderDataTlv.Get(aLeaderData);
@@ -1245,61 +1245,61 @@ exit:
return error;
}
Error Mle::AppendNetworkData(Message &aMessage, NetworkData::Type aType)
Error Mle::TxMessage::AppendNetworkDataTlv(NetworkData::Type aType)
{
Error error = kErrorNone;
uint8_t networkData[NetworkData::NetworkData::kMaxSize];
uint8_t length;
VerifyOrExit(!mRetrieveNewNetworkData, error = kErrorInvalidState);
VerifyOrExit(!Get<Mle>().mRetrieveNewNetworkData, error = kErrorInvalidState);
length = sizeof(networkData);
IgnoreError(Get<NetworkData::Leader>().CopyNetworkData(aType, networkData, length));
error = Tlv::Append<NetworkDataTlv>(aMessage, networkData, length);
error = Tlv::Append<NetworkDataTlv>(*this, networkData, length);
exit:
return error;
}
Error Mle::AppendTlvRequest(Message &aMessage, const uint8_t *aTlvs, uint8_t aTlvsLength)
Error Mle::TxMessage::AppendTlvRequestTlv(const uint8_t *aTlvs, uint8_t aTlvsLength)
{
return Tlv::Append<TlvRequestTlv>(aMessage, aTlvs, aTlvsLength);
return Tlv::Append<TlvRequestTlv>(*this, aTlvs, aTlvsLength);
}
Error Mle::FindTlvRequest(const Message &aMessage, RequestedTlvs &aRequestedTlvs)
Error Mle::RxMessage::ReadTlvRequestTlv(RequestedTlvs &aRequestedTlvs) const
{
Error error;
uint16_t offset;
uint16_t length;
SuccessOrExit(error = Tlv::FindTlvValueOffset(aMessage, Tlv::kTlvRequest, offset, length));
SuccessOrExit(error = Tlv::FindTlvValueOffset(*this, Tlv::kTlvRequest, offset, length));
if (length > sizeof(aRequestedTlvs.mTlvs))
{
length = sizeof(aRequestedTlvs.mTlvs);
}
aMessage.ReadBytes(offset, aRequestedTlvs.mTlvs, length);
ReadBytes(offset, aRequestedTlvs.mTlvs, length);
aRequestedTlvs.mNumTlvs = static_cast<uint8_t>(length);
exit:
return error;
}
Error Mle::AppendScanMask(Message &aMessage, uint8_t aScanMask)
Error Mle::TxMessage::AppendScanMaskTlv(uint8_t aScanMask)
{
return Tlv::Append<ScanMaskTlv>(aMessage, aScanMask);
return Tlv::Append<ScanMaskTlv>(*this, aScanMask);
}
Error Mle::AppendLinkMargin(Message &aMessage, uint8_t aLinkMargin)
Error Mle::TxMessage::AppendLinkMarginTlv(uint8_t aLinkMargin)
{
return Tlv::Append<LinkMarginTlv>(aMessage, aLinkMargin);
return Tlv::Append<LinkMarginTlv>(*this, aLinkMargin);
}
Error Mle::AppendVersion(Message &aMessage)
Error Mle::TxMessage::AppendVersionTlv(void)
{
return Tlv::Append<VersionTlv>(aMessage, kThreadVersion);
return Tlv::Append<VersionTlv>(*this, kThreadVersion);
}
bool Mle::HasUnregisteredAddress(void)
@@ -1330,7 +1330,7 @@ exit:
return retval;
}
Error Mle::AppendAddressRegistration(Message &aMessage, AddressRegistrationMode aMode)
Error Mle::TxMessage::AppendAddressRegistrationTlv(AddressRegistrationMode aMode)
{
Error error = kErrorNone;
Tlv tlv;
@@ -1338,18 +1338,18 @@ Error Mle::AppendAddressRegistration(Message &aMessage, AddressRegistrationMode
Lowpan::Context context;
uint8_t length = 0;
uint8_t counter = 0;
uint16_t startOffset = aMessage.GetLength();
uint16_t startOffset = GetLength();
#if OPENTHREAD_CONFIG_DUA_ENABLE
Ip6::Address domainUnicastAddress;
#endif
tlv.SetType(Tlv::kAddressRegistration);
SuccessOrExit(error = aMessage.Append(tlv));
SuccessOrExit(error = Append(tlv));
// Prioritize ML-EID
entry.SetContextId(kMeshLocalPrefixContextId);
entry.SetIid(GetMeshLocal64().GetIid());
SuccessOrExit(error = aMessage.AppendBytes(&entry, entry.GetLength()));
entry.SetIid(Get<Mle>().GetMeshLocal64().GetIid());
SuccessOrExit(error = AppendBytes(&entry, entry.GetLength()));
length += entry.GetLength();
// Continue to append the other addresses if not `kAppendMeshLocalOnly` mode
@@ -1367,7 +1367,7 @@ Error Mle::AppendAddressRegistration(Message &aMessage, AddressRegistrationMode
// Prioritize DUA, compressed entry
entry.SetContextId(context.mContextId);
entry.SetIid(domainUnicastAddress.GetIid());
SuccessOrExit(error = aMessage.AppendBytes(&entry, entry.GetLength()));
SuccessOrExit(error = AppendBytes(&entry, entry.GetLength()));
length += entry.GetLength();
counter++;
}
@@ -1375,8 +1375,8 @@ Error Mle::AppendAddressRegistration(Message &aMessage, AddressRegistrationMode
for (const Ip6::Netif::UnicastAddress &addr : Get<ThreadNetif>().GetUnicastAddresses())
{
if (addr.GetAddress().IsLinkLocal() || IsRoutingLocator(addr.GetAddress()) ||
IsAnycastLocator(addr.GetAddress()) || addr.GetAddress() == GetMeshLocal64())
if (addr.GetAddress().IsLinkLocal() || Get<Mle>().IsRoutingLocator(addr.GetAddress()) ||
Get<Mle>().IsAnycastLocator(addr.GetAddress()) || addr.GetAddress() == Get<Mle>().GetMeshLocal64())
{
continue;
}
@@ -1402,7 +1402,7 @@ Error Mle::AppendAddressRegistration(Message &aMessage, AddressRegistrationMode
entry.SetIp6Address(addr.GetAddress());
}
SuccessOrExit(error = aMessage.AppendBytes(&entry, entry.GetLength()));
SuccessOrExit(error = AppendBytes(&entry, entry.GetLength()));
length += entry.GetLength();
counter++;
// only continue to append if there is available entry.
@@ -1414,9 +1414,9 @@ Error Mle::AppendAddressRegistration(Message &aMessage, AddressRegistrationMode
// indirect transmission. Since Thread 1.2, non-sleepy MED should
// also register external multicast addresses of scope larger than
// realm with a 1.2 or higher parent.
if (!IsRxOnWhenIdle()
if (!Get<Mle>().IsRxOnWhenIdle()
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|| !GetParent().IsThreadVersion1p1()
|| !Get<Mle>().GetParent().IsThreadVersion1p1()
#endif
)
{
@@ -1425,7 +1425,7 @@ Error Mle::AppendAddressRegistration(Message &aMessage, AddressRegistrationMode
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
// For Thread 1.2 MED, skip multicast address with scope not
// larger than realm local when registering.
if (IsRxOnWhenIdle() && !addr.GetAddress().IsMulticastLargerThanRealmLocal())
if (Get<Mle>().IsRxOnWhenIdle() && !addr.GetAddress().IsMulticastLargerThanRealmLocal())
{
continue;
}
@@ -1433,7 +1433,7 @@ Error Mle::AppendAddressRegistration(Message &aMessage, AddressRegistrationMode
entry.SetUncompressed();
entry.SetIp6Address(addr.GetAddress());
SuccessOrExit(error = aMessage.AppendBytes(&entry, entry.GetLength()));
SuccessOrExit(error = AppendBytes(&entry, entry.GetLength()));
length += entry.GetLength();
counter++;
@@ -1447,20 +1447,20 @@ exit:
if (error == kErrorNone && length > 0)
{
tlv.SetLength(length);
aMessage.Write(startOffset, tlv);
Write(startOffset, tlv);
}
return error;
}
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
Error Mle::AppendTimeRequest(Message &aMessage)
Error Mle::TxMessage::AppendTimeRequestTlv(void)
{
// `TimeRequestTlv` has no value.
return Tlv::Append<TimeRequestTlv>(aMessage, nullptr, 0);
return Tlv::Append<TimeRequestTlv>(*this, nullptr, 0);
}
Error Mle::AppendTimeParameter(Message &aMessage)
Error Mle::TxMessage::AppendTimeParameterTlv(void)
{
TimeParameterTlv tlv;
@@ -1468,41 +1468,41 @@ Error Mle::AppendTimeParameter(Message &aMessage)
tlv.SetTimeSyncPeriod(Get<TimeSync>().GetTimeSyncPeriod());
tlv.SetXtalThreshold(Get<TimeSync>().GetXtalThreshold());
return tlv.AppendTo(aMessage);
return tlv.AppendTo(*this);
}
Error Mle::AppendXtalAccuracy(Message &aMessage)
Error Mle::TxMessage::AppendXtalAccuracyTlv(void)
{
return Tlv::Append<XtalAccuracyTlv>(aMessage, otPlatTimeGetXtalAccuracy());
return Tlv::Append<XtalAccuracyTlv>(*this, otPlatTimeGetXtalAccuracy());
}
#endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
Error Mle::AppendActiveTimestamp(Message &aMessage)
Error Mle::TxMessage::AppendActiveTimestampTlv(void)
{
Error error = kErrorNone;
const MeshCoP::Timestamp *timestamp = Get<MeshCoP::ActiveDatasetManager>().GetTimestamp();
VerifyOrExit(timestamp != nullptr);
error = Tlv::Append<ActiveTimestampTlv>(aMessage, *timestamp);
error = Tlv::Append<ActiveTimestampTlv>(*this, *timestamp);
exit:
return error;
}
Error Mle::AppendPendingTimestamp(Message &aMessage)
Error Mle::TxMessage::AppendPendingTimestampTlv(void)
{
Error error = kErrorNone;
const MeshCoP::Timestamp *timestamp = Get<MeshCoP::PendingDatasetManager>().GetTimestamp();
VerifyOrExit(timestamp != nullptr && timestamp->GetSeconds() != 0);
error = Tlv::Append<PendingTimestampTlv>(aMessage, *timestamp);
error = Tlv::Append<PendingTimestampTlv>(*this, *timestamp);
exit:
return error;
}
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
Error Mle::AppendCslChannel(Message &aMessage)
Error Mle::TxMessage::AppendCslChannelTlv(void)
{
Error error = kErrorNone;
CslChannelTlv cslChannel;
@@ -1517,16 +1517,17 @@ Error Mle::AppendCslChannel(Message &aMessage)
cslChannel.SetChannelPage(0);
cslChannel.SetChannel(Get<Mac::Mac>().GetCslChannel());
SuccessOrExit(error = aMessage.Append(cslChannel));
SuccessOrExit(error = Append(cslChannel));
exit:
return error;
}
Error Mle::AppendCslTimeout(Message &aMessage)
Error Mle::TxMessage::AppendCslTimeoutTlv(void)
{
OT_ASSERT(Get<Mac::Mac>().IsCslEnabled());
return Tlv::Append<CslTimeoutTlv>(aMessage, mCslTimeout == 0 ? mTimeout : mCslTimeout);
return Tlv::Append<CslTimeoutTlv>(*this,
Get<Mle>().mCslTimeout == 0 ? Get<Mle>().mTimeout : Get<Mle>().mCslTimeout);
}
void Mle::SetCslTimeout(uint32_t aTimeout)
@@ -1548,7 +1549,7 @@ exit:
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
Error Mle::AppendCslClockAccuracy(Message &aMessage)
Error Mle::TxMessage::AppendCslClockAccuracyTlv(void)
{
Error error = kErrorNone;
CslClockAccuracyTlv cslClockAccuracy;
@@ -1558,7 +1559,7 @@ Error Mle::AppendCslClockAccuracy(Message &aMessage)
cslClockAccuracy.SetCslClockAccuracy(Get<Radio>().GetCslAccuracy());
cslClockAccuracy.SetCslUncertainty(Get<Radio>().GetCslUncertainty());
SuccessOrExit(error = aMessage.Append(cslClockAccuracy));
SuccessOrExit(error = Append(cslClockAccuracy));
exit:
return error;
@@ -2054,7 +2055,7 @@ void Mle::HandleDelayedResponseTimer(void)
else
{
mDelayedResponses.Dequeue(message);
SendDelayedResponse(message, metadata);
SendDelayedResponse(static_cast<TxMessage &>(message), metadata);
}
}
@@ -2064,7 +2065,7 @@ void Mle::HandleDelayedResponseTimer(void)
}
}
void Mle::SendDelayedResponse(Message &aMessage, const DelayedResponseMetadata &aMetadata)
void Mle::SendDelayedResponse(TxMessage &aMessage, const DelayedResponseMetadata &aMetadata)
{
Error error = kErrorNone;
@@ -2072,11 +2073,11 @@ void Mle::SendDelayedResponse(Message &aMessage, const DelayedResponseMetadata &
if (aMessage.GetSubType() == Message::kSubTypeMleDataRequest)
{
SuccessOrExit(error = AppendActiveTimestamp(aMessage));
SuccessOrExit(error = AppendPendingTimestamp(aMessage));
SuccessOrExit(error = aMessage.AppendActiveTimestampTlv());
SuccessOrExit(error = aMessage.AppendPendingTimestampTlv());
}
SuccessOrExit(error = SendMessage(aMessage, aMetadata.mDestination));
SuccessOrExit(error = aMessage.SendTo(aMetadata.mDestination));
Log(kMessageSend, kTypeGenericDelayed, aMetadata.mDestination);
@@ -2123,7 +2124,7 @@ void Mle::RemoveDelayedMessage(Message::SubType aSubType, MessageType aMessageTy
void Mle::SendParentRequest(ParentRequestType aType)
{
Error error = kErrorNone;
Message * message;
TxMessage * message;
uint8_t scanMask = 0;
Ip6::Address destination;
@@ -2141,16 +2142,16 @@ void Mle::SendParentRequest(ParentRequestType aType)
}
VerifyOrExit((message = NewMleMessage(kCommandParentRequest)) != nullptr, error = kErrorNoBufs);
SuccessOrExit(error = AppendMode(*message, mDeviceMode));
SuccessOrExit(error = AppendChallenge(*message, mParentRequestChallenge));
SuccessOrExit(error = AppendScanMask(*message, scanMask));
SuccessOrExit(error = AppendVersion(*message));
SuccessOrExit(error = message->AppendModeTlv(mDeviceMode));
SuccessOrExit(error = message->AppendChallengeTlv(mParentRequestChallenge));
SuccessOrExit(error = message->AppendScanMaskTlv(scanMask));
SuccessOrExit(error = message->AppendVersionTlv());
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
SuccessOrExit(error = AppendTimeRequest(*message));
SuccessOrExit(error = message->AppendTimeRequestTlv());
#endif
destination.SetToLinkLocalAllRoutersMulticast();
SuccessOrExit(error = SendMessage(*message, destination));
SuccessOrExit(error = message->SendTo(destination));
switch (aType)
{
@@ -2181,7 +2182,7 @@ Error Mle::SendChildIdRequest(void)
Error error = kErrorNone;
uint8_t tlvs[] = {Tlv::kAddress16, Tlv::kNetworkData, Tlv::kRoute};
uint8_t tlvsLen = sizeof(tlvs);
Message * message = nullptr;
TxMessage * message = nullptr;
Ip6::Address destination;
if (mParent.GetExtAddress() == mParentCandidate.GetExtAddress())
@@ -2203,29 +2204,29 @@ Error Mle::SendChildIdRequest(void)
}
VerifyOrExit((message = NewMleMessage(kCommandChildIdRequest)) != nullptr, error = kErrorNoBufs);
SuccessOrExit(error = AppendResponse(*message, mParentCandidateChallenge));
SuccessOrExit(error = AppendLinkFrameCounter(*message));
SuccessOrExit(error = AppendMleFrameCounter(*message));
SuccessOrExit(error = AppendMode(*message, mDeviceMode));
SuccessOrExit(error = AppendTimeout(*message, mTimeout));
SuccessOrExit(error = AppendVersion(*message));
SuccessOrExit(error = message->AppendResponseTlv(mParentCandidateChallenge));
SuccessOrExit(error = message->AppendLinkFrameCounterTlv());
SuccessOrExit(error = message->AppendMleFrameCounterTlv());
SuccessOrExit(error = message->AppendModeTlv(mDeviceMode));
SuccessOrExit(error = message->AppendTimeoutTlv(mTimeout));
SuccessOrExit(error = message->AppendVersionTlv());
if (!IsFullThreadDevice())
{
SuccessOrExit(error = AppendAddressRegistration(*message, mAddressRegistrationMode));
SuccessOrExit(error = message->AppendAddressRegistrationTlv(mAddressRegistrationMode));
// no need to request the last Route64 TLV for MTD
tlvsLen -= 1;
}
SuccessOrExit(error = AppendTlvRequest(*message, tlvs, tlvsLen));
SuccessOrExit(error = AppendActiveTimestamp(*message));
SuccessOrExit(error = AppendPendingTimestamp(*message));
SuccessOrExit(error = message->AppendTlvRequestTlv(tlvs, tlvsLen));
SuccessOrExit(error = message->AppendActiveTimestampTlv());
SuccessOrExit(error = message->AppendPendingTimestampTlv());
mParentCandidate.SetState(Neighbor::kStateValid);
destination.SetToLinkLocalAddress(mParentCandidate.GetExtAddress());
SuccessOrExit(error = SendMessage(*message, destination));
SuccessOrExit(error = message->SendTo(destination));
Log(kMessageSend,
(mAddressRegistrationMode == kAppendMeshLocalOnly) ? kTypeChildIdRequestShort : kTypeChildIdRequest,
@@ -2249,13 +2250,13 @@ Error Mle::SendDataRequest(const Ip6::Address &aDestination,
const uint8_t * aExtraTlvs,
uint8_t aExtraTlvsLength)
{
Error error = kErrorNone;
Message *message;
Error error = kErrorNone;
TxMessage *message;
RemoveDelayedDataRequestMessage(aDestination);
VerifyOrExit((message = NewMleMessage(kCommandDataRequest)) != nullptr, error = kErrorNoBufs);
SuccessOrExit(error = AppendTlvRequest(*message, aTlvs, aTlvsLength));
SuccessOrExit(error = message->AppendTlvRequestTlv(aTlvs, aTlvsLength));
if (aExtraTlvs != nullptr && aExtraTlvsLength > 0)
{
@@ -2264,15 +2265,15 @@ Error Mle::SendDataRequest(const Ip6::Address &aDestination,
if (aDelay)
{
SuccessOrExit(error = AddDelayedResponse(*message, aDestination, aDelay));
SuccessOrExit(error = message->SendAfterDelay(aDestination, aDelay));
Log(kMessageDelay, kTypeDataRequest, aDestination);
}
else
{
SuccessOrExit(error = AppendActiveTimestamp(*message));
SuccessOrExit(error = AppendPendingTimestamp(*message));
SuccessOrExit(error = message->AppendActiveTimestampTlv());
SuccessOrExit(error = message->AppendPendingTimestampTlv());
SuccessOrExit(error = SendMessage(*message, aDestination));
SuccessOrExit(error = message->SendTo(aDestination));
Log(kMessageSend, kTypeDataRequest, aDestination);
if (!IsRxOnWhenIdle())
@@ -2424,7 +2425,7 @@ Error Mle::SendChildUpdateRequest(void)
{
Error error = kErrorNone;
Ip6::Address destination;
Message * message = nullptr;
TxMessage * message = nullptr;
AddressRegistrationMode mode = kAppendAllAddresses;
if (!mParent.IsStateValidOrRestoring())
@@ -2438,25 +2439,25 @@ Error Mle::SendChildUpdateRequest(void)
ScheduleMessageTransmissionTimer();
VerifyOrExit((message = NewMleMessage(kCommandChildUpdateRequest)) != nullptr, error = kErrorNoBufs);
SuccessOrExit(error = AppendMode(*message, mDeviceMode));
SuccessOrExit(error = message->AppendModeTlv(mDeviceMode));
switch (mRole)
{
case kRoleDetached:
mParentRequestChallenge.GenerateRandom();
SuccessOrExit(error = AppendChallenge(*message, mParentRequestChallenge));
SuccessOrExit(error = message->AppendChallengeTlv(mParentRequestChallenge));
mode = kAppendMeshLocalOnly;
break;
case kRoleChild:
SuccessOrExit(error = AppendSourceAddress(*message));
SuccessOrExit(error = AppendLeaderData(*message));
SuccessOrExit(error = AppendTimeout(*message, mTimeout));
SuccessOrExit(error = message->AppendSourceAddressTlv());
SuccessOrExit(error = message->AppendLeaderDataTlv());
SuccessOrExit(error = message->AppendTimeoutTlv(mTimeout));
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (Get<Mac::Mac>().IsCslEnabled())
{
SuccessOrExit(error = AppendCslChannel(*message));
SuccessOrExit(error = AppendCslTimeout(*message));
SuccessOrExit(error = message->AppendCslChannelTlv());
SuccessOrExit(error = message->AppendCslTimeoutTlv());
}
#endif
break;
@@ -2470,11 +2471,11 @@ Error Mle::SendChildUpdateRequest(void)
if (!IsFullThreadDevice())
{
SuccessOrExit(error = AppendAddressRegistration(*message, mode));
SuccessOrExit(error = message->AppendAddressRegistrationTlv(mode));
}
destination.SetToLinkLocalAddress(mParent.GetExtAddress());
SuccessOrExit(error = SendMessage(*message, destination));
SuccessOrExit(error = message->SendTo(destination));
Log(kMessageSend, kTypeChildUpdateRequestOfParent, destination);
@@ -2501,23 +2502,23 @@ Error Mle::SendChildUpdateResponse(const uint8_t *aTlvs, uint8_t aNumTlvs, const
{
Error error = kErrorNone;
Ip6::Address destination;
Message * message;
TxMessage * message;
bool checkAddress = false;
VerifyOrExit((message = NewMleMessage(kCommandChildUpdateResponse)) != nullptr, error = kErrorNoBufs);
SuccessOrExit(error = AppendSourceAddress(*message));
SuccessOrExit(error = AppendLeaderData(*message));
SuccessOrExit(error = message->AppendSourceAddressTlv());
SuccessOrExit(error = message->AppendLeaderDataTlv());
for (int i = 0; i < aNumTlvs; i++)
{
switch (aTlvs[i])
{
case Tlv::kTimeout:
SuccessOrExit(error = AppendTimeout(*message, mTimeout));
SuccessOrExit(error = message->AppendTimeoutTlv(mTimeout));
break;
case Tlv::kStatus:
SuccessOrExit(error = AppendStatus(*message, StatusTlv::kError));
SuccessOrExit(error = message->AppendStatusTlv(StatusTlv::kError));
break;
case Tlv::kAddressRegistration:
@@ -2528,29 +2529,29 @@ Error Mle::SendChildUpdateResponse(const uint8_t *aTlvs, uint8_t aNumTlvs, const
// addresses to register we follow up with a "Child Update
// Request".
SuccessOrExit(error = AppendAddressRegistration(*message, kAppendMeshLocalOnly));
SuccessOrExit(error = message->AppendAddressRegistrationTlv(kAppendMeshLocalOnly));
checkAddress = true;
}
break;
case Tlv::kResponse:
SuccessOrExit(error = AppendResponse(*message, aChallenge));
SuccessOrExit(error = message->AppendResponseTlv(aChallenge));
break;
case Tlv::kLinkFrameCounter:
SuccessOrExit(error = AppendLinkFrameCounter(*message));
SuccessOrExit(error = message->AppendLinkFrameCounterTlv());
break;
case Tlv::kMleFrameCounter:
SuccessOrExit(error = AppendMleFrameCounter(*message));
SuccessOrExit(error = message->AppendMleFrameCounterTlv());
break;
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
case Tlv::kCslTimeout:
if (Get<Mac::Mac>().IsCslEnabled())
{
SuccessOrExit(error = AppendCslTimeout(*message));
SuccessOrExit(error = message->AppendCslTimeoutTlv());
}
break;
#endif
@@ -2558,7 +2559,7 @@ Error Mle::SendChildUpdateResponse(const uint8_t *aTlvs, uint8_t aNumTlvs, const
}
destination.SetToLinkLocalAddress(mParent.GetExtAddress());
SuccessOrExit(error = SendMessage(*message, destination));
SuccessOrExit(error = message->SendTo(destination));
Log(kMessageSend, kTypeChildUpdateResponseOfParent, destination);
@@ -2586,7 +2587,7 @@ void Mle::SendAnnounce(uint8_t aChannel, const Ip6::Address &aDestination, Annou
Error error = kErrorNone;
ChannelTlv channel;
MeshCoP::Timestamp activeTimestamp;
Message * message = nullptr;
TxMessage * message = nullptr;
VerifyOrExit(Get<Mac::Mac>().GetSupportedChannelMask().ContainsChannel(aChannel), error = kErrorInvalidArgs);
VerifyOrExit((message = NewMleMessage(kCommandAnnounce)) != nullptr, error = kErrorNoBufs);
@@ -2607,13 +2608,13 @@ void Mle::SendAnnounce(uint8_t aChannel, const Ip6::Address &aDestination, Annou
break;
case kNormalAnnounce:
SuccessOrExit(error = AppendActiveTimestamp(*message));
SuccessOrExit(error = message->AppendActiveTimestampTlv());
break;
}
SuccessOrExit(error = Tlv::Append<PanIdTlv>(*message, Get<Mac::Mac>().GetPanId()));
SuccessOrExit(error = SendMessage(*message, aDestination));
SuccessOrExit(error = message->SendTo(aDestination));
LogInfo("Send Announce on channel %d", aChannel);
@@ -2647,10 +2648,10 @@ bool Mle::HasMoreChannelsToAnnouce(void) const
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
Error Mle::SendLinkMetricsManagementResponse(const Ip6::Address &aDestination, LinkMetrics::Status aStatus)
{
Error error = kErrorNone;
Message *message;
Tlv tlv;
ot::Tlv statusSubTlv;
Error error = kErrorNone;
TxMessage *message;
Tlv tlv;
ot::Tlv statusSubTlv;
VerifyOrExit((message = NewMleMessage(kCommandLinkMetricsManagementResponse)) != nullptr, error = kErrorNoBufs);
@@ -2663,7 +2664,7 @@ Error Mle::SendLinkMetricsManagementResponse(const Ip6::Address &aDestination, L
SuccessOrExit(error = message->Append(statusSubTlv));
SuccessOrExit(error = message->Append(aStatus));
SuccessOrExit(error = SendMessage(*message, aDestination));
SuccessOrExit(error = message->SendTo(aDestination));
exit:
FreeMessageOnError(message, error);
@@ -2674,9 +2675,9 @@ exit:
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
Error Mle::SendLinkProbe(const Ip6::Address &aDestination, uint8_t aSeriesId, uint8_t *aBuf, uint8_t aLength)
{
Error error = kErrorNone;
Message *message;
Tlv tlv;
Error error = kErrorNone;
TxMessage *message;
Tlv tlv;
VerifyOrExit((message = NewMleMessage(kCommandLinkProbe)) != nullptr, error = kErrorNoBufs);
@@ -2687,7 +2688,7 @@ Error Mle::SendLinkProbe(const Ip6::Address &aDestination, uint8_t aSeriesId, ui
SuccessOrExit(error = message->Append(aSeriesId));
SuccessOrExit(error = message->AppendBytes(aBuf, aLength));
SuccessOrExit(error = SendMessage(*message, aDestination));
SuccessOrExit(error = message->SendTo(aDestination));
exit:
FreeMessageOnError(message, error);
@@ -2787,7 +2788,7 @@ exit:
return error;
}
Error Mle::SendMessage(Message &aMessage, const Ip6::Address &aDestination)
Error Mle::TxMessage::SendTo(const Ip6::Address &aDestination)
{
Error error = kErrorNone;
uint16_t offset = 0;
@@ -2795,11 +2796,11 @@ Error Mle::SendMessage(Message &aMessage, const Ip6::Address &aDestination)
Ip6::MessageInfo messageInfo;
messageInfo.SetPeerAddr(aDestination);
messageInfo.SetSockAddr(mLinkLocal64.GetAddress());
messageInfo.SetSockAddr(Get<Mle>().mLinkLocal64.GetAddress());
messageInfo.SetPeerPort(kUdpPort);
messageInfo.SetHopLimit(kMleHopLimit);
IgnoreError(aMessage.Read(offset, securitySuite));
IgnoreError(Read(offset, securitySuite));
offset += sizeof(securitySuite);
if (securitySuite == k154Security)
@@ -2808,24 +2809,25 @@ Error Mle::SendMessage(Message &aMessage, const Ip6::Address &aDestination)
// Update the fields in the security header
IgnoreError(aMessage.Read(offset, header));
IgnoreError(Read(offset, header));
header.SetFrameCounter(Get<KeyManager>().GetMleFrameCounter());
header.SetKeyId(Get<KeyManager>().GetCurrentKeySequence());
aMessage.Write(offset, header);
Write(offset, header);
offset += sizeof(SecurityHeader);
SuccessOrExit(error = ProcessMessageSecurity(Crypto::AesCcm::kEncrypt, aMessage, messageInfo, offset, header));
SuccessOrExit(
error = Get<Mle>().ProcessMessageSecurity(Crypto::AesCcm::kEncrypt, *this, messageInfo, offset, header));
Get<KeyManager>().IncrementMleFrameCounter();
}
SuccessOrExit(error = mSocket.SendTo(aMessage, messageInfo));
SuccessOrExit(error = Get<Mle>().mSocket.SendTo(*this, messageInfo));
exit:
return error;
}
Error Mle::AddDelayedResponse(Message &aMessage, const Ip6::Address &aDestination, uint16_t aDelay)
Error Mle::TxMessage::SendAfterDelay(const Ip6::Address &aDestination, uint16_t aDelay)
{
Error error = kErrorNone;
DelayedResponseMetadata metadata;
@@ -2833,10 +2835,10 @@ Error Mle::AddDelayedResponse(Message &aMessage, const Ip6::Address &aDestinatio
metadata.mSendTime = TimerMilli::GetNow() + aDelay;
metadata.mDestination = aDestination;
SuccessOrExit(error = metadata.AppendTo(aMessage));
mDelayedResponses.Enqueue(aMessage);
SuccessOrExit(error = metadata.AppendTo(*this));
Get<Mle>().mDelayedResponses.Enqueue(*this);
mDelayedResponseTimer.FireAtIfEarlier(metadata.mSendTime);
Get<Mle>().mDelayedResponseTimer.FireAtIfEarlier(metadata.mSendTime);
exit:
return error;
@@ -3116,7 +3118,7 @@ void Mle::HandleAdvertisement(RxInfo &aRxInfo)
Log(kMessageReceive, kTypeAdvertisement, aRxInfo.mMessageInfo.GetPeerAddr(), sourceAddress);
// Leader Data
SuccessOrExit(error = ReadLeaderData(aRxInfo.mMessage, leaderData));
SuccessOrExit(error = aRxInfo.mMessage.ReadLeaderDataTlv(leaderData));
if (!IsDetached())
{
@@ -3245,7 +3247,7 @@ Error Mle::HandleLeaderData(RxInfo &aRxInfo)
Tlv tlv;
// Leader Data
SuccessOrExit(error = ReadLeaderData(aRxInfo.mMessage, leaderData));
SuccessOrExit(error = aRxInfo.mMessage.ReadLeaderDataTlv(leaderData));
if ((leaderData.GetPartitionId() != mLeaderData.GetPartitionId()) ||
(leaderData.GetWeighting() != mLeaderData.GetWeighting()) || (leaderData.GetLeaderRouterId() != GetLeaderId()))
@@ -3518,7 +3520,7 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo)
VerifyOrExit(version >= OT_THREAD_VERSION_1_1, error = kErrorParse);
// Response
SuccessOrExit(error = ReadResponse(aRxInfo.mMessage, response));
SuccessOrExit(error = aRxInfo.mMessage.ReadResponseTlv(response));
VerifyOrExit(response == mParentRequestChallenge, error = kErrorParse);
aRxInfo.mMessageInfo.GetPeerAddr().GetIid().ConvertToExtAddress(extAddress);
@@ -3529,7 +3531,7 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo)
}
// Leader Data
SuccessOrExit(error = ReadLeaderData(aRxInfo.mMessage, leaderData));
SuccessOrExit(error = aRxInfo.mMessage.ReadLeaderDataTlv(leaderData));
// Link Margin
SuccessOrExit(error = Tlv::Find<LinkMarginTlv>(aRxInfo.mMessage, linkMarginFromTlv));
@@ -3639,7 +3641,7 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo)
}
// Link/MLE Frame Counters
SuccessOrExit(error = ReadFrameCounters(aRxInfo.mMessage, linkFrameCounter, mleFrameCounter));
SuccessOrExit(error = aRxInfo.mMessage.ReadFrameCounterTlvs(linkFrameCounter, mleFrameCounter));
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
@@ -3663,7 +3665,7 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo)
#endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
// Challenge
SuccessOrExit(error = ReadChallenge(aRxInfo.mMessage, mParentCandidateChallenge));
SuccessOrExit(error = aRxInfo.mMessage.ReadChallengeTlv(mParentCandidateChallenge));
mParentCandidate.SetExtAddress(extAddress);
mParentCandidate.SetRloc16(sourceAddress);
@@ -3724,7 +3726,7 @@ void Mle::HandleChildIdResponse(RxInfo &aRxInfo)
VerifyOrExit(RouterIdMatch(sourceAddress, shortAddress), error = kErrorRejected);
// Leader Data
SuccessOrExit(error = ReadLeaderData(aRxInfo.mMessage, leaderData));
SuccessOrExit(error = aRxInfo.mMessage.ReadLeaderDataTlv(leaderData));
// Network Data
error = Tlv::FindTlvOffset(aRxInfo.mMessage, Tlv::kNetworkData, networkDataOffset);
@@ -3852,7 +3854,7 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo)
Log(kMessageReceive, kTypeChildUpdateRequestOfParent, aRxInfo.mMessageInfo.GetPeerAddr(), sourceAddress);
// Challenge
switch (ReadChallenge(aRxInfo.mMessage, challenge))
switch (aRxInfo.mMessage.ReadChallengeTlv(challenge))
{
case kErrorNone:
tlvs[numTlvs++] = Tlv::kResponse;
@@ -3906,7 +3908,7 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo)
}
// TLV Request
switch (FindTlvRequest(aRxInfo.mMessage, requestedTlvs))
switch (aRxInfo.mMessage.ReadTlvRequestTlv(requestedTlvs))
{
case kErrorNone:
for (uint8_t i = 0; i < requestedTlvs.mNumTlvs; i++)
@@ -3958,7 +3960,7 @@ void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo)
switch (mRole)
{
case kRoleDetached:
SuccessOrExit(error = ReadResponse(aRxInfo.mMessage, response));
SuccessOrExit(error = aRxInfo.mMessage.ReadResponseTlv(response));
VerifyOrExit(response == mParentRequestChallenge, error = kErrorSecurity);
break;
@@ -3985,7 +3987,7 @@ void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo)
switch (mRole)
{
case kRoleDetached:
SuccessOrExit(error = ReadFrameCounters(aRxInfo.mMessage, linkFrameCounter, mleFrameCounter));
SuccessOrExit(error = aRxInfo.mMessage.ReadFrameCounterTlvs(linkFrameCounter, mleFrameCounter));
mParent.GetLinkFrameCounters().SetAll(linkFrameCounter);
mParent.SetLinkAckFrameCounter(linkFrameCounter);
@@ -4674,9 +4676,9 @@ const char *Mle::ReattachStateToString(ReattachState aState)
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
Error Mle::SendLinkMetricsManagementRequest(const Ip6::Address &aDestination, const uint8_t *aSubTlvs, uint8_t aLength)
{
Error error = kErrorNone;
Message *message;
Tlv tlv;
Error error = kErrorNone;
TxMessage *message;
Tlv tlv;
VerifyOrExit((message = NewMleMessage(kCommandLinkMetricsManagementRequest)) != nullptr, error = kErrorNoBufs);
@@ -4687,7 +4689,7 @@ Error Mle::SendLinkMetricsManagementRequest(const Ip6::Address &aDestination, co
SuccessOrExit(error = message->AppendBytes(&tlv, sizeof(tlv)));
SuccessOrExit(error = message->AppendBytes(aSubTlvs, aLength));
SuccessOrExit(error = SendMessage(*message, aDestination));
SuccessOrExit(error = message->SendTo(aDestination));
exit:
FreeMessageOnError(message, error);
+420 -395
View File
@@ -822,7 +822,7 @@ protected:
static constexpr uint16_t kMleMaxResponseDelay = 1000u; ///< Max delay before responding to a multicast request.
/**
* This enumeration type is used in `AppendAddressRegistration()` to determine which addresses to include in the
* This enumeration type is used in `AppendAddressRegistrationTlv()` to determine which addresses to include in the
* appended Address Registration TLV.
*
*/
@@ -941,6 +941,421 @@ protected:
uint8_t mNumTlvs; ///< Number of TLVs in the array.
};
/**
* This class represents an MLE Tx message.
*
*/
class TxMessage : public Message
{
public:
/**
* This method appends a Source Address TLV to the message.
*
* @retval kErrorNone Successfully appended the Source Address TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Source Address TLV.
*
*/
Error AppendSourceAddressTlv(void);
/**
* This method appends a Mode TLV to the message.
*
* @param[in] aMode The Device Mode.
*
* @retval kErrorNone Successfully appended the Mode TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Mode TLV.
*
*/
Error AppendModeTlv(DeviceMode aMode);
/**
* This method appends a Timeout TLV to the message.
*
* @param[in] aTimeout The Timeout value.
*
* @retval kErrorNone Successfully appended the Timeout TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Timeout TLV.
*
*/
Error AppendTimeoutTlv(uint32_t aTimeout);
/**
* This method appends a Challenge TLV to the message.
*
* @param[in] aChallenge A pointer to the Challenge value.
* @param[in] aChallengeLength The length of the Challenge value in bytes.
*
* @retval kErrorNone Successfully appended the Challenge TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Challenge TLV.
*
*/
Error AppendChallengeTlv(const uint8_t *aChallenge, uint8_t aChallengeLength);
/**
* This method appends a Challenge TLV to the message.
*
* @param[in] aChallenge A reference to the Challenge data.
*
* @retval kErrorNone Successfully appended the Challenge TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Challenge TLV.
*
*/
Error AppendChallengeTlv(const Challenge &aChallenge);
/**
* This method appends a Response TLV to the message.
*
* @param[in] aResponse A reference to the Response data.
*
* @retval kErrorNone Successfully appended the Response TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Response TLV.
*
*/
Error AppendResponseTlv(const Challenge &aResponse);
/**
* This method appends a Link Frame Counter TLV to the message.
*
* @retval kErrorNone Successfully appended the Link Frame Counter TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Link Frame Counter TLV.
*
*/
Error AppendLinkFrameCounterTlv(void);
/**
* This method appends an MLE Frame Counter TLV to the message.
*
* @retval kErrorNone Successfully appended the Frame Counter TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the MLE Frame Counter TLV.
*
*/
Error AppendMleFrameCounterTlv(void);
/**
* This method appends an Address16 TLV to the message.
*
* @param[in] aRloc16 The RLOC16 value.
*
* @retval kErrorNone Successfully appended the Address16 TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Address16 TLV.
*
*/
Error AppendAddress16Tlv(uint16_t aRloc16);
/**
* This method appends a Network Data TLV to the message.
*
* @param[in] aType The Network Data type to append, full set or stable subset.
*
* @retval kErrorNone Successfully appended the Network Data TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Network Data TLV.
*
*/
Error AppendNetworkDataTlv(NetworkData::Type aType);
/**
* This method appends a TLV Request TLV to the message.
*
* @param[in] aTlvs A pointer to the list of TLV types.
* @param[in] aTlvsLength The number of TLV types in @p aTlvs
*
* @retval kErrorNone Successfully appended the TLV Request TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the TLV Request TLV.
*
*/
Error AppendTlvRequestTlv(const uint8_t *aTlvs, uint8_t aTlvsLength);
/**
* This method appends a Leader Data TLV to the message.
*
* @retval kErrorNone Successfully appended the Leader Data TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Leader Data TLV.
*
*/
Error AppendLeaderDataTlv(void);
/**
* This method appends a Scan Mask TLV to th message.
*
* @param[in] aScanMask The Scan Mask value.
*
* @retval kErrorNone Successfully appended the Scan Mask TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Scan Mask TLV.
*
*/
Error AppendScanMaskTlv(uint8_t aScanMask);
/**
* This method appends a Status TLV to the message.
*
* @param[in] aStatus The Status value.
*
* @retval kErrorNone Successfully appended the Status TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Status TLV.
*
*/
Error AppendStatusTlv(StatusTlv::Status aStatus);
/**
* This method appends a Link Margin TLV to the message.
*
* @param[in] aLinkMargin The Link Margin value.
*
* @retval kErrorNone Successfully appended the Link Margin TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Link Margin TLV.
*
*/
Error AppendLinkMarginTlv(uint8_t aLinkMargin);
/**
* This method appends a Version TLV to the message.
*
* @retval kErrorNone Successfully appended the Version TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Version TLV.
*
*/
Error AppendVersionTlv(void);
/**
* This method appends an Address Registration TLV to the message.
*
* @param[in] aMode Determines which addresses to include in the TLV (see `AddressRegistrationMode`).
*
* @retval kErrorNone Successfully appended the Address Registration TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Address Registration TLV.
*
*/
Error AppendAddressRegistrationTlv(AddressRegistrationMode aMode = kAppendAllAddresses);
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
/**
* This method appends a Time Request TLV to the message.
*
* @retval kErrorNone Successfully appended the Time Request TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Time Request TLV.
*
*/
Error AppendTimeRequestTlv(void);
/**
* This method appends a Time Parameter TLV to the message.
*
* @retval kErrorNone Successfully appended the Time Parameter TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Time Parameter TLV.
*
*/
Error AppendTimeParameterTlv(void);
#endif
/**
* This method appends a XTAL Accuracy TLV to the message.
*
* @retval kErrorNone Successfully appended the XTAL Accuracy TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the XTAl Accuracy TLV.
*
*/
Error AppendXtalAccuracyTlv(void);
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
/**
* This method appends a CSL Channel TLV to the message.
*
* @retval kErrorNone Successfully appended the CSL Channel TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the CSL Channel TLV.
*
*/
Error AppendCslChannelTlv(void);
/**
* This method appends a CSL Sync Timeout TLV to the message.
*
* @retval kErrorNone Successfully appended the CSL Timeout TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the CSL Timeout TLV.
*
*/
Error AppendCslTimeoutTlv(void);
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
/**
* This method appends a CSL Clock Accuracy TLV to the message.
*
* @retval kErrorNone Successfully appended the CSL Accuracy TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the CSL Accuracy TLV.
*
*/
Error AppendCslClockAccuracyTlv(void);
#endif
/**
* This method appends a Active Timestamp TLV to the message.
*
* @retval kErrorNone Successfully appended the Active Timestamp TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Active Timestamp TLV.
*
*/
Error AppendActiveTimestampTlv(void);
/**
* This method appends a Pending Timestamp TLV to the message.
*
* @retval kErrorNone Successfully appended the Pending Timestamp TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Pending Timestamp TLV.
*
*/
Error AppendPendingTimestampTlv(void);
#if OPENTHREAD_FTD
/**
* This method appends a Route TLV to the message.
*
* @param[in] aNeighbor A pointer to the intended destination (can be `nullptr`).
*
* @retval kErrorNone Successfully appended the Route TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Route TLV.
*
*/
Error AppendRouteTlv(Neighbor *aNeighbor = nullptr);
/**
* This method appends a Active Dataset TLV to the message.
*
* @retval kErrorNone Successfully appended the Active Dataset TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Active Dataset TLV.
*
*/
Error AppendActiveDatasetTlv(void);
/**
* This method appends a Pending Dataset TLV to the message.
*
* @retval kErrorNone Successfully appended the Pending Dataset TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Pending Dataset TLV.
*
*/
Error AppendPendingDatasetTlv(void);
/**
* This method appends a Connectivity TLV to the message.
*
* @retval kErrorNone Successfully appended the Connectivity TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Connectivity TLV.
*
*/
Error AppendConnectivityTlv(void);
/**
* This method appends a Address Registration TLV to the message with addresses from a given child.
*
* @param[in] aChild The child to include its list of addresses in the Address Registration TLV.
*
* @retval kErrorNone Successfully appended the Connectivity TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Connectivity TLV.
*
*/
Error AppendAddresseRegisterationTlv(Child &aChild);
#endif // OPENTHREAD_FTD
/**
* This method submits the MLE message to the UDP socket to be sent.
*
* @param[in] aDestination A reference to the IPv6 address of the destination.
*
* @retval kErrorNone Successfully submitted the MLE message.
* @retval kErrorNoBufs Insufficient buffers to form the rest of the MLE message.
*
*/
Error SendTo(const Ip6::Address &aDestination);
/**
* This method enqueues the message to be sent after a given delay.
*
* @param[in] aDestination The IPv6 address of the recipient of the message.
* @param[in] aDelay The delay in milliseconds before transmission of the message.
*
* @retval kErrorNone Successfully queued the message to transmit after the delay.
* @retval kErrorNoBufs Insufficient buffers to queue the message.
*
*/
Error SendAfterDelay(const Ip6::Address &aDestination, uint16_t aDelay);
};
/**
* This class represents an MLE Rx message.
*
*/
class RxMessage : public Message
{
public:
/**
* This method reads Challenge TLV from the message.
*
* @param[out] aChallenge A reference to the Challenge data where to output the read value.
*
* @retval kErrorNone Successfully read the Challenge TLV.
* @retval kErrorNotFound Challenge TLV was not found in the message.
* @retval kErrorParse Challenge TLV was found but could not be parsed.
*
*/
Error ReadChallengeTlv(Challenge &aChallenge) const;
/**
* This method reads Response TLV from the message.
*
* @param[out] aResponse A reference to the Response data where to output the read value.
*
* @retval kErrorNone Successfully read the Response TLV.
* @retval kErrorNotFound Response TLV was not found in the message.
* @retval kErrorParse Response TLV was found but could not be parsed.
*
*/
Error ReadResponseTlv(Challenge &aResponse) const;
/**
* This method reads Link and MLE Frame Counters from the message.
*
* Link Frame Counter TLV must be present in the message and its value is read into @p aLinkFrameCounter. If MLE
* Frame Counter TLV is present in the message, its value is read into @p aMleFrameCounter. If the MLE Frame
* Counter TLV is not present in the message, then @p aMleFrameCounter is set to the same value as
* @p aLinkFrameCounter.
*
* @param[out] aLinkFrameCounter A reference to an `uint32_t` to output the Link Frame Counter.
* @param[out] aMleFrameCounter A reference to an `uint32_t` to output the MLE Frame Counter.
*
* @retval kErrorNone Successfully read the counters.
* @retval kErrorNotFound Link Frame Counter TLV was not found in the message.
* @retval kErrorParse TLVs are not well-formed.
*
*/
Error ReadFrameCounterTlvs(uint32_t &aLinkFrameCounter, uint32_t &aMleFrameCounter) const;
/**
* This method reads TLV Request TLV from the message.
*
* @param[out] aRequestedTlvs A reference to output the read list of requested TLVs.
*
* @retval kErrorNone Successfully read the TLV.
* @retval kErrorNotFound TLV was not found in the message.
* @retval kErrorParse TLV was found but could not be parsed.
*
*/
Error ReadTlvRequestTlv(RequestedTlvs &aRequestedTlvs) const;
/**
* This method reads Leader Data TLV from a message.
*
* @param[out] aLeaderData A reference to output the Leader Data.
*
* @retval kErrorNone Successfully read the TLV.
* @retval kErrorNotFound TLV was not found in the message.
* @retval kErrorParse TLV was found but could not be parsed.
*
*/
Error ReadLeaderDataTlv(LeaderData &aLeaderData) const;
private:
Error ReadChallengeOrResponse(uint8_t aTlvType, Challenge &aBuffer) const;
};
/**
* This structure represents a received MLE message containing additional information about the message (e.g.
* key sequence, neighbor from which it was received).
@@ -956,7 +1371,7 @@ protected:
*
*/
RxInfo(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
: mMessage(aMessage)
: mMessage(static_cast<RxMessage &>(aMessage))
, mMessageInfo(aMessageInfo)
, mFrameCounter(0)
, mKeySequence(0)
@@ -964,7 +1379,7 @@ protected:
{
}
Message & mMessage; ///< The MLE message.
RxMessage & mMessage; ///< The MLE message.
const Ip6::MessageInfo &mMessageInfo; ///< The `MessageInfo` associated with the message.
uint32_t mFrameCounter; ///< The frame counter from aux security header.
uint32_t mKeySequence; ///< The key sequence from the aux security header.
@@ -979,7 +1394,7 @@ protected:
* @returns A pointer to the message or `nullptr` if insufficient message buffers are available.
*
*/
Message *NewMleMessage(Command aCommand);
TxMessage *NewMleMessage(Command aCommand);
/**
* This method sets the device role.
@@ -1005,370 +1420,6 @@ protected:
*/
void SetAttachState(AttachState aState);
/**
* This method appends a Source Address TLV to a message.
*
* @param[in] aMessage A reference to the message.
*
* @retval kErrorNone Successfully appended the Source Address TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Source Address TLV.
*
*/
Error AppendSourceAddress(Message &aMessage) const;
/**
* This method appends a Mode TLV to a message.
*
* @param[in] aMessage A reference to the message.
* @param[in] aMode The Device Mode.
*
* @retval kErrorNone Successfully appended the Mode TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Mode TLV.
*
*/
Error AppendMode(Message &aMessage, DeviceMode aMode);
/**
* This method appends a Timeout TLV to a message.
*
* @param[in] aMessage A reference to the message.
* @param[in] aTimeout The Timeout value.
*
* @retval kErrorNone Successfully appended the Timeout TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Timeout TLV.
*
*/
Error AppendTimeout(Message &aMessage, uint32_t aTimeout);
/**
* This method appends a Challenge TLV to a message.
*
* @param[in] aMessage A reference to the message.
* @param[in] aChallenge A pointer to the Challenge value.
* @param[in] aChallengeLength The length of the Challenge value in bytes.
*
* @retval kErrorNone Successfully appended the Challenge TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Challenge TLV.
*
*/
Error AppendChallenge(Message &aMessage, const uint8_t *aChallenge, uint8_t aChallengeLength);
/**
* This method appends a Challenge TLV to a message.
*
* @param[in] aMessage A reference to the message.
* @param[in] aChallenge A reference to the Challenge data.
*
* @retval kErrorNone Successfully appended the Challenge TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Challenge TLV.
*
*/
Error AppendChallenge(Message &aMessage, const Challenge &aChallenge);
/**
* This method reads Challenge TLV from a message.
*
* @param[in] aMessage A reference to the message.
* @param[out] aChallenge A reference to the Challenge data where to output the read value.
*
* @retval kErrorNone Successfully read the Challenge TLV.
* @retval kErrorNotFound Challenge TLV was not found in the message.
* @retval kErrorParse Challenge TLV was found but could not be parsed.
*
*/
Error ReadChallenge(const Message &aMessage, Challenge &aChallenge);
/**
* This method appends a Response TLV to a message.
*
* @param[in] aMessage A reference to the message.
* @param[in] aResponse A reference to the Response data.
*
* @retval kErrorNone Successfully appended the Response TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Response TLV.
*
*/
Error AppendResponse(Message &aMessage, const Challenge &aResponse);
/**
* This method reads Response TLV from a message.
*
* @param[in] aMessage A reference to the message.
* @param[out] aResponse A reference to the Response data where to output the read value.
*
* @retval kErrorNone Successfully read the Response TLV.
* @retval kErrorNotFound Response TLV was not found in the message.
* @retval kErrorParse Response TLV was found but could not be parsed.
*
*/
Error ReadResponse(const Message &aMessage, Challenge &aResponse);
/**
* This method appends a Link Frame Counter TLV to a message.
*
* @param[in] aMessage A reference to the message.
*
* @retval kErrorNone Successfully appended the Link Frame Counter TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Link Frame Counter TLV.
*
*/
Error AppendLinkFrameCounter(Message &aMessage);
/**
* This method reads Link and MLE Frame Counters from a message.
*
* Link Frame Counter TLV must be present in the message and its value is read into @p aLinkFrameCounter. If MLE
* Frame Counter TLV is present in the message, its value is read into @p aMleFrameCounter. If the MLE Frame
* Counter TLV is not present in the message, then @p aMleFrameCounter is set to same value as @p aLinkFrameCounter.
*
* @param[in] aMessage A reference to the message to read from.
* @param[out] aLinkFrameCounter A reference to an `uint32_t` to output the Link Frame Counter.
* @param[out] aMleFrameCounter A reference to an `uint32_t` to output the MLE Frame Counter.
*
* @retval kErrorNone Successfully read the counters.
* @retval kErrorNotFound Link Frame Counter TLV was not found in the message.
* @retval kErrorParse TLVs are not well-formed.
*
*/
Error ReadFrameCounters(const Message &aMessage, uint32_t &aLinkFrameCounter, uint32_t &aMleFrameCounter) const;
/**
* This method appends an MLE Frame Counter TLV to a message.
*
* @param[in] aMessage A reference to the message.
*
* @retval kErrorNone Successfully appended the Frame Counter TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the MLE Frame Counter TLV.
*
*/
Error AppendMleFrameCounter(Message &aMessage);
/**
* This method appends an Address16 TLV to a message.
*
* @param[in] aMessage A reference to the message.
* @param[in] aRloc16 The RLOC16 value.
*
* @retval kErrorNone Successfully appended the Address16 TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Address16 TLV.
*
*/
Error AppendAddress16(Message &aMessage, uint16_t aRloc16);
/**
* This method appends a Network Data TLV to the message.
*
* @param[in] aMessage A reference to the message.
* @param[in] aType The Network Data type to append, full set or stable subset.
*
* @retval kErrorNone Successfully appended the Network Data TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Network Data TLV.
*
*/
Error AppendNetworkData(Message &aMessage, NetworkData::Type aType);
/**
* This method appends a TLV Request TLV to a message.
*
* @param[in] aMessage A reference to the message.
* @param[in] aTlvs A pointer to the list of TLV types.
* @param[in] aTlvsLength The number of TLV types in @p aTlvs
*
* @retval kErrorNone Successfully appended the TLV Request TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the TLV Request TLV.
*
*/
Error AppendTlvRequest(Message &aMessage, const uint8_t *aTlvs, uint8_t aTlvsLength);
/**
* This method reads TLV Request TLV from a message.
*
* @param[in] aMessage A reference to the message.
* @param[out] aRequestedTlvs A reference to output the read list of requested TLVs.
*
* @retval kErrorNone Successfully read the TLV.
* @retval kErrorNotFound TLV was not found in the message.
* @retval kErrorParse TLV was found but could not be parsed.
*
*/
Error FindTlvRequest(const Message &aMessage, RequestedTlvs &aRequestedTlvs);
/**
* This method appends a Leader Data TLV to a message.
*
* @param[in] aMessage A reference to the message.
*
* @retval kErrorNone Successfully appended the Leader Data TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Leader Data TLV.
*
*/
Error AppendLeaderData(Message &aMessage);
/**
* This method reads Leader Data TLV from a message.
*
* @param[in] aMessage A reference to the message.
* @param[out] aLeaderData A reference to output the Leader Data.
*
* @retval kErrorNone Successfully read the TLV.
* @retval kErrorNotFound TLV was not found in the message.
* @retval kErrorParse TLV was found but could not be parsed.
*
*/
Error ReadLeaderData(const Message &aMessage, LeaderData &aLeaderData);
/**
* This method appends a Scan Mask TLV to a message.
*
* @param[in] aMessage A reference to the message.
* @param[in] aScanMask The Scan Mask value.
*
* @retval kErrorNone Successfully appended the Scan Mask TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Scan Mask TLV.
*
*/
Error AppendScanMask(Message &aMessage, uint8_t aScanMask);
/**
* This method appends a Status TLV to a message.
*
* @param[in] aMessage A reference to the message.
* @param[in] aStatus The Status value.
*
* @retval kErrorNone Successfully appended the Status TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Status TLV.
*
*/
Error AppendStatus(Message &aMessage, StatusTlv::Status aStatus);
/**
* This method appends a Link Margin TLV to a message.
*
* @param[in] aMessage A reference to the message.
* @param[in] aLinkMargin The Link Margin value.
*
* @retval kErrorNone Successfully appended the Link Margin TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Link Margin TLV.
*
*/
Error AppendLinkMargin(Message &aMessage, uint8_t aLinkMargin);
/**
* This method appends a Version TLV to a message.
*
* @param[in] aMessage A reference to the message.
*
* @retval kErrorNone Successfully appended the Version TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Version TLV.
*
*/
Error AppendVersion(Message &aMessage);
/**
* This method appends an Address Registration TLV to a message.
*
* @param[in] aMessage A reference to the message.
* @param[in] aMode Determines which addresses to include in the TLV (see `AddressRegistrationMode`).
*
* @retval kErrorNone Successfully appended the Address Registration TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Address Registration TLV.
*
*/
Error AppendAddressRegistration(Message &aMessage, AddressRegistrationMode aMode = kAppendAllAddresses);
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
/**
* This method appends a Time Request TLV to a message.
*
* @param[in] aMessage A reference to the message.
*
* @retval kErrorNone Successfully appended the Time Request TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Time Request TLV.
*
*/
Error AppendTimeRequest(Message &aMessage);
/**
* This method appends a Time Parameter TLV to a message.
*
* @param[in] aMessage A reference to the message.
*
* @retval kErrorNone Successfully appended the Time Parameter TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Time Parameter TLV.
*
*/
Error AppendTimeParameter(Message &aMessage);
/**
* This method appends a XTAL Accuracy TLV to a message.
*
* @param[in] aMessage A reference to the message.
*
* @retval kErrorNone Successfully appended the XTAL Accuracy TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the XTAl Accuracy TLV.
*
*/
Error AppendXtalAccuracy(Message &aMessage);
#endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
#if (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE) || OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
/**
* This method appends a CSL Channel TLV to a message.
*
* @param[in] aMessage A reference to the message.
*
* @retval kErrorNone Successfully appended the CSL Channel TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the CSL Channel TLV.
*
*/
Error AppendCslChannel(Message &aMessage);
/**
* This method appends a CSL Sync Timeout TLV to a message.
*
* @param[in] aMessage A reference to the message.
*
* @retval kErrorNone Successfully appended the CSL Timeout TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the CSL Timeout TLV.
*
*/
Error AppendCslTimeout(Message &aMessage);
#endif // (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE) || OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
/**
* This method appends a CSL Clock Accuracy TLV to a message.
*
* @param[in] aMessage A reference to the message.
*
* @retval kErrorNone Successfully appended the CSL Accuracy TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the CSL Accuracy TLV.
*/
Error AppendCslClockAccuracy(Message &aMessage);
#endif
/**
* This method appends a Active Timestamp TLV to a message.
*
* @param[in] aMessage A reference to the message.
*
* @retval kErrorNone Successfully appended the Active Timestamp TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Active Timestamp TLV.
*
*/
Error AppendActiveTimestamp(Message &aMessage);
/**
* This method appends a Pending Timestamp TLV to a message.
*
* @param[in] aMessage A reference to the message.
*
* @retval kErrorNone Successfully appended the Pending Timestamp TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Pending Timestamp TLV.
*
*/
Error AppendPendingTimestamp(Message &aMessage);
/**
* This method checks if the destination is reachable.
*
@@ -1434,18 +1485,6 @@ protected:
*/
Error SendChildUpdateResponse(const uint8_t *aTlvs, uint8_t aNumTlvs, const Challenge &aChallenge);
/**
* This method submits an MLE message to the UDP socket.
*
* @param[in] aMessage A reference to the message.
* @param[in] aDestination A reference to the IPv6 address of the destination.
*
* @retval kErrorNone Successfully submitted the MLE message.
* @retval kErrorNoBufs Insufficient buffers to form the rest of the MLE message.
*
*/
Error SendMessage(Message &aMessage, const Ip6::Address &aDestination);
/**
* This method sets the RLOC16 assigned to the Thread interface.
*
@@ -1476,19 +1515,6 @@ protected:
*/
void SetLeaderData(uint32_t aPartitionId, uint8_t aWeighting, uint8_t aLeaderRouterId);
/**
* This method adds a message to the message queue. The queued message will be transmitted after given delay.
*
* @param[in] aMessage The message to transmit after given delay.
* @param[in] aDestination The IPv6 address of the recipient of the message.
* @param[in] aDelay The delay in milliseconds before transmission of the message.
*
* @retval kErrorNone Successfully queued the message to transmit after the delay.
* @retval kErrorNoBufs Insufficient buffers to queue the message.
*
*/
Error AddDelayedResponse(Message &aMessage, const Ip6::Address &aDestination, uint16_t aDelay);
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
/**
* This static method emits a log message with an IPv6 address.
@@ -1763,13 +1789,12 @@ private:
void HandleAttachTimer(void);
static void HandleDelayedResponseTimer(Timer &aTimer);
void HandleDelayedResponseTimer(void);
void SendDelayedResponse(Message &aMessage, const DelayedResponseMetadata &aMetadata);
void SendDelayedResponse(TxMessage &aMessage, const DelayedResponseMetadata &aMetadata);
static void HandleMessageTransmissionTimer(Timer &aTimer);
void HandleMessageTransmissionTimer(void);
static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
void ScheduleMessageTransmissionTimer(void);
Error ReadChallengeOrResponse(const Message &aMessage, uint8_t aTlvType, Challenge &aBuffer);
void HandleAdvertisement(RxInfo &aRxInfo);
void HandleChildIdResponse(RxInfo &aRxInfo);
+138 -137
View File
@@ -481,7 +481,7 @@ void MleRouter::SendAdvertisement(void)
{
Error error = kErrorNone;
Ip6::Address destination;
Message * message = nullptr;
TxMessage * message = nullptr;
// Suppress MLE Advertisements when trying to attach to a better partition.
//
@@ -497,8 +497,8 @@ void MleRouter::SendAdvertisement(void)
VerifyOrExit(!mAddressSolicitPending);
VerifyOrExit((message = NewMleMessage(kCommandAdvertisement)) != nullptr, error = kErrorNoBufs);
SuccessOrExit(error = AppendSourceAddress(*message));
SuccessOrExit(error = AppendLeaderData(*message));
SuccessOrExit(error = message->AppendSourceAddressTlv());
SuccessOrExit(error = message->AppendLeaderDataTlv());
switch (mRole)
{
@@ -512,12 +512,12 @@ void MleRouter::SendAdvertisement(void)
case kRoleRouter:
case kRoleLeader:
SuccessOrExit(error = AppendRoute(*message));
SuccessOrExit(error = message->AppendRouteTlv());
break;
}
destination.SetToLinkLocalAllNodesMulticast();
SuccessOrExit(error = SendMessage(*message, destination));
SuccessOrExit(error = message->SendTo(destination));
Log(kMessageSend, kTypeAdvertisement, destination);
@@ -532,13 +532,13 @@ Error MleRouter::SendLinkRequest(Neighbor *aNeighbor)
static const uint8_t routerTlvs[] = {Tlv::kLinkMargin};
static const uint8_t validNeighborTlvs[] = {Tlv::kLinkMargin, Tlv::kRoute};
Error error = kErrorNone;
Message * message;
TxMessage * message;
Ip6::Address destination;
destination.Clear();
VerifyOrExit((message = NewMleMessage(kCommandLinkRequest)) != nullptr, error = kErrorNoBufs);
SuccessOrExit(error = AppendVersion(*message));
SuccessOrExit(error = message->AppendVersionTlv());
switch (mRole)
{
@@ -547,32 +547,32 @@ Error MleRouter::SendLinkRequest(Neighbor *aNeighbor)
OT_UNREACHABLE_CODE(break);
case kRoleDetached:
SuccessOrExit(error = AppendTlvRequest(*message, detachedTlvs, sizeof(detachedTlvs)));
SuccessOrExit(error = message->AppendTlvRequestTlv(detachedTlvs, sizeof(detachedTlvs)));
break;
case kRoleChild:
SuccessOrExit(error = AppendSourceAddress(*message));
SuccessOrExit(error = AppendLeaderData(*message));
SuccessOrExit(error = message->AppendSourceAddressTlv());
SuccessOrExit(error = message->AppendLeaderDataTlv());
break;
case kRoleRouter:
case kRoleLeader:
if (aNeighbor == nullptr || !aNeighbor->IsStateValid())
{
SuccessOrExit(error = AppendTlvRequest(*message, routerTlvs, sizeof(routerTlvs)));
SuccessOrExit(error = message->AppendTlvRequestTlv(routerTlvs, sizeof(routerTlvs)));
}
else
{
SuccessOrExit(error = AppendTlvRequest(*message, validNeighborTlvs, sizeof(validNeighborTlvs)));
SuccessOrExit(error = message->AppendTlvRequestTlv(validNeighborTlvs, sizeof(validNeighborTlvs)));
}
SuccessOrExit(error = AppendSourceAddress(*message));
SuccessOrExit(error = AppendLeaderData(*message));
SuccessOrExit(error = message->AppendSourceAddressTlv());
SuccessOrExit(error = message->AppendLeaderDataTlv());
break;
}
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
SuccessOrExit(error = AppendTimeRequest(*message));
SuccessOrExit(error = message->AppendTimeRequestTlv());
#endif
if (aNeighbor == nullptr)
@@ -580,7 +580,7 @@ Error MleRouter::SendLinkRequest(Neighbor *aNeighbor)
mChallenge.GenerateRandom();
mChallengeTimeout = (((2 * kMaxResponseDelay) + kStateUpdatePeriod - 1) / kStateUpdatePeriod);
SuccessOrExit(error = AppendChallenge(*message, mChallenge));
SuccessOrExit(error = message->AppendChallengeTlv(mChallenge));
destination.SetToLinkLocalAllRoutersMulticast();
}
else
@@ -588,20 +588,21 @@ Error MleRouter::SendLinkRequest(Neighbor *aNeighbor)
if (!aNeighbor->IsStateValid())
{
aNeighbor->GenerateChallenge();
SuccessOrExit(error = AppendChallenge(*message, aNeighbor->GetChallenge(), aNeighbor->GetChallengeSize()));
SuccessOrExit(error =
message->AppendChallengeTlv(aNeighbor->GetChallenge(), aNeighbor->GetChallengeSize()));
}
else
{
Challenge challenge;
challenge.GenerateRandom();
SuccessOrExit(error = AppendChallenge(*message, challenge));
SuccessOrExit(error = message->AppendChallengeTlv(challenge));
}
destination.SetToLinkLocalAddress(aNeighbor->GetExtAddress());
}
SuccessOrExit(error = SendMessage(*message, destination));
SuccessOrExit(error = message->SendTo(destination));
Log(kMessageSend, kTypeLinkRequest, destination);
@@ -627,14 +628,14 @@ void MleRouter::HandleLinkRequest(RxInfo &aRxInfo)
VerifyOrExit(!IsAttaching(), error = kErrorInvalidState);
// Challenge
SuccessOrExit(error = ReadChallenge(aRxInfo.mMessage, challenge));
SuccessOrExit(error = aRxInfo.mMessage.ReadChallengeTlv(challenge));
// Version
SuccessOrExit(error = Tlv::Find<VersionTlv>(aRxInfo.mMessage, version));
VerifyOrExit(version >= OT_THREAD_VERSION_1_1, error = kErrorParse);
// Leader Data
switch (ReadLeaderData(aRxInfo.mMessage, leaderData))
switch (aRxInfo.mMessage.ReadLeaderDataTlv(leaderData))
{
case kErrorNone:
VerifyOrExit(leaderData.GetPartitionId() == mLeaderData.GetPartitionId(), error = kErrorInvalidState);
@@ -689,7 +690,7 @@ void MleRouter::HandleLinkRequest(RxInfo &aRxInfo)
}
// TLV Request
switch (FindTlvRequest(aRxInfo.mMessage, requestedTlvs))
switch (aRxInfo.mMessage.ReadTlvRequestTlv(requestedTlvs))
{
case kErrorNone:
break;
@@ -727,28 +728,28 @@ Error MleRouter::SendLinkAccept(const Ip6::MessageInfo &aMessageInfo,
{
Error error = kErrorNone;
static const uint8_t routerTlvs[] = {Tlv::kLinkMargin};
Message * message;
TxMessage * message;
Command command;
uint8_t linkMargin;
command = (aNeighbor == nullptr || aNeighbor->IsStateValid()) ? kCommandLinkAccept : kCommandLinkAcceptAndRequest;
VerifyOrExit((message = NewMleMessage(command)) != nullptr, error = kErrorNoBufs);
SuccessOrExit(error = AppendVersion(*message));
SuccessOrExit(error = AppendSourceAddress(*message));
SuccessOrExit(error = AppendResponse(*message, aChallenge));
SuccessOrExit(error = AppendLinkFrameCounter(*message));
SuccessOrExit(error = AppendMleFrameCounter(*message));
SuccessOrExit(error = message->AppendVersionTlv());
SuccessOrExit(error = message->AppendSourceAddressTlv());
SuccessOrExit(error = message->AppendResponseTlv(aChallenge));
SuccessOrExit(error = message->AppendLinkFrameCounterTlv());
SuccessOrExit(error = message->AppendMleFrameCounterTlv());
// always append a link margin, regardless of whether or not it was requested
linkMargin = LinkQualityInfo::ConvertRssToLinkMargin(Get<Mac::Mac>().GetNoiseFloor(),
aMessageInfo.GetThreadLinkInfo()->GetRss());
SuccessOrExit(error = AppendLinkMargin(*message, linkMargin));
SuccessOrExit(error = message->AppendLinkMarginTlv(linkMargin));
if (aNeighbor != nullptr && IsActiveRouter(aNeighbor->GetRloc16()))
{
SuccessOrExit(error = AppendLeaderData(*message));
SuccessOrExit(error = message->AppendLeaderDataTlv());
}
for (uint8_t i = 0; i < aRequestedTlvs.mNumTlvs; i++)
@@ -756,12 +757,12 @@ Error MleRouter::SendLinkAccept(const Ip6::MessageInfo &aMessageInfo,
switch (aRequestedTlvs.mTlvs[i])
{
case Tlv::kRoute:
SuccessOrExit(error = AppendRoute(*message, aNeighbor));
SuccessOrExit(error = message->AppendRouteTlv(aNeighbor));
break;
case Tlv::kAddress16:
VerifyOrExit(aNeighbor != nullptr, error = kErrorDrop);
SuccessOrExit(error = AppendAddress16(*message, aNeighbor->GetRloc16()));
SuccessOrExit(error = message->AppendAddress16Tlv(aNeighbor->GetRloc16()));
break;
case Tlv::kLinkMargin:
@@ -776,8 +777,8 @@ Error MleRouter::SendLinkAccept(const Ip6::MessageInfo &aMessageInfo,
{
aNeighbor->GenerateChallenge();
SuccessOrExit(error = AppendChallenge(*message, aNeighbor->GetChallenge(), aNeighbor->GetChallengeSize()));
SuccessOrExit(error = AppendTlvRequest(*message, routerTlvs, sizeof(routerTlvs)));
SuccessOrExit(error = message->AppendChallengeTlv(aNeighbor->GetChallenge(), aNeighbor->GetChallengeSize()));
SuccessOrExit(error = message->AppendTlvRequestTlv(routerTlvs, sizeof(routerTlvs)));
aNeighbor->SetLastHeard(TimerMilli::GetNow());
aNeighbor->SetState(Neighbor::kStateLinkRequest);
}
@@ -791,14 +792,14 @@ Error MleRouter::SendLinkAccept(const Ip6::MessageInfo &aMessageInfo,
if (aMessageInfo.GetSockAddr().IsMulticast())
{
SuccessOrExit(error = AddDelayedResponse(*message, aMessageInfo.GetPeerAddr(),
1 + Random::NonCrypto::GetUint16InRange(0, kMaxResponseDelay)));
SuccessOrExit(error = message->SendAfterDelay(aMessageInfo.GetPeerAddr(),
1 + Random::NonCrypto::GetUint16InRange(0, kMaxResponseDelay)));
Log(kMessageDelay, kTypeLinkAccept, aMessageInfo.GetPeerAddr());
}
else
{
SuccessOrExit(error = SendMessage(*message, aMessageInfo.GetPeerAddr()));
SuccessOrExit(error = message->SendTo(aMessageInfo.GetPeerAddr()));
Log(kMessageSend, kTypeLinkAccept, aMessageInfo.GetPeerAddr());
}
@@ -854,7 +855,7 @@ Error MleRouter::HandleLinkAccept(RxInfo &aRxInfo, bool aRequest)
neighborState = (router != nullptr) ? router->GetState() : Neighbor::kStateInvalid;
// Response
SuccessOrExit(error = ReadResponse(aRxInfo.mMessage, response));
SuccessOrExit(error = aRxInfo.mMessage.ReadResponseTlv(response));
// verify response
switch (neighborState)
@@ -886,7 +887,7 @@ Error MleRouter::HandleLinkAccept(RxInfo &aRxInfo, bool aRequest)
VerifyOrExit(version >= OT_THREAD_VERSION_1_1, error = kErrorParse);
// Link and MLE Frame Counters
SuccessOrExit(error = ReadFrameCounters(aRxInfo.mMessage, linkFrameCounter, mleFrameCounter));
SuccessOrExit(error = aRxInfo.mMessage.ReadFrameCounterTlvs(linkFrameCounter, mleFrameCounter));
// Link Margin
switch (Tlv::Find<LinkMarginTlv>(aRxInfo.mMessage, linkMargin))
@@ -915,7 +916,7 @@ Error MleRouter::HandleLinkAccept(RxInfo &aRxInfo, bool aRequest)
VerifyOrExit(GetRloc16() == address16, error = kErrorDrop);
// Leader Data
SuccessOrExit(error = ReadLeaderData(aRxInfo.mMessage, leaderData));
SuccessOrExit(error = aRxInfo.mMessage.ReadLeaderDataTlv(leaderData));
SetLeaderData(leaderData.GetPartitionId(), leaderData.GetWeighting(), leaderData.GetLeaderRouterId());
// Route
@@ -950,7 +951,7 @@ Error MleRouter::HandleLinkAccept(RxInfo &aRxInfo, bool aRequest)
VerifyOrExit(router != nullptr);
// Leader Data
SuccessOrExit(error = ReadLeaderData(aRxInfo.mMessage, leaderData));
SuccessOrExit(error = aRxInfo.mMessage.ReadLeaderDataTlv(leaderData));
VerifyOrExit(leaderData.GetPartitionId() == mLeaderData.GetPartitionId());
if (mRetrieveNewNetworkData ||
@@ -1014,10 +1015,10 @@ Error MleRouter::HandleLinkAccept(RxInfo &aRxInfo, bool aRequest)
RequestedTlvs requestedTlvs;
// Challenge
SuccessOrExit(error = ReadChallenge(aRxInfo.mMessage, challenge));
SuccessOrExit(error = aRxInfo.mMessage.ReadChallengeTlv(challenge));
// TLV Request
switch (FindTlvRequest(aRxInfo.mMessage, requestedTlvs))
switch (aRxInfo.mMessage.ReadTlvRequestTlv(requestedTlvs))
{
case kErrorNone:
break;
@@ -1227,7 +1228,7 @@ Error MleRouter::HandleAdvertisement(RxInfo &aRxInfo)
SuccessOrExit(error = Tlv::Find<SourceAddressTlv>(aRxInfo.mMessage, sourceAddress));
// Leader Data
SuccessOrExit(error = ReadLeaderData(aRxInfo.mMessage, leaderData));
SuccessOrExit(error = aRxInfo.mMessage.ReadLeaderDataTlv(leaderData));
// Route Data (optional)
if (Tlv::FindTlv(aRxInfo.mMessage, route) == kErrorNone)
@@ -1707,7 +1708,7 @@ void MleRouter::HandleParentRequest(RxInfo &aRxInfo)
}
// Challenge
SuccessOrExit(error = ReadChallenge(aRxInfo.mMessage, challenge));
SuccessOrExit(error = aRxInfo.mMessage.ReadChallengeTlv(challenge));
child = mChildTable.FindChild(extAddr, Child::kInStateAnyExceptInvalid);
@@ -1985,38 +1986,38 @@ void MleRouter::SendParentResponse(Child *aChild, const Challenge &aChallenge, b
{
Error error = kErrorNone;
Ip6::Address destination;
Message * message;
TxMessage * message;
uint16_t delay;
VerifyOrExit((message = NewMleMessage(kCommandParentResponse)) != nullptr, error = kErrorNoBufs);
message->SetDirectTransmission();
SuccessOrExit(error = AppendSourceAddress(*message));
SuccessOrExit(error = AppendLeaderData(*message));
SuccessOrExit(error = AppendLinkFrameCounter(*message));
SuccessOrExit(error = AppendMleFrameCounter(*message));
SuccessOrExit(error = AppendResponse(*message, aChallenge));
SuccessOrExit(error = message->AppendSourceAddressTlv());
SuccessOrExit(error = message->AppendLeaderDataTlv());
SuccessOrExit(error = message->AppendLinkFrameCounterTlv());
SuccessOrExit(error = message->AppendMleFrameCounterTlv());
SuccessOrExit(error = message->AppendResponseTlv(aChallenge));
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
if (aChild->IsTimeSyncEnabled())
{
SuccessOrExit(error = AppendTimeParameter(*message));
SuccessOrExit(error = message->AppendTimeParameterTlv());
}
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
if (aChild->IsThreadVersionCslCapable())
{
SuccessOrExit(error = AppendCslClockAccuracy(*message));
SuccessOrExit(error = message->AppendCslClockAccuracyTlv());
}
#endif
aChild->GenerateChallenge();
SuccessOrExit(error = AppendChallenge(*message, aChild->GetChallenge(), aChild->GetChallengeSize()));
error = AppendLinkMargin(*message, aChild->GetLinkInfo().GetLinkMargin());
SuccessOrExit(error = message->AppendChallengeTlv(aChild->GetChallenge(), aChild->GetChallengeSize()));
error = message->AppendLinkMarginTlv(aChild->GetLinkInfo().GetLinkMargin());
SuccessOrExit(error);
SuccessOrExit(error = AppendConnectivity(*message));
SuccessOrExit(error = AppendVersion(*message));
SuccessOrExit(error = message->AppendConnectivityTlv());
SuccessOrExit(error = message->AppendVersionTlv());
destination.SetToLinkLocalAddress(aChild->GetExtAddress());
@@ -2029,7 +2030,7 @@ void MleRouter::SendParentResponse(Child *aChild, const Challenge &aChallenge, b
delay = 1 + Random::NonCrypto::GetUint16InRange(0, kParentResponseMaxDelayAll);
}
SuccessOrExit(error = AddDelayedResponse(*message, destination, delay));
SuccessOrExit(error = message->SendAfterDelay(destination, delay));
Log(kMessageDelay, kTypeParentResponse, destination);
@@ -2299,7 +2300,7 @@ void MleRouter::HandleChildIdRequest(RxInfo &aRxInfo)
VerifyOrExit(version >= OT_THREAD_VERSION_1_1, error = kErrorParse);
// Response
SuccessOrExit(error = ReadResponse(aRxInfo.mMessage, response));
SuccessOrExit(error = aRxInfo.mMessage.ReadResponseTlv(response));
VerifyOrExit(response.Matches(child->GetChallenge(), child->GetChallengeSize()), error = kErrorSecurity);
// Remove existing MLE messages
@@ -2309,7 +2310,7 @@ void MleRouter::HandleChildIdRequest(RxInfo &aRxInfo)
Get<MeshForwarder>().RemoveMessages(*child, Message::kSubTypeMleDataResponse);
// Link-Layer and MLE Frame Counters
SuccessOrExit(error = ReadFrameCounters(aRxInfo.mMessage, linkFrameCounter, mleFrameCounter));
SuccessOrExit(error = aRxInfo.mMessage.ReadFrameCounterTlvs(linkFrameCounter, mleFrameCounter));
// Mode
SuccessOrExit(error = Tlv::Find<ModeTlv>(aRxInfo.mMessage, modeBitmask));
@@ -2319,7 +2320,7 @@ void MleRouter::HandleChildIdRequest(RxInfo &aRxInfo)
SuccessOrExit(error = Tlv::Find<TimeoutTlv>(aRxInfo.mMessage, timeout));
// TLV Request
SuccessOrExit(error = FindTlvRequest(aRxInfo.mMessage, requestedTlvs));
SuccessOrExit(error = aRxInfo.mMessage.ReadTlvRequestTlv(requestedTlvs));
VerifyOrExit(requestedTlvs.mNumTlvs <= Child::kMaxRequestTlvs, error = kErrorParse);
// Active Timestamp
@@ -2453,7 +2454,7 @@ void MleRouter::HandleChildUpdateRequest(RxInfo &aRxInfo)
mode.Set(modeBitmask);
// Challenge
switch (ReadChallenge(aRxInfo.mMessage, challenge))
switch (aRxInfo.mMessage.ReadChallengeTlv(challenge))
{
case kErrorNone:
tlvs[tlvslength++] = Tlv::kResponse;
@@ -2513,7 +2514,7 @@ void MleRouter::HandleChildUpdateRequest(RxInfo &aRxInfo)
}
// Leader Data
switch (ReadLeaderData(aRxInfo.mMessage, leaderData))
switch (aRxInfo.mMessage.ReadLeaderDataTlv(leaderData))
{
case kErrorNone:
child->SetNetworkDataVersion(leaderData.GetDataVersion(child->GetNetworkDataType()));
@@ -2545,7 +2546,7 @@ void MleRouter::HandleChildUpdateRequest(RxInfo &aRxInfo)
}
// TLV Request
switch (FindTlvRequest(aRxInfo.mMessage, requestedTlvs))
switch (aRxInfo.mMessage.ReadTlvRequestTlv(requestedTlvs))
{
case kErrorNone:
VerifyOrExit(requestedTlvs.mNumTlvs <= (kMaxResponseTlvs - tlvslength), error = kErrorParse);
@@ -2658,7 +2659,7 @@ void MleRouter::HandleChildUpdateResponse(RxInfo &aRxInfo)
child = static_cast<Child *>(aRxInfo.mNeighbor);
// Response
switch (ReadResponse(aRxInfo.mMessage, response))
switch (aRxInfo.mMessage.ReadResponseTlv(response))
{
case kErrorNone:
VerifyOrExit(response.Matches(child->GetChallenge(), child->GetChallengeSize()), error = kErrorSecurity);
@@ -2748,7 +2749,7 @@ void MleRouter::HandleChildUpdateResponse(RxInfo &aRxInfo)
}
// Leader Data
switch (ReadLeaderData(aRxInfo.mMessage, leaderData))
switch (aRxInfo.mMessage.ReadLeaderDataTlv(leaderData))
{
case kErrorNone:
child->SetNetworkDataVersion(leaderData.GetDataVersion(child->GetNetworkDataType()));
@@ -2781,7 +2782,7 @@ void MleRouter::HandleDataRequest(RxInfo &aRxInfo)
VerifyOrExit(aRxInfo.mNeighbor && aRxInfo.mNeighbor->IsStateValid(), error = kErrorSecurity);
// TLV Request
SuccessOrExit(error = FindTlvRequest(aRxInfo.mMessage, requestedTlvs));
SuccessOrExit(error = aRxInfo.mMessage.ReadTlvRequestTlv(requestedTlvs));
VerifyOrExit(requestedTlvs.mNumTlvs <= sizeof(tlvs), error = kErrorParse);
memset(tlvs, Tlv::kInvalid, sizeof(tlvs));
@@ -2987,7 +2988,7 @@ exit:
Error MleRouter::SendDiscoveryResponse(const Ip6::Address &aDestination, const Message &aDiscoverRequestMessage)
{
Error error = kErrorNone;
Message * message;
TxMessage * message;
uint16_t startOffset;
Tlv tlv;
MeshCoP::DiscoveryResponseTlv discoveryResponse;
@@ -3071,7 +3072,7 @@ Error MleRouter::SendDiscoveryResponse(const Ip6::Address &aDestination, const M
delay = Random::NonCrypto::GetUint16InRange(0, kDiscoveryMaxJitter + 1);
SuccessOrExit(error = AddDelayedResponse(*message, aDestination, delay));
SuccessOrExit(error = message->SendAfterDelay(aDestination, delay));
Log(kMessageDelay, kTypeDiscoveryResponse, aDestination);
@@ -3085,13 +3086,13 @@ Error MleRouter::SendChildIdResponse(Child &aChild)
{
Error error = kErrorNone;
Ip6::Address destination;
Message * message;
TxMessage * message;
VerifyOrExit((message = NewMleMessage(kCommandChildIdResponse)) != nullptr, error = kErrorNoBufs);
SuccessOrExit(error = AppendSourceAddress(*message));
SuccessOrExit(error = AppendLeaderData(*message));
SuccessOrExit(error = AppendActiveTimestamp(*message));
SuccessOrExit(error = AppendPendingTimestamp(*message));
SuccessOrExit(error = message->AppendSourceAddressTlv());
SuccessOrExit(error = message->AppendLeaderDataTlv());
SuccessOrExit(error = message->AppendActiveTimestampTlv());
SuccessOrExit(error = message->AppendPendingTimestampTlv());
if ((aChild.GetRloc16() == 0) || !RouterIdMatch(aChild.GetRloc16(), GetRloc16()))
{
@@ -3115,26 +3116,26 @@ Error MleRouter::SendChildIdResponse(Child &aChild)
aChild.SetRloc16(rloc16);
}
SuccessOrExit(error = AppendAddress16(*message, aChild.GetRloc16()));
SuccessOrExit(error = message->AppendAddress16Tlv(aChild.GetRloc16()));
for (uint8_t i = 0; i < Child::kMaxRequestTlvs; i++)
{
switch (aChild.GetRequestTlv(i))
{
case Tlv::kNetworkData:
SuccessOrExit(error = AppendNetworkData(*message, aChild.GetNetworkDataType()));
SuccessOrExit(error = message->AppendNetworkDataTlv(aChild.GetNetworkDataType()));
break;
case Tlv::kRoute:
SuccessOrExit(error = AppendRoute(*message));
SuccessOrExit(error = message->AppendRouteTlv());
break;
case Tlv::kActiveDataset:
SuccessOrExit(error = AppendActiveDataset(*message));
SuccessOrExit(error = message->AppendActiveDatasetTlv());
break;
case Tlv::kPendingDataset:
SuccessOrExit(error = AppendPendingDataset(*message));
SuccessOrExit(error = message->AppendPendingDatasetTlv());
break;
default:
@@ -3144,7 +3145,7 @@ Error MleRouter::SendChildIdResponse(Child &aChild)
if (!aChild.IsFullThreadDevice())
{
SuccessOrExit(error = AppendChildAddresses(*message, aChild));
SuccessOrExit(error = message->AppendAddresseRegisterationTlv(aChild));
}
SetChildStateToValid(aChild);
@@ -3162,7 +3163,7 @@ Error MleRouter::SendChildIdResponse(Child &aChild)
#endif
destination.SetToLinkLocalAddress(aChild.GetExtAddress());
SuccessOrExit(error = SendMessage(*message, destination));
SuccessOrExit(error = message->SendTo(destination));
Log(kMessageSend, kTypeChildIdResponse, destination, aChild.GetRloc16());
@@ -3176,7 +3177,7 @@ Error MleRouter::SendChildUpdateRequest(Child &aChild)
static const uint8_t tlvs[] = {Tlv::kTimeout, Tlv::kAddressRegistration};
Error error = kErrorNone;
Ip6::Address destination;
Message * message = nullptr;
TxMessage * message = nullptr;
if (!aChild.IsRxOnWhenIdle())
{
@@ -3201,21 +3202,21 @@ Error MleRouter::SendChildUpdateRequest(Child &aChild)
}
VerifyOrExit((message = NewMleMessage(kCommandChildUpdateRequest)) != nullptr, error = kErrorNoBufs);
SuccessOrExit(error = AppendSourceAddress(*message));
SuccessOrExit(error = AppendLeaderData(*message));
SuccessOrExit(error = AppendNetworkData(*message, aChild.GetNetworkDataType()));
SuccessOrExit(error = AppendActiveTimestamp(*message));
SuccessOrExit(error = AppendPendingTimestamp(*message));
SuccessOrExit(error = message->AppendSourceAddressTlv());
SuccessOrExit(error = message->AppendLeaderDataTlv());
SuccessOrExit(error = message->AppendNetworkDataTlv(aChild.GetNetworkDataType()));
SuccessOrExit(error = message->AppendActiveTimestampTlv());
SuccessOrExit(error = message->AppendPendingTimestampTlv());
if (!aChild.IsStateValid())
{
SuccessOrExit(error = AppendTlvRequest(*message, tlvs, sizeof(tlvs)));
SuccessOrExit(error = message->AppendTlvRequestTlv(tlvs, sizeof(tlvs)));
aChild.GenerateChallenge();
SuccessOrExit(error = AppendChallenge(*message, aChild.GetChallenge(), aChild.GetChallengeSize()));
SuccessOrExit(error = message->AppendChallengeTlv(aChild.GetChallenge(), aChild.GetChallengeSize()));
}
destination.SetToLinkLocalAddress(aChild.GetExtAddress());
SuccessOrExit(error = SendMessage(*message, destination));
SuccessOrExit(error = message->SendTo(destination));
if (aChild.IsRxOnWhenIdle())
{
@@ -3236,8 +3237,8 @@ void MleRouter::SendChildUpdateResponse(Child * aChild,
uint8_t aTlvsLength,
const Challenge & aChallenge)
{
Error error = kErrorNone;
Message *message;
Error error = kErrorNone;
TxMessage *message;
VerifyOrExit((message = NewMleMessage(kCommandChildUpdateResponse)) != nullptr, error = kErrorNoBufs);
@@ -3246,59 +3247,59 @@ void MleRouter::SendChildUpdateResponse(Child * aChild,
switch (aTlvs[i])
{
case Tlv::kStatus:
SuccessOrExit(error = AppendStatus(*message, StatusTlv::kError));
SuccessOrExit(error = message->AppendStatusTlv(StatusTlv::kError));
break;
case Tlv::kAddressRegistration:
SuccessOrExit(error = AppendChildAddresses(*message, *aChild));
SuccessOrExit(error = message->AppendAddresseRegisterationTlv(*aChild));
break;
case Tlv::kLeaderData:
SuccessOrExit(error = AppendLeaderData(*message));
SuccessOrExit(error = message->AppendLeaderDataTlv());
break;
case Tlv::kMode:
SuccessOrExit(error = AppendMode(*message, aChild->GetDeviceMode()));
SuccessOrExit(error = message->AppendModeTlv(aChild->GetDeviceMode()));
break;
case Tlv::kNetworkData:
SuccessOrExit(error = AppendNetworkData(*message, aChild->GetNetworkDataType()));
SuccessOrExit(error = AppendActiveTimestamp(*message));
SuccessOrExit(error = AppendPendingTimestamp(*message));
SuccessOrExit(error = message->AppendNetworkDataTlv(aChild->GetNetworkDataType()));
SuccessOrExit(error = message->AppendActiveTimestampTlv());
SuccessOrExit(error = message->AppendPendingTimestampTlv());
break;
case Tlv::kResponse:
SuccessOrExit(error = AppendResponse(*message, aChallenge));
SuccessOrExit(error = message->AppendResponseTlv(aChallenge));
break;
case Tlv::kSourceAddress:
SuccessOrExit(error = AppendSourceAddress(*message));
SuccessOrExit(error = message->AppendSourceAddressTlv());
break;
case Tlv::kTimeout:
SuccessOrExit(error = AppendTimeout(*message, aChild->GetTimeout()));
SuccessOrExit(error = message->AppendTimeoutTlv(aChild->GetTimeout()));
break;
case Tlv::kMleFrameCounter:
SuccessOrExit(error = AppendMleFrameCounter(*message));
SuccessOrExit(error = message->AppendMleFrameCounterTlv());
break;
case Tlv::kLinkFrameCounter:
SuccessOrExit(error = AppendLinkFrameCounter(*message));
SuccessOrExit(error = message->AppendLinkFrameCounterTlv());
break;
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
case Tlv::kCslClockAccuracy:
if (!aChild->IsRxOnWhenIdle())
{
SuccessOrExit(error = AppendCslClockAccuracy(*message));
SuccessOrExit(error = message->AppendCslClockAccuracyTlv());
}
break;
#endif
}
}
SuccessOrExit(error = SendMessage(*message, aMessageInfo.GetPeerAddr()));
SuccessOrExit(error = message->SendTo(aMessageInfo.GetPeerAddr()));
if (aChild == nullptr)
{
@@ -3321,9 +3322,9 @@ void MleRouter::SendDataResponse(const Ip6::Address &aDestination,
{
OT_UNUSED_VARIABLE(aRequestMessage);
Error error = kErrorNone;
Message * message = nullptr;
Neighbor *neighbor;
Error error = kErrorNone;
TxMessage *message = nullptr;
Neighbor * neighbor;
if (mRetrieveNewNetworkData)
{
@@ -3332,10 +3333,10 @@ void MleRouter::SendDataResponse(const Ip6::Address &aDestination,
}
VerifyOrExit((message = NewMleMessage(kCommandDataResponse)) != nullptr, error = kErrorNoBufs);
SuccessOrExit(error = AppendSourceAddress(*message));
SuccessOrExit(error = AppendLeaderData(*message));
SuccessOrExit(error = AppendActiveTimestamp(*message));
SuccessOrExit(error = AppendPendingTimestamp(*message));
SuccessOrExit(error = message->AppendSourceAddressTlv());
SuccessOrExit(error = message->AppendLeaderDataTlv());
SuccessOrExit(error = message->AppendActiveTimestampTlv());
SuccessOrExit(error = message->AppendPendingTimestampTlv());
for (int i = 0; i < aTlvsLength; i++)
{
@@ -3343,16 +3344,16 @@ void MleRouter::SendDataResponse(const Ip6::Address &aDestination,
{
case Tlv::kNetworkData:
neighbor = mNeighborTable.FindNeighbor(aDestination);
SuccessOrExit(error = AppendNetworkData(*message, (neighbor != nullptr) ? neighbor->GetNetworkDataType()
: NetworkData::kFullSet));
SuccessOrExit(error = message->AppendNetworkDataTlv((neighbor != nullptr) ? neighbor->GetNetworkDataType()
: NetworkData::kFullSet));
break;
case Tlv::kActiveDataset:
SuccessOrExit(error = AppendActiveDataset(*message));
SuccessOrExit(error = message->AppendActiveDatasetTlv());
break;
case Tlv::kPendingDataset:
SuccessOrExit(error = AppendPendingDataset(*message));
SuccessOrExit(error = message->AppendPendingDatasetTlv());
break;
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
@@ -3374,12 +3375,12 @@ void MleRouter::SendDataResponse(const Ip6::Address &aDestination,
// Remove multicast MLE Data Response from Delayed Message Queue.
RemoveDelayedDataResponseMessage();
SuccessOrExit(error = AddDelayedResponse(*message, aDestination, aDelay));
SuccessOrExit(error = message->SendAfterDelay(aDestination, aDelay));
Log(kMessageDelay, kTypeDataResponse, aDestination);
}
else
{
SuccessOrExit(error = SendMessage(*message, aDestination));
SuccessOrExit(error = message->SendTo(aDestination));
Log(kMessageSend, kTypeDataResponse, aDestination);
}
@@ -3659,7 +3660,7 @@ Error MleRouter::SendAddressSolicit(ThreadStatusTlv::Status aStatus)
SuccessOrExit(error = Tlv::Append<ThreadStatusTlv>(*message, aStatus));
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
SuccessOrExit(error = AppendXtalAccuracy(*message));
SuccessOrExit(error = Tlv::Append<XtalAccuracyTlv>(*message, otPlatTimeGetXtalAccuracy()));
#endif
SuccessOrExit(error = messageInfo.SetSockAddrToRlocPeerAddrToLeaderRloc());
@@ -4104,27 +4105,27 @@ void MleRouter::FillConnectivityTlv(ConnectivityTlv &aTlv)
aTlv.SetSedDatagramCount(OPENTHREAD_CONFIG_DEFAULT_SED_DATAGRAM_COUNT);
}
Error MleRouter::AppendConnectivity(Message &aMessage)
Error Mle::TxMessage::AppendConnectivityTlv(void)
{
ConnectivityTlv tlv;
tlv.Init();
FillConnectivityTlv(tlv);
Get<MleRouter>().FillConnectivityTlv(tlv);
return tlv.AppendTo(aMessage);
return tlv.AppendTo(*this);
}
Error MleRouter::AppendChildAddresses(Message &aMessage, Child &aChild)
Error Mle::TxMessage::AppendAddresseRegisterationTlv(Child &aChild)
{
Error error;
Tlv tlv;
AddressRegistrationEntry entry;
Lowpan::Context context;
uint8_t length = 0;
uint16_t startOffset = aMessage.GetLength();
uint16_t startOffset = GetLength();
tlv.SetType(Tlv::kAddressRegistration);
SuccessOrExit(error = aMessage.Append(tlv));
SuccessOrExit(error = Append(tlv));
for (const Ip6::Address &address : aChild.IterateIp6Addresses())
{
@@ -4145,12 +4146,12 @@ Error MleRouter::AppendChildAddresses(Message &aMessage, Child &aChild)
continue;
}
SuccessOrExit(error = aMessage.AppendBytes(&entry, entry.GetLength()));
SuccessOrExit(error = AppendBytes(&entry, entry.GetLength()));
length += entry.GetLength();
}
tlv.SetLength(length);
aMessage.Write(startOffset, tlv);
Write(startOffset, tlv);
exit:
return error;
@@ -4257,24 +4258,24 @@ void MleRouter::FillRouteTlv(RouteTlv &aTlv, Neighbor *aNeighbor)
aTlv.SetRouteDataLength(routerCount);
}
Error MleRouter::AppendRoute(Message &aMessage, Neighbor *aNeighbor)
Error Mle::TxMessage::AppendRouteTlv(Neighbor *aNeighbor)
{
RouteTlv tlv;
tlv.Init();
FillRouteTlv(tlv, aNeighbor);
Get<MleRouter>().FillRouteTlv(tlv, aNeighbor);
return tlv.AppendTo(aMessage);
return tlv.AppendTo(*this);
}
Error MleRouter::AppendActiveDataset(Message &aMessage)
Error Mle::TxMessage::AppendActiveDatasetTlv(void)
{
return Get<MeshCoP::ActiveDatasetManager>().AppendMleDatasetTlv(aMessage);
return Get<MeshCoP::ActiveDatasetManager>().AppendMleDatasetTlv(*this);
}
Error MleRouter::AppendPendingDataset(Message &aMessage)
Error Mle::TxMessage::AppendPendingDatasetTlv(void)
{
return Get<MeshCoP::PendingDatasetManager>().AppendMleDatasetTlv(aMessage);
return Get<MeshCoP::PendingDatasetManager>().AppendMleDatasetTlv(*this);
}
bool MleRouter::HasMinDowngradeNeighborRouters(void)
@@ -4465,14 +4466,14 @@ Error MleRouter::SendTimeSync(void)
{
Error error = kErrorNone;
Ip6::Address destination;
Message * message = nullptr;
TxMessage * message = nullptr;
VerifyOrExit((message = NewMleMessage(kCommandTimeSync)) != nullptr, error = kErrorNoBufs);
message->SetTimeSync(true);
destination.SetToLinkLocalAllNodesMulticast();
SuccessOrExit(error = SendMessage(*message, destination));
SuccessOrExit(error = message->SendTo(destination));
Log(kMessageSend, kTypeTimeSync, destination);
-5
View File
@@ -580,11 +580,6 @@ private:
// Network Data).
static constexpr uint8_t kRouterUpgradeBorderRouterRequestThreshold = 2;
Error AppendConnectivity(Message &aMessage);
Error AppendChildAddresses(Message &aMessage, Child &aChild);
Error AppendRoute(Message &aMessage, Neighbor *aNeighbor = nullptr);
Error AppendActiveDataset(Message &aMessage);
Error AppendPendingDataset(Message &aMessage);
void HandleDetachStart(void);
void HandleChildStart(AttachMode aMode);
void HandleLinkRequest(RxInfo &aRxInfo);