mirror of
https://github.com/espressif/openthread.git
synced 2026-09-12 20:20:04 +00:00
[lowpan] simplify FragmentHeader and its use in MeshForwarder (#4453)
This commit updates the `Lowpan::FragmentHeader` class to provide methods to parse/write the Fragment Header from/to a given frame or message.
This commit is contained in:
committed by
Jonathan Hui
parent
2ec0d2f8d4
commit
17168e9ba1
+48
-23
@@ -1319,19 +1319,40 @@ uint16_t MeshHeader::WriteTo(Message &aMessage, uint16_t aOffset) const
|
||||
return headerLength;
|
||||
}
|
||||
|
||||
otError FragmentHeader::Init(const uint8_t *aFrame, uint16_t aFrameLength)
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// FragmentHeader
|
||||
|
||||
void FragmentHeader::Init(uint16_t aSize, uint16_t aTag, uint16_t aOffset)
|
||||
{
|
||||
mSize = (aSize & kSizeMask);
|
||||
mTag = aTag;
|
||||
mOffset = (aOffset & kOffsetMask);
|
||||
}
|
||||
|
||||
bool FragmentHeader::IsFragmentHeader(const uint8_t *aFrame, uint16_t aFrameLength)
|
||||
{
|
||||
return (aFrameLength >= kFirstFragmentHeaderSize) && ((*aFrame & kDispatchMask) == kDispatch);
|
||||
}
|
||||
|
||||
otError FragmentHeader::ParseFrom(const uint8_t *aFrame, uint16_t aFrameLength, uint16_t &aHeaderLength)
|
||||
{
|
||||
otError error = OT_ERROR_PARSE;
|
||||
|
||||
VerifyOrExit(aFrameLength >= sizeof(mDispatchSize) + sizeof(mTag));
|
||||
memcpy(reinterpret_cast<uint8_t *>(&mDispatchSize), aFrame, sizeof(mDispatchSize) + sizeof(mTag));
|
||||
aFrame += sizeof(mDispatchSize) + sizeof(mTag);
|
||||
aFrameLength -= sizeof(mDispatchSize) + sizeof(mTag);
|
||||
VerifyOrExit(IsFragmentHeader(aFrame, aFrameLength));
|
||||
|
||||
if (IsOffsetPresent())
|
||||
mSize = ReadUint16(aFrame + kSizeIndex) & kSizeMask;
|
||||
mTag = ReadUint16(aFrame + kTagIndex);
|
||||
|
||||
if ((*aFrame & kOffsetFlag) == kOffsetFlag)
|
||||
{
|
||||
VerifyOrExit(aFrameLength >= sizeof(mOffset));
|
||||
mOffset = *aFrame++;
|
||||
VerifyOrExit(aFrameLength >= kSubsequentFragmentHeaderSize);
|
||||
mOffset = aFrame[kOffsetIndex] * 8;
|
||||
aHeaderLength = kSubsequentFragmentHeaderSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
mOffset = 0;
|
||||
aHeaderLength = kFirstFragmentHeaderSize;
|
||||
}
|
||||
|
||||
error = OT_ERROR_NONE;
|
||||
@@ -1340,29 +1361,33 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError FragmentHeader::Init(const Message &aMessage, uint16_t aOffset)
|
||||
otError FragmentHeader::ParseFrom(const Message &aMessage, uint16_t aOffset, uint16_t &aHeaderLength)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint16_t bytesRead;
|
||||
uint8_t frame[kSubsequentFragmentHeaderSize];
|
||||
uint16_t frameLength;
|
||||
|
||||
bytesRead = aMessage.Read(aOffset, sizeof(mDispatchSize), reinterpret_cast<void *>(&mDispatchSize));
|
||||
VerifyOrExit(bytesRead == sizeof(mDispatchSize), error = OT_ERROR_PARSE);
|
||||
aOffset += bytesRead;
|
||||
frameLength = aMessage.Read(aOffset, sizeof(frame), frame);
|
||||
|
||||
VerifyOrExit(IsFragmentHeader(), error = OT_ERROR_PARSE);
|
||||
return ParseFrom(frame, frameLength, aHeaderLength);
|
||||
}
|
||||
|
||||
bytesRead = aMessage.Read(aOffset, sizeof(mTag), reinterpret_cast<void *>(&mTag));
|
||||
VerifyOrExit(bytesRead == sizeof(mTag), error = OT_ERROR_PARSE);
|
||||
aOffset += bytesRead;
|
||||
uint16_t FragmentHeader::WriteTo(uint8_t *aFrame) const
|
||||
{
|
||||
uint8_t *cur = aFrame;
|
||||
|
||||
if (IsOffsetPresent())
|
||||
WriteUint16((kDispatch << 8) + mSize, cur);
|
||||
cur += sizeof(uint16_t);
|
||||
|
||||
WriteUint16(mTag, cur);
|
||||
cur += sizeof(uint16_t);
|
||||
|
||||
if (mOffset != 0)
|
||||
{
|
||||
bytesRead = aMessage.Read(aOffset, sizeof(mOffset), &mOffset);
|
||||
VerifyOrExit(bytesRead == sizeof(mOffset), error = OT_ERROR_PARSE);
|
||||
*aFrame |= kOffsetFlag;
|
||||
*cur++ = static_cast<uint8_t>(mOffset >> 3);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
return static_cast<uint16_t>(cur - aFrame);
|
||||
}
|
||||
|
||||
} // namespace Lowpan
|
||||
|
||||
+59
-85
@@ -550,81 +550,76 @@ private:
|
||||
* This class implements Fragment Header generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class FragmentHeader
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kInitialHeaderSize = 4, ///< Initial fragment header size in octets.
|
||||
kSubsequentHeaderSize = 5, ///< Subsequent fragment header size in octets.
|
||||
kFirstFragmentHeaderSize = 4, ///< First fragment header size in octets.
|
||||
kSubsequentFragmentHeaderSize = 5, ///< Subsequent fragment header size in octets.
|
||||
};
|
||||
|
||||
/**
|
||||
* This constructor initializes the Fragment Header.
|
||||
* This method initializes the Fragment Header as a first fragment.
|
||||
*
|
||||
* A first fragment header starts at offset zero.
|
||||
*
|
||||
* @param[in] aSize The Datagram Size value.
|
||||
* @param[in] aTage The Datagram Tag value.
|
||||
*
|
||||
*/
|
||||
FragmentHeader(void)
|
||||
{
|
||||
mDispatchSize = HostSwap16(kDispatch);
|
||||
mTag = 0;
|
||||
mOffset = 0;
|
||||
}
|
||||
void InitFirstFragment(uint16_t aSize, uint16_t aTag) { Init(aSize, aTag, 0); }
|
||||
|
||||
/**
|
||||
* This method initializes the Fragment Header.
|
||||
*
|
||||
*/
|
||||
void Init(void) { mDispatchSize = HostSwap16(kDispatch); }
|
||||
|
||||
/**
|
||||
* This method initializes the fragment header from a frame @p aFrame.
|
||||
* The @p aOffset value will be truncated to become a multiple of 8.
|
||||
*
|
||||
* @param[in] aFrame The pointer to the frame.
|
||||
* @param[in] aFrameLength The length of the frame.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Fragment Header initialized successfully.
|
||||
* @retval OT_ERROR_PARSE Fragment header could not be parsed from @p aFrame.
|
||||
* @param[in] aSize The Datagram Size value.
|
||||
* @param[in] aTage The Datagram Tag value.
|
||||
* @param[in] aOffset The Datagram Offset value.
|
||||
*
|
||||
*/
|
||||
otError Init(const uint8_t *aFrame, uint16_t aFrameLength);
|
||||
void Init(uint16_t aSize, uint16_t aTag, uint16_t aOffset);
|
||||
|
||||
/**
|
||||
* This method initializes the fragment header from a message @p aMessage.
|
||||
* This static method indicates whether or not the header (in a given frame) is a Fragment Header.
|
||||
*
|
||||
* @param[in] aMessage The message object.
|
||||
* @param[in] aOffset An offset into the message to read the header.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Fragment Header initialized successfully.
|
||||
* @retval OT_ERROR_PARSE Fragment header could not be parsed from @p aMessage.
|
||||
*
|
||||
*/
|
||||
otError Init(const Message &aMessage, uint16_t aOffset);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the header is a Fragment Header.
|
||||
* @note This method checks whether the frame has the minimum required length and that the first byte in
|
||||
* header (dispatch byte) matches the Fragment Header dispatch value. It does not fully parse and validate the
|
||||
* Fragment Header. `ParseFrom()` method can be used to fully parse and validate the header.
|
||||
*
|
||||
* @retval TRUE If the header matches the Fragment Header dispatch value.
|
||||
* @retval FALSE If the header does not match the Fragment Header dispatch value.
|
||||
*
|
||||
*/
|
||||
bool IsFragmentHeader(void) const { return (HostSwap16(mDispatchSize) & kDispatchMask) == kDispatch; }
|
||||
static bool IsFragmentHeader(const uint8_t *aFrame, uint16_t aFrameLength);
|
||||
|
||||
/**
|
||||
* This method returns the Fragment Header length.
|
||||
* This method parses the Fragment Header from a frame @p aFrame.
|
||||
*
|
||||
* @returns The Fragment Header length in bytes.
|
||||
* @param[in] aFrame The pointer to the frame.
|
||||
* @param[in] aFrameLength The length of the frame.
|
||||
* @param[out] aHeaderLength A reference to a variable to output the parsed header length (on success).
|
||||
*
|
||||
* @retval OT_ERROR_NONE Fragment Header parsed successfully.
|
||||
* @retval OT_ERROR_PARSE Fragment header could not be parsed from @p aFrame.
|
||||
*
|
||||
*/
|
||||
uint8_t GetHeaderLength(void) const { return IsOffsetPresent() ? sizeof(*this) : sizeof(*this) - sizeof(mOffset); }
|
||||
otError ParseFrom(const uint8_t *aFrame, uint16_t aFrameLength, uint16_t &aHeaderLength);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the Offset field is present.
|
||||
* This method parses the Fragment Header from a message.
|
||||
*
|
||||
* @returns TRUE if the Offset field is present, FALSE otherwise.
|
||||
* @param[in] aMessage The message to read from.
|
||||
* @param[in] aOffset The offset within the message to start reading from.
|
||||
* @param[out] aHeaderLength A reference to a variable to output the parsed header length (on success).
|
||||
*
|
||||
* @retval OT_ERROR_NONE Fragment Header parsed successfully.
|
||||
* @retval OT_ERROR_PARSE Fragment header could not be parsed from @p aFrame.
|
||||
*
|
||||
*/
|
||||
bool IsOffsetPresent(void) const { return (HostSwap16(mDispatchSize) & kOffset) != 0; }
|
||||
otError ParseFrom(const Message &aMessage, uint16_t aOffset, uint16_t &aHeaderLength);
|
||||
|
||||
/**
|
||||
* This method returns the Datagram Size value.
|
||||
@@ -632,18 +627,7 @@ public:
|
||||
* @returns The Datagram Size value.
|
||||
*
|
||||
*/
|
||||
uint16_t GetDatagramSize(void) const { return HostSwap16(mDispatchSize) & kSizeMask; }
|
||||
|
||||
/**
|
||||
* This method sets the Datagram Size value.
|
||||
*
|
||||
* @param[in] aSize The Datagram Size value.
|
||||
*
|
||||
*/
|
||||
void SetDatagramSize(uint16_t aSize)
|
||||
{
|
||||
mDispatchSize = HostSwap16((HostSwap16(mDispatchSize) & ~kSizeMask) | (aSize & kSizeMask));
|
||||
}
|
||||
uint16_t GetDatagramSize(void) const { return mSize; }
|
||||
|
||||
/**
|
||||
* This method returns the Datagram Tag value.
|
||||
@@ -651,57 +635,47 @@ public:
|
||||
* @returns The Datagram Tag value.
|
||||
*
|
||||
*/
|
||||
uint16_t GetDatagramTag(void) const { return HostSwap16(mTag); }
|
||||
|
||||
/**
|
||||
* This method sets the Datagram Tag value.
|
||||
*
|
||||
* @param[in] aTag The Datagram Tag value.
|
||||
*
|
||||
*/
|
||||
void SetDatagramTag(uint16_t aTag) { mTag = HostSwap16(aTag); }
|
||||
uint16_t GetDatagramTag(void) const { return mTag; }
|
||||
|
||||
/**
|
||||
* This method returns the Datagram Offset value.
|
||||
*
|
||||
* @returns The Datagram Offset value.
|
||||
* The returned offset value is always multiple of 8.
|
||||
*
|
||||
* @returns The Datagram Offset value (multiple of 8).
|
||||
*
|
||||
*/
|
||||
uint16_t GetDatagramOffset(void) const { return IsOffsetPresent() ? static_cast<uint16_t>(mOffset) * 8 : 0; }
|
||||
uint16_t GetDatagramOffset(void) const { return mOffset; }
|
||||
|
||||
/**
|
||||
* This method sets the Datagram Offset value.
|
||||
* This method writes the Fragment Header into a given frame.
|
||||
*
|
||||
* @param[in] aOffset The Datagram Offset value.
|
||||
* @note This method expects the frame buffer to have enough space for the entire Fragment Header
|
||||
*
|
||||
* @param[out] aFrame The pointer to the frame buffer to write to.
|
||||
*
|
||||
* @returns The header length (number of bytes written).
|
||||
*
|
||||
*/
|
||||
void SetDatagramOffset(uint16_t aOffset)
|
||||
{
|
||||
if (aOffset == 0)
|
||||
{
|
||||
mDispatchSize = HostSwap16(HostSwap16(mDispatchSize) & ~kOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
mDispatchSize = HostSwap16(HostSwap16(mDispatchSize) | kOffset);
|
||||
mOffset = (aOffset >> 3) & kOffsetMask;
|
||||
}
|
||||
}
|
||||
uint16_t WriteTo(uint8_t *aFrame) const;
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kDispatch = 3 << 14,
|
||||
kOffset = 1 << 13,
|
||||
kDispatchMask = 0xd800, ///< Accept FRAG1 and FRAGN only.
|
||||
kSizeMask = 0x7ff,
|
||||
kOffsetMask = 0xff,
|
||||
kDispatch = 0xc0, // 0b1100_0000
|
||||
kDispatchMask = 0xd8, // 0b1101_1000 which accepts first frag (0b1100_0xxx) and next frag (0b1110_0xxx).
|
||||
kOffsetFlag = 1 << 5, // Dispatch flag to indicate first (no offset) vs. next (offset is present) fragment.
|
||||
kSizeMask = 0x7ff, // 0b0111_1111_1111 (first 11 bits).
|
||||
kOffsetMask = 0xfff8, // Clears the last 3 bits to ensure offset is a multiple of 8.
|
||||
kSizeIndex = 0, // Start index of Size field in the Fragment Header byte sequence.
|
||||
kTagIndex = 2, // Start index of Tag field in the Fragment Header byte sequence.
|
||||
kOffsetIndex = 4, // Start index of Offset field in the Fragment Header byte sequence.
|
||||
};
|
||||
|
||||
uint16_t mDispatchSize;
|
||||
uint16_t mSize;
|
||||
uint16_t mTag;
|
||||
uint8_t mOffset;
|
||||
} OT_TOOL_PACKED_END;
|
||||
uint16_t mOffset;
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@@ -389,21 +389,6 @@ void MeshForwarder::GetMacDestinationAddress(const Ip6::Address &aIp6Addr, Mac::
|
||||
}
|
||||
}
|
||||
|
||||
otError MeshForwarder::GetFragmentHeader(const uint8_t * aFrame,
|
||||
uint16_t aFrameLength,
|
||||
Lowpan::FragmentHeader &aFragmentHeader)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
VerifyOrExit(aFrameLength >= 1 && reinterpret_cast<const Lowpan::FragmentHeader *>(aFrame)->IsFragmentHeader(),
|
||||
error = OT_ERROR_NOT_FOUND);
|
||||
|
||||
SuccessOrExit(error = aFragmentHeader.Init(aFrame, aFrameLength));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError MeshForwarder::DecompressIp6Header(const uint8_t * aFrame,
|
||||
uint16_t aFrameLength,
|
||||
const Mac::Address &aMacSource,
|
||||
@@ -415,14 +400,15 @@ otError MeshForwarder::DecompressIp6Header(const uint8_t * aFrame,
|
||||
otError error = OT_ERROR_NONE;
|
||||
const uint8_t * start = aFrame;
|
||||
Lowpan::FragmentHeader fragmentHeader;
|
||||
uint16_t fragmentHeaderLength;
|
||||
int headerLength;
|
||||
|
||||
if (GetFragmentHeader(aFrame, aFrameLength, fragmentHeader) == OT_ERROR_NONE)
|
||||
if (fragmentHeader.ParseFrom(aFrame, aFrameLength, fragmentHeaderLength) == OT_ERROR_NONE)
|
||||
{
|
||||
// only the first fragment header is followed by a LOWPAN_IPHC header
|
||||
// Only the first fragment header is followed by a LOWPAN_IPHC header
|
||||
VerifyOrExit(fragmentHeader.GetDatagramOffset() == 0, error = OT_ERROR_NOT_FOUND);
|
||||
aFrame += fragmentHeader.GetHeaderLength();
|
||||
aFrameLength -= fragmentHeader.GetHeaderLength();
|
||||
aFrame += fragmentHeaderLength;
|
||||
aFrameLength -= fragmentHeaderLength;
|
||||
}
|
||||
|
||||
VerifyOrExit(aFrameLength >= 1 && Lowpan::Lowpan::IsLowpanHc(aFrame), error = OT_ERROR_NOT_FOUND);
|
||||
@@ -700,7 +686,7 @@ start:
|
||||
if (aMessage.GetOffset() == 0)
|
||||
{
|
||||
Lowpan::BufferWriter buffer(payload, aFrame.GetMaxPayloadLength() - headerLength -
|
||||
Lowpan::FragmentHeader::kInitialHeaderSize);
|
||||
Lowpan::FragmentHeader::kFirstFragmentHeaderSize);
|
||||
uint8_t hcLength;
|
||||
Mac::Address meshSource, meshDest;
|
||||
otError error;
|
||||
@@ -712,8 +698,8 @@ start:
|
||||
}
|
||||
else
|
||||
{
|
||||
meshDest = aMacDest;
|
||||
meshSource = aMacSource;
|
||||
meshDest = aMacDest;
|
||||
}
|
||||
|
||||
error = Get<Lowpan::Lowpan>().Compress(aMessage, meshSource, meshDest, buffer);
|
||||
@@ -726,7 +712,7 @@ start:
|
||||
|
||||
if (payloadLength > fragmentLength)
|
||||
{
|
||||
Lowpan::FragmentHeader *fragmentHeader;
|
||||
Lowpan::FragmentHeader fragmentHeader;
|
||||
|
||||
if ((!aMessage.IsLinkSecurityEnabled()) && aMessage.IsSubTypeMle())
|
||||
{
|
||||
@@ -748,16 +734,13 @@ start:
|
||||
aMessage.SetDatagramTag(mFragTag++);
|
||||
}
|
||||
|
||||
memmove(payload + Lowpan::FragmentHeader::kInitialHeaderSize, payload, hcLength);
|
||||
memmove(payload + Lowpan::FragmentHeader::kFirstFragmentHeaderSize, payload, hcLength);
|
||||
|
||||
fragmentHeader = reinterpret_cast<Lowpan::FragmentHeader *>(payload);
|
||||
fragmentHeader->Init();
|
||||
fragmentHeader->SetDatagramSize(aMessage.GetLength());
|
||||
fragmentHeader->SetDatagramTag(static_cast<uint16_t>(aMessage.GetDatagramTag()));
|
||||
fragmentHeader->SetDatagramOffset(0);
|
||||
fragmentHeader.InitFirstFragment(aMessage.GetLength(), static_cast<uint16_t>(aMessage.GetDatagramTag()));
|
||||
fragmentHeader.WriteTo(payload);
|
||||
|
||||
payload += fragmentHeader->GetHeaderLength();
|
||||
headerLength += fragmentHeader->GetHeaderLength();
|
||||
payload += Lowpan::FragmentHeader::kFirstFragmentHeaderSize;
|
||||
headerLength += Lowpan::FragmentHeader::kFirstFragmentHeaderSize;
|
||||
payloadLength = (aFrame.GetMaxPayloadLength() - headerLength) & ~0x7;
|
||||
}
|
||||
|
||||
@@ -772,19 +755,18 @@ start:
|
||||
}
|
||||
else
|
||||
{
|
||||
Lowpan::FragmentHeader *fragmentHeader;
|
||||
Lowpan::FragmentHeader fragmentHeader;
|
||||
uint16_t fragmentHeaderLength;
|
||||
|
||||
payloadLength = aMessage.GetLength() - aMessage.GetOffset();
|
||||
|
||||
// Write Fragment header
|
||||
fragmentHeader = reinterpret_cast<Lowpan::FragmentHeader *>(payload);
|
||||
fragmentHeader->Init();
|
||||
fragmentHeader->SetDatagramSize(aMessage.GetLength());
|
||||
fragmentHeader->SetDatagramTag(static_cast<uint16_t>(aMessage.GetDatagramTag()));
|
||||
fragmentHeader->SetDatagramOffset(aMessage.GetOffset());
|
||||
fragmentHeader.Init(aMessage.GetLength(), static_cast<uint16_t>(aMessage.GetDatagramTag()),
|
||||
aMessage.GetOffset());
|
||||
fragmentHeaderLength = fragmentHeader.WriteTo(payload);
|
||||
|
||||
payload += fragmentHeader->GetHeaderLength();
|
||||
headerLength += fragmentHeader->GetHeaderLength();
|
||||
payload += fragmentHeaderLength;
|
||||
headerLength += fragmentHeaderLength;
|
||||
|
||||
fragmentLength = (aFrame.GetMaxPayloadLength() - headerLength) & ~0x7;
|
||||
|
||||
@@ -1048,8 +1030,7 @@ void MeshForwarder::HandleReceivedFrame(Mac::RxFrame &aFrame)
|
||||
HandleMesh(payload, payloadLength, macSource, linkInfo);
|
||||
#endif
|
||||
}
|
||||
else if (payloadLength >= sizeof(Lowpan::FragmentHeader) &&
|
||||
reinterpret_cast<Lowpan::FragmentHeader *>(payload)->IsFragmentHeader())
|
||||
else if (Lowpan::FragmentHeader::IsFragmentHeader(payload, payloadLength))
|
||||
{
|
||||
HandleFragment(payload, payloadLength, macSource, macDest, linkInfo);
|
||||
}
|
||||
@@ -1090,12 +1071,13 @@ void MeshForwarder::HandleFragment(uint8_t * aFrame,
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
Lowpan::FragmentHeader fragmentHeader;
|
||||
uint16_t fragmentHeaderLength;
|
||||
Message * message = NULL;
|
||||
|
||||
// Check the fragment header
|
||||
SuccessOrExit(error = fragmentHeader.Init(aFrame, aFrameLength));
|
||||
aFrame += fragmentHeader.GetHeaderLength();
|
||||
aFrameLength -= fragmentHeader.GetHeaderLength();
|
||||
SuccessOrExit(error = fragmentHeader.ParseFrom(aFrame, aFrameLength, fragmentHeaderLength));
|
||||
aFrame += fragmentHeaderLength;
|
||||
aFrameLength -= fragmentHeaderLength;
|
||||
|
||||
if (fragmentHeader.GetDatagramOffset() == 0)
|
||||
{
|
||||
|
||||
@@ -375,11 +375,6 @@ private:
|
||||
const Mac::Address & aMacSource,
|
||||
const Mac::Address & aMacDest,
|
||||
const otThreadLinkInfo &aLinkInfo);
|
||||
|
||||
static otError GetFragmentHeader(const uint8_t * aFrame,
|
||||
uint16_t aFrameLength,
|
||||
Lowpan::FragmentHeader &aFragmentHeader);
|
||||
|
||||
uint16_t PrepareDataFrame(Mac::TxFrame & aFrame,
|
||||
Message & aMessage,
|
||||
const Mac::Address &aMacSource,
|
||||
|
||||
@@ -524,7 +524,7 @@ void MeshForwarder::HandleMesh(uint8_t * aFrame,
|
||||
if (meshDest.GetShort() == Get<Mac::Mac>().GetShortAddress() ||
|
||||
Get<Mle::MleRouter>().IsMinimalChild(meshDest.GetShort()))
|
||||
{
|
||||
if (reinterpret_cast<Lowpan::FragmentHeader *>(aFrame)->IsFragmentHeader())
|
||||
if (Lowpan::FragmentHeader::IsFragmentHeader(aFrame, aFrameLength))
|
||||
{
|
||||
HandleFragment(aFrame, aFrameLength, meshSource, meshDest, aLinkInfo);
|
||||
}
|
||||
@@ -740,12 +740,13 @@ otError MeshForwarder::GetForwardFramePriority(const uint8_t * aFrame,
|
||||
otError error = OT_ERROR_NONE;
|
||||
bool isFragment = false;
|
||||
Lowpan::FragmentHeader fragmentHeader;
|
||||
uint16_t fragmentHeaderLength;
|
||||
|
||||
if (GetFragmentHeader(aFrame, aFrameLength, fragmentHeader) == OT_ERROR_NONE)
|
||||
if (fragmentHeader.ParseFrom(aFrame, aFrameLength, fragmentHeaderLength) == OT_ERROR_NONE)
|
||||
{
|
||||
isFragment = true;
|
||||
aFrame += fragmentHeader.GetHeaderLength();
|
||||
aFrameLength -= fragmentHeader.GetHeaderLength();
|
||||
aFrame += fragmentHeaderLength;
|
||||
aFrameLength -= fragmentHeaderLength;
|
||||
|
||||
if (fragmentHeader.GetDatagramOffset() > 0)
|
||||
{
|
||||
@@ -848,19 +849,19 @@ otError MeshForwarder::LogMeshFragmentHeader(MessageAction aAction,
|
||||
bool shouldLogRss;
|
||||
Lowpan::MeshHeader meshHeader;
|
||||
Lowpan::FragmentHeader fragmentHeader;
|
||||
uint16_t meshHeaderLength;
|
||||
uint16_t headerLength;
|
||||
|
||||
SuccessOrExit(meshHeader.ParseFrom(aMessage, meshHeaderLength));
|
||||
SuccessOrExit(meshHeader.ParseFrom(aMessage, headerLength));
|
||||
|
||||
aMeshSource.SetShort(meshHeader.GetSource());
|
||||
aMeshDest.SetShort(meshHeader.GetDestination());
|
||||
|
||||
aOffset = meshHeaderLength;
|
||||
aOffset = headerLength;
|
||||
|
||||
if (fragmentHeader.Init(aMessage, aOffset) == OT_ERROR_NONE)
|
||||
if (fragmentHeader.ParseFrom(aMessage, aOffset, headerLength) == OT_ERROR_NONE)
|
||||
{
|
||||
hasFragmentHeader = true;
|
||||
aOffset += fragmentHeader.GetHeaderLength();
|
||||
aOffset += headerLength;
|
||||
}
|
||||
|
||||
shouldLogRss = (aAction == kMessageReceive) || (aAction == kMessageReassemblyDrop);
|
||||
|
||||
Reference in New Issue
Block a user