[mac-frame] update InitMacHeader() (#8660)

This commit updates how we prepare the MAC headers:
- New `enum`s are defined in `Mac::Frame` to specify the frame
 `Type`,  `Version`, `SecurityLevel`, etc.
- `InitMacHeader()` will itself determine the Frame Control Field
  from the given address info.
- It now uses `FrameBuilder` to prepare the headers.
- New helper `MeshForwarder::PrepareMacHeaders()` is added which
  takes care of adding MAC (address, security header) along with
  any IE headers.
- These changes ensure that PAN ID Compression bit is properly
  set on MAC frames when using 2015 version (ensure that PAN
  IDs are not omitted when both addresses use Extended format).
This commit is contained in:
Abtin Keshavarzian
2023-01-17 20:01:26 -08:00
committed by GitHub
parent 57733ea668
commit fe1cf3a294
21 changed files with 664 additions and 396 deletions
+3 -3
View File
@@ -68,17 +68,17 @@ exit:
bool otMacFrameIsAck(const otRadioFrame *aFrame)
{
return static_cast<const Mac::Frame *>(aFrame)->GetType() == Mac::Frame::kFcfFrameAck;
return static_cast<const Mac::Frame *>(aFrame)->GetType() == Mac::Frame::kTypeAck;
}
bool otMacFrameIsData(const otRadioFrame *aFrame)
{
return static_cast<const Mac::Frame *>(aFrame)->GetType() == Mac::Frame::kFcfFrameData;
return static_cast<const Mac::Frame *>(aFrame)->GetType() == Mac::Frame::kTypeData;
}
bool otMacFrameIsCommand(const otRadioFrame *aFrame)
{
return static_cast<const Mac::Frame *>(aFrame)->GetType() == Mac::Frame::kFcfFrameMacCmd;
return static_cast<const Mac::Frame *>(aFrame)->GetType() == Mac::Frame::kTypeMacCmd;
}
bool otMacFrameIsDataRequest(const otRadioFrame *aFrame)
+2
View File
@@ -726,6 +726,8 @@ openthread_radio_sources = [
"common/binary_search.cpp",
"common/binary_search.hpp",
"common/error.hpp",
"common/frame_builder.cpp",
"common/frame_builder.hpp",
"common/instance.cpp",
"common/log.cpp",
"common/random.cpp",
+1
View File
@@ -255,6 +255,7 @@ set(RADIO_COMMON_SOURCES
api/tasklet_api.cpp
common/binary_search.cpp
common/error.cpp
common/frame_builder.cpp
common/instance.cpp
common/log.cpp
common/random.cpp
+1
View File
@@ -345,6 +345,7 @@ RADIO_SOURCES_COMMON = \
api/tasklet_api.cpp \
common/binary_search.cpp \
common/error.cpp \
common/frame_builder.cpp \
common/instance.cpp \
common/log.cpp \
common/random.cpp \
+36
View File
@@ -33,6 +33,16 @@
#include "frame_builder.hpp"
#include <string.h>
#include "common/code_utils.hpp"
#include "common/debug.hpp"
#include "common/encoding.hpp"
#if OPENTHREAD_FTD || OPENTHREAD_MTD
#include "common/message.hpp"
#endif
namespace ot {
void FrameBuilder::Init(void *aBuffer, uint16_t aLength)
@@ -76,6 +86,31 @@ exit:
return error;
}
Error FrameBuilder::AppendMacAddress(const Mac::Address &aMacAddress)
{
Error error = kErrorNone;
switch (aMacAddress.GetType())
{
case Mac::Address::kTypeNone:
break;
case Mac::Address::kTypeShort:
error = AppendLittleEndianUint16(aMacAddress.GetShort());
break;
case Mac::Address::kTypeExtended:
VerifyOrExit(CanAppend(sizeof(Mac::ExtAddress)), error = kErrorNoBufs);
aMacAddress.GetExtended().CopyTo(mBuffer + mLength, Mac::ExtAddress::kReverseByteOrder);
mLength += sizeof(Mac::ExtAddress);
break;
}
exit:
return error;
}
#if OPENTHREAD_FTD || OPENTHREAD_MTD
Error FrameBuilder::AppendBytesFromMessage(const Message &aMessage, uint16_t aOffset, uint16_t aLength)
{
Error error = kErrorNone;
@@ -87,6 +122,7 @@ Error FrameBuilder::AppendBytesFromMessage(const Message &aMessage, uint16_t aOf
exit:
return error;
}
#endif
void FrameBuilder::WriteBytes(uint16_t aOffset, const void *aBuffer, uint16_t aLength)
{
+15 -1
View File
@@ -37,10 +37,11 @@
#include "openthread-core-config.h"
#include "common/error.hpp"
#include "common/message.hpp"
#include "common/type_traits.hpp"
#include "mac/mac_types.hpp"
namespace ot {
class Message;
/**
* The `FrameBuilder` can be used to construct frame content in a given data buffer.
@@ -182,6 +183,18 @@ public:
*/
Error AppendBytes(const void *aBuffer, uint16_t aLength);
/**
* This method appends a given `Mac::Address` to the `FrameBuilder`.
*
* @param[in] aMacAddress A `Mac::Address` to append.
*
* @retval kErrorNone Successfully appended the address.
* @retval kErrorNoBufs Insufficient available buffers.
*
*/
Error AppendMacAddress(const Mac::Address &aMacAddress);
#if OPENTHREAD_FTD || OPENTHREAD_MTD
/**
* This method appends bytes read from a given message to the `FrameBuilder`.
*
@@ -195,6 +208,7 @@ public:
*
*/
Error AppendBytesFromMessage(const Message &aMessage, uint16_t aOffset, uint16_t aLength);
#endif
/**
* This method appends an object to the `FrameBuilder`.
+13 -38
View File
@@ -563,66 +563,41 @@ uint32_t DataPollSender::GetDefaultPollPeriod(void) const
Mac::TxFrame *DataPollSender::PrepareDataRequest(Mac::TxFrames &aTxFrames)
{
Mac::TxFrame *frame = nullptr;
Mac::Address src, dst;
uint16_t fcf;
bool iePresent;
Mac::TxFrame *frame = nullptr;
Mac::Addresses addresses;
Mac::PanIds panIds;
#if OPENTHREAD_CONFIG_MULTI_RADIO
Mac::RadioType radio;
SuccessOrExit(GetPollDestinationAddress(dst, radio));
SuccessOrExit(GetPollDestinationAddress(addresses.mDestination, radio));
frame = &aTxFrames.GetTxFrame(radio);
#else
SuccessOrExit(GetPollDestinationAddress(dst));
SuccessOrExit(GetPollDestinationAddress(addresses.mDestination));
frame = &aTxFrames.GetTxFrame();
#endif
fcf = Mac::Frame::kFcfFrameMacCmd | Mac::Frame::kFcfPanidCompression | Mac::Frame::kFcfAckRequest |
Mac::Frame::kFcfSecurityEnabled;
iePresent = Get<MeshForwarder>().CalcIePresent(nullptr);
if (iePresent)
if (addresses.mDestination.IsExtended())
{
fcf |= Mac::Frame::kFcfIePresent;
}
fcf |= Get<MeshForwarder>().CalcFrameVersion(Get<NeighborTable>().FindNeighbor(dst), iePresent);
if (dst.IsExtended())
{
fcf |= Mac::Frame::kFcfDstAddrExt | Mac::Frame::kFcfSrcAddrExt;
src.SetExtended(Get<Mac::Mac>().GetExtAddress());
addresses.mSource.SetExtended(Get<Mac::Mac>().GetExtAddress());
}
else
{
fcf |= Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrShort;
src.SetShort(Get<Mac::Mac>().GetShortAddress());
addresses.mSource.SetShort(Get<Mac::Mac>().GetShortAddress());
}
frame->InitMacHeader(fcf, Mac::Frame::kKeyIdMode1 | Mac::Frame::kSecEncMic32);
panIds.mSource = Get<Mac::Mac>().GetPanId();
panIds.mDestination = Get<Mac::Mac>().GetPanId();
if (frame->IsDstPanIdPresent())
{
frame->SetDstPanId(Get<Mac::Mac>().GetPanId());
}
Get<MeshForwarder>().PrepareMacHeaders(*frame, Mac::Frame::kTypeMacCmd, addresses, panIds,
Mac::Frame::kSecurityEncMic32, Mac::Frame::kKeyIdMode1, nullptr);
frame->SetSrcAddr(src);
frame->SetDstAddr(dst);
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
if (iePresent)
{
Get<MeshForwarder>().AppendHeaderIe(nullptr, *frame);
}
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT && OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (frame->GetHeaderIe(Mac::CslIe::kHeaderIeId) != nullptr)
{
// Disable frame retransmission when the data poll has CSL IE included
aTxFrames.SetMaxFrameRetries(0);
}
#endif
#endif
IgnoreError(frame->SetCommandId(Mac::Frame::kMacCmdDataRequest));
+28 -22
View File
@@ -224,7 +224,7 @@ Error Mac::ConvertBeaconToActiveScanResult(const RxFrame *aBeaconFrame, ActiveSc
VerifyOrExit(aBeaconFrame != nullptr, error = kErrorInvalidArgs);
VerifyOrExit(aBeaconFrame->GetType() == Frame::kFcfFrameBeacon, error = kErrorParse);
VerifyOrExit(aBeaconFrame->GetType() == Frame::kTypeBeacon, error = kErrorParse);
SuccessOrExit(error = aBeaconFrame->GetSrcAddr(address));
VerifyOrExit(address.IsExtended(), error = kErrorParse);
aResult.mExtAddress = address.GetExtended();
@@ -719,12 +719,16 @@ void Mac::FinishOperation(void)
TxFrame *Mac::PrepareBeaconRequest(void)
{
TxFrame &frame = mLinks.GetTxFrames().GetBroadcastTxFrame();
uint16_t fcf = Frame::kFcfFrameMacCmd | Frame::kFcfDstAddrShort | Frame::kFcfSrcAddrNone;
TxFrame &frame = mLinks.GetTxFrames().GetBroadcastTxFrame();
Addresses addrs;
PanIds panIds;
addrs.mSource.SetNone();
addrs.mDestination.SetShort(kShortAddrBroadcast);
panIds.mDestination = kShortAddrBroadcast;
frame.InitMacHeader(Frame::kTypeMacCmd, Frame::kVersion2003, addrs, panIds, Frame::kSecurityNone);
frame.InitMacHeader(fcf, Frame::kSecNone);
frame.SetDstPanId(kShortAddrBroadcast);
frame.SetDstAddr(kShortAddrBroadcast);
IgnoreError(frame.SetCommandId(Frame::kMacCmdBeaconRequest));
LogInfo("Sending Beacon Request");
@@ -734,9 +738,10 @@ TxFrame *Mac::PrepareBeaconRequest(void)
TxFrame *Mac::PrepareBeacon(void)
{
TxFrame *frame;
uint16_t fcf;
Beacon *beacon = nullptr;
TxFrame *frame;
Beacon *beacon = nullptr;
Addresses addrs;
PanIds panIds;
#if OPENTHREAD_CONFIG_MAC_OUTGOING_BEACON_PAYLOAD_ENABLE
uint8_t beaconLength;
BeaconPayload *beaconPayload = nullptr;
@@ -750,10 +755,11 @@ TxFrame *Mac::PrepareBeacon(void)
frame = &mLinks.GetTxFrames().GetBroadcastTxFrame();
#endif
fcf = Frame::kFcfFrameBeacon | Frame::kFcfDstAddrNone | Frame::kFcfSrcAddrExt;
frame->InitMacHeader(fcf, Frame::kSecNone);
IgnoreError(frame->SetSrcPanId(mPanId));
frame->SetSrcAddr(GetExtAddress());
addrs.mSource.SetExtended(GetExtAddress());
panIds.mSource = mPanId;
addrs.mDestination.SetNone();
frame->InitMacHeader(Frame::kTypeBeacon, Frame::kVersion2003, addrs, panIds, Frame::kSecurityNone);
beacon = reinterpret_cast<Beacon *>(frame->GetPayload());
beacon->Init();
@@ -1198,7 +1204,7 @@ void Mac::RecordFrameTransmitStatus(const TxFrame &aFrame,
ProcessEnhAckProbing(*aAckFrame, *neighbor);
#endif
#if OPENTHREAD_FTD
if (aAckFrame->GetVersion() == Frame::kFcfFrameVersion2015)
if (aAckFrame->GetVersion() == Frame::kVersion2015)
{
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
ProcessCsl(*aAckFrame, dstAddr);
@@ -1500,7 +1506,7 @@ Error Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Neig
VerifyOrExit(aFrame.GetSecurityEnabled(), error = kErrorNone);
IgnoreError(aFrame.GetSecurityLevel(securityLevel));
VerifyOrExit(securityLevel == Frame::kSecEncMic32);
VerifyOrExit(securityLevel == Frame::kSecurityEncMic32);
IgnoreError(aFrame.GetFrameCounter(frameCounter));
LogDebg("Rx security - frame counter %lu", ToUlong(frameCounter));
@@ -1638,7 +1644,7 @@ Error Mac::ProcessEnhAckSecurity(TxFrame &aTxFrame, RxFrame &aAckFrame)
VerifyOrExit(aAckFrame.IsVersion2015());
IgnoreError(aAckFrame.GetSecurityLevel(securityLevel));
VerifyOrExit(securityLevel == Frame::kSecEncMic32);
VerifyOrExit(securityLevel == Frame::kSecurityEncMic32);
IgnoreError(aAckFrame.GetKeyIdMode(keyIdMode));
VerifyOrExit(keyIdMode == Frame::kKeyIdMode1, error = kErrorNone);
@@ -1837,7 +1843,7 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, Error aError)
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
if (aFrame->GetVersion() == Frame::kFcfFrameVersion2015)
if (aFrame->GetVersion() == Frame::kVersion2015)
{
ProcessCsl(*aFrame, srcaddr);
}
@@ -1878,7 +1884,7 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, Error aError)
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 && OPENTHREAD_FTD
// From Thread 1.2, MAC Data Frame can also act as keep-alive message if child supports
if (aFrame->GetType() == Frame::kFcfFrameData && !neighbor->IsRxOnWhenIdle() &&
if (aFrame->GetType() == Frame::kTypeData && !neighbor->IsRxOnWhenIdle() &&
neighbor->IsEnhancedKeepAliveSupported())
{
neighbor->SetLastHeard(TimerMilli::GetNow());
@@ -1896,7 +1902,7 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, Error aError)
{
case kOperationActiveScan:
if (aFrame->GetType() == Frame::kFcfFrameBeacon)
if (aFrame->GetType() == Frame::kTypeBeacon)
{
mCounters.mRxBeacon++;
ReportActiveScanResult(aFrame);
@@ -1941,7 +1947,7 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, Error aError)
switch (aFrame->GetType())
{
case Frame::kFcfFrameMacCmd:
case Frame::kTypeMacCmd:
if (HandleMacCommand(*aFrame)) // returns `true` when handled
{
ExitNow(error = kErrorNone);
@@ -1949,11 +1955,11 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, Error aError)
break;
case Frame::kFcfFrameBeacon:
case Frame::kTypeBeacon:
mCounters.mRxBeacon++;
break;
case Frame::kFcfFrameData:
case Frame::kTypeData:
mCounters.mRxData++;
break;
+127 -46
View File
@@ -37,6 +37,7 @@
#include "common/code_utils.hpp"
#include "common/debug.hpp"
#include "common/frame_builder.hpp"
#include "common/log.hpp"
#include "radio/trel_link.hpp"
#if !OPENTHREAD_RADIO || OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
@@ -58,23 +59,106 @@ void HeaderIe::Init(uint16_t aId, uint8_t aLen)
SetLength(aLen);
}
void Frame::InitMacHeader(uint16_t aFcf, uint8_t aSecurityControl)
void Frame::InitMacHeader(Type aType,
Version aVersion,
const Addresses &aAddrs,
const PanIds &aPanIds,
SecurityLevel aSecurityLevel,
KeyIdMode aKeyIdMode)
{
mLength = CalculateAddrFieldSize(aFcf);
uint16_t fcf;
FrameBuilder builder;
OT_ASSERT(mLength != kInvalidSize);
fcf = static_cast<uint16_t>(aType) | static_cast<uint16_t>(aVersion);
WriteUint16(aFcf, mPsdu);
if (aFcf & kFcfSecurityEnabled)
switch (aAddrs.mSource.GetType())
{
mPsdu[mLength] = aSecurityControl;
mLength += CalculateSecurityHeaderSize(aSecurityControl);
mLength += CalculateMicSize(aSecurityControl);
case Address::kTypeNone:
fcf |= kFcfSrcAddrNone;
break;
case Address::kTypeShort:
fcf |= kFcfSrcAddrShort;
break;
case Address::kTypeExtended:
fcf |= kFcfSrcAddrExt;
break;
}
if ((aFcf & kFcfFrameTypeMask) == kFcfFrameMacCmd)
switch (aAddrs.mDestination.GetType())
{
case Address::kTypeNone:
fcf |= kFcfDstAddrNone;
break;
case Address::kTypeShort:
fcf |= kFcfDstAddrShort;
fcf |= ((aAddrs.mDestination.GetShort() == kShortAddrBroadcast) ? 0 : kFcfAckRequest);
break;
case Address::kTypeExtended:
fcf |= (kFcfDstAddrExt | kFcfAckRequest);
break;
}
fcf |= (aSecurityLevel != kSecurityNone) ? kFcfSecurityEnabled : 0;
// When we have both source and destination addresses we check PAN
// IDs to determine whether to include `kFcfPanidCompression`.
if (!aAddrs.mSource.IsNone() && !aAddrs.mDestination.IsNone() && (aPanIds.mSource == aPanIds.mDestination))
{
switch (aVersion)
{
case kVersion2015:
// Special case for a IEEE 802.15.4-2015 frame: When both
// addresses are extended, the PAN ID compression is set
// to one to indicate that no PAN ID is in the frame,
// while setting the PAN ID Compression to zero indicates
// the presence of the destination PAN ID in the frame.
if (aAddrs.mSource.IsExtended() && aAddrs.mDestination.IsExtended())
{
break;
}
OT_FALL_THROUGH;
case kVersion2003:
case kVersion2006:
fcf |= kFcfPanidCompression;
break;
}
}
builder.Init(mPsdu, GetMtu());
IgnoreError(builder.AppendLittleEndianUint16(fcf));
IgnoreError(builder.AppendUint8(0)); // Seq number
if (IsDstPanIdPresent(fcf))
{
IgnoreError(builder.AppendLittleEndianUint16(aPanIds.mDestination));
}
IgnoreError(builder.AppendMacAddress(aAddrs.mDestination));
if (IsSrcPanIdPresent(fcf))
{
IgnoreError(builder.AppendLittleEndianUint16(aPanIds.mSource));
}
IgnoreError(builder.AppendMacAddress(aAddrs.mSource));
mLength = builder.GetLength();
if (aSecurityLevel != kSecurityNone)
{
uint8_t secCtl = static_cast<uint8_t>(aSecurityLevel) | static_cast<uint8_t>(aKeyIdMode);
IgnoreError(builder.AppendUint8(secCtl));
mLength += CalculateSecurityHeaderSize(secCtl);
mLength += CalculateMicSize(secCtl);
}
if (aType == kTypeMacCmd)
{
mLength += kCommandIdSize;
}
@@ -136,7 +220,6 @@ bool Frame::IsDstPanIdPresent(uint16_t aFcf)
{
bool present = true;
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
if (IsVersion2015(aFcf))
{
switch (aFcf & (kFcfDstAddrMask | kFcfSrcAddrMask | kFcfPanidCompression))
@@ -156,7 +239,6 @@ bool Frame::IsDstPanIdPresent(uint16_t aFcf)
}
}
else
#endif
{
present = IsDstAddrPresent(aFcf);
}
@@ -277,26 +359,21 @@ exit:
bool Frame::IsSrcPanIdPresent(uint16_t aFcf)
{
bool srcPanIdPresent = false;
bool present = IsSrcAddrPresent(aFcf) && ((aFcf & kFcfPanidCompression) == 0);
if ((aFcf & kFcfSrcAddrMask) != kFcfSrcAddrNone && (aFcf & kFcfPanidCompression) == 0)
// Special case for a IEEE 802.15.4-2015 frame: When both
// addresses are extended, then the source PAN iD is not present
// independent of PAN ID Compression. In this case, if the PAN ID
// compression is set, it indicates that no PAN ID is in the
// frame, while if the PAN ID Compression is zero, it indicates
// the presence of the destination PAN ID in the frame.
if (IsVersion2015(aFcf) && ((aFcf & (kFcfDstAddrMask | kFcfSrcAddrMask)) == (kFcfDstAddrExt | kFcfSrcAddrExt)))
{
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
// Handle a special case in IEEE 802.15.4-2015, when Pan ID Compression is 0, but Src Pan ID is not present:
// Dest Address: Extended
// Source Address: Extended
// Dest Pan ID: Present
// Src Pan ID: Not Present
// Pan ID Compression: 0
if (!IsVersion2015(aFcf) || (aFcf & kFcfDstAddrMask) != kFcfDstAddrExt ||
(aFcf & kFcfSrcAddrMask) != kFcfSrcAddrExt)
#endif
{
srcPanIdPresent = true;
}
present = false;
}
return srcPanIdPresent;
return present;
}
Error Frame::GetSrcPanId(PanId &aPanId) const
@@ -619,7 +696,7 @@ bool Frame::IsDataRequestCommand(void) const
bool isDataRequest = false;
uint8_t commandId;
VerifyOrExit(GetType() == kFcfFrameMacCmd);
VerifyOrExit(GetType() == kTypeMacCmd);
SuccessOrExit(GetCommandId(commandId));
isDataRequest = (commandId == kMacCmdDataRequest);
@@ -647,23 +724,23 @@ uint8_t Frame::CalculateMicSize(uint8_t aSecurityControl)
switch (aSecurityControl & kSecLevelMask)
{
case kSecNone:
case kSecEnc:
case kSecurityNone:
case kSecurityEnc:
micSize = kMic0Size;
break;
case kSecMic32:
case kSecEncMic32:
case kSecurityMic32:
case kSecurityEncMic32:
micSize = kMic32Size;
break;
case kSecMic64:
case kSecEncMic64:
case kSecurityMic64:
case kSecurityEncMic64:
micSize = kMic64Size;
break;
case kSecMic128:
case kSecEncMic128:
case kSecurityMic128:
case kSecurityEncMic128:
micSize = kMic128Size;
break;
}
@@ -707,7 +784,7 @@ uint8_t Frame::CalculateSecurityHeaderSize(uint8_t aSecurityControl)
{
uint8_t size = kSecurityControlSize + kFrameCounterSize;
VerifyOrExit((aSecurityControl & kSecLevelMask) != kSecNone, size = kInvalidSize);
VerifyOrExit((aSecurityControl & kSecLevelMask) != kSecurityNone, size = kInvalidSize);
switch (aSecurityControl & kKeyIdModeMask)
{
@@ -845,7 +922,7 @@ uint8_t Frame::FindPayloadIndex(void) const
}
#endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
if (!IsVersion2015() && (GetFrameControlField() & kFcfFrameTypeMask) == kFcfFrameMacCmd)
if (!IsVersion2015() && (GetFrameControlField() & kFcfFrameTypeMask) == kTypeMacCmd)
{
index += kCommandIdSize;
}
@@ -898,6 +975,8 @@ Error Frame::InitIeHeaderAt(uint8_t &aIndex, uint8_t ieId, uint8_t ieContentSize
{
Error error = kErrorNone;
WriteUint16(GetFrameControlField() | kFcfIePresent, mPsdu);
if (aIndex == 0)
{
aIndex = FindHeaderIeIndex();
@@ -1175,7 +1254,7 @@ exit:
void TxFrame::GenerateImmAck(const RxFrame &aFrame, bool aIsFramePending)
{
uint16_t fcf = kFcfFrameAck | aFrame.GetVersion();
uint16_t fcf = static_cast<uint16_t>(kTypeAck) | aFrame.GetVersion();
mChannel = aFrame.mChannel;
memset(&mInfo.mTxInfo, 0, sizeof(mInfo.mTxInfo));
@@ -1196,13 +1275,15 @@ Error TxFrame::GenerateEnhAck(const RxFrame &aFrame, bool aIsFramePending, const
{
Error error = kErrorNone;
uint16_t fcf = kFcfFrameAck | kFcfFrameVersion2015 | kFcfSrcAddrNone;
uint16_t fcf;
Address address;
PanId panId;
uint8_t footerLength;
uint8_t securityControlField;
uint8_t keyId;
fcf = static_cast<uint16_t>(kTypeAck) | static_cast<uint16_t>(kVersion2015) | kFcfSrcAddrNone;
mChannel = aFrame.mChannel;
memset(&mInfo.mTxInfo, 0, sizeof(mInfo.mTxInfo));
@@ -1366,19 +1447,19 @@ Frame::InfoString Frame::ToInfoString(void) const
switch (type)
{
case kFcfFrameBeacon:
case kTypeBeacon:
string.Append("Beacon");
break;
case kFcfFrameData:
case kTypeData:
string.Append("Data");
break;
case kFcfFrameAck:
case kTypeAck:
string.Append("Ack");
break;
case kFcfFrameMacCmd:
case kTypeMacCmd:
if (GetCommandId(commandId) != kErrorNone)
{
commandId = 0xff;
+133 -70
View File
@@ -275,75 +275,81 @@ public:
class Frame : public otRadioFrame
{
public:
static constexpr uint8_t kFcfSize = sizeof(uint16_t);
static constexpr uint8_t kDsnSize = sizeof(uint8_t);
static constexpr uint8_t kSecurityControlSize = sizeof(uint8_t);
static constexpr uint8_t kFrameCounterSize = sizeof(uint32_t);
static constexpr uint8_t kCommandIdSize = sizeof(uint8_t);
static constexpr uint8_t k154FcsSize = sizeof(uint16_t);
/**
* This enumeration represents the MAC frame type.
*
* Values match the Frame Type field in Frame Control Field (FCF) as an `uint16_t`.
*
*/
enum Type : uint16_t
{
kTypeBeacon = 0, ///< Beacon Frame Type.
kTypeData = 1, ///< Data Frame Type.
kTypeAck = 2, ///< Ack Frame Type.
kTypeMacCmd = 3, ///< MAC Command Frame Type.
};
static constexpr uint16_t kFcfFrameBeacon = 0 << 0;
static constexpr uint16_t kFcfFrameData = 1 << 0;
static constexpr uint16_t kFcfFrameAck = 2 << 0;
static constexpr uint16_t kFcfFrameMacCmd = 3 << 0;
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 kFcfFrameVersion2006 = 1 << 12;
static constexpr uint16_t kFcfFrameVersion2015 = 2 << 12;
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;
/**
* This enumeration represents the MAC frame version.
*
* Values match the Version field in Frame Control Field (FCF) as an `uint16_t`.
*
*/
enum Version : uint16_t
{
kVersion2003 = 0 << 12, ///< 2003 Frame Version.
kVersion2006 = 1 << 12, ///< 2006 Frame Version.
kVersion2015 = 2 << 12, ///< 2015 Frame Version.
};
static constexpr uint8_t kSecNone = 0 << 0;
static constexpr uint8_t kSecMic32 = 1 << 0;
static constexpr uint8_t kSecMic64 = 2 << 0;
static constexpr uint8_t kSecMic128 = 3 << 0;
static constexpr uint8_t kSecEnc = 4 << 0;
static constexpr uint8_t kSecEncMic32 = 5 << 0;
static constexpr uint8_t kSecEncMic64 = 6 << 0;
static constexpr uint8_t kSecEncMic128 = 7 << 0;
static constexpr uint8_t kSecLevelMask = 7 << 0;
/**
* This enumeration represents the MAC frame security level.
*
* Values match the Security Level field in Security Control Field as an `uint8_t`.
*
*/
enum SecurityLevel : uint8_t
{
kSecurityNone = 0, ///< No security.
kSecurityMic32 = 1, ///< No encryption, MIC-32 authentication.
kSecurityMic64 = 2, ///< No encryption, MIC-64 authentication.
kSecurityMic128 = 3, ///< No encryption, MIC-128 authentication.
kSecurityEnc = 4, ///< Encryption, no authentication
kSecurityEncMic32 = 5, ///< Encryption with MIC-32 authentication.
kSecurityEncMic64 = 6, ///< Encryption with MIC-64 authentication.
kSecurityEncMic128 = 7, ///< Encryption with MIC-128 authentication.
};
static constexpr uint8_t kMic0Size = 0;
static constexpr uint8_t kMic32Size = 32 / CHAR_BIT;
static constexpr uint8_t kMic64Size = 64 / CHAR_BIT;
static constexpr uint8_t kMic128Size = 128 / CHAR_BIT;
static constexpr uint8_t kMaxMicSize = kMic128Size;
/**
* This enumeration represents the MAC frame security key identifier mode.
*
* Values match the Key Identifier Mode field in Security Control Field as an `uint8_t`.
*
*/
enum KeyIdMode : uint8_t
{
kKeyIdMode0 = 0 << 3, ///< Key ID Mode 0 - Key is determined implicitly.
kKeyIdMode1 = 1 << 3, ///< Key ID Mode 1 - Key is determined from Key Index field.
kKeyIdMode2 = 2 << 3, ///< Key ID Mode 2 - Key is determined from 4-bytes Key Source and Index fields.
kKeyIdMode3 = 3 << 3, ///< Key ID Mode 3 - Key is determined from 8-bytes Key Source and Index fields.
};
static constexpr uint8_t kKeyIdMode0 = 0 << 3;
static constexpr uint8_t kKeyIdMode1 = 1 << 3;
static constexpr uint8_t kKeyIdMode2 = 2 << 3;
static constexpr uint8_t kKeyIdMode3 = 3 << 3;
static constexpr uint8_t kKeyIdModeMask = 3 << 3;
static constexpr uint8_t kKeySourceSizeMode0 = 0;
static constexpr uint8_t kKeySourceSizeMode1 = 0;
static constexpr uint8_t kKeySourceSizeMode2 = 4;
static constexpr uint8_t kKeySourceSizeMode3 = 8;
static constexpr uint8_t kKeyIndexSize = sizeof(uint8_t);
static constexpr uint8_t kMacCmdAssociationRequest = 1;
static constexpr uint8_t kMacCmdAssociationResponse = 2;
static constexpr uint8_t kMacCmdDisassociationNotification = 3;
static constexpr uint8_t kMacCmdDataRequest = 4;
static constexpr uint8_t kMacCmdPanidConflictNotification = 5;
static constexpr uint8_t kMacCmdOrphanNotification = 6;
static constexpr uint8_t kMacCmdBeaconRequest = 7;
static constexpr uint8_t kMacCmdCoordinatorRealignment = 8;
static constexpr uint8_t kMacCmdGtsRequest = 9;
static constexpr uint8_t kImmAckLength = kFcfSize + kDsnSize + k154FcsSize;
/**
* This enumeration represents a subset of MAC Command Identifiers.
*
*/
enum CommandId : uint8_t
{
kMacCmdAssociationRequest = 1,
kMacCmdAssociationResponse = 2,
kMacCmdDisassociationNotification = 3,
kMacCmdDataRequest = 4,
kMacCmdPanidConflictNotification = 5,
kMacCmdOrphanNotification = 6,
kMacCmdBeaconRequest = 7,
kMacCmdCoordinatorRealignment = 8,
kMacCmdGtsRequest = 9,
};
static constexpr uint16_t kInfoStringSize = 128; ///< Max chars for `InfoString` (ToInfoString()).
@@ -365,11 +371,26 @@ public:
/**
* This method initializes the MAC header.
*
* @param[in] aFcf The Frame Control field.
* @param[in] aSecurityControl The Security Control field.
* This method determines and writes the Frame Control Field (FCF) and Security Control in the frame along with
* given source and destination addresses and PAN IDs.
*
* The Ack Request bit in FCF is set if there is destination and it is not broadcast. The Frame Pending and IE
* Present bits are not set.
*
* @param[in] aType Frame type.
* @param[in] aVerion Frame version.
* @param[in] aAddrs Frame source and destination addresses (each can be none, short, or extended).
* @param[in] aPanIds Source and destination PAN IDs.
* @param[in] aSeucirtyLevel Frame security level.
* @param[in] aKeyIdMode Frame security key ID mode.
*
*/
void InitMacHeader(uint16_t aFcf, uint8_t aSecurityControl);
void InitMacHeader(Type aType,
Version aVersion,
const Addresses &aAddrs,
const PanIds &aPanIds,
SecurityLevel aSecurityLevel,
KeyIdMode aKeyIdMode = kKeyIdMode0);
/**
* This method validates the frame.
@@ -395,7 +416,7 @@ public:
* @retval FALSE If this is not an Ack.
*
*/
bool IsAck(void) const { return GetType() == kFcfFrameAck; }
bool IsAck(void) const { return GetType() == kTypeAck; }
/**
* This method returns the IEEE 802.15.4 Frame Version.
@@ -918,6 +939,8 @@ public:
/**
* This template method appends an Header IE at specified index in this frame.
*
* This method also sets the IE present bit in the Frame Control Field (FCF).
*
* @param[in,out] aIndex The index to append IE. If `aIndex` is `0` on input, this method finds the index
* for the first IE and appends the IE at that position. If the position is not found
* successfully, `aIndex` will be set to `kInvalidIndex`. Otherwise the IE will be
@@ -1066,6 +1089,46 @@ public:
uint16_t GetFrameControlField(void) const;
protected:
static constexpr uint8_t kFcfSize = sizeof(uint16_t);
static constexpr uint8_t kDsnSize = sizeof(uint8_t);
static constexpr uint8_t kSecurityControlSize = sizeof(uint8_t);
static constexpr uint8_t kFrameCounterSize = sizeof(uint32_t);
static constexpr uint8_t kCommandIdSize = sizeof(uint8_t);
static constexpr uint8_t k154FcsSize = sizeof(uint16_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 uint8_t kSecLevelMask = 7 << 0;
static constexpr uint8_t kKeyIdModeMask = 3 << 3;
static constexpr uint8_t kMic0Size = 0;
static constexpr uint8_t kMic32Size = 32 / CHAR_BIT;
static constexpr uint8_t kMic64Size = 64 / CHAR_BIT;
static constexpr uint8_t kMic128Size = 128 / CHAR_BIT;
static constexpr uint8_t kMaxMicSize = kMic128Size;
static constexpr uint8_t kKeySourceSizeMode0 = 0;
static constexpr uint8_t kKeySourceSizeMode1 = 0;
static constexpr uint8_t kKeySourceSizeMode2 = 4;
static constexpr uint8_t kKeySourceSizeMode3 = 8;
static constexpr uint8_t kImmAckLength = kFcfSize + kDsnSize + k154FcsSize;
static constexpr uint8_t kInvalidIndex = 0xff;
static constexpr uint8_t kInvalidSize = kInvalidIndex;
static constexpr uint8_t kMaxPsduSize = kInvalidSize - 1;
@@ -1092,7 +1155,7 @@ protected:
static bool IsDstPanIdPresent(uint16_t aFcf);
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) == kFcfFrameVersion2015; }
static bool IsVersion2015(uint16_t aFcf) { return (aFcf & kFcfFrameVersionMask) == kVersion2015; }
static uint8_t CalculateAddrFieldSize(uint16_t aFcf);
static uint8_t CalculateSecurityHeaderSize(uint8_t aSecurityControl);
+10
View File
@@ -421,6 +421,16 @@ struct Addresses
Address mDestination; ///< Destination address.
};
/**
* This structure represents two PAN IDs corresponding to source and destination.
*
*/
struct PanIds
{
PanId mSource; ///< Source PAN ID.
PanId mDestination; ///< Destination PAN ID.
};
/**
* This class represents a MAC key.
*
+2 -2
View File
@@ -216,11 +216,11 @@ void Link::BeginTransmit(void)
if (mTxFrame.GetAckRequest())
{
uint16_t fcf = Mac::Frame::kFcfFrameAck;
uint16_t fcf = Mac::Frame::kTypeAck;
if (!Get<Mle::MleRouter>().IsRxOnWhenIdle())
{
fcf |= Mac::Frame::kFcfFramePending;
fcf |= kFcfFramePending;
}
// Prepare the ack frame (FCF followed by sequence number)
+1
View File
@@ -153,6 +153,7 @@ private:
static constexpr uint16_t k154AckFrameSize = 3 + kFcsSize;
static constexpr int8_t kRxRssi = -20; // The RSSI value used for received frames on TREL radio link.
static constexpr uint32_t kAckWaitWindow = 750; // (in msec)
static constexpr uint16_t kFcfFramePending = 1 << 4;
enum State : uint8_t
{
+3 -3
View File
@@ -137,13 +137,13 @@ bool SeriesInfo::IsFrameTypeMatch(uint8_t aFrameType) const
VerifyOrExit(!mSeriesFlags.IsMacDataFlagSet()); // Ignore this when Mac Data is accounted
match = mSeriesFlags.IsLinkProbeFlagSet();
break;
case Mac::Frame::kFcfFrameData:
case Mac::Frame::kTypeData:
match = mSeriesFlags.IsMacDataFlagSet();
break;
case Mac::Frame::kFcfFrameMacCmd:
case Mac::Frame::kTypeMacCmd:
match = mSeriesFlags.IsMacDataRequestFlagSet();
break;
case Mac::Frame::kFcfFrameAck:
case Mac::Frame::kTypeAck:
match = mSeriesFlags.IsMacAckFlagSet();
break;
default:
+2 -2
View File
@@ -273,8 +273,8 @@ class SeriesInfo : public LinkedListEntry<SeriesInfo>
public:
/**
* This constant represents Link Probe when filtering frames to be accounted using Series Flag. There's
* already `kFcfFrameData`, `kFcfFrameAck` and `kFcfFrameMacCmd`. This item is added so that we can
* filter a Link Probe for series in the same way as other frames.
* already `Mac::Frame::kTypeData`, `Mac::Frame::kTypeAck` and `Mac::Frame::kTypeMacCmd`. This item is
* added so that we can filter a Link Probe for series in the same way as other frames.
*
*/
static constexpr uint8_t kSeriesTypeLinkProbe = 0;
+61 -130
View File
@@ -164,51 +164,24 @@ exit:
void MeshForwarder::PrepareEmptyFrame(Mac::TxFrame &aFrame, const Mac::Address &aMacDest, bool aAckRequest)
{
uint16_t fcf = 0;
bool iePresent = CalcIePresent(nullptr);
Mac::Addresses addresses;
Mac::PanIds panIds;
Mac::Address macSource;
macSource.SetShort(Get<Mac::Mac>().GetShortAddress());
addresses.mSource.SetShort(Get<Mac::Mac>().GetShortAddress());
if (macSource.IsShortAddrInvalid() || aMacDest.IsExtended())
if (addresses.mSource.IsShortAddrInvalid() || aMacDest.IsExtended())
{
macSource.SetExtended(Get<Mac::Mac>().GetExtAddress());
addresses.mSource.SetExtended(Get<Mac::Mac>().GetExtAddress());
}
fcf = Mac::Frame::kFcfFrameData | Mac::Frame::kFcfPanidCompression | Mac::Frame::kFcfSecurityEnabled;
addresses.mDestination = aMacDest;
panIds.mSource = Get<Mac::Mac>().GetPanId();
panIds.mDestination = Get<Mac::Mac>().GetPanId();
if (iePresent)
{
fcf |= Mac::Frame::kFcfIePresent;
}
PrepareMacHeaders(aFrame, Mac::Frame::kTypeData, addresses, panIds, Mac::Frame::kSecurityEncMic32,
Mac::Frame::kKeyIdMode1, nullptr);
fcf |= CalcFrameVersion(Get<NeighborTable>().FindNeighbor(aMacDest), iePresent);
if (aAckRequest)
{
fcf |= Mac::Frame::kFcfAckRequest;
}
fcf |= (aMacDest.IsShort()) ? Mac::Frame::kFcfDstAddrShort : Mac::Frame::kFcfDstAddrExt;
fcf |= (macSource.IsShort()) ? Mac::Frame::kFcfSrcAddrShort : Mac::Frame::kFcfSrcAddrExt;
aFrame.InitMacHeader(fcf, Mac::Frame::kKeyIdMode1 | Mac::Frame::kSecEncMic32);
if (aFrame.IsDstPanIdPresent())
{
aFrame.SetDstPanId(Get<Mac::Mac>().GetPanId());
}
IgnoreError(aFrame.SetSrcPanId(Get<Mac::Mac>().GetPanId()));
aFrame.SetDstAddr(aMacDest);
aFrame.SetSrcAddr(macSource);
aFrame.SetFramePending(false);
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
if (iePresent)
{
AppendHeaderIe(nullptr, aFrame);
}
#endif
aFrame.SetAckRequest(aAckRequest);
aFrame.SetPayloadLength(0);
}
@@ -819,6 +792,30 @@ exit:
return frame;
}
void MeshForwarder::PrepareMacHeaders(Mac::TxFrame &aFrame,
Mac::Frame::Type aFrameType,
const Mac::Addresses &aMacAddrs,
const Mac::PanIds &aPanIds,
Mac::Frame::SecurityLevel aSecurityLevel,
Mac::Frame::KeyIdMode aKeyIdMode,
const Message *aMessage)
{
bool iePresent;
Mac::Frame::Version version;
iePresent = CalcIePresent(aMessage);
version = CalcFrameVersion(Get<NeighborTable>().FindNeighbor(aMacAddrs.mDestination), iePresent);
aFrame.InitMacHeader(aFrameType, version, aMacAddrs, aPanIds, aSecurityLevel, aKeyIdMode);
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
if (iePresent)
{
AppendHeaderIe(aMessage, aFrame);
}
#endif
}
// This method constructs a MAC data from from a given IPv6 message.
//
// This method handles generation of MAC header, mesh header (if
@@ -838,125 +835,59 @@ uint16_t MeshForwarder::PrepareDataFrame(Mac::TxFrame &aFrame,
uint16_t aMeshDest,
bool aAddFragHeader)
{
uint16_t fcf;
uint16_t payloadLength;
uint16_t dstpan;
uint8_t secCtl;
uint16_t origMsgOffset;
uint16_t nextOffset;
FrameBuilder frameBuilder;
bool iePresent = CalcIePresent(&aMessage);
Mac::Frame::SecurityLevel securityLevel;
Mac::Frame::KeyIdMode keyIdMode;
Mac::PanIds panIds;
uint16_t payloadLength;
uint16_t origMsgOffset;
uint16_t nextOffset;
FrameBuilder frameBuilder;
start:
// Initialize MAC header
fcf = Mac::Frame::kFcfFrameData;
fcf |= (aMacAddrs.mDestination.IsShort()) ? Mac::Frame::kFcfDstAddrShort : Mac::Frame::kFcfDstAddrExt;
fcf |= (aMacAddrs.mSource.IsShort()) ? Mac::Frame::kFcfSrcAddrShort : Mac::Frame::kFcfSrcAddrExt;
if (iePresent)
{
fcf |= Mac::Frame::kFcfIePresent;
}
fcf |= CalcFrameVersion(Get<NeighborTable>().FindNeighbor(aMacAddrs.mDestination), iePresent);
// All unicast frames request ACK
if (aMacAddrs.mDestination.IsExtended() || !aMacAddrs.mDestination.IsBroadcast())
{
fcf |= Mac::Frame::kFcfAckRequest;
}
securityLevel = Mac::Frame::kSecurityNone;
keyIdMode = Mac::Frame::kKeyIdMode1;
if (aMessage.IsLinkSecurityEnabled())
{
fcf |= Mac::Frame::kFcfSecurityEnabled;
securityLevel = Mac::Frame::kSecurityEncMic32;
switch (aMessage.GetSubType())
{
case Message::kSubTypeJoinerEntrust:
secCtl = static_cast<uint8_t>(Mac::Frame::kKeyIdMode0);
keyIdMode = Mac::Frame::kKeyIdMode0;
break;
case Message::kSubTypeMleAnnounce:
secCtl = static_cast<uint8_t>(Mac::Frame::kKeyIdMode2);
keyIdMode = Mac::Frame::kKeyIdMode2;
break;
default:
secCtl = static_cast<uint8_t>(Mac::Frame::kKeyIdMode1);
// Use the `kKeyIdMode1`
break;
}
secCtl |= Mac::Frame::kSecEncMic32;
}
else
{
secCtl = Mac::Frame::kSecNone;
}
dstpan = Get<Mac::Mac>().GetPanId();
panIds.mSource = Get<Mac::Mac>().GetPanId();
panIds.mDestination = Get<Mac::Mac>().GetPanId();
switch (aMessage.GetSubType())
{
case Message::kSubTypeMleAnnounce:
aFrame.SetChannel(aMessage.GetChannel());
dstpan = Mac::kPanIdBroadcast;
panIds.mDestination = Mac::kPanIdBroadcast;
break;
case Message::kSubTypeMleDiscoverRequest:
case Message::kSubTypeMleDiscoverResponse:
dstpan = aMessage.GetPanId();
panIds.mDestination = aMessage.GetPanId();
break;
default:
break;
}
// Handle special case in 15.4-2015:
// Dest Address: Extended
// Source Address: Extended
// Dest PanId: Present
// Src Panid: Not Present
// Pan ID Compression: 0
if (dstpan == Get<Mac::Mac>().GetPanId() &&
((fcf & Mac::Frame::kFcfFrameVersionMask) == Mac::Frame::kFcfFrameVersion2006 ||
(fcf & Mac::Frame::kFcfDstAddrMask) != Mac::Frame::kFcfDstAddrExt ||
(fcf & Mac::Frame::kFcfSrcAddrMask) != Mac::Frame::kFcfSrcAddrExt))
{
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
// Handle a special case in IEEE 802.15.4-2015, when Pan ID Compression is 0, but Src Pan ID is not present:
// Dest Address: Extended
// Src Address: Extended
// Dest Pan ID: Present
// Src Pan ID: Not Present
// Pan ID Compression: 0
if ((fcf & Mac::Frame::kFcfFrameVersionMask) != Mac::Frame::kFcfFrameVersion2015 ||
(fcf & Mac::Frame::kFcfDstAddrMask) != Mac::Frame::kFcfDstAddrExt ||
(fcf & Mac::Frame::kFcfSrcAddrMask) != Mac::Frame::kFcfSrcAddrExt)
#endif
{
fcf |= Mac::Frame::kFcfPanidCompression;
}
}
aFrame.InitMacHeader(fcf, secCtl);
if (aFrame.IsDstPanIdPresent())
{
aFrame.SetDstPanId(dstpan);
}
IgnoreError(aFrame.SetSrcPanId(Get<Mac::Mac>().GetPanId()));
aFrame.SetDstAddr(aMacAddrs.mDestination);
aFrame.SetSrcAddr(aMacAddrs.mSource);
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
if (iePresent)
{
AppendHeaderIe(&aMessage, aFrame);
}
#endif
PrepareMacHeaders(aFrame, Mac::Frame::kTypeData, aMacAddrs, panIds, securityLevel, keyIdMode, &aMessage);
frameBuilder.Init(aFrame.GetPayload(), aFrame.GetMaxPayloadLength());
@@ -1376,7 +1307,7 @@ void MeshForwarder::HandleReceivedFrame(Mac::RxFrame &aFrame)
switch (aFrame.GetType())
{
case Mac::Frame::kFcfFrameData:
case Mac::Frame::kTypeData:
if (Lowpan::MeshHeader::IsMeshHeader(frameData))
{
#if OPENTHREAD_FTD
@@ -1400,7 +1331,7 @@ void MeshForwarder::HandleReceivedFrame(Mac::RxFrame &aFrame)
break;
case Mac::Frame::kFcfFrameBeacon:
case Mac::Frame::kTypeBeacon:
break;
default:
@@ -1756,7 +1687,7 @@ void MeshForwarder::AppendHeaderIe(const Message *aMessage, Mac::TxFrame &aFrame
uint8_t index = 0;
bool iePresent = false;
bool payloadPresent =
(aFrame.GetType() == Mac::Frame::kFcfFrameMacCmd) || (aMessage != nullptr && aMessage->GetLength() != 0);
(aFrame.GetType() == Mac::Frame::kTypeMacCmd) || (aMessage != nullptr && aMessage->GetLength() != 0);
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
if (aMessage != nullptr && aMessage->IsTimeSync())
@@ -1786,26 +1717,26 @@ void MeshForwarder::AppendHeaderIe(const Message *aMessage, Mac::TxFrame &aFrame
}
#endif
uint16_t MeshForwarder::CalcFrameVersion(const Neighbor *aNeighbor, bool aIePresent)
Mac::Frame::Version MeshForwarder::CalcFrameVersion(const Neighbor *aNeighbor, bool aIePresent) const
{
uint16_t version = Mac::Frame::kFcfFrameVersion2006;
Mac::Frame::Version version = Mac::Frame::kVersion2006;
OT_UNUSED_VARIABLE(aNeighbor);
if (aIePresent)
{
version = Mac::Frame::kFcfFrameVersion2015;
version = Mac::Frame::kVersion2015;
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
else if ((aNeighbor != nullptr) && Get<ChildTable>().Contains(*aNeighbor) &&
static_cast<const Child *>(aNeighbor)->IsCslSynchronized())
{
version = Mac::Frame::kFcfFrameVersion2015;
version = Mac::Frame::kVersion2015;
}
#endif
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
else if (aNeighbor != nullptr && aNeighbor->IsEnhAckProbingActive())
{
version = Mac::Frame::kFcfFrameVersion2015; ///< Set version to 2015 to fetch Link Metrics data in Enh-ACK.
version = Mac::Frame::kVersion2015; ///< Set version to 2015 to fetch Link Metrics data in Enh-ACK.
}
#endif
+11 -2
View File
@@ -445,6 +445,15 @@ private:
void HandleMesh(FrameData &aFrameData, const Mac::Address &aMacSource, const ThreadLinkInfo &aLinkInfo);
void HandleFragment(FrameData &aFrameData, const Mac::Addresses &aMacAddrs, const ThreadLinkInfo &aLinkInfo);
void HandleLowpanHC(const FrameData &aFrameData, const Mac::Addresses &aMacAddrs, const ThreadLinkInfo &aLinkInfo);
void PrepareMacHeaders(Mac::TxFrame &aFrame,
Mac::Frame::Type aFrameType,
const Mac::Addresses &aMacAddr,
const Mac::PanIds &aPanIds,
Mac::Frame::SecurityLevel aSecurityLevel,
Mac::Frame::KeyIdMode aKeyIdMode,
const Message *aMessage);
uint16_t PrepareDataFrame(Mac::TxFrame &aFrame,
Message &aMessage,
const Mac::Addresses &aMacAddrs,
@@ -504,8 +513,8 @@ private:
const Mac::Addresses &aMeshAddrs,
Message::Priority &aPriority);
bool CalcIePresent(const Message *aMessage);
uint16_t CalcFrameVersion(const Neighbor *aNeighbor, bool aIePresent);
bool CalcIePresent(const Message *aMessage);
Mac::Frame::Version CalcFrameVersion(const Neighbor *aNeighbor, bool aIePresent) const;
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
void AppendHeaderIe(const Message *aMessage, Mac::TxFrame &aFrame);
#endif
+5 -23
View File
@@ -349,31 +349,13 @@ void MeshForwarder::RemoveDataResponseMessages(void)
void MeshForwarder::SendMesh(Message &aMessage, Mac::TxFrame &aFrame)
{
uint16_t fcf;
bool iePresent = CalcIePresent(&aMessage);
Mac::PanIds panIds;
// initialize MAC header
fcf = Mac::Frame::kFcfFrameData | Mac::Frame::kFcfPanidCompression | Mac::Frame::kFcfDstAddrShort |
Mac::Frame::kFcfSrcAddrShort | Mac::Frame::kFcfAckRequest | Mac::Frame::kFcfSecurityEnabled;
panIds.mSource = Get<Mac::Mac>().GetPanId();
panIds.mDestination = Get<Mac::Mac>().GetPanId();
if (iePresent)
{
fcf |= Mac::Frame::kFcfIePresent;
}
fcf |= CalcFrameVersion(Get<NeighborTable>().FindNeighbor(mMacAddrs.mDestination), iePresent);
aFrame.InitMacHeader(fcf, Mac::Frame::kKeyIdMode1 | Mac::Frame::kSecEncMic32);
aFrame.SetDstPanId(Get<Mac::Mac>().GetPanId());
aFrame.SetDstAddr(mMacAddrs.mDestination.GetShort());
aFrame.SetSrcAddr(mMacAddrs.mSource);
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
if (iePresent)
{
AppendHeaderIe(&aMessage, aFrame);
}
#endif
PrepareMacHeaders(aFrame, Mac::Frame::kTypeData, mMacAddrs, panIds, Mac::Frame::kSecurityEncMic32,
Mac::Frame::kKeyIdMode1, &aMessage);
// write payload
OT_ASSERT(aMessage.GetLength() <= aFrame.GetMaxPayloadLength());
+1 -1
View File
@@ -2328,7 +2328,7 @@ Error Mle::ProcessMessageSecurity(Crypto::AesCcm::Mode aMode,
}
senderAddress->GetIid().ConvertToExtAddress(extAddress);
Crypto::AesCcm::GenerateNonce(extAddress, aHeader.GetFrameCounter(), Mac::Frame::kSecEncMic32, nonce);
Crypto::AesCcm::GenerateNonce(extAddress, aHeader.GetFrameCounter(), Mac::Frame::kSecurityEncMic32, nonce);
keySequence = aHeader.GetKeyId();
+2 -1
View File
@@ -1836,7 +1836,8 @@ private:
}
private:
static constexpr uint8_t kKeyIdMode2Mic32 = (Mac::Frame::kKeyIdMode2 | Mac::Frame::kSecEncMic32);
static constexpr uint8_t kKeyIdMode2Mic32 =
static_cast<uint8_t>(Mac::Frame::kKeyIdMode2) | static_cast<uint8_t>(Mac::Frame::kSecurityEncMic32);
uint8_t mSecurityControl;
uint32_t mFrameCounter;
+207 -52
View File
@@ -53,6 +53,30 @@ bool CompareReversed(const uint8_t *aFirst, const uint8_t *aSecond, uint16_t aLe
return matches;
}
bool CompareAddresses(const Mac::Address &aFirst, const Mac::Address &aSecond)
{
bool matches = false;
VerifyOrExit(aFirst.GetType() == aSecond.GetType());
switch (aFirst.GetType())
{
case Mac::Address::kTypeNone:
break;
case Mac::Address::kTypeShort:
VerifyOrExit(aFirst.GetShort() == aSecond.GetShort());
break;
case Mac::Address::kTypeExtended:
VerifyOrExit(aFirst.GetExtended() == aSecond.GetExtended());
break;
}
matches = true;
exit:
return matches;
}
void TestMacAddress(void)
{
const uint8_t kExtAddr[OT_EXT_ADDRESS_SIZE] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
@@ -156,57 +180,186 @@ void TestMacAddress(void)
void TestMacHeader(void)
{
static const struct
enum AddrType : uint8_t
{
uint16_t fcf;
uint8_t secCtl;
uint8_t headerLength;
uint8_t footerLength;
} tests[] = {
{Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrNone | Mac::Frame::kFcfSrcAddrNone, 0, 3, 2},
{Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrNone | Mac::Frame::kFcfSrcAddrShort, 0, 7, 2},
{Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrNone | Mac::Frame::kFcfSrcAddrExt, 0, 13, 2},
{Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrNone, 0, 7, 2},
{Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrExt | Mac::Frame::kFcfSrcAddrNone, 0, 13, 2},
{Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrShort, 0, 11, 2},
{Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrExt, 0, 17, 2},
{Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrExt | Mac::Frame::kFcfSrcAddrShort, 0, 17, 2},
{Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrExt | Mac::Frame::kFcfSrcAddrExt, 0, 23, 2},
{Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrShort |
Mac::Frame::kFcfPanidCompression,
0, 9, 2},
{Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrExt |
Mac::Frame::kFcfPanidCompression,
0, 15, 2},
{Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrExt | Mac::Frame::kFcfSrcAddrShort |
Mac::Frame::kFcfPanidCompression,
0, 15, 2},
{Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrExt | Mac::Frame::kFcfSrcAddrExt |
Mac::Frame::kFcfPanidCompression,
0, 21, 2},
{Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrShort |
Mac::Frame::kFcfPanidCompression | Mac::Frame::kFcfSecurityEnabled,
Mac::Frame::kSecMic32 | Mac::Frame::kKeyIdMode1, 15, 6},
{Mac::Frame::kFcfFrameVersion2006 | Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrShort |
Mac::Frame::kFcfPanidCompression | Mac::Frame::kFcfSecurityEnabled,
Mac::Frame::kSecMic32 | Mac::Frame::kKeyIdMode2, 19, 6},
kNoneAddr,
kShrtAddr,
kExtdAddr,
};
for (const auto &test : tests)
enum PanIdMode
{
uint8_t psdu[OT_RADIO_FRAME_MAX_SIZE];
Mac::TxFrame frame;
kSamePanIds,
kDiffPanIds,
};
struct TestCase
{
Mac::Frame::Version mVersion;
AddrType mSrcAddrType;
AddrType mDstAddrType;
PanIdMode mPanIdMode;
Mac::Frame::SecurityLevel mSecurity;
Mac::Frame::KeyIdMode mKeyIdMode;
uint8_t mHeaderLength;
uint8_t mFooterLength;
};
static constexpr Mac::Frame::Version kVer2006 = Mac::Frame::kVersion2006;
static constexpr Mac::Frame::Version kVer2015 = Mac::Frame::kVersion2015;
static constexpr Mac::Frame::SecurityLevel kNoSec = Mac::Frame::kSecurityNone;
static constexpr Mac::Frame::SecurityLevel kMic32 = Mac::Frame::kSecurityMic32;
static constexpr Mac::Frame::KeyIdMode kModeId1 = Mac::Frame::kKeyIdMode1;
static constexpr Mac::Frame::KeyIdMode kModeId2 = Mac::Frame::kKeyIdMode2;
static constexpr TestCase kTestCases[] = {
{kVer2006, kNoneAddr, kNoneAddr, kSamePanIds, kNoSec, kModeId1, 3, 2},
{kVer2006, kShrtAddr, kNoneAddr, kSamePanIds, kNoSec, kModeId1, 7, 2},
{kVer2006, kExtdAddr, kNoneAddr, kSamePanIds, kNoSec, kModeId1, 13, 2},
{kVer2006, kNoneAddr, kShrtAddr, kSamePanIds, kNoSec, kModeId1, 7, 2},
{kVer2006, kNoneAddr, kExtdAddr, kSamePanIds, kNoSec, kModeId1, 13, 2},
{kVer2006, kShrtAddr, kShrtAddr, kDiffPanIds, kNoSec, kModeId1, 11, 2},
{kVer2006, kShrtAddr, kExtdAddr, kDiffPanIds, kNoSec, kModeId1, 17, 2},
{kVer2006, kExtdAddr, kShrtAddr, kDiffPanIds, kNoSec, kModeId1, 17, 2},
{kVer2006, kExtdAddr, kExtdAddr, kDiffPanIds, kNoSec, kModeId1, 23, 2},
{kVer2006, kShrtAddr, kShrtAddr, kSamePanIds, kNoSec, kModeId1, 9, 2},
{kVer2006, kShrtAddr, kExtdAddr, kSamePanIds, kNoSec, kModeId1, 15, 2},
{kVer2006, kExtdAddr, kShrtAddr, kSamePanIds, kNoSec, kModeId1, 15, 2},
{kVer2006, kExtdAddr, kExtdAddr, kSamePanIds, kNoSec, kModeId1, 21, 2},
{kVer2006, kShrtAddr, kShrtAddr, kSamePanIds, kMic32, kModeId1, 15, 6},
{kVer2006, kShrtAddr, kShrtAddr, kSamePanIds, kMic32, kModeId2, 19, 6},
{kVer2015, kNoneAddr, kNoneAddr, kSamePanIds, kNoSec, kModeId1, 3, 2},
{kVer2015, kShrtAddr, kNoneAddr, kSamePanIds, kNoSec, kModeId1, 7, 2},
{kVer2015, kExtdAddr, kNoneAddr, kSamePanIds, kNoSec, kModeId1, 13, 2},
{kVer2015, kNoneAddr, kShrtAddr, kSamePanIds, kNoSec, kModeId1, 7, 2},
{kVer2015, kNoneAddr, kExtdAddr, kSamePanIds, kNoSec, kModeId1, 13, 2},
{kVer2015, kShrtAddr, kShrtAddr, kDiffPanIds, kNoSec, kModeId1, 11, 2},
{kVer2015, kShrtAddr, kExtdAddr, kDiffPanIds, kNoSec, kModeId1, 17, 2},
{kVer2015, kExtdAddr, kShrtAddr, kDiffPanIds, kNoSec, kModeId1, 17, 2},
{kVer2015, kShrtAddr, kShrtAddr, kSamePanIds, kNoSec, kModeId1, 9, 2},
{kVer2015, kShrtAddr, kExtdAddr, kSamePanIds, kNoSec, kModeId1, 15, 2},
{kVer2015, kExtdAddr, kShrtAddr, kSamePanIds, kNoSec, kModeId1, 15, 2},
{kVer2015, kExtdAddr, kExtdAddr, kSamePanIds, kNoSec, kModeId1, 21, 2},
{kVer2015, kShrtAddr, kShrtAddr, kSamePanIds, kMic32, kModeId1, 15, 6},
{kVer2015, kShrtAddr, kShrtAddr, kSamePanIds, kMic32, kModeId2, 19, 6},
};
const uint16_t kPanId1 = 0xbaba;
const uint16_t kPanId2 = 0xdede;
const uint16_t kShortAddr1 = 0x1234;
const uint16_t kShortAddr2 = 0x5678;
const uint8_t kExtAddr1[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
const uint8_t kExtAddr2[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
Mac::ExtAddress extAddr1;
Mac::ExtAddress extAddr2;
extAddr1.Set(kExtAddr1);
extAddr2.Set(kExtAddr2);
printf("TestMacHeader\n");
for (const TestCase &testCase : kTestCases)
{
uint8_t psdu[OT_RADIO_FRAME_MAX_SIZE];
Mac::TxFrame frame;
Mac::Addresses addresses;
Mac::Address address;
Mac::PanIds panIds;
Mac::PanId panId;
frame.mPsdu = psdu;
frame.mLength = 0;
frame.mRadioType = 0;
frame.InitMacHeader(test.fcf, test.secCtl);
VerifyOrQuit(frame.GetHeaderLength() == test.headerLength);
VerifyOrQuit(frame.GetFooterLength() == test.footerLength);
VerifyOrQuit(frame.GetLength() == test.headerLength + test.footerLength);
switch (testCase.mSrcAddrType)
{
case kNoneAddr:
addresses.mSource.SetNone();
break;
case kShrtAddr:
addresses.mSource.SetShort(kShortAddr1);
break;
case kExtdAddr:
addresses.mSource.SetExtended(extAddr1);
break;
}
switch (testCase.mDstAddrType)
{
case kNoneAddr:
addresses.mDestination.SetNone();
break;
case kShrtAddr:
addresses.mDestination.SetShort(kShortAddr2);
break;
case kExtdAddr:
addresses.mDestination.SetExtended(extAddr2);
break;
}
switch (testCase.mPanIdMode)
{
case kSamePanIds:
panIds.mSource = panIds.mDestination = kPanId1;
break;
case kDiffPanIds:
panIds.mSource = kPanId1;
panIds.mDestination = kPanId2;
break;
}
frame.InitMacHeader(Mac::Frame::kTypeData, testCase.mVersion, addresses, panIds, testCase.mSecurity,
testCase.mKeyIdMode);
VerifyOrQuit(frame.GetHeaderLength() == testCase.mHeaderLength);
VerifyOrQuit(frame.GetFooterLength() == testCase.mFooterLength);
VerifyOrQuit(frame.GetLength() == testCase.mHeaderLength + testCase.mFooterLength);
VerifyOrQuit(frame.GetType() == Mac::Frame::kTypeData);
VerifyOrQuit(!frame.IsAck());
VerifyOrQuit(frame.GetVersion() == testCase.mVersion);
VerifyOrQuit(frame.GetSecurityEnabled() == (testCase.mSecurity != kNoSec));
VerifyOrQuit(!frame.GetFramePending());
VerifyOrQuit(!frame.IsIePresent());
VerifyOrQuit(frame.GetAckRequest() == (testCase.mDstAddrType != kNoneAddr));
VerifyOrQuit(frame.IsSrcAddrPresent() == (testCase.mSrcAddrType != kNoneAddr));
SuccessOrQuit(frame.GetSrcAddr(address));
VerifyOrQuit(CompareAddresses(address, addresses.mSource));
VerifyOrQuit(frame.IsDstAddrPresent() == (testCase.mDstAddrType != kNoneAddr));
SuccessOrQuit(frame.GetDstAddr(address));
VerifyOrQuit(CompareAddresses(address, addresses.mDestination));
if (testCase.mDstAddrType != kNoneAddr)
{
VerifyOrQuit(frame.IsDstPanIdPresent());
SuccessOrQuit(frame.GetDstPanId(panId));
VerifyOrQuit(panId == panIds.mDestination);
}
if (frame.IsSrcPanIdPresent())
{
SuccessOrQuit(frame.GetSrcPanId(panId));
VerifyOrQuit(panId == panIds.mSource);
}
if (frame.GetSecurityEnabled())
{
uint8_t security;
uint8_t keyIdMode;
SuccessOrQuit(frame.GetSecurityLevel(security));
VerifyOrQuit(security == testCase.mSecurity);
SuccessOrQuit(frame.GetKeyIdMode(keyIdMode));
VerifyOrQuit(keyIdMode == testCase.mKeyIdMode);
}
printf(" %d, %d\n", testCase.mHeaderLength, testCase.mFooterLength);
}
}
@@ -381,14 +534,14 @@ void TestMacFrameApi(void)
// FCS: 0x9bd2 (Correct)
frame.mPsdu = ack_psdu1;
frame.mLength = sizeof(ack_psdu1);
VerifyOrQuit(frame.GetType() == Mac::Frame::kFcfFrameAck);
VerifyOrQuit(frame.GetType() == Mac::Frame::kTypeAck);
VerifyOrQuit(!frame.GetSecurityEnabled());
VerifyOrQuit(!frame.GetFramePending());
VerifyOrQuit(!frame.GetAckRequest());
VerifyOrQuit(!frame.IsIePresent());
VerifyOrQuit(!frame.IsDstPanIdPresent());
VerifyOrQuit(!frame.IsDstAddrPresent());
VerifyOrQuit(frame.GetVersion() == Mac::Frame::kFcfFrameVersion2006);
VerifyOrQuit(frame.GetVersion() == Mac::Frame::kVersion2006);
VerifyOrQuit(!frame.IsSrcAddrPresent());
VerifyOrQuit(frame.GetSequence() == 94);
@@ -420,8 +573,8 @@ void TestMacFrameApi(void)
frame.mPsdu = mac_cmd_psdu1;
frame.mLength = sizeof(mac_cmd_psdu1);
VerifyOrQuit(frame.GetSequence() == 133);
VerifyOrQuit(frame.GetVersion() == Mac::Frame::kFcfFrameVersion2006);
VerifyOrQuit(frame.GetType() == Mac::Frame::kFcfFrameMacCmd);
VerifyOrQuit(frame.GetVersion() == Mac::Frame::kVersion2006);
VerifyOrQuit(frame.GetType() == Mac::Frame::kTypeMacCmd);
SuccessOrQuit(frame.GetCommandId(commandId));
VerifyOrQuit(commandId == Mac::Frame::kMacCmdDataRequest);
SuccessOrQuit(frame.SetCommandId(Mac::Frame::kMacCmdBeaconRequest));
@@ -439,7 +592,7 @@ void TestMacFrameApi(void)
frame.mLength = sizeof(mac_cmd_psdu2);
VerifyOrQuit(frame.GetSequence() == 141);
VerifyOrQuit(frame.IsVersion2015());
VerifyOrQuit(frame.GetType() == Mac::Frame::kFcfFrameMacCmd);
VerifyOrQuit(frame.GetType() == Mac::Frame::kTypeMacCmd);
SuccessOrQuit(frame.GetCommandId(commandId));
VerifyOrQuit(commandId == Mac::Frame::kMacCmdDataRequest);
printf("commandId:%d\n", commandId);
@@ -452,6 +605,8 @@ void TestMacFrameApi(void)
void TestMacFrameAckGeneration(void)
{
constexpr uint8_t kImmAckLength = 5;
Mac::RxFrame receivedFrame;
Mac::TxFrame ackFrame;
uint8_t ackFrameBuffer[100];
@@ -487,8 +642,8 @@ void TestMacFrameAckGeneration(void)
receivedFrame.mLength = sizeof(data_psdu1);
ackFrame.GenerateImmAck(receivedFrame, false);
VerifyOrQuit(ackFrame.mLength == Mac::Frame::kImmAckLength);
VerifyOrQuit(ackFrame.GetType() == Mac::Frame::kFcfFrameAck);
VerifyOrQuit(ackFrame.mLength == kImmAckLength);
VerifyOrQuit(ackFrame.GetType() == Mac::Frame::kTypeAck);
VerifyOrQuit(!ackFrame.GetSecurityEnabled());
VerifyOrQuit(!ackFrame.GetFramePending());
@@ -497,7 +652,7 @@ void TestMacFrameAckGeneration(void)
VerifyOrQuit(!ackFrame.IsDstPanIdPresent());
VerifyOrQuit(!ackFrame.IsDstAddrPresent());
VerifyOrQuit(!ackFrame.IsSrcAddrPresent());
VerifyOrQuit(ackFrame.GetVersion() == Mac::Frame::kFcfFrameVersion2006);
VerifyOrQuit(ackFrame.GetVersion() == Mac::Frame::kVersion2006);
VerifyOrQuit(ackFrame.GetSequence() == 189);
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
@@ -548,13 +703,13 @@ void TestMacFrameAckGeneration(void)
IgnoreError(ackFrame.GenerateEnhAck(receivedFrame, false, ie_data, sizeof(ie_data)));
csl = reinterpret_cast<Mac::CslIe *>(ackFrame.GetHeaderIe(Mac::CslIe::kHeaderIeId) + sizeof(Mac::HeaderIe));
VerifyOrQuit(ackFrame.mLength == 23);
VerifyOrQuit(ackFrame.GetType() == Mac::Frame::kFcfFrameAck);
VerifyOrQuit(ackFrame.GetType() == Mac::Frame::kTypeAck);
VerifyOrQuit(ackFrame.GetSecurityEnabled());
VerifyOrQuit(ackFrame.IsIePresent());
VerifyOrQuit(!ackFrame.IsDstPanIdPresent());
VerifyOrQuit(ackFrame.IsDstAddrPresent());
VerifyOrQuit(!ackFrame.IsSrcAddrPresent());
VerifyOrQuit(ackFrame.GetVersion() == Mac::Frame::kFcfFrameVersion2015);
VerifyOrQuit(ackFrame.GetVersion() == Mac::Frame::kVersion2015);
VerifyOrQuit(ackFrame.GetSequence() == 142);
VerifyOrQuit(csl->GetPeriod() == 3125 && csl->GetPhase() == 3105);