diff --git a/examples/platforms/utils/mac_frame.cpp b/examples/platforms/utils/mac_frame.cpp index d092e4c7c..0ae88db34 100644 --- a/examples/platforms/utils/mac_frame.cpp +++ b/examples/platforms/utils/mac_frame.cpp @@ -68,17 +68,17 @@ exit: bool otMacFrameIsAck(const otRadioFrame *aFrame) { - return static_cast(aFrame)->GetType() == Mac::Frame::kFcfFrameAck; + return static_cast(aFrame)->GetType() == Mac::Frame::kTypeAck; } bool otMacFrameIsData(const otRadioFrame *aFrame) { - return static_cast(aFrame)->GetType() == Mac::Frame::kFcfFrameData; + return static_cast(aFrame)->GetType() == Mac::Frame::kTypeData; } bool otMacFrameIsCommand(const otRadioFrame *aFrame) { - return static_cast(aFrame)->GetType() == Mac::Frame::kFcfFrameMacCmd; + return static_cast(aFrame)->GetType() == Mac::Frame::kTypeMacCmd; } bool otMacFrameIsDataRequest(const otRadioFrame *aFrame) diff --git a/src/core/BUILD.gn b/src/core/BUILD.gn index 2d2a9cc39..997cd638a 100644 --- a/src/core/BUILD.gn +++ b/src/core/BUILD.gn @@ -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", diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 078ab4ed8..7b4356f37 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -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 diff --git a/src/core/Makefile.am b/src/core/Makefile.am index c02878c12..282c89018 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -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 \ diff --git a/src/core/common/frame_builder.cpp b/src/core/common/frame_builder.cpp index 61620b6a6..88247ca67 100644 --- a/src/core/common/frame_builder.cpp +++ b/src/core/common/frame_builder.cpp @@ -33,6 +33,16 @@ #include "frame_builder.hpp" +#include + +#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) { diff --git a/src/core/common/frame_builder.hpp b/src/core/common/frame_builder.hpp index 42385ac88..bbbb73154 100644 --- a/src/core/common/frame_builder.hpp +++ b/src/core/common/frame_builder.hpp @@ -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`. diff --git a/src/core/mac/data_poll_sender.cpp b/src/core/mac/data_poll_sender.cpp index c42bba579..84486ffd2 100644 --- a/src/core/mac/data_poll_sender.cpp +++ b/src/core/mac/data_poll_sender.cpp @@ -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().CalcIePresent(nullptr); - - if (iePresent) + if (addresses.mDestination.IsExtended()) { - fcf |= Mac::Frame::kFcfIePresent; - } - - fcf |= Get().CalcFrameVersion(Get().FindNeighbor(dst), iePresent); - - if (dst.IsExtended()) - { - fcf |= Mac::Frame::kFcfDstAddrExt | Mac::Frame::kFcfSrcAddrExt; - src.SetExtended(Get().GetExtAddress()); + addresses.mSource.SetExtended(Get().GetExtAddress()); } else { - fcf |= Mac::Frame::kFcfDstAddrShort | Mac::Frame::kFcfSrcAddrShort; - src.SetShort(Get().GetShortAddress()); + addresses.mSource.SetShort(Get().GetShortAddress()); } - frame->InitMacHeader(fcf, Mac::Frame::kKeyIdMode1 | Mac::Frame::kSecEncMic32); + panIds.mSource = Get().GetPanId(); + panIds.mDestination = Get().GetPanId(); - if (frame->IsDstPanIdPresent()) - { - frame->SetDstPanId(Get().GetPanId()); - } + Get().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().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)); diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index 7e7480a7e..27731ad14 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -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(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; diff --git a/src/core/mac/mac_frame.cpp b/src/core/mac/mac_frame.cpp index 27e404bb4..a31350b19 100644 --- a/src/core/mac/mac_frame.cpp +++ b/src/core/mac/mac_frame.cpp @@ -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(aType) | static_cast(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(aSecurityLevel) | static_cast(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(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(kTypeAck) | static_cast(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; diff --git a/src/core/mac/mac_frame.hpp b/src/core/mac/mac_frame.hpp index 9ffe2d57c..edfb1a0da 100644 --- a/src/core/mac/mac_frame.hpp +++ b/src/core/mac/mac_frame.hpp @@ -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); diff --git a/src/core/mac/mac_types.hpp b/src/core/mac/mac_types.hpp index 3e03c75cb..9ee73986c 100644 --- a/src/core/mac/mac_types.hpp +++ b/src/core/mac/mac_types.hpp @@ -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. * diff --git a/src/core/radio/trel_link.cpp b/src/core/radio/trel_link.cpp index 9a12a9b37..f5635012d 100644 --- a/src/core/radio/trel_link.cpp +++ b/src/core/radio/trel_link.cpp @@ -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().IsRxOnWhenIdle()) { - fcf |= Mac::Frame::kFcfFramePending; + fcf |= kFcfFramePending; } // Prepare the ack frame (FCF followed by sequence number) diff --git a/src/core/radio/trel_link.hpp b/src/core/radio/trel_link.hpp index 1aa95b9ca..f19b0bbae 100644 --- a/src/core/radio/trel_link.hpp +++ b/src/core/radio/trel_link.hpp @@ -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 { diff --git a/src/core/thread/link_metrics_types.cpp b/src/core/thread/link_metrics_types.cpp index 146393692..cd5872176 100644 --- a/src/core/thread/link_metrics_types.cpp +++ b/src/core/thread/link_metrics_types.cpp @@ -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: diff --git a/src/core/thread/link_metrics_types.hpp b/src/core/thread/link_metrics_types.hpp index ce92d7b71..f0d564a3f 100644 --- a/src/core/thread/link_metrics_types.hpp +++ b/src/core/thread/link_metrics_types.hpp @@ -273,8 +273,8 @@ class SeriesInfo : public LinkedListEntry 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; diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index 877528e6f..2d8b6db52 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -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().GetShortAddress()); + addresses.mSource.SetShort(Get().GetShortAddress()); - if (macSource.IsShortAddrInvalid() || aMacDest.IsExtended()) + if (addresses.mSource.IsShortAddrInvalid() || aMacDest.IsExtended()) { - macSource.SetExtended(Get().GetExtAddress()); + addresses.mSource.SetExtended(Get().GetExtAddress()); } - fcf = Mac::Frame::kFcfFrameData | Mac::Frame::kFcfPanidCompression | Mac::Frame::kFcfSecurityEnabled; + addresses.mDestination = aMacDest; + panIds.mSource = Get().GetPanId(); + panIds.mDestination = Get().GetPanId(); - if (iePresent) - { - fcf |= Mac::Frame::kFcfIePresent; - } + PrepareMacHeaders(aFrame, Mac::Frame::kTypeData, addresses, panIds, Mac::Frame::kSecurityEncMic32, + Mac::Frame::kKeyIdMode1, nullptr); - fcf |= CalcFrameVersion(Get().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().GetPanId()); - } - IgnoreError(aFrame.SetSrcPanId(Get().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().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().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(Mac::Frame::kKeyIdMode0); + keyIdMode = Mac::Frame::kKeyIdMode0; break; case Message::kSubTypeMleAnnounce: - secCtl = static_cast(Mac::Frame::kKeyIdMode2); + keyIdMode = Mac::Frame::kKeyIdMode2; break; default: - secCtl = static_cast(Mac::Frame::kKeyIdMode1); + // Use the `kKeyIdMode1` break; } - - secCtl |= Mac::Frame::kSecEncMic32; - } - else - { - secCtl = Mac::Frame::kSecNone; } - dstpan = Get().GetPanId(); + panIds.mSource = Get().GetPanId(); + panIds.mDestination = Get().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().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().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().Contains(*aNeighbor) && static_cast(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 diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp index e836e027f..9ee160b5c 100644 --- a/src/core/thread/mesh_forwarder.hpp +++ b/src/core/thread/mesh_forwarder.hpp @@ -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 diff --git a/src/core/thread/mesh_forwarder_ftd.cpp b/src/core/thread/mesh_forwarder_ftd.cpp index 0e5bd0ad1..589a60f3d 100644 --- a/src/core/thread/mesh_forwarder_ftd.cpp +++ b/src/core/thread/mesh_forwarder_ftd.cpp @@ -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().GetPanId(); + panIds.mDestination = Get().GetPanId(); - if (iePresent) - { - fcf |= Mac::Frame::kFcfIePresent; - } - - fcf |= CalcFrameVersion(Get().FindNeighbor(mMacAddrs.mDestination), iePresent); - - aFrame.InitMacHeader(fcf, Mac::Frame::kKeyIdMode1 | Mac::Frame::kSecEncMic32); - aFrame.SetDstPanId(Get().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()); diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 132b6f6ea..c840a517f 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -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(); diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index f5a246274..dafbac82f 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -1836,7 +1836,8 @@ private: } private: - static constexpr uint8_t kKeyIdMode2Mic32 = (Mac::Frame::kKeyIdMode2 | Mac::Frame::kSecEncMic32); + static constexpr uint8_t kKeyIdMode2Mic32 = + static_cast(Mac::Frame::kKeyIdMode2) | static_cast(Mac::Frame::kSecurityEncMic32); uint8_t mSecurityControl; uint32_t mFrameCounter; diff --git a/tests/unit/test_mac_frame.cpp b/tests/unit/test_mac_frame.cpp index 846c6373e..7966b70e9 100644 --- a/tests/unit/test_mac_frame.cpp +++ b/tests/unit/test_mac_frame.cpp @@ -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(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);