mirror of
https://github.com/espressif/openthread.git
synced 2026-11-13 09:51:02 +00:00
[mac] check frame version for sequence number suppression (#13388)
In IEEE 802.15.4-2015, bit 8 of the Frame Control Field (FCF) was introduced as the Sequence Number Suppression bit. In legacy frame versions (IEEE 802.15.4-2003 and IEEE 802.15.4-2006), this bit was reserved and has no defined meaning. Previously, IsSequencePresent() checked whether bit 8 was cleared without inspecting the frame version field. Consequently, if a legacy frame was received with reserved bit 8 set to 1, it would be incorrectly processed as having its sequence number suppressed, leading to improper MAC frame parsing and handling. This commit introduces IsSequenceSuppressed() to verify that the frame version is IEEE 802.15.4-2015 before evaluating the Sequence Number Suppression bit. For 2003 and 2006 frame versions, sequence suppression is ignored and IsSequencePresent() unconditionally returns true. Unit tests are also added to verify correct detection across all frame versions.
This commit is contained in:
@@ -183,7 +183,7 @@ void TxFrame::BuildInfo::PrepareHeadersIn(TxFrame &aTxFrame) const
|
||||
builder.Init(aTxFrame.mPsdu, aTxFrame.GetMtu());
|
||||
IgnoreError(builder.AppendUint<kLittleEndian>(fcf));
|
||||
|
||||
if (IsSequencePresent(fcf))
|
||||
if (!IsSequenceSuppressed(fcf))
|
||||
{
|
||||
builder.Append<uint8_t>(); // Place holder for seq number
|
||||
}
|
||||
@@ -305,7 +305,7 @@ uint8_t Frame::SkipSequenceIndex(void) const
|
||||
uint16_t fcf = GetFrameControlField();
|
||||
uint8_t index = kFcfSize;
|
||||
|
||||
if (IsSequencePresent(fcf))
|
||||
if (!IsSequenceSuppressed(fcf))
|
||||
{
|
||||
index += kDsnSize;
|
||||
}
|
||||
@@ -906,7 +906,7 @@ exit:
|
||||
|
||||
uint8_t Frame::CalculateAddrFieldSize(uint16_t aFcf)
|
||||
{
|
||||
uint8_t size = kFcfSize + (IsSequencePresent(aFcf) ? kDsnSize : 0);
|
||||
uint8_t size = kFcfSize + (IsSequenceSuppressed(aFcf) ? 0 : kDsnSize);
|
||||
|
||||
// This static method calculates the size (number of bytes) of
|
||||
// Address header field for a given Frame Control `aFcf` value.
|
||||
|
||||
@@ -281,7 +281,7 @@ public:
|
||||
*
|
||||
* @returns TRUE if the Sequence Number is present, FALSE otherwise.
|
||||
*/
|
||||
uint8_t IsSequencePresent(void) const { return IsSequencePresent(GetFrameControlField()); }
|
||||
uint8_t IsSequencePresent(void) const { return !IsSequenceSuppressed(GetFrameControlField()); }
|
||||
|
||||
/**
|
||||
* Indicates whether or not the Destination PAN ID is present.
|
||||
@@ -677,7 +677,10 @@ protected:
|
||||
|
||||
static uint16_t GetFcfDstAddr(uint16_t aFcf) { return ReadBits<uint16_t, kFcfDstAddrMask>(aFcf); }
|
||||
static uint16_t GetFcfSrcAddr(uint16_t aFcf) { return ReadBits<uint16_t, kFcfSrcAddrMask>(aFcf); }
|
||||
static bool IsSequencePresent(uint16_t aFcf) { return (aFcf & kFcfSequenceSuppression) == 0; }
|
||||
static bool IsSequenceSuppressed(uint16_t aFcf)
|
||||
{
|
||||
return IsVersion2015(aFcf) && ((aFcf & kFcfSequenceSuppression) != 0);
|
||||
}
|
||||
static bool IsDstAddrPresent(uint16_t aFcf) { return (aFcf & kFcfDstAddrMask) != 0; }
|
||||
static bool IsSrcAddrPresent(uint16_t aFcf) { return (aFcf & kFcfSrcAddrMask) != 0; }
|
||||
static bool IsSecurityEnabled(uint16_t aFcf) { return (aFcf & kFcfSecurityEnabled) != 0; }
|
||||
|
||||
@@ -752,6 +752,36 @@ void TestMacFrameApi(void)
|
||||
printf("commandId:%d\n", commandId);
|
||||
|
||||
#endif
|
||||
|
||||
{
|
||||
uint8_t psdu2003WithBit8[] = {0x00, 0x01, 0x11};
|
||||
uint8_t psdu2006WithBit8[] = {0x00, 0x11, 0x22};
|
||||
uint8_t psdu2015WithBit8[] = {0x00, 0x21, 0x33};
|
||||
uint8_t psdu2015NoBit8[] = {0x00, 0x20, 0x44};
|
||||
|
||||
frame.mPsdu = psdu2003WithBit8;
|
||||
frame.mLength = sizeof(psdu2003WithBit8);
|
||||
VerifyOrQuit(frame.GetVersion() == Mac::Frame::kVersion2003);
|
||||
VerifyOrQuit(frame.IsSequencePresent());
|
||||
VerifyOrQuit(frame.GetSequence() == 0x11);
|
||||
|
||||
frame.mPsdu = psdu2006WithBit8;
|
||||
frame.mLength = sizeof(psdu2006WithBit8);
|
||||
VerifyOrQuit(frame.GetVersion() == Mac::Frame::kVersion2006);
|
||||
VerifyOrQuit(frame.IsSequencePresent());
|
||||
VerifyOrQuit(frame.GetSequence() == 0x22);
|
||||
|
||||
frame.mPsdu = psdu2015WithBit8;
|
||||
frame.mLength = sizeof(psdu2015WithBit8);
|
||||
VerifyOrQuit(frame.GetVersion() == Mac::Frame::kVersion2015);
|
||||
VerifyOrQuit(!frame.IsSequencePresent());
|
||||
|
||||
frame.mPsdu = psdu2015NoBit8;
|
||||
frame.mLength = sizeof(psdu2015NoBit8);
|
||||
VerifyOrQuit(frame.GetVersion() == Mac::Frame::kVersion2015);
|
||||
VerifyOrQuit(frame.IsSequencePresent());
|
||||
VerifyOrQuit(frame.GetSequence() == 0x44);
|
||||
}
|
||||
}
|
||||
|
||||
void TestMacFrameAckGeneration(void)
|
||||
|
||||
Reference in New Issue
Block a user