[mac] support frames without sequence number (#10544)

This commit adds the capability to support frames without sequence
number.
This commit is contained in:
Yakun Xu
2024-08-02 09:50:45 -07:00
committed by GitHub
parent 03113e8502
commit e219fe92f1
7 changed files with 155 additions and 41 deletions
+5 -1
View File
@@ -606,7 +606,11 @@ static void radioReceive(otInstance *aInstance)
{
if (otMacFrameIsAckRequested(&sTransmitFrame))
{
isTxDone = isAck && otMacFrameGetSequence(&sReceiveFrame) == otMacFrameGetSequence(&sTransmitFrame);
uint8_t rxSeq;
uint8_t txSeq;
isTxDone = isAck && otMacFrameGetSequence(&sReceiveFrame, &rxSeq) == OT_ERROR_NONE &&
otMacFrameGetSequence(&sTransmitFrame, &txSeq) == OT_ERROR_NONE && rxSeq == txSeq;
}
#if OPENTHREAD_SIMULATION_VIRTUAL_TIME
// Simulate tx done when receiving the echo frame.
+14 -2
View File
@@ -139,9 +139,21 @@ exit:
return error;
}
uint8_t otMacFrameGetSequence(const otRadioFrame *aFrame)
otError otMacFrameGetSequence(const otRadioFrame *aFrame, uint8_t *aSequence)
{
return static_cast<const Mac::Frame *>(aFrame)->GetSequence();
otError error;
if (static_cast<const Mac::Frame *>(aFrame)->IsSequencePresent())
{
*aSequence = static_cast<const Mac::Frame *>(aFrame)->GetSequence();
error = kErrorNone;
}
else
{
error = kErrorParse;
}
return error;
}
void otMacFrameProcessTransmitAesCcm(otRadioFrame *aFrame, const otExtAddress *aExtAddress)
+4 -2
View File
@@ -169,11 +169,13 @@ otError otMacFrameGetDstAddr(const otRadioFrame *aFrame, otMacAddress *aMacAddre
* Get the sequence of @p aFrame.
*
* @param[in] aFrame A pointer to the frame.
* @param[out] aSequence A pointer to the sequence.
*
* @returns The sequence of the frame.
* @retval OT_ERROR_NONE Successfully got the sequence.
* @retval OT_ERROR_PARSE Failed to parse the sequence.
*
*/
uint8_t otMacFrameGetSequence(const otRadioFrame *aFrame);
otError otMacFrameGetSequence(const otRadioFrame *aFrame, uint8_t *aSequence);
/**
* Performs AES CCM on the frame which is going to be sent.
+46 -9
View File
@@ -59,7 +59,8 @@ void Frame::InitMacHeader(Type aType,
const Addresses &aAddrs,
const PanIds &aPanIds,
SecurityLevel aSecurityLevel,
KeyIdMode aKeyIdMode)
KeyIdMode aKeyIdMode,
bool aSuppressSequence)
{
uint16_t fcf;
FrameBuilder builder;
@@ -124,6 +125,9 @@ void Frame::InitMacHeader(Type aType,
{
fcf |= kFcfPanidCompression;
}
// Sequence Number Suppression bit was reserved, and must not be set on initialization.
OT_ASSERT(!aSuppressSequence);
break;
case kVersion2015:
@@ -194,9 +198,18 @@ void Frame::InitMacHeader(Type aType,
break;
}
if (aSuppressSequence)
{
fcf |= kFcfSequenceSupression;
}
builder.Init(mPsdu, GetMtu());
IgnoreError(builder.AppendLittleEndianUint16(fcf));
IgnoreError(builder.AppendUint8(0)); // Seq number
if (!IsSequenceSuppressed(fcf))
{
IgnoreError(builder.AppendUint8(0)); // Seq number
}
if (IsDstPanIdPresent(fcf))
{
@@ -294,7 +307,7 @@ uint8_t Frame::FindDstPanIdIndex(void) const
VerifyOrExit(IsDstPanIdPresent(), index = kInvalidIndex);
index = kFcfSize + kDsnSize;
index = kFcfSize + GetSeqNumSize();
exit:
return index;
@@ -373,7 +386,22 @@ void Frame::SetDstPanId(PanId aPanId)
LittleEndian::WriteUint16(aPanId, &mPsdu[index]);
}
uint8_t Frame::FindDstAddrIndex(void) const { return kFcfSize + kDsnSize + (IsDstPanIdPresent() ? sizeof(PanId) : 0); }
uint8_t Frame::GetSequence(void) const
{
OT_ASSERT(IsSequencePresent());
return GetPsdu()[kSequenceIndex];
}
void Frame::SetSequence(uint8_t aSequence)
{
OT_ASSERT(IsSequencePresent());
GetPsdu()[kSequenceIndex] = aSequence;
}
uint8_t Frame::FindDstAddrIndex(void) const
{
return kFcfSize + GetSeqNumSize() + (IsDstPanIdPresent() ? sizeof(PanId) : 0);
}
Error Frame::GetDstAddr(Address &aAddress) const
{
@@ -442,7 +470,7 @@ uint8_t Frame::FindSrcPanIdIndex(void) const
VerifyOrExit(IsSrcPanIdPresent(), index = kInvalidIndex);
index += kFcfSize + kDsnSize;
index += kFcfSize + GetSeqNumSize();
if (IsDstPanIdPresent(fcf))
{
@@ -533,7 +561,7 @@ uint8_t Frame::FindSrcAddrIndex(void) const
uint8_t index = 0;
uint16_t fcf = GetFrameControlField();
index += kFcfSize + kDsnSize;
index += kFcfSize + GetSeqNumSize();
if (IsDstPanIdPresent(fcf))
{
@@ -941,7 +969,9 @@ uint8_t Frame::SkipAddrFieldIndex(void) const
{
uint8_t index;
VerifyOrExit(kFcfSize + kDsnSize + GetFcsSize() <= mLength, index = kInvalidIndex);
VerifyOrExit(kFcfSize + GetFcsSize() <= mLength, index = kInvalidIndex);
VerifyOrExit(!IsSequencePresent() || kFcfSize + kDsnSize + GetFcsSize() <= mLength, index = kInvalidIndex);
index = CalculateAddrFieldSize(GetFrameControlField());
@@ -951,7 +981,7 @@ exit:
uint8_t Frame::CalculateAddrFieldSize(uint16_t aFcf)
{
uint8_t size = kFcfSize + kDsnSize;
uint8_t size = kFcfSize + GetSeqNumSize(aFcf);
// This static method calculates the size (number of bytes) of
// Address header field for a given Frame Control `aFcf` value.
@@ -1538,7 +1568,14 @@ Frame::InfoString Frame::ToInfoString(void) const
uint8_t commandId, type;
Address src, dst;
string.Append("len:%d, seqnum:%d, type:", mLength, GetSequence());
if (IsSequencePresent())
{
string.Append("len:%d, seqnum:%d, type:", mLength, GetSequence());
}
else
{
string.Append("len:%d, type:", mLength);
}
type = GetType();
+44 -18
View File
@@ -386,6 +386,7 @@ public:
* @param[in] aPanIds Source and destination PAN IDs.
* @param[in] aSecurityLevel Frame security level.
* @param[in] aKeyIdMode Frame security key ID mode.
* @param[in] aSuppressSequence Whether to suppress sequence number.
*
*/
void InitMacHeader(Type aType,
@@ -393,7 +394,8 @@ public:
const Addresses &aAddrs,
const PanIds &aPanIds,
SecurityLevel aSecurityLevel,
KeyIdMode aKeyIdMode = kKeyIdMode0);
KeyIdMode aKeyIdMode = kKeyIdMode0,
bool aSuppressSequence = false);
/**
* Validates the frame.
@@ -512,7 +514,7 @@ public:
* @returns The Sequence Number value.
*
*/
uint8_t GetSequence(void) const { return GetPsdu()[kSequenceIndex]; }
uint8_t GetSequence(void) const;
/**
* Sets the Sequence Number value.
@@ -520,7 +522,24 @@ public:
* @param[in] aSequence The Sequence Number value.
*
*/
void SetSequence(uint8_t aSequence) { GetPsdu()[kSequenceIndex] = aSequence; }
void SetSequence(uint8_t aSequence);
/**
* Indicates whether or not the Sequence Number is present.
*
* @returns TRUE if the Sequence Number is present, FALSE otherwise.
*
*/
uint8_t IsSequencePresent(void) const { return !IsSequenceSuppressed(GetFrameControlField()); }
/**
* Get the size of the sequence number.
*
* @retval 0 The size of sequence number is 0, indicating it's not present.
* @retval 1 The size of sequence number is 1, indicating it's present.
*
*/
uint8_t GetSeqNumSize(void) const { return GetSeqNumSize(GetFrameControlField()); }
/**
* Indicates whether or not the Destination PAN ID is present.
@@ -1089,21 +1108,22 @@ protected:
static constexpr uint8_t kCommandIdSize = sizeof(uint8_t);
static constexpr uint8_t kKeyIndexSize = sizeof(uint8_t);
static constexpr uint16_t kFcfFrameTypeMask = 7 << 0;
static constexpr uint16_t kFcfSecurityEnabled = 1 << 3;
static constexpr uint16_t kFcfFramePending = 1 << 4;
static constexpr uint16_t kFcfAckRequest = 1 << 5;
static constexpr uint16_t kFcfPanidCompression = 1 << 6;
static constexpr uint16_t kFcfIePresent = 1 << 9;
static constexpr uint16_t kFcfDstAddrNone = 0 << 10;
static constexpr uint16_t kFcfDstAddrShort = 2 << 10;
static constexpr uint16_t kFcfDstAddrExt = 3 << 10;
static constexpr uint16_t kFcfDstAddrMask = 3 << 10;
static constexpr uint16_t kFcfFrameVersionMask = 3 << 12;
static constexpr uint16_t kFcfSrcAddrNone = 0 << 14;
static constexpr uint16_t kFcfSrcAddrShort = 2 << 14;
static constexpr uint16_t kFcfSrcAddrExt = 3 << 14;
static constexpr uint16_t kFcfSrcAddrMask = 3 << 14;
static constexpr uint16_t kFcfFrameTypeMask = 7 << 0;
static constexpr uint16_t kFcfSecurityEnabled = 1 << 3;
static constexpr uint16_t kFcfFramePending = 1 << 4;
static constexpr uint16_t kFcfAckRequest = 1 << 5;
static constexpr uint16_t kFcfPanidCompression = 1 << 6;
static constexpr uint16_t kFcfSequenceSupression = 1 << 8;
static constexpr uint16_t kFcfIePresent = 1 << 9;
static constexpr uint16_t kFcfDstAddrNone = 0 << 10;
static constexpr uint16_t kFcfDstAddrShort = 2 << 10;
static constexpr uint16_t kFcfDstAddrExt = 3 << 10;
static constexpr uint16_t kFcfDstAddrMask = 3 << 10;
static constexpr uint16_t kFcfFrameVersionMask = 3 << 12;
static constexpr uint16_t kFcfSrcAddrNone = 0 << 14;
static constexpr uint16_t kFcfSrcAddrShort = 2 << 14;
static constexpr uint16_t kFcfSrcAddrExt = 3 << 14;
static constexpr uint16_t kFcfSrcAddrMask = 3 << 14;
static constexpr uint8_t kSecLevelMask = 7 << 0;
static constexpr uint8_t kKeyIdModeMask = 3 << 3;
@@ -1144,6 +1164,12 @@ protected:
static bool IsDstAddrPresent(uint16_t aFcf) { return (aFcf & kFcfDstAddrMask) != kFcfDstAddrNone; }
static bool IsDstPanIdPresent(uint16_t aFcf);
static bool IsSequenceSuppressed(uint16_t aFcf)
{
return (aFcf & (kFcfSequenceSupression | kFcfFrameVersionMask)) == (kFcfSequenceSupression | kVersion2015);
}
static uint8_t GetSeqNumSize(uint16_t aFcf) { return !IsSequenceSuppressed(aFcf) ? kDsnSize : 0; }
static bool IsSrcAddrPresent(uint16_t aFcf) { return (aFcf & kFcfSrcAddrMask) != kFcfSrcAddrNone; }
static bool IsSrcPanIdPresent(uint16_t aFcf);
static bool IsVersion2015(uint16_t aFcf) { return (aFcf & kFcfFrameVersionMask) == kVersion2015; }
+18 -3
View File
@@ -77,9 +77,21 @@ bool otMacFrameIsAckRequested(const otRadioFrame *aFrame)
return static_cast<const Mac::Frame *>(aFrame)->GetAckRequest();
}
uint8_t otMacFrameGetSequence(const otRadioFrame *aFrame)
otError otMacFrameGetSequence(const otRadioFrame *aFrame, uint8_t *aSequence)
{
return static_cast<const Mac::Frame *>(aFrame)->GetSequence();
otError error;
if (static_cast<const Mac::Frame *>(aFrame)->IsSequencePresent())
{
*aSequence = static_cast<const Mac::Frame *>(aFrame)->GetSequence();
error = kErrorNone;
}
else
{
error = kErrorParse;
}
return error;
}
void FuzzerPlatformInit(void)
@@ -101,10 +113,13 @@ void FuzzerPlatformProcess(otInstance *aInstance)
if (otMacFrameIsAckRequested(&sRadioTransmitFrame))
{
otError error;
sRadioAckFrame.mLength = IEEE802154_ACK_LENGTH;
sRadioAckFrame.mPsdu[0] = IEEE802154_FRAME_TYPE_ACK;
sRadioAckFrame.mPsdu[1] = 0;
sRadioAckFrame.mPsdu[2] = otMacFrameGetSequence(&sRadioTransmitFrame);
error = otMacFrameGetSequence(&sRadioTransmitFrame, &sRadioAckFrame.mPsdu[2]);
OT_ASSERT(error == OT_ERROR_NONE);
sRadioAckFrame.mChannel = sRadioTransmitFrame.mChannel;
otPlatRadioTxDone(aInstance, &sRadioTransmitFrame, &sRadioAckFrame, OT_ERROR_NONE);
+24 -6
View File
@@ -205,6 +205,7 @@ void TestMacHeader(void)
Mac::Frame::KeyIdMode mKeyIdMode;
uint8_t mHeaderLength;
uint8_t mFooterLength;
bool mSuppressSequence;
};
static constexpr Mac::Frame::Version kVer2006 = Mac::Frame::kVersion2006;
@@ -265,6 +266,7 @@ void TestMacHeader(void)
{kVer2015, kExtdAddr, kNoPanId, kNoneAddr, kNoPanId, kMic32, kModeId1, 17, 6},
{kVer2015, kExtdAddr, kNoPanId, kExtdAddr, kNoPanId, kNoSec, kModeId1, 19, 2},
{kVer2015, kExtdAddr, kNoPanId, kExtdAddr, kNoPanId, kMic32, kModeId1, 25, 6},
{kVer2015, kExtdAddr, kNoPanId, kExtdAddr, kNoPanId, kMic32, kModeId1, 24, 6, true},
};
const uint16_t kPanId1 = 0xbaba;
@@ -285,7 +287,9 @@ void TestMacHeader(void)
for (const TestCase &testCase : kTestCases)
{
uint8_t psdu[OT_RADIO_FRAME_MAX_SIZE];
uint8_t psdu[OT_RADIO_FRAME_MAX_SIZE];
uint8_t offset;
Mac::TxFrame frame;
Mac::Addresses addresses;
Mac::Address address;
@@ -352,7 +356,7 @@ void TestMacHeader(void)
}
frame.InitMacHeader(Mac::Frame::kTypeData, testCase.mVersion, addresses, panIds, testCase.mSecurity,
testCase.mKeyIdMode);
testCase.mKeyIdMode, testCase.mSuppressSequence);
VerifyOrQuit(frame.GetHeaderLength() == testCase.mHeaderLength);
VerifyOrQuit(frame.GetFooterLength() == testCase.mFooterLength);
@@ -401,11 +405,20 @@ void TestMacHeader(void)
VerifyOrQuit(keyIdMode == testCase.mKeyIdMode);
}
snprintf(string, sizeof(string), "\nver:%s, src[addr:%s, pan:%s], dst[addr:%s, pan:%s], sec:%s",
(testCase.mVersion == kVer2006) ? "2006" : "2015", kAddrTypeStrings[testCase.mSrcAddrType],
kPanIdModeStrings[testCase.mSrcPanIdMode], kAddrTypeStrings[testCase.mDstAddrType],
kPanIdModeStrings[testCase.mDstPanIdMode], testCase.mSecurity == kNoSec ? "no" : "mic32");
offset = snprintf(string, sizeof(string), "\nver:%s, src[addr:%s, pan:%s], dst[addr:%s, pan:%s], sec:%s",
(testCase.mVersion == kVer2006) ? "2006" : "2015", kAddrTypeStrings[testCase.mSrcAddrType],
kPanIdModeStrings[testCase.mSrcPanIdMode], kAddrTypeStrings[testCase.mDstAddrType],
kPanIdModeStrings[testCase.mDstPanIdMode], testCase.mSecurity == kNoSec ? "no" : "mic32");
if (!testCase.mSuppressSequence)
{
VerifyOrQuit(frame.IsSequencePresent());
offset += snprintf(string + offset, sizeof(string) - offset, ", seq:%u", frame.GetSequence());
}
else
{
VerifyOrQuit(!frame.IsSequencePresent());
}
DumpBuffer(string, frame.GetPsdu(), frame.GetLength());
}
}
@@ -590,6 +603,7 @@ void TestMacFrameApi(void)
VerifyOrQuit(!frame.IsDstAddrPresent());
VerifyOrQuit(frame.GetVersion() == Mac::Frame::kVersion2006);
VerifyOrQuit(!frame.IsSrcAddrPresent());
VerifyOrQuit(frame.IsSequencePresent());
VerifyOrQuit(frame.GetSequence() == 94);
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
@@ -619,6 +633,7 @@ void TestMacFrameApi(void)
uint8_t commandId;
frame.mPsdu = mac_cmd_psdu1;
frame.mLength = sizeof(mac_cmd_psdu1);
VerifyOrQuit(frame.IsSequencePresent());
VerifyOrQuit(frame.GetSequence() == 133);
VerifyOrQuit(frame.GetVersion() == Mac::Frame::kVersion2006);
VerifyOrQuit(frame.GetType() == Mac::Frame::kTypeMacCmd);
@@ -637,6 +652,7 @@ void TestMacFrameApi(void)
// Command Identifier: Data Request (0x04)
frame.mPsdu = mac_cmd_psdu2;
frame.mLength = sizeof(mac_cmd_psdu2);
VerifyOrQuit(frame.IsSequencePresent());
VerifyOrQuit(frame.GetSequence() == 141);
VerifyOrQuit(frame.IsVersion2015());
VerifyOrQuit(frame.GetType() == Mac::Frame::kTypeMacCmd);
@@ -700,6 +716,7 @@ void TestMacFrameAckGeneration(void)
VerifyOrQuit(!ackFrame.IsDstAddrPresent());
VerifyOrQuit(!ackFrame.IsSrcAddrPresent());
VerifyOrQuit(ackFrame.GetVersion() == Mac::Frame::kVersion2006);
VerifyOrQuit(ackFrame.IsSequencePresent());
VerifyOrQuit(ackFrame.GetSequence() == 189);
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
@@ -758,6 +775,7 @@ void TestMacFrameAckGeneration(void)
VerifyOrQuit(ackFrame.IsDstAddrPresent());
VerifyOrQuit(!ackFrame.IsSrcAddrPresent());
VerifyOrQuit(ackFrame.GetVersion() == Mac::Frame::kVersion2015);
VerifyOrQuit(ackFrame.IsSequencePresent());
VerifyOrQuit(ackFrame.GetSequence() == 142);
VerifyOrQuit(csl->GetPeriod() == 3125 && csl->GetPhase() == 3105);