From 4639dc6fd189f5046f5625c75b45a5e471316a7f Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Mon, 14 Aug 2023 13:35:08 -0700 Subject: [PATCH] [mac-frame] update `InitMacFrame()` (#9337) This commit updates the `InitMacFrame()` method to allow the caller to specify whether the source or destination PAN IDs are present or not. It also handles all cases related to PAN ID compression as defined by IEEE 802.15.4-2015. While these cases are not used by the Thread stack itself, adding them to `InitMacFrame()` makes it more capable allowing future use-cases of this method such as generating enhanced ACKs based on a received frame. The `test_mac_frame` unit test has been updated to cover the newly added cases. --- src/core/mac/data_poll_sender.cpp | 3 +- src/core/mac/mac.cpp | 4 +- src/core/mac/mac_frame.cpp | 171 +++++++++++++++++++++---- src/core/mac/mac_frame.hpp | 4 +- src/core/mac/mac_types.cpp | 18 +++ src/core/mac/mac_types.hpp | 74 ++++++++++- src/core/thread/mesh_forwarder.cpp | 10 +- src/core/thread/mesh_forwarder_ftd.cpp | 3 +- tests/unit/test_mac_frame.cpp | 137 +++++++++++++------- 9 files changed, 334 insertions(+), 90 deletions(-) diff --git a/src/core/mac/data_poll_sender.cpp b/src/core/mac/data_poll_sender.cpp index e11f1c82b..93fad6b83 100644 --- a/src/core/mac/data_poll_sender.cpp +++ b/src/core/mac/data_poll_sender.cpp @@ -577,8 +577,7 @@ Mac::TxFrame *DataPollSender::PrepareDataRequest(Mac::TxFrames &aTxFrames) addresses.mSource.SetShort(Get().GetShortAddress()); } - panIds.mSource = Get().GetPanId(); - panIds.mDestination = Get().GetPanId(); + panIds.SetBothSourceDestination(Get().GetPanId()); Get().PrepareMacHeaders(*frame, Mac::Frame::kTypeMacCmd, addresses, panIds, Mac::Frame::kSecurityEncMic32, Mac::Frame::kKeyIdMode1, nullptr); diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index f0c3951c7..ca11ec31e 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -738,7 +738,7 @@ TxFrame *Mac::PrepareBeaconRequest(void) addrs.mSource.SetNone(); addrs.mDestination.SetShort(kShortAddrBroadcast); - panIds.mDestination = kShortAddrBroadcast; + panIds.SetDestination(kShortAddrBroadcast); frame.InitMacHeader(Frame::kTypeMacCmd, Frame::kVersion2003, addrs, panIds, Frame::kSecurityNone); @@ -769,7 +769,7 @@ TxFrame *Mac::PrepareBeacon(void) #endif addrs.mSource.SetExtended(GetExtAddress()); - panIds.mSource = mPanId; + panIds.SetSource(mPanId); addrs.mDestination.SetNone(); frame->InitMacHeader(Frame::kTypeBeacon, Frame::kVersion2003, addrs, panIds, Frame::kSecurityNone); diff --git a/src/core/mac/mac_frame.cpp b/src/core/mac/mac_frame.cpp index f33e17bcf..7c54f288f 100644 --- a/src/core/mac/mac_frame.cpp +++ b/src/core/mac/mac_frame.cpp @@ -98,34 +98,105 @@ void Frame::InitMacHeader(Type aType, break; } + if (aType == kTypeAck) + { + fcf &= ~kFcfAckRequest; + } + fcf |= (aSecurityLevel != kSecurityNone) ? kFcfSecurityEnabled : 0; - // When we have both source and destination addresses we check PAN - // IDs to determine whether to include `kFcfPanidCompression`. + // PAN ID compression - if (!aAddrs.mSource.IsNone() && !aAddrs.mDestination.IsNone() && (aPanIds.mSource == aPanIds.mDestination)) + switch (aVersion) { - 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. + case kVersion2003: + case kVersion2006: - if (aAddrs.mSource.IsExtended() && aAddrs.mDestination.IsExtended()) + // For 2003-2006 versions: + // + // - If only either the destination or the source addressing information is present, + // the PAN ID Compression field shall be set to zero, and the PAN ID field of the + // single address shall be included in the transmitted frame. + // - If both destination and source addressing information is present, the MAC shall + // compare the destination and source PAN identifiers. If the PAN IDs are identical, + // the PAN ID Compression field shall be set to one, and the Source PAN ID field + // shall be omitted from the transmitted frame. If the PAN IDs are different, the + // PAN ID Compression field shall be set to zero, and both Destination PAN ID + // field and Source PAN ID fields shall be included in the transmitted frame. + + if (!aAddrs.mSource.IsNone() && !aAddrs.mDestination.IsNone() && + (aPanIds.GetSource() == aPanIds.GetDestination())) + { + fcf |= kFcfPanidCompression; + } + break; + + case kVersion2015: + // +----+--------------+--------------+--------------+--------------+--------------+ + // | No | Dest Addr | Src Addr | Dst PAN ID | Src PAN ID | PAN ID Comp | + // +----+--------------+--------------+--------------+--------------+--------------+ + // | 1 | Not Present | Not Present | Not Present | Not Present | 0 | + // | 2 | Not Present | Not Present | Present | Not Present | 1 | + // | 3 | Present | Not Present | Present | Not Present | 0 | + // | 4 | Present | Not Present | Not Present | Not Present | 1 | + // | 5 | Not Present | Present | Not Present | Present | 0 | + // | 6 | Not Present | Present | Not Present | Not Present | 1 | + // +----+--------------+--------------+--------------+--------------+--------------+ + // | 7 | Extended | Extended | Present | Not Present | 0 | + // | 8 | Extended | Extended | Not Present | Not Present | 1 | + // |----+--------------+--------------+--------------+--------------+--------------+ + // | 9 | Short | Short | Present | Present | 0 | + // | 10 | Short | Extended | Present | Present | 0 | + // | 11 | Extended | Short | Present | Present | 0 | + // | 12 | Short | Extended | Present | Not Present | 1 | + // | 13 | Extended | Short | Present | Not Present | 1 | + // | 14 | Short | Short | Present | Not Present | 1 | + // +----+--------------+--------------+--------------+--------------+--------------+ + + if (aAddrs.mDestination.IsNone()) + { + // Dst addr not present - rows 1,2,5,6. + + if ((aAddrs.mSource.IsNone() && aPanIds.IsDestinationPresent()) || // Row 2. + (!aAddrs.mSource.IsNone() && !aPanIds.IsDestinationPresent() && !aPanIds.IsSourcePresent())) // Row 6. + { + fcf |= kFcfPanidCompression; + } + + break; + } + + if (aAddrs.mSource.IsNone()) + { + // Dst addr present, Src addr not present - rows 3,4. + + if (!aPanIds.IsDestinationPresent()) // Row 4. + { + fcf |= kFcfPanidCompression; + } + + break; + } + + // Both addresses are present - rows 7 to 14. + + if (aAddrs.mSource.IsExtended() && aAddrs.mDestination.IsExtended()) + { + // Both addresses are extended - rows 7,8. + + if (aPanIds.IsDestinationPresent()) // Row 7. { break; } - - OT_FALL_THROUGH; - - case kVersion2003: - case kVersion2006: - fcf |= kFcfPanidCompression; + } + else if (aPanIds.GetSource() != aPanIds.GetDestination()) // Rows 9-14. + { break; } + + fcf |= kFcfPanidCompression; + + break; } builder.Init(mPsdu, GetMtu()); @@ -134,14 +205,14 @@ void Frame::InitMacHeader(Type aType, if (IsDstPanIdPresent(fcf)) { - IgnoreError(builder.AppendLittleEndianUint16(aPanIds.mDestination)); + IgnoreError(builder.AppendLittleEndianUint16(aPanIds.GetDestination())); } IgnoreError(builder.AppendMacAddress(aAddrs.mDestination)); if (IsSrcPanIdPresent(fcf)) { - IgnoreError(builder.AppendLittleEndianUint16(aPanIds.mSource)); + IgnoreError(builder.AppendLittleEndianUint16(aPanIds.GetSource())); } IgnoreError(builder.AppendMacAddress(aAddrs.mSource)); @@ -222,16 +293,39 @@ bool Frame::IsDstPanIdPresent(uint16_t aFcf) if (IsVersion2015(aFcf)) { + // Original table at `InitMacHeader()` + // + // +----+--------------+--------------+--------------++--------------+ + // | No | Dest Addr | Src Addr | PAN ID Comp || Dst PAN ID | + // +----+--------------+--------------+--------------++--------------+ + // | 1 | Not Present | Not Present | 0 || Not Present | + // | 2 | Not Present | Not Present | 1 || Present | + // | 3 | Present | Not Present | 0 || Present | + // | 4 | Present | Not Present | 1 || Not Present | + // | 5 | Not Present | Present | 0 || Not Present | + // | 6 | Not Present | Present | 1 || Not Present | + // +----+--------------+--------------+--------------++--------------+ + // | 7 | Extended | Extended | 0 || Present | + // | 8 | Extended | Extended | 1 || Not Present | + // |----+--------------+--------------+--------------++--------------+ + // | 9 | Short | Short | 0 || Present | + // | 10 | Short | Extended | 0 || Present | + // | 11 | Extended | Short | 0 || Present | + // | 12 | Short | Extended | 1 || Present | + // | 13 | Extended | Short | 1 || Present | + // | 14 | Short | Short | 1 || Present | + // +----+--------------+--------------+--------------++--------------+ + switch (aFcf & (kFcfDstAddrMask | kFcfSrcAddrMask | kFcfPanidCompression)) { - case (kFcfDstAddrNone | kFcfSrcAddrNone): - case (kFcfDstAddrExt | kFcfSrcAddrNone | kFcfPanidCompression): - case (kFcfDstAddrShort | kFcfSrcAddrNone | kFcfPanidCompression): - case (kFcfDstAddrNone | kFcfSrcAddrExt): - case (kFcfDstAddrNone | kFcfSrcAddrShort): - case (kFcfDstAddrNone | kFcfSrcAddrExt | kFcfPanidCompression): - case (kFcfDstAddrNone | kFcfSrcAddrShort | kFcfPanidCompression): - case (kFcfDstAddrExt | kFcfSrcAddrExt | kFcfPanidCompression): + case (kFcfDstAddrNone | kFcfSrcAddrNone): // 1 + case (kFcfDstAddrShort | kFcfSrcAddrNone | kFcfPanidCompression): // 4 (short dst) + case (kFcfDstAddrExt | kFcfSrcAddrNone | kFcfPanidCompression): // 4 (ext dst) + case (kFcfDstAddrNone | kFcfSrcAddrShort): // 5 (short src) + case (kFcfDstAddrNone | kFcfSrcAddrExt): // 5 (ext src) + case (kFcfDstAddrNone | kFcfSrcAddrShort | kFcfPanidCompression): // 6 (short src) + case (kFcfDstAddrNone | kFcfSrcAddrExt | kFcfPanidCompression): // 6 (ext src) + case (kFcfDstAddrExt | kFcfSrcAddrExt | kFcfPanidCompression): // 8 present = false; break; default: @@ -367,6 +461,27 @@ bool Frame::IsSrcPanIdPresent(uint16_t aFcf) // 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. + // + // +----+--------------+--------------+--------------++--------------+ + // | No | Dest Addr | Src Addr | PAN ID Comp || Src PAN ID | + // +----+--------------+--------------+--------------++--------------+ + // | 1 | Not Present | Not Present | 0 || Not Present | + // | 2 | Not Present | Not Present | 1 || Not Present | + // | 3 | Present | Not Present | 0 || Not Present | + // | 4 | Present | Not Present | 1 || Not Present | + // | 5 | Not Present | Present | 0 || Present | + // | 6 | Not Present | Present | 1 || Not Present | + // +----+--------------+--------------+--------------++--------------+ + // | 7 | Extended | Extended | 0 || Not Present | + // | 8 | Extended | Extended | 1 || Not Present | + // |----+--------------+--------------+--------------++--------------+ + // | 9 | Short | Short | 0 || Present | + // | 10 | Short | Extended | 0 || Present | + // | 11 | Extended | Short | 0 || Present | + // | 12 | Short | Extended | 1 || Not Present | + // | 13 | Extended | Short | 1 || Not Present | + // | 14 | Short | Short | 1 || Not Present | + // +----+--------------+--------------+--------------++--------------+ if (IsVersion2015(aFcf) && ((aFcf & (kFcfDstAddrMask | kFcfSrcAddrMask)) == (kFcfDstAddrExt | kFcfSrcAddrExt))) { diff --git a/src/core/mac/mac_frame.hpp b/src/core/mac/mac_frame.hpp index 695f8c7ef..4b3eb81f2 100644 --- a/src/core/mac/mac_frame.hpp +++ b/src/core/mac/mac_frame.hpp @@ -383,8 +383,8 @@ public: * 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. + * The Ack Request bit in FCF is set if there is destination and it is not broadcast and frame type @p aType is not + * ACK. The Frame Pending and IE Present bits are not set. * * @param[in] aType Frame type. * @param[in] aVerion Frame version. diff --git a/src/core/mac/mac_types.cpp b/src/core/mac/mac_types.cpp index 9ea115e44..87fb718ee 100644 --- a/src/core/mac/mac_types.cpp +++ b/src/core/mac/mac_types.cpp @@ -110,6 +110,24 @@ Address::InfoString Address::ToString(void) const return string; } +void PanIds::SetSource(PanId aPanId) +{ + mSource = aPanId; + mIsSourcePresent = true; +} + +void PanIds::SetDestination(PanId aPanId) +{ + mDestination = aPanId; + mIsDestinationPresent = true; +} + +void PanIds::SetBothSourceDestination(PanId aPanId) +{ + SetSource(aPanId); + SetDestination(aPanId); +} + #if OPENTHREAD_CONFIG_MULTI_RADIO const RadioType RadioTypes::kAllRadioTypes[kNumRadioTypes] = { diff --git a/src/core/mac/mac_types.hpp b/src/core/mac/mac_types.hpp index 1530b7361..955be0e20 100644 --- a/src/core/mac/mac_types.hpp +++ b/src/core/mac/mac_types.hpp @@ -425,10 +425,78 @@ struct Addresses * Represents two PAN IDs corresponding to source and destination. * */ -struct PanIds +class PanIds : public Clearable { - PanId mSource; ///< Source PAN ID. - PanId mDestination; ///< Destination PAN ID. +public: + /** + * Initializes PAN IDs as empty (no source or destination PAN ID). + * + */ + PanIds(void) { Clear(); } + + /** + * Indicates whether or not source PAN ID is present. + * + * @retval TRUE The source PAN ID is present. + * @retval FALSE The source PAN ID is not present. + * + */ + bool IsSourcePresent(void) const { return mIsSourcePresent; } + + /** + * Gets the source PAN ID when it is present. + * + * @returns The source PAN ID. + * + */ + PanId GetSource(void) const { return mSource; } + + /** + * Indicates whether or not destination PAN ID is present. + * + * @retval TRUE The destination PAN ID is present. + * @retval FALSE The destination PAN ID is not present. + * + */ + bool IsDestinationPresent(void) const { return mIsDestinationPresent; } + + /** + * Gets the destination PAN ID when it is present. + * + * @returns The destination PAN ID. + * + */ + PanId GetDestination(void) const { return mDestination; } + + /** + * Sets the source PAN ID. + * + * @param[in] aPanId The source PAN ID. + * + */ + void SetSource(PanId aPanId); + + /** + * Sets the destination PAN ID. + * + * @param[in] aPanId The source PAN ID. + * + */ + void SetDestination(PanId aPanId); + + /** + * Sets both source and destination PAN IDs to the same value. + * + * @param[in] aPanId The PAN ID. + * + */ + void SetBothSourceDestination(PanId aPanId); + +private: + PanId mSource; + PanId mDestination; + bool mIsSourcePresent; + bool mIsDestinationPresent; }; /** diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index 343e9e721..3a521e59b 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -193,8 +193,7 @@ void MeshForwarder::PrepareEmptyFrame(Mac::TxFrame &aFrame, const Mac::Address & } addresses.mDestination = aMacDest; - panIds.mSource = Get().GetPanId(); - panIds.mDestination = Get().GetPanId(); + panIds.SetBothSourceDestination(Get().GetPanId()); PrepareMacHeaders(aFrame, Mac::Frame::kTypeData, addresses, panIds, Mac::Frame::kSecurityEncMic32, Mac::Frame::kKeyIdMode1, nullptr); @@ -926,20 +925,19 @@ start: } } - panIds.mSource = Get().GetPanId(); - panIds.mDestination = Get().GetPanId(); + panIds.SetBothSourceDestination(Get().GetPanId()); switch (aMessage.GetSubType()) { case Message::kSubTypeMleAnnounce: aFrame.SetChannel(aMessage.GetChannel()); aFrame.SetRxChannelAfterTxDone(Get().GetPanChannel()); - panIds.mDestination = Mac::kPanIdBroadcast; + panIds.SetDestination(Mac::kPanIdBroadcast); break; case Message::kSubTypeMleDiscoverRequest: case Message::kSubTypeMleDiscoverResponse: - panIds.mDestination = aMessage.GetPanId(); + panIds.SetDestination(aMessage.GetPanId()); break; default: diff --git a/src/core/thread/mesh_forwarder_ftd.cpp b/src/core/thread/mesh_forwarder_ftd.cpp index ffec4c716..d77da246b 100644 --- a/src/core/thread/mesh_forwarder_ftd.cpp +++ b/src/core/thread/mesh_forwarder_ftd.cpp @@ -349,8 +349,7 @@ void MeshForwarder::SendMesh(Message &aMessage, Mac::TxFrame &aFrame) { Mac::PanIds panIds; - panIds.mSource = Get().GetPanId(); - panIds.mDestination = Get().GetPanId(); + panIds.SetBothSourceDestination(Get().GetPanId()); PrepareMacHeaders(aFrame, Mac::Frame::kTypeData, mMacAddrs, panIds, Mac::Frame::kSecurityEncMic32, Mac::Frame::kKeyIdMode1, &aMessage); diff --git a/tests/unit/test_mac_frame.cpp b/tests/unit/test_mac_frame.cpp index b92003f8c..714371af7 100644 --- a/tests/unit/test_mac_frame.cpp +++ b/tests/unit/test_mac_frame.cpp @@ -33,7 +33,7 @@ #include "radio/radio.hpp" #include "test_platform.h" -#include "test_util.h" +#include "test_util.hpp" namespace ot { @@ -189,16 +189,18 @@ void TestMacHeader(void) enum PanIdMode { - kSamePanIds, - kDiffPanIds, + kNoPanId, + kUsePanId1, + kUsePanId2, }; struct TestCase { Mac::Frame::Version mVersion; AddrType mSrcAddrType; + PanIdMode mSrcPanIdMode; AddrType mDstAddrType; - PanIdMode mPanIdMode; + PanIdMode mDstPanIdMode; Mac::Frame::SecurityLevel mSecurity; Mac::Frame::KeyIdMode mKeyIdMode; uint8_t mHeaderLength; @@ -214,37 +216,55 @@ void TestMacHeader(void) 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}, + static const char *kAddrTypeStrings[] = {"None", "Short", "Extd"}; + static const char *kPanIdModeStrings[] = {"No", "Id1", "Id2"}; - {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}, + static constexpr TestCase kTestCases[] = { + {kVer2006, kNoneAddr, kNoPanId, kNoneAddr, kNoPanId, kNoSec, kModeId1, 3, 2}, + {kVer2006, kShrtAddr, kUsePanId1, kNoneAddr, kNoPanId, kNoSec, kModeId1, 7, 2}, + {kVer2006, kExtdAddr, kUsePanId1, kNoneAddr, kNoPanId, kNoSec, kModeId1, 13, 2}, + {kVer2006, kNoneAddr, kNoPanId, kShrtAddr, kUsePanId1, kNoSec, kModeId1, 7, 2}, + {kVer2006, kNoneAddr, kNoPanId, kExtdAddr, kUsePanId1, kNoSec, kModeId1, 13, 2}, + {kVer2006, kShrtAddr, kUsePanId1, kShrtAddr, kUsePanId2, kNoSec, kModeId1, 11, 2}, + {kVer2006, kShrtAddr, kUsePanId1, kExtdAddr, kUsePanId2, kNoSec, kModeId1, 17, 2}, + {kVer2006, kExtdAddr, kUsePanId1, kShrtAddr, kUsePanId2, kNoSec, kModeId1, 17, 2}, + {kVer2006, kExtdAddr, kUsePanId1, kExtdAddr, kUsePanId2, kNoSec, kModeId1, 23, 2}, + {kVer2006, kShrtAddr, kUsePanId1, kShrtAddr, kUsePanId1, kNoSec, kModeId1, 9, 2}, + {kVer2006, kShrtAddr, kUsePanId1, kExtdAddr, kUsePanId1, kNoSec, kModeId1, 15, 2}, + {kVer2006, kExtdAddr, kUsePanId1, kShrtAddr, kUsePanId1, kNoSec, kModeId1, 15, 2}, + {kVer2006, kExtdAddr, kUsePanId1, kExtdAddr, kUsePanId1, kNoSec, kModeId1, 21, 2}, + {kVer2006, kShrtAddr, kUsePanId1, kShrtAddr, kUsePanId1, kMic32, kModeId1, 15, 6}, + {kVer2006, kShrtAddr, kUsePanId1, kShrtAddr, kUsePanId1, kMic32, kModeId2, 19, 6}, + + {kVer2015, kNoneAddr, kNoPanId, kNoneAddr, kNoPanId, kNoSec, kModeId1, 3, 2}, + {kVer2015, kShrtAddr, kUsePanId1, kNoneAddr, kNoPanId, kNoSec, kModeId1, 7, 2}, + {kVer2015, kExtdAddr, kUsePanId1, kNoneAddr, kNoPanId, kNoSec, kModeId1, 13, 2}, + {kVer2015, kNoneAddr, kNoPanId, kShrtAddr, kUsePanId1, kNoSec, kModeId1, 7, 2}, + {kVer2015, kNoneAddr, kNoPanId, kExtdAddr, kUsePanId1, kNoSec, kModeId1, 13, 2}, + {kVer2015, kShrtAddr, kUsePanId1, kShrtAddr, kUsePanId2, kNoSec, kModeId1, 11, 2}, + {kVer2015, kShrtAddr, kUsePanId1, kExtdAddr, kUsePanId2, kNoSec, kModeId1, 17, 2}, + {kVer2015, kExtdAddr, kUsePanId1, kShrtAddr, kUsePanId2, kNoSec, kModeId1, 17, 2}, + {kVer2015, kShrtAddr, kUsePanId1, kShrtAddr, kUsePanId1, kNoSec, kModeId1, 9, 2}, + {kVer2015, kShrtAddr, kUsePanId1, kExtdAddr, kUsePanId1, kNoSec, kModeId1, 15, 2}, + {kVer2015, kExtdAddr, kUsePanId1, kShrtAddr, kUsePanId1, kNoSec, kModeId1, 15, 2}, + {kVer2015, kExtdAddr, kUsePanId1, kExtdAddr, kUsePanId1, kNoSec, kModeId1, 21, 2}, + {kVer2015, kShrtAddr, kUsePanId1, kShrtAddr, kUsePanId1, kMic32, kModeId1, 15, 6}, + {kVer2015, kShrtAddr, kUsePanId1, kShrtAddr, kUsePanId1, kMic32, kModeId2, 19, 6}, + + {kVer2015, kNoneAddr, kNoPanId, kShrtAddr, kNoPanId, kNoSec, kModeId1, 5, 2}, + {kVer2015, kNoneAddr, kNoPanId, kShrtAddr, kNoPanId, kMic32, kModeId1, 11, 6}, + {kVer2015, kNoneAddr, kNoPanId, kNoneAddr, kUsePanId1, kNoSec, kModeId1, 5, 2}, + {kVer2015, kNoneAddr, kNoPanId, kNoneAddr, kUsePanId1, kMic32, kModeId1, 11, 6}, + {kVer2015, kNoneAddr, kNoPanId, kShrtAddr, kNoPanId, kNoSec, kModeId1, 5, 2}, + {kVer2015, kNoneAddr, kNoPanId, kExtdAddr, kNoPanId, kNoSec, kModeId1, 11, 2}, + {kVer2015, kNoneAddr, kNoPanId, kShrtAddr, kNoPanId, kMic32, kModeId1, 11, 6}, + {kVer2015, kNoneAddr, kNoPanId, kExtdAddr, kNoPanId, kMic32, kModeId1, 17, 6}, + {kVer2015, kShrtAddr, kNoPanId, kNoneAddr, kNoPanId, kNoSec, kModeId1, 5, 2}, + {kVer2015, kShrtAddr, kNoPanId, kNoneAddr, kNoPanId, kMic32, kModeId1, 11, 6}, + {kVer2015, kExtdAddr, kNoPanId, kNoneAddr, kNoPanId, kNoSec, kModeId1, 11, 2}, + {kVer2015, kExtdAddr, kNoPanId, kNoneAddr, kNoPanId, kMic32, kModeId1, 17, 6}, + {kVer2015, kExtdAddr, kNoPanId, kExtdAddr, kNoPanId, kNoSec, kModeId1, 19, 2}, + {kVer2015, kExtdAddr, kNoPanId, kExtdAddr, kNoPanId, kMic32, kModeId1, 25, 6}, }; const uint16_t kPanId1 = 0xbaba; @@ -254,6 +274,7 @@ void TestMacHeader(void) const uint8_t kExtAddr1[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}; const uint8_t kExtAddr2[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; + char string[100]; Mac::ExtAddress extAddr1; Mac::ExtAddress extAddr2; @@ -275,6 +296,11 @@ void TestMacHeader(void) frame.mLength = 0; frame.mRadioType = 0; + VerifyOrQuit(addresses.mSource.IsNone()); + VerifyOrQuit(addresses.mDestination.IsNone()); + VerifyOrQuit(!panIds.IsSourcePresent()); + VerifyOrQuit(!panIds.IsDestinationPresent()); + switch (testCase.mSrcAddrType) { case kNoneAddr: @@ -301,14 +327,27 @@ void TestMacHeader(void) break; } - switch (testCase.mPanIdMode) + switch (testCase.mSrcPanIdMode) { - case kSamePanIds: - panIds.mSource = panIds.mDestination = kPanId1; + case kNoPanId: break; - case kDiffPanIds: - panIds.mSource = kPanId1; - panIds.mDestination = kPanId2; + case kUsePanId1: + panIds.SetSource(kPanId1); + break; + case kUsePanId2: + panIds.SetSource(kPanId2); + break; + } + + switch (testCase.mDstPanIdMode) + { + case kNoPanId: + break; + case kUsePanId1: + panIds.SetDestination(kPanId1); + break; + case kUsePanId2: + panIds.SetDestination(kPanId2); break; } @@ -334,17 +373,20 @@ void TestMacHeader(void) SuccessOrQuit(frame.GetDstAddr(address)); VerifyOrQuit(CompareAddresses(address, addresses.mDestination)); - if (testCase.mDstAddrType != kNoneAddr) + VerifyOrQuit(frame.IsDstPanIdPresent() == (testCase.mDstPanIdMode != kNoPanId)); + + if (frame.IsDstPanIdPresent()) { - VerifyOrQuit(frame.IsDstPanIdPresent()); SuccessOrQuit(frame.GetDstPanId(panId)); - VerifyOrQuit(panId == panIds.mDestination); + VerifyOrQuit(panId == panIds.GetDestination()); + VerifyOrQuit(panIds.IsDestinationPresent()); } if (frame.IsSrcPanIdPresent()) { SuccessOrQuit(frame.GetSrcPanId(panId)); - VerifyOrQuit(panId == panIds.mSource); + VerifyOrQuit(panId == panIds.GetSource()); + VerifyOrQuit(panIds.IsSourcePresent()); } if (frame.GetSecurityEnabled()) @@ -359,7 +401,12 @@ void TestMacHeader(void) VerifyOrQuit(keyIdMode == testCase.mKeyIdMode); } - printf(" %d, %d\n", testCase.mHeaderLength, testCase.mFooterLength); + snprintf(string, sizeof(string), "\nver:%s, src[addr:%s, pan:%s], dst[addr:%s, pan:%s], sec:%s", + (testCase.mVersion == kVer2006) ? "2006" : "2015", kAddrTypeStrings[testCase.mSrcAddrType], + kPanIdModeStrings[testCase.mSrcPanIdMode], kAddrTypeStrings[testCase.mDstAddrType], + kPanIdModeStrings[testCase.mDstPanIdMode], testCase.mSecurity == kNoSec ? "no" : "mic32"); + + DumpBuffer(string, frame.GetPsdu(), frame.GetLength()); } }