mirror of
https://github.com/espressif/openthread.git
synced 2026-10-01 13:27:42 +00:00
[mac-frame] parse and store unpacked FCF/SCF fields in ParseInfo (#13534)
This commit refactors `Frame::ParseInfo` by replacing the raw `mFcf` and `mSecCtl` control field members with parsed, typed fields and boolean bit-flags, `mType`, `mVersion`, `mIsSecurityEnabled`, `mIsFramePending`, etc. This simplifies callers by allowing direct access to the parsed properties without repeatedly calling static FCF decoding helper functions.
This commit is contained in:
+50
-38
@@ -274,8 +274,9 @@ Error Frame::ParseInfo::ParseFrom(const Frame &aFrame, ParseMode aMode)
|
|||||||
|
|
||||||
Error error = kErrorParse;
|
Error error = kErrorParse;
|
||||||
FrameData frameData;
|
FrameData frameData;
|
||||||
uint16_t value;
|
uint16_t fcf;
|
||||||
uint8_t size;
|
PanId panId;
|
||||||
|
uint8_t value;
|
||||||
|
|
||||||
VerifyOrExit(aFrame.GetPsdu() != nullptr);
|
VerifyOrExit(aFrame.GetPsdu() != nullptr);
|
||||||
|
|
||||||
@@ -284,36 +285,47 @@ Error Frame::ParseInfo::ParseFrom(const Frame &aFrame, ParseMode aMode)
|
|||||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// Address Fields
|
// Address Fields
|
||||||
|
|
||||||
SuccessOrExit(frameData.ReadUint<kLittleEndian>(mFcf));
|
SuccessOrExit(frameData.ReadUint<kLittleEndian>(fcf));
|
||||||
|
|
||||||
// Only accept standard frame types (Beacon, Data, Ack, MAC Command).
|
// Only accept standard frame types (Beacon, Data, Ack, MAC Command).
|
||||||
// Other types (e.g., Multipurpose) use a different FCF/header layout.
|
// Other types (e.g., Multipurpose) use a different FCF/header layout.
|
||||||
// Also restrict frame version to 2003, 2006, 2015. Future frame
|
// Also restrict frame version to 2003, 2006, 2015. Future frame
|
||||||
// versions can alter the MAC header layout.
|
// versions can alter the MAC header layout.
|
||||||
|
|
||||||
VerifyOrExit(ReadType(mFcf) <= kTypeMacCmd);
|
value = ReadType(fcf);
|
||||||
VerifyOrExit(ReadVersion(mFcf) <= kVersion2015);
|
VerifyOrExit(value <= kTypeMacCmd);
|
||||||
|
mType = static_cast<Type>(value);
|
||||||
|
|
||||||
if (IsSeqPresent(mFcf))
|
value = ReadVersion(fcf);
|
||||||
|
VerifyOrExit(value <= kVersion2015);
|
||||||
|
mVersion = static_cast<Version>(value);
|
||||||
|
|
||||||
|
mIsSecurityEnabled = IsSecurityEnabled(fcf);
|
||||||
|
mIsFramePending = IsFramePending(fcf);
|
||||||
|
mIsAckRequest = IsAckRequest(fcf);
|
||||||
|
mIsSeqNumPresent = IsSeqPresent(fcf);
|
||||||
|
mIsIePresent = IsIePresent(fcf);
|
||||||
|
|
||||||
|
if (mIsSeqNumPresent)
|
||||||
{
|
{
|
||||||
SuccessOrExit(frameData.ReadUint8(mSequenceNum));
|
SuccessOrExit(frameData.ReadUint8(mSequenceNum));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsDstPanIdPresent(mFcf))
|
if (IsDstPanIdPresent(fcf))
|
||||||
{
|
{
|
||||||
SuccessOrExit(frameData.ReadUint<kLittleEndian>(value));
|
SuccessOrExit(frameData.ReadUint<kLittleEndian>(panId));
|
||||||
mPanIds.SetDestination(value);
|
mPanIds.SetDestination(panId);
|
||||||
}
|
}
|
||||||
|
|
||||||
SuccessOrExit(ParseAddress(frameData, ReadDstAddrMode(mFcf), mAddrs.mDestination));
|
SuccessOrExit(ParseAddress(frameData, ReadDstAddrMode(fcf), mAddrs.mDestination));
|
||||||
|
|
||||||
if (IsSrcPanIdPresent(mFcf))
|
if (IsSrcPanIdPresent(fcf))
|
||||||
{
|
{
|
||||||
SuccessOrExit(frameData.ReadUint<kLittleEndian>(value));
|
SuccessOrExit(frameData.ReadUint<kLittleEndian>(panId));
|
||||||
mPanIds.SetSource(value);
|
mPanIds.SetSource(panId);
|
||||||
}
|
}
|
||||||
|
|
||||||
SuccessOrExit(ParseAddress(frameData, ReadSrcAddrMode(mFcf), mAddrs.mSource));
|
SuccessOrExit(ParseAddress(frameData, ReadSrcAddrMode(fcf), mAddrs.mSource));
|
||||||
|
|
||||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// FCS
|
// FCS
|
||||||
@@ -328,12 +340,15 @@ Error Frame::ParseInfo::ParseFrom(const Frame &aFrame, ParseMode aMode)
|
|||||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// Aux Security Header
|
// Aux Security Header
|
||||||
|
|
||||||
if (IsSecurityEnabled(mFcf))
|
if (mIsSecurityEnabled)
|
||||||
{
|
{
|
||||||
SuccessOrExit(frameData.ReadUint8(mSecCtl));
|
uint8_t scf;
|
||||||
|
uint8_t size;
|
||||||
|
|
||||||
mSecurityLevel = ReadSecurityLevel(mSecCtl);
|
SuccessOrExit(frameData.ReadUint8(scf));
|
||||||
mKeyIdMode = ReadKeyIdMode(mSecCtl);
|
|
||||||
|
mSecurityLevel = ReadSecurityLevel(scf);
|
||||||
|
mKeyIdMode = ReadKeyIdMode(scf);
|
||||||
|
|
||||||
VerifyOrExit(mSecurityLevel != kSecurityNone);
|
VerifyOrExit(mSecurityLevel != kSecurityNone);
|
||||||
|
|
||||||
@@ -358,14 +373,14 @@ Error Frame::ParseInfo::ParseFrom(const Frame &aFrame, ParseMode aMode)
|
|||||||
|
|
||||||
if (aMode == kParseSecurityHeader)
|
if (aMode == kParseSecurityHeader)
|
||||||
{
|
{
|
||||||
VerifyOrExit(IsSecurityEnabled(mFcf), error = kErrorNotFound);
|
VerifyOrExit(mIsSecurityEnabled, error = kErrorNotFound);
|
||||||
ExitNow(error = kErrorNone);
|
ExitNow(error = kErrorNone);
|
||||||
}
|
}
|
||||||
|
|
||||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// Header IE
|
// Header IE
|
||||||
|
|
||||||
if (IsIePresent(mFcf))
|
if (mIsIePresent)
|
||||||
{
|
{
|
||||||
#if !OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
|
#if !OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
|
||||||
ExitNow();
|
ExitNow();
|
||||||
@@ -404,7 +419,7 @@ Error Frame::ParseInfo::ParseFrom(const Frame &aFrame, ParseMode aMode)
|
|||||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// MAC Command
|
// MAC Command
|
||||||
|
|
||||||
if (ReadType(mFcf) == kTypeMacCmd)
|
if (mType == kTypeMacCmd)
|
||||||
{
|
{
|
||||||
VerifyOrExit(frameData.CanRead(sizeof(mCommandId)));
|
VerifyOrExit(frameData.CanRead(sizeof(mCommandId)));
|
||||||
|
|
||||||
@@ -415,7 +430,7 @@ Error Frame::ParseInfo::ParseFrom(const Frame &aFrame, ParseMode aMode)
|
|||||||
// encrypted payload, while in earlier versions, it is part of
|
// encrypted payload, while in earlier versions, it is part of
|
||||||
// the MAC header.
|
// the MAC header.
|
||||||
|
|
||||||
if (!IsVersion2015(mFcf))
|
if (mVersion != kVersion2015)
|
||||||
{
|
{
|
||||||
frameData.SkipOver(sizeof(mCommandId));
|
frameData.SkipOver(sizeof(mCommandId));
|
||||||
}
|
}
|
||||||
@@ -789,7 +804,7 @@ Error Frame::GetCommandId(uint8_t &aCommandId) const
|
|||||||
ParseInfo info;
|
ParseInfo info;
|
||||||
|
|
||||||
SuccessOrExit(error = info.ParseFrom(*this, kParseFully));
|
SuccessOrExit(error = info.ParseFrom(*this, kParseFully));
|
||||||
VerifyOrExit(ReadType(info.mFcf) == kTypeMacCmd, error = kErrorNotFound);
|
VerifyOrExit(info.mType == kTypeMacCmd, error = kErrorNotFound);
|
||||||
aCommandId = info.mCommandId;
|
aCommandId = info.mCommandId;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
@@ -901,7 +916,7 @@ const HeaderIe *Frame::FindHeaderIe(HeaderIeMatcher aMatcher) const
|
|||||||
|
|
||||||
SuccessOrExit(info.ParseFrom(*this, kParseFully));
|
SuccessOrExit(info.ParseFrom(*this, kParseFully));
|
||||||
|
|
||||||
VerifyOrExit(IsIePresent(info.mFcf));
|
VerifyOrExit(info.mIsIePresent);
|
||||||
|
|
||||||
// `ParseFrom()` already validates that Header IE(s) are
|
// `ParseFrom()` already validates that Header IE(s) are
|
||||||
// well-formed and contained within the frame. Here we
|
// well-formed and contained within the frame. Here we
|
||||||
@@ -1098,9 +1113,9 @@ Error TxFrame::GenerateEnhAck(const RxFrame &aRxFrame, bool aIsFramePending, con
|
|||||||
|
|
||||||
SuccessOrExit(rxInfo.ParseFrom(aRxFrame, kParseFully));
|
SuccessOrExit(rxInfo.ParseFrom(aRxFrame, kParseFully));
|
||||||
|
|
||||||
VerifyOrExit(IsVersion2015(rxInfo.mFcf));
|
VerifyOrExit(rxInfo.mVersion == kVersion2015);
|
||||||
VerifyOrExit(IsAckRequest(rxInfo.mFcf));
|
VerifyOrExit(rxInfo.mIsAckRequest);
|
||||||
VerifyOrExit(IsSeqPresent(rxInfo.mFcf));
|
VerifyOrExit(rxInfo.mIsSeqNumPresent);
|
||||||
|
|
||||||
// Check `aRxFrame` has a valid destination address. The ack frame
|
// Check `aRxFrame` has a valid destination address. The ack frame
|
||||||
// will not use this as its source though and will always use no
|
// will not use this as its source though and will always use no
|
||||||
@@ -1114,7 +1129,7 @@ Error TxFrame::GenerateEnhAck(const RxFrame &aRxFrame, bool aIsFramePending, con
|
|||||||
buildInfo.mAddrs.mDestination = rxInfo.mAddrs.mSource;
|
buildInfo.mAddrs.mDestination = rxInfo.mAddrs.mSource;
|
||||||
VerifyOrExit(!buildInfo.mAddrs.mDestination.IsNone());
|
VerifyOrExit(!buildInfo.mAddrs.mDestination.IsNone());
|
||||||
|
|
||||||
if (IsSecurityEnabled(rxInfo.mFcf))
|
if (rxInfo.mIsSecurityEnabled)
|
||||||
{
|
{
|
||||||
VerifyOrExit(rxInfo.mSecurityLevel == kSecurityEncMic32);
|
VerifyOrExit(rxInfo.mSecurityLevel == kSecurityEncMic32);
|
||||||
VerifyOrExit(rxInfo.mKeyIdMode == kKeyIdMode1);
|
VerifyOrExit(rxInfo.mKeyIdMode == kKeyIdMode1);
|
||||||
@@ -1144,7 +1159,7 @@ Error TxFrame::GenerateEnhAck(const RxFrame &aRxFrame, bool aIsFramePending, con
|
|||||||
SetFramePending(aIsFramePending);
|
SetFramePending(aIsFramePending);
|
||||||
SetSequence(rxInfo.mSequenceNum);
|
SetSequence(rxInfo.mSequenceNum);
|
||||||
|
|
||||||
if (IsSecurityEnabled(rxInfo.mFcf))
|
if (rxInfo.mIsSecurityEnabled)
|
||||||
{
|
{
|
||||||
SetKeyIndex(rxInfo.mKeyIndex);
|
SetKeyIndex(rxInfo.mKeyIndex);
|
||||||
}
|
}
|
||||||
@@ -1233,7 +1248,6 @@ Frame::InfoString Frame::ToInfoString(void) const
|
|||||||
{
|
{
|
||||||
InfoString string;
|
InfoString string;
|
||||||
ParseInfo info;
|
ParseInfo info;
|
||||||
uint8_t type;
|
|
||||||
|
|
||||||
string.Append("len:%u", mLength);
|
string.Append("len:%u", mLength);
|
||||||
|
|
||||||
@@ -1243,16 +1257,14 @@ Frame::InfoString Frame::ToInfoString(void) const
|
|||||||
ExitNow();
|
ExitNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsSeqPresent(info.mFcf))
|
if (info.mIsSeqNumPresent)
|
||||||
{
|
{
|
||||||
string.Append(", seqnum:%u", info.mSequenceNum);
|
string.Append(", seqnum:%u", info.mSequenceNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
string.Append(", type:");
|
string.Append(", type:");
|
||||||
|
|
||||||
type = ReadType(info.mFcf);
|
switch (info.mType)
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
{
|
||||||
case kTypeBeacon:
|
case kTypeBeacon:
|
||||||
string.Append("Beacon");
|
string.Append("Beacon");
|
||||||
@@ -1285,15 +1297,15 @@ Frame::InfoString Frame::ToInfoString(void) const
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
string.Append("%u", type);
|
string.Append("%u", info.mType);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
string.Append(", src:%s, dst:%s, sec:%s, ackreq:%s", info.mAddrs.mSource.ToString().AsCString(),
|
string.Append(", src:%s, dst:%s, sec:%s, ackreq:%s", info.mAddrs.mSource.ToString().AsCString(),
|
||||||
info.mAddrs.mDestination.ToString().AsCString(), ToYesNo(IsSecurityEnabled(info.mFcf)),
|
info.mAddrs.mDestination.ToString().AsCString(), ToYesNo(info.mIsSecurityEnabled),
|
||||||
ToYesNo(IsAckRequest(info.mFcf)));
|
ToYesNo(info.mIsAckRequest));
|
||||||
|
|
||||||
if (IsSecurityEnabled(info.mFcf))
|
if (info.mIsSecurityEnabled)
|
||||||
{
|
{
|
||||||
string.Append(", fc:%lu", ToUlong(info.mFrameCounter));
|
string.Append(", fc:%lu", ToUlong(info.mFrameCounter));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -624,14 +624,19 @@ protected:
|
|||||||
public:
|
public:
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// Mac Header Address Info
|
// Mac Header Address Info
|
||||||
uint16_t mFcf;
|
Type mType;
|
||||||
|
Version mVersion;
|
||||||
|
bool mIsSecurityEnabled : 1;
|
||||||
|
bool mIsFramePending : 1;
|
||||||
|
bool mIsAckRequest : 1;
|
||||||
|
bool mIsSeqNumPresent : 1;
|
||||||
|
bool mIsIePresent : 1;
|
||||||
|
uint8_t mSequenceNum;
|
||||||
PanIds mPanIds;
|
PanIds mPanIds;
|
||||||
Addresses mAddrs;
|
Addresses mAddrs;
|
||||||
uint8_t mSequenceNum;
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// Aux Security Header
|
// Aux Security Header
|
||||||
uint8_t mSecCtl;
|
|
||||||
SecurityLevel mSecurityLevel;
|
SecurityLevel mSecurityLevel;
|
||||||
KeyIdMode mKeyIdMode;
|
KeyIdMode mKeyIdMode;
|
||||||
uint8_t mKeyIndex;
|
uint8_t mKeyIndex;
|
||||||
|
|||||||
Reference in New Issue
Block a user