From cb41668c0cb0ad8138ab866cc83181c8f0c25edd Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Tue, 17 May 2022 11:25:41 -0700 Subject: [PATCH] [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()`. --- src/core/thread/discover_scanner.cpp | 4 +- src/core/thread/mle.cpp | 352 ++++++------ src/core/thread/mle.hpp | 815 ++++++++++++++------------- src/core/thread/mle_router.cpp | 275 ++++----- src/core/thread/mle_router.hpp | 5 - 5 files changed, 737 insertions(+), 714 deletions(-) diff --git a/src/core/thread/discover_scanner.cpp b/src/core/thread/discover_scanner.cpp index e652afe58..ff0b6f899 100644 --- a/src/core/thread/discover_scanner.cpp +++ b/src/core/thread/discover_scanner.cpp @@ -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().SendMessage(*message, destination)); + SuccessOrExit(error = message->SendTo(destination)); if ((aPanId == Mac::kPanIdBroadcast) && (Get().GetPanId() == Mac::kPanIdBroadcast)) { diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 619171f6e..8e3a646cb 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -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(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(aMessage, GetRloc16()); + return Tlv::Append(*this, Get().GetRloc16()); } -Error Mle::AppendStatus(Message &aMessage, StatusTlv::Status aStatus) +Error Mle::TxMessage::AppendStatusTlv(StatusTlv::Status aStatus) { - return Tlv::Append(aMessage, aStatus); + return Tlv::Append(*this, aStatus); } -Error Mle::AppendMode(Message &aMessage, DeviceMode aMode) +Error Mle::TxMessage::AppendModeTlv(DeviceMode aMode) { - return Tlv::Append(aMessage, aMode.Get()); + return Tlv::Append(*this, aMode.Get()); } -Error Mle::AppendTimeout(Message &aMessage, uint32_t aTimeout) +Error Mle::TxMessage::AppendTimeoutTlv(uint32_t aTimeout) { - return Tlv::Append(aMessage, aTimeout); + return Tlv::Append(*this, aTimeout); } -Error Mle::AppendChallenge(Message &aMessage, const Challenge &aChallenge) +Error Mle::TxMessage::AppendChallengeTlv(const Challenge &aChallenge) { - return Tlv::Append(aMessage, aChallenge.mBuffer, aChallenge.mLength); + return Tlv::Append(*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(aMessage, aChallenge, aChallengeLength); + return Tlv::Append(*this, aChallenge, aChallengeLength); } -Error Mle::AppendResponse(Message &aMessage, const Challenge &aResponse) +Error Mle::TxMessage::AppendResponseTlv(const Challenge &aResponse) { - return Tlv::Append(aMessage, aResponse.mBuffer, aResponse.mLength); + return Tlv::Append(*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(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().SetAllMacFrameCounters(counter); #endif - return Tlv::Append(aMessage, counter); + return Tlv::Append(*this, counter); } -Error Mle::AppendMleFrameCounter(Message &aMessage) +Error Mle::TxMessage::AppendMleFrameCounterTlv(void) { - return Tlv::Append(aMessage, Get().GetMleFrameCounter()); + return Tlv::Append(*this, Get().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(aMessage, aLinkFrameCounter)); + SuccessOrExit(error = Tlv::Find(*this, aLinkFrameCounter)); - switch (Tlv::Find(aMessage, aMleFrameCounter)) + switch (Tlv::Find(*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(aMessage, aRloc16); + return Tlv::Append(*this, aRloc16); } -Error Mle::AppendLeaderData(Message &aMessage) +Error Mle::TxMessage::AppendLeaderDataTlv(void) { LeaderDataTlv leaderDataTlv; - mLeaderData.SetDataVersion(Get().GetVersion(NetworkData::kFullSet)); - mLeaderData.SetStableDataVersion(Get().GetVersion(NetworkData::kStableSubset)); + Get().mLeaderData.SetDataVersion(Get().GetVersion(NetworkData::kFullSet)); + Get().mLeaderData.SetStableDataVersion(Get().GetVersion(NetworkData::kStableSubset)); leaderDataTlv.Init(); - leaderDataTlv.Set(mLeaderData); + leaderDataTlv.Set(Get().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().mRetrieveNewNetworkData, error = kErrorInvalidState); length = sizeof(networkData); IgnoreError(Get().CopyNetworkData(aType, networkData, length)); - error = Tlv::Append(aMessage, networkData, length); + error = Tlv::Append(*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(aMessage, aTlvs, aTlvsLength); + return Tlv::Append(*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(length); exit: return error; } -Error Mle::AppendScanMask(Message &aMessage, uint8_t aScanMask) +Error Mle::TxMessage::AppendScanMaskTlv(uint8_t aScanMask) { - return Tlv::Append(aMessage, aScanMask); + return Tlv::Append(*this, aScanMask); } -Error Mle::AppendLinkMargin(Message &aMessage, uint8_t aLinkMargin) +Error Mle::TxMessage::AppendLinkMarginTlv(uint8_t aLinkMargin) { - return Tlv::Append(aMessage, aLinkMargin); + return Tlv::Append(*this, aLinkMargin); } -Error Mle::AppendVersion(Message &aMessage) +Error Mle::TxMessage::AppendVersionTlv(void) { - return Tlv::Append(aMessage, kThreadVersion); + return Tlv::Append(*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().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().GetUnicastAddresses()) { - if (addr.GetAddress().IsLinkLocal() || IsRoutingLocator(addr.GetAddress()) || - IsAnycastLocator(addr.GetAddress()) || addr.GetAddress() == GetMeshLocal64()) + if (addr.GetAddress().IsLinkLocal() || Get().IsRoutingLocator(addr.GetAddress()) || + Get().IsAnycastLocator(addr.GetAddress()) || addr.GetAddress() == Get().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().IsRxOnWhenIdle() #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) - || !GetParent().IsThreadVersion1p1() + || !Get().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().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(aMessage, nullptr, 0); + return Tlv::Append(*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().GetTimeSyncPeriod()); tlv.SetXtalThreshold(Get().GetXtalThreshold()); - return tlv.AppendTo(aMessage); + return tlv.AppendTo(*this); } -Error Mle::AppendXtalAccuracy(Message &aMessage) +Error Mle::TxMessage::AppendXtalAccuracyTlv(void) { - return Tlv::Append(aMessage, otPlatTimeGetXtalAccuracy()); + return Tlv::Append(*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().GetTimestamp(); VerifyOrExit(timestamp != nullptr); - error = Tlv::Append(aMessage, *timestamp); + error = Tlv::Append(*this, *timestamp); exit: return error; } -Error Mle::AppendPendingTimestamp(Message &aMessage) +Error Mle::TxMessage::AppendPendingTimestampTlv(void) { Error error = kErrorNone; const MeshCoP::Timestamp *timestamp = Get().GetTimestamp(); VerifyOrExit(timestamp != nullptr && timestamp->GetSeconds() != 0); - error = Tlv::Append(aMessage, *timestamp); + error = Tlv::Append(*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().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().IsCslEnabled()); - return Tlv::Append(aMessage, mCslTimeout == 0 ? mTimeout : mCslTimeout); + return Tlv::Append(*this, + Get().mCslTimeout == 0 ? Get().mTimeout : Get().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().GetCslAccuracy()); cslClockAccuracy.SetCslUncertainty(Get().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(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().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().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().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(*message, Get().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().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().GetMleFrameCounter()); header.SetKeyId(Get().GetCurrentKeySequence()); - aMessage.Write(offset, header); + Write(offset, header); offset += sizeof(SecurityHeader); - SuccessOrExit(error = ProcessMessageSecurity(Crypto::AesCcm::kEncrypt, aMessage, messageInfo, offset, header)); + SuccessOrExit( + error = Get().ProcessMessageSecurity(Crypto::AesCcm::kEncrypt, *this, messageInfo, offset, header)); Get().IncrementMleFrameCounter(); } - SuccessOrExit(error = mSocket.SendTo(aMessage, messageInfo)); + SuccessOrExit(error = Get().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().mDelayedResponses.Enqueue(*this); - mDelayedResponseTimer.FireAtIfEarlier(metadata.mSendTime); + Get().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(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); diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 6c870c326..ff3c173e8 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -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(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); diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index bde40428c..86335e05f 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -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(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().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(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(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().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(aRxInfo.mMessage, modeBitmask)); @@ -2319,7 +2320,7 @@ void MleRouter::HandleChildIdRequest(RxInfo &aRxInfo) SuccessOrExit(error = Tlv::Find(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(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(*message, aStatus)); #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE - SuccessOrExit(error = AppendXtalAccuracy(*message)); + SuccessOrExit(error = Tlv::Append(*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().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().FillRouteTlv(tlv, aNeighbor); - return tlv.AppendTo(aMessage); + return tlv.AppendTo(*this); } -Error MleRouter::AppendActiveDataset(Message &aMessage) +Error Mle::TxMessage::AppendActiveDatasetTlv(void) { - return Get().AppendMleDatasetTlv(aMessage); + return Get().AppendMleDatasetTlv(*this); } -Error MleRouter::AppendPendingDataset(Message &aMessage) +Error Mle::TxMessage::AppendPendingDatasetTlv(void) { - return Get().AppendMleDatasetTlv(aMessage); + return Get().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); diff --git a/src/core/thread/mle_router.hpp b/src/core/thread/mle_router.hpp index 6645498e6..fc9434a4b 100644 --- a/src/core/thread/mle_router.hpp +++ b/src/core/thread/mle_router.hpp @@ -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);