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()); } }