mirror of
https://github.com/espressif/openthread.git
synced 2026-07-29 23:27:46 +00:00
[message] add ReadAtAndAdvanceOffset() helper method (#12503)
This commit adds `ReadAtAndAdvanceOffset()` to the `Message` class to simplify reading data from the message at the current message offset and then advancing the message offset. This pattern is commonly used when processing message headers sequentially. The new method helps reduce code verbosity and ensures the offset is always advanced by the correct size. The new helper is adopted in various core modules including DHCPv6, IPv6, 6LoWPAN, MLE, and UDP processing.
This commit is contained in:
@@ -663,6 +663,17 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error Message::ReadAtAndAdvanceOffset(void *aBuf, uint16_t aLength)
|
||||
{
|
||||
Error error;
|
||||
|
||||
SuccessOrExit(error = Read(GetOffset(), aBuf, aLength));
|
||||
MoveOffset(aLength);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
bool Message::CompareBytes(uint16_t aOffset, const void *aBuf, uint16_t aLength, ByteMatcher aMatcher) const
|
||||
{
|
||||
uint16_t bytesToCompare = aLength;
|
||||
|
||||
@@ -925,6 +925,34 @@ public:
|
||||
return Read(aOffsetRange, &aObject, sizeof(ObjectType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a given number of bytes from the message at the current message offset and advances the message offset.
|
||||
*
|
||||
* @param[out] aBuf A pointer to a data buffer to copy the read bytes into.
|
||||
* @param[in] aLength Number of bytes to read.
|
||||
*
|
||||
* @retval kErrorNone Requested bytes were successfully read from message. Message offset is advanced.
|
||||
* @retval kErrorParse Not enough bytes remaining to read the requested @p aLength. Message offset is unchanged.
|
||||
*/
|
||||
Error ReadAtAndAdvanceOffset(void *aBuf, uint16_t aLength);
|
||||
|
||||
/**
|
||||
* Reads an object from the message at the current message offset and advances the message offset.
|
||||
*
|
||||
* @tparam ObjectType The object type to read from the message.
|
||||
*
|
||||
* @param[out] aObject A reference to the object to read into.
|
||||
*
|
||||
* @retval kErrorNone Object @p aObject was successfully read from message. Message offset is advanced.
|
||||
* @retval kErrorParse Not enough bytes remaining in message to read the entire object. Offset is unchanged.
|
||||
*/
|
||||
template <typename ObjectType> Error ReadAtAndAdvanceOffset(ObjectType &aObject)
|
||||
{
|
||||
static_assert(!TypeTraits::IsPointer<ObjectType>::kValue, "ObjectType must not be a pointer");
|
||||
|
||||
return ReadAtAndAdvanceOffset(&aObject, sizeof(ObjectType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the bytes in the message at a given offset with a given byte array.
|
||||
*
|
||||
|
||||
@@ -358,8 +358,7 @@ void Client::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessag
|
||||
|
||||
Header header;
|
||||
|
||||
SuccessOrExit(aMessage.Read(aMessage.GetOffset(), header));
|
||||
aMessage.MoveOffset(sizeof(header));
|
||||
SuccessOrExit(aMessage.ReadAtAndAdvanceOffset(header));
|
||||
|
||||
if ((header.GetMsgType() == kMsgTypeReply) && (header.GetTransactionId() == mTransactionId))
|
||||
{
|
||||
|
||||
@@ -177,8 +177,7 @@ void Server::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessag
|
||||
{
|
||||
Header header;
|
||||
|
||||
SuccessOrExit(aMessage.Read(aMessage.GetOffset(), header));
|
||||
aMessage.MoveOffset(sizeof(header));
|
||||
SuccessOrExit(aMessage.ReadAtAndAdvanceOffset(header));
|
||||
|
||||
VerifyOrExit((header.GetMsgType() == kMsgTypeSolicit));
|
||||
|
||||
|
||||
@@ -800,15 +800,13 @@ Error Ip6::FragmentDatagram(Message &aMessage, uint8_t aIpProto)
|
||||
|
||||
Error Ip6::HandleFragment(Message &aMessage)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Error error;
|
||||
FragmentHeader fragmentHeader;
|
||||
|
||||
SuccessOrExit(error = aMessage.Read(aMessage.GetOffset(), fragmentHeader));
|
||||
SuccessOrExit(error = aMessage.ReadAtAndAdvanceOffset(fragmentHeader));
|
||||
|
||||
VerifyOrExit(fragmentHeader.GetOffset() == 0 && !fragmentHeader.IsMoreFlagSet(), error = kErrorDrop);
|
||||
|
||||
aMessage.MoveOffset(sizeof(fragmentHeader));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -450,13 +450,12 @@ Error Udp::HandleMessage(Message &aMessage, MessageInfo &aMessageInfo)
|
||||
Error error = kErrorNone;
|
||||
Header udpHeader;
|
||||
|
||||
SuccessOrExit(error = aMessage.Read(aMessage.GetOffset(), udpHeader));
|
||||
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
SuccessOrExit(error = Checksum::VerifyMessageChecksum(aMessage, aMessageInfo, kProtoUdp));
|
||||
#endif
|
||||
|
||||
aMessage.MoveOffset(sizeof(udpHeader));
|
||||
SuccessOrExit(error = aMessage.ReadAtAndAdvanceOffset(udpHeader));
|
||||
|
||||
aMessageInfo.mPeerPort = udpHeader.GetSourcePort();
|
||||
aMessageInfo.mSockPort = udpHeader.GetDestinationPort();
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ Error Lowpan::Compress(Message &aMessage,
|
||||
uint8_t headerDepth = 0;
|
||||
uint8_t headerMaxDepth = aHeaderDepth;
|
||||
|
||||
SuccessOrExit(error = aMessage.Read(aMessage.GetOffset(), ip6Header));
|
||||
SuccessOrExit(error = aMessage.ReadAtAndAdvanceOffset(ip6Header));
|
||||
|
||||
FindContextToCompressAddress(ip6Header.GetSource(), srcContext);
|
||||
FindContextToCompressAddress(ip6Header.GetDestination(), dstContext);
|
||||
@@ -395,8 +395,6 @@ Error Lowpan::Compress(Message &aMessage,
|
||||
|
||||
headerDepth++;
|
||||
|
||||
aMessage.MoveOffset(sizeof(ip6Header));
|
||||
|
||||
nextHeader = static_cast<uint8_t>(ip6Header.GetNextHeader());
|
||||
|
||||
while (headerDepth < headerMaxDepth)
|
||||
@@ -450,8 +448,7 @@ Error Lowpan::CompressExtensionHeader(Message &aMessage, FrameBuilder &aFrameBui
|
||||
uint16_t padLength = 0;
|
||||
uint8_t tmpByte;
|
||||
|
||||
SuccessOrExit(error = aMessage.Read(aMessage.GetOffset(), extHeader));
|
||||
aMessage.MoveOffset(sizeof(extHeader));
|
||||
SuccessOrExit(error = aMessage.ReadAtAndAdvanceOffset(extHeader));
|
||||
|
||||
tmpByte = kExtHdrDispatch | kExtHdrEidHbh;
|
||||
|
||||
@@ -526,7 +523,7 @@ Error Lowpan::CompressUdp(Message &aMessage, FrameBuilder &aFrameBuilder)
|
||||
uint16_t source;
|
||||
uint16_t destination;
|
||||
|
||||
SuccessOrExit(error = aMessage.Read(aMessage.GetOffset(), udpHeader));
|
||||
SuccessOrExit(error = aMessage.ReadAtAndAdvanceOffset(udpHeader));
|
||||
|
||||
source = udpHeader.GetSourcePort();
|
||||
destination = udpHeader.GetDestinationPort();
|
||||
@@ -556,8 +553,6 @@ Error Lowpan::CompressUdp(Message &aMessage, FrameBuilder &aFrameBuilder)
|
||||
|
||||
SuccessOrExit(error = aFrameBuilder.AppendBigEndianUint16(udpHeader.GetChecksum()));
|
||||
|
||||
aMessage.MoveOffset(sizeof(udpHeader));
|
||||
|
||||
exit:
|
||||
if (error != kErrorNone)
|
||||
{
|
||||
|
||||
@@ -1564,13 +1564,11 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
|
||||
|
||||
VerifyOrExit(aMessageInfo.GetHopLimit() == kMleHopLimit, error = kErrorParse);
|
||||
|
||||
SuccessOrExit(error = aMessage.Read(aMessage.GetOffset(), securitySuite));
|
||||
aMessage.MoveOffset(sizeof(securitySuite));
|
||||
SuccessOrExit(error = aMessage.ReadAtAndAdvanceOffset(securitySuite));
|
||||
|
||||
if (securitySuite == kNoSecurity)
|
||||
{
|
||||
SuccessOrExit(error = aMessage.Read(aMessage.GetOffset(), command));
|
||||
aMessage.MoveOffset(sizeof(command));
|
||||
SuccessOrExit(error = aMessage.ReadAtAndAdvanceOffset(command));
|
||||
|
||||
switch (command)
|
||||
{
|
||||
@@ -1593,8 +1591,7 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
|
||||
VerifyOrExit(!IsDisabled(), error = kErrorInvalidState);
|
||||
VerifyOrExit(securitySuite == k154Security, error = kErrorParse);
|
||||
|
||||
SuccessOrExit(error = aMessage.Read(aMessage.GetOffset(), header));
|
||||
aMessage.MoveOffset(sizeof(header));
|
||||
SuccessOrExit(error = aMessage.ReadAtAndAdvanceOffset(header));
|
||||
|
||||
VerifyOrExit(header.IsSecurityControlValid(), error = kErrorParse);
|
||||
|
||||
@@ -1604,8 +1601,7 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
|
||||
SuccessOrExit(
|
||||
error = ProcessMessageSecurity(Crypto::AesCcm::kDecrypt, aMessage, aMessageInfo, aMessage.GetOffset(), header));
|
||||
|
||||
IgnoreError(aMessage.Read(aMessage.GetOffset(), command));
|
||||
aMessage.MoveOffset(sizeof(command));
|
||||
IgnoreError(aMessage.ReadAtAndAdvanceOffset(command));
|
||||
|
||||
extAddr.SetFromIid(aMessageInfo.GetPeerAddr().GetIid());
|
||||
neighbor = (command == kCommandChildIdResponse) ? mNeighborTable.FindParent(extAddr)
|
||||
|
||||
Reference in New Issue
Block a user