[mac] refactor code to add frame version and header IE in TX frames (#6189)

This commit refactors the code to set frame version, IE present field
in frame control field and to append Header IE.

- Split UpdateFrameControlField into two methods: CalcIePresent and
  CalcFrameVersion. Currently UpdateFrameControlField` is not
  easy-to-read and hard to extend the method to handle more cases.

- Move this code from Mac to MeshForwarder. I think it should be
  MeshForwarder's responsibility (PrepareDataFrame) to prepare the
  frame (though Mac sometimes prepare data frames itself). Since when
  preparing the frame, most information comes from the Message which
  is only in MeshForwarder, we can put this code for preparing frame
  in MeshForwarder.

- Enhance the way to append Header IEs to the frame. Currently in
  Mac::AppendHeaderIe, it generates a list of HeaderIe first and then
  call Frame::AppendHeaderIe. There are two problems here: 1. it uses
  another copy (copy HeaderIe to the frame's buffer). 2. it has to
  initialize Vendor IE (e.g. TimeSync IE) after Vendor IE header has
  been copied to the buffer. Currently it directly finds the first
  Vendor IE in the buffer and initialize it as TimeSync IE, which is
  not extensible. This commit shifts the responsibility of 'how to
  append the IE' to Frame, by providing AppendHeaderIeAt method. And
  MeshForwarder can decide which IEs to append and directly call the
  method to append IEs to the frame.
This commit is contained in:
Li Cao
2021-02-25 08:02:52 -08:00
committed by GitHub
parent 2195f39e94
commit 75ac125771
9 changed files with 263 additions and 183 deletions
+2 -2
View File
@@ -230,7 +230,7 @@ uint8_t otMacFrameGenerateCslIeTemplate(uint8_t *aDest)
{
assert(aDest != nullptr);
reinterpret_cast<Mac::HeaderIe *>(aDest)->SetId(Mac::Frame::kHeaderIeCsl);
reinterpret_cast<Mac::HeaderIe *>(aDest)->SetId(Mac::CslIe::kHeaderIeId);
reinterpret_cast<Mac::HeaderIe *>(aDest)->SetLength(sizeof(Mac::CslIe));
return sizeof(Mac::HeaderIe) + sizeof(Mac::CslIe);
@@ -244,7 +244,7 @@ uint8_t otMacFrameGenerateEnhAckProbingIe(uint8_t *aDest, const uint8_t *aIeData
assert(aDest != nullptr);
reinterpret_cast<Mac::HeaderIe *>(aDest)->SetId(Mac::Frame::kHeaderIeVendor);
reinterpret_cast<Mac::HeaderIe *>(aDest)->SetId(Mac::ThreadIe::kHeaderIeId);
reinterpret_cast<Mac::HeaderIe *>(aDest)->SetLength(len);
aDest += sizeof(Mac::HeaderIe);
+13 -107
View File
@@ -903,6 +903,7 @@ TxFrame *Mac::PrepareDataRequest(void)
TxFrame *frame = nullptr;
Address src, dst;
uint16_t fcf;
bool iePresent = Get<MeshForwarder>().CalcIePresent(nullptr);
#if OPENTHREAD_CONFIG_MULTI_RADIO
RadioType radio;
@@ -915,7 +916,13 @@ TxFrame *Mac::PrepareDataRequest(void)
#endif
fcf = Frame::kFcfFrameMacCmd | Frame::kFcfPanidCompression | Frame::kFcfAckRequest | Frame::kFcfSecurityEnabled;
UpdateFrameControlField(nullptr, /* aIsTimeSync */ false, fcf);
if (iePresent)
{
fcf |= Frame::kFcfIePresent;
}
fcf |= Get<MeshForwarder>().CalcFrameVersion(Get<NeighborTable>().FindNeighbor(dst), iePresent);
if (dst.IsExtended())
{
@@ -938,7 +945,10 @@ TxFrame *Mac::PrepareDataRequest(void)
frame->SetSrcAddr(src);
frame->SetDstAddr(dst);
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
IgnoreError(AppendHeaderIe(false, *frame));
if (iePresent)
{
Get<MeshForwarder>().AppendHeaderIe(nullptr, *frame);
}
#endif
IgnoreError(frame->SetCommandId(Frame::kMacCmdDataRequest));
@@ -2565,7 +2575,7 @@ bool Mac::IsCslEnabled(void) const
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
void Mac::ProcessCsl(const RxFrame &aFrame, const Address &aSrcAddr)
{
const uint8_t *cur = aFrame.GetHeaderIe(Frame::kHeaderIeCsl);
const uint8_t *cur = aFrame.GetHeaderIe(CslIe::kHeaderIeId);
Child * child = Get<ChildTable>().FindChild(aSrcAddr, Child::kInStateAnyExceptInvalid);
const CslIe * csl;
@@ -2615,109 +2625,5 @@ exit:
}
#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_ENABLE
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
otError Mac::AppendHeaderIe(bool aIsTimeSync, TxFrame &aFrame) const
{
OT_UNUSED_VARIABLE(aIsTimeSync);
const size_t kMaxNumHeaderIe = 3; // TimeSync + CSL + Termination2
HeaderIe ieList[kMaxNumHeaderIe];
otError error = OT_ERROR_NONE;
uint8_t ieCount = 0;
VerifyOrExit(aFrame.IsVersion2015() && aFrame.IsIePresent());
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
if (aIsTimeSync)
{
ieList[ieCount].Init();
ieList[ieCount].SetId(Frame::kHeaderIeVendor);
ieList[ieCount].SetLength(sizeof(TimeIe));
ieCount++;
}
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (IsCslEnabled())
{
OT_ASSERT(aFrame.GetSecurityEnabled());
aFrame.mInfo.mTxInfo.mCslPresent = true;
ieList[ieCount].Init();
ieList[ieCount].SetId(Frame::kHeaderIeCsl);
ieList[ieCount].SetLength(sizeof(CslIe));
ieCount++;
}
else
#endif
{
aFrame.mInfo.mTxInfo.mCslPresent = false;
}
if (ieCount > 0)
{
ieList[ieCount].Init();
ieList[ieCount].SetId(Frame::kHeaderIeTermination2);
ieList[ieCount].SetLength(0);
SuccessOrExit(error = aFrame.AppendHeaderIe(ieList, ++ieCount));
}
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
if (aIsTimeSync)
{
uint8_t *cur = aFrame.GetHeaderIe(Frame::kHeaderIeVendor);
TimeIe * ie = reinterpret_cast<TimeIe *>(cur + sizeof(HeaderIe));
ie->Init();
}
#endif
exit:
return error;
}
#endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
void Mac::UpdateFrameControlField(const Neighbor *aNeighbor, bool aIsTimeSync, uint16_t &aFcf) const
{
OT_UNUSED_VARIABLE(aIsTimeSync);
OT_UNUSED_VARIABLE(aNeighbor);
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
if (aIsTimeSync)
{
aFcf |= Frame::kFcfFrameVersion2015 | Frame::kFcfIePresent;
}
else
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (IsCslEnabled())
{
aFcf |= Frame::kFcfFrameVersion2015 | Frame::kFcfIePresent;
}
else
#endif
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
if (aNeighbor != nullptr && !Mle::MleRouter::IsActiveRouter(aNeighbor->GetRloc16()) &&
static_cast<const Child *>(aNeighbor)->IsCslSynchronized())
{
aFcf |= Frame::kFcfFrameVersion2015;
}
else
#endif
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_ENABLE
if (aNeighbor != nullptr && aNeighbor->IsEnhAckProbingActive())
{
aFcf |= Frame::kFcfFrameVersion2015; ///< Set version to 2015 to fetch Link Metrics data in Enh-ACK.
}
else
#endif
#endif
{
aFcf |= Frame::kFcfFrameVersion2006;
}
}
} // namespace Mac
} // namespace ot
-29
View File
@@ -746,35 +746,6 @@ public:
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
/**
* This method appends header IEs to a TX-frame according to its
* frame control field and if time sync is enabled.
*
* @param[in] aIsTimeSync A boolean indicates if time sync is being used.
* @param[in,out] aFrame A reference to the TX-frame to which the IEs will be appended.
*
* @retval OT_ERROR_NONE If append header IEs successfully.
* @retval OT_ERROR_NOT_FOUND If cannot find header IE position in the frame.
*
*/
otError AppendHeaderIe(bool aIsTimeSync, TxFrame &aFrame) const;
#endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
/**
* This method updates frame control field.
*
* If the frame would contain header IEs, IE present field would be set.
* If this is a CSL transmission frame or header IE is present in this frame,
* the version should be set to 2015. Otherwise, the version would be set to 2006.
*
* @param[in] aNeighbor A pointer to the destination device, could be `nullptr`.
* @param[in] aIsTimeSync A boolean indicates if time sync is being used.
* @param[out] aFcf A reference to the frame control field to set.
*
*/
void UpdateFrameControlField(const Neighbor *aNeighbor, bool aIsTimeSync, uint16_t &aFcf) const;
private:
enum
{
+67 -15
View File
@@ -50,6 +50,13 @@ using ot::Encoding::LittleEndian::ReadUint32;
using ot::Encoding::LittleEndian::WriteUint16;
using ot::Encoding::LittleEndian::WriteUint32;
void HeaderIe::Init(uint16_t aId, uint8_t aLen)
{
Init();
SetId(aId);
SetLength(aLen);
}
void Frame::InitMacHeader(uint16_t aFcf, uint8_t aSecurityControl)
{
mLength = CalculateAddrFieldSize(aFcf);
@@ -829,7 +836,7 @@ uint8_t Frame::FindPayloadIndex(void) const
index += ie->GetLength();
VerifyOrExit(index + footerLength <= mLength, index = kInvalidIndex);
if (ie->GetId() == kHeaderIeTermination2)
if (ie->GetId() == Termination2Ie::kHeaderIeId)
{
break;
}
@@ -886,25 +893,59 @@ exit:
return index;
}
otError Frame::AppendHeaderIe(HeaderIe *aIeList, uint8_t aIeCount)
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
template <typename IeType> otError Frame::AppendHeaderIeAt(uint8_t &aIndex)
{
otError error = OT_ERROR_NONE;
uint16_t index = FindHeaderIeIndex();
otError error = OT_ERROR_NONE;
VerifyOrExit(index != kInvalidIndex, error = OT_ERROR_NOT_FOUND);
SuccessOrExit(error = InitIeHeaderAt(aIndex, IeType::kHeaderIeId, IeType::kIeContentSize));
for (uint8_t i = 0; i < aIeCount; i++)
{
memcpy(&mPsdu[index], &aIeList[i], sizeof(HeaderIe));
index += sizeof(HeaderIe) + aIeList[i].GetLength();
mLength += sizeof(HeaderIe) + aIeList[i].GetLength();
}
InitIeContentAt<IeType>(aIndex);
exit:
return error;
}
otError Frame::InitIeHeaderAt(uint8_t &aIndex, uint8_t ieId, uint8_t ieContentSize)
{
otError error = OT_ERROR_NONE;
if (aIndex == 0)
{
aIndex = FindHeaderIeIndex();
}
VerifyOrExit(aIndex != kInvalidIndex, error = OT_ERROR_NOT_FOUND);
reinterpret_cast<HeaderIe *>(mPsdu + aIndex)->Init(ieId, ieContentSize);
aIndex += sizeof(HeaderIe);
mLength += sizeof(HeaderIe) + ieContentSize;
exit:
return error;
}
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
template <> void Frame::InitIeContentAt<TimeIe>(uint8_t &aIndex)
{
reinterpret_cast<TimeIe *>(mPsdu + aIndex)->Init();
aIndex += sizeof(TimeIe);
}
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
template <> void Frame::InitIeContentAt<CslIe>(uint8_t &aIndex)
{
aIndex += sizeof(CslIe);
}
#endif
template <> void Frame::InitIeContentAt<Termination2Ie>(uint8_t &aIndex)
{
OT_UNUSED_VARIABLE(aIndex);
}
#endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
const uint8_t *Frame::GetHeaderIe(uint8_t aIeId) const
{
uint8_t index = FindHeaderIeIndex();
@@ -948,7 +989,7 @@ const uint8_t *Frame::GetThreadIe(uint8_t aSubType) const
{
const HeaderIe *ie = reinterpret_cast<const HeaderIe *>(&mPsdu[index]);
if (ie->GetId() == kHeaderIeVendor)
if (ie->GetId() == VendorIeHeader::kHeaderIeId)
{
const VendorIeHeader *vendorIe =
reinterpret_cast<const VendorIeHeader *>(reinterpret_cast<const uint8_t *>(ie) + sizeof(HeaderIe));
@@ -972,7 +1013,7 @@ exit:
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
void Frame::SetCslIe(uint16_t aCslPeriod, uint16_t aCslPhase)
{
uint8_t *cur = GetHeaderIe(Frame::kHeaderIeCsl);
uint8_t *cur = GetHeaderIe(CslIe::kHeaderIeId);
CslIe * csl;
VerifyOrExit(cur != nullptr);
@@ -1002,7 +1043,7 @@ const TimeIe *Frame::GetTimeIe(void) const
const TimeIe * timeIe = nullptr;
const uint8_t *cur = nullptr;
cur = GetHeaderIe(kHeaderIeVendor);
cur = GetHeaderIe(VendorIeHeader::kHeaderIeId);
VerifyOrExit(cur != nullptr);
cur += sizeof(HeaderIe);
@@ -1079,6 +1120,17 @@ uint8_t Frame::GetFcsSize(void) const
}
#endif
// Explicit instantiation
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
template otError Frame::AppendHeaderIeAt<TimeIe>(uint8_t &aIndex);
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
template otError Frame::AppendHeaderIeAt<CslIe>(uint8_t &aIndex);
#endif
template otError Frame::AppendHeaderIeAt<Termination2Ie>(uint8_t &aIndex);
#endif
void TxFrame::CopyFrom(const TxFrame &aFromFrame)
{
uint8_t * psduBuffer = mPsdu;
+64 -10
View File
@@ -71,6 +71,15 @@ public:
*/
void Init(void) { mFields.m16 = 0; }
/**
* This method initializes the Header IE with Id and Length.
*
* @param[in] aId The IE Element Id.
* @param[in] aLen The IE content length.
*
*/
void Init(uint16_t aId, uint8_t aLen);
/**
* This method returns the IE Element Id.
*
@@ -144,6 +153,12 @@ OT_TOOL_PACKED_BEGIN
class VendorIeHeader
{
public:
enum : uint8_t
{
kHeaderIeId = 0x00,
kIeContentSize = sizeof(uint8_t) * 4,
};
/**
* This method returns the Vendor OUI.
*
@@ -205,6 +220,12 @@ public:
kVendorIeTime = 0x01,
};
enum
{
kHeaderIeId = VendorIeHeader::kHeaderIeId,
kIeContentSize = VendorIeHeader::kIeContentSize + sizeof(uint8_t) + sizeof(uint64_t),
};
/**
* This method initializes the time IE.
*
@@ -257,6 +278,12 @@ private:
class ThreadIe
{
public:
enum : uint8_t
{
kHeaderIeId = VendorIeHeader::kHeaderIeId,
kIeContentSize = VendorIeHeader::kIeContentSize,
};
enum : uint32_t
{
kVendorOuiThreadCompanyId = 0xeab89b,
@@ -348,10 +375,6 @@ public:
kMacCmdCoordinatorRealignment = 8,
kMacCmdGtsRequest = 9,
kHeaderIeVendor = 0x00,
kHeaderIeCsl = 0x1a,
kHeaderIeTermination2 = 0x7f,
kImmAckLength = kFcfSize + kDsnSize + k154FcsSize,
kInfoStringSize = 128, ///< Max chars needed for the info string representation (@sa ToInfoString()).
@@ -923,16 +946,22 @@ public:
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
/**
* This method appends Header IEs to MAC header.
* This template method appends an Header IE at specified index in this frame.
*
* @param[in] aIeList The pointer to the Header IEs array.
* @param[in] aIeCount The number of Header IEs in the array.
* @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
* appended at `aIndex` on input. And on output, `aIndex` will be set to the end of the
* IE just appended.
*
* @retval OT_ERROR_NONE Successfully appended the Header IEs.
* @retval OT_ERROR_FAILED If IE Present bit is not set.
* @tparam IeType The Header IE type, it MUST contain an enum `kHeaderIeId` equal to the IE's Id
* and an enum `kIeContentSize` indicating the IE body's size.
*
* @retval OT_ERROR_NONE Successfully appended the Header IE.
* @retval OT_ERROR_NOT_FOUND The position for first IE is not found.
*
*/
otError AppendHeaderIe(HeaderIe *aIeList, uint8_t aIeCount);
template <typename IeType> otError AppendHeaderIeAt(uint8_t &aIndex);
/**
* This method returns a pointer to the Header IE.
@@ -1091,6 +1120,9 @@ protected:
uint8_t FindPayloadIndex(void) const;
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
uint8_t FindHeaderIeIndex(void) const;
otError InitIeHeaderAt(uint8_t &aIndex, uint8_t ieId, uint8_t ieContentSize);
template <typename IeType> void InitIeContentAt(uint8_t &aIndex);
#endif
static uint8_t GetKeySourceLength(uint8_t aKeyIdMode);
@@ -1642,6 +1674,12 @@ OT_TOOL_PACKED_BEGIN
class CslIe
{
public:
enum : uint8_t
{
kHeaderIeId = 0x1a,
kIeContentSize = sizeof(uint16_t) * 2,
};
/**
* This method returns the CSL Period.
*
@@ -1679,6 +1717,22 @@ private:
uint16_t mPeriod;
} OT_TOOL_PACKED_END;
/**
* This class implements Termination2 IE.
*
* This class is empty for template specialization.
*
*/
class Termination2Ie
{
public:
enum : uint8_t
{
kHeaderIeId = 0x7f,
kIeContentSize = 0,
};
};
/**
* @}
*
+97 -6
View File
@@ -154,7 +154,8 @@ exit:
void MeshForwarder::PrepareEmptyFrame(Mac::TxFrame &aFrame, const Mac::Address &aMacDest, bool aAckRequest)
{
uint16_t fcf = 0;
uint16_t fcf = 0;
bool iePresent = CalcIePresent(nullptr);
Mac::Address macSource;
macSource.SetShort(Get<Mac::Mac>().GetShortAddress());
@@ -166,6 +167,13 @@ void MeshForwarder::PrepareEmptyFrame(Mac::TxFrame &aFrame, const Mac::Address &
fcf = Mac::Frame::kFcfFrameData | Mac::Frame::kFcfPanidCompression | Mac::Frame::kFcfSecurityEnabled;
if (iePresent)
{
fcf |= Mac::Frame::kFcfIePresent;
}
fcf |= CalcFrameVersion(Get<NeighborTable>().FindNeighbor(aMacDest), iePresent);
if (aAckRequest)
{
fcf |= Mac::Frame::kFcfAckRequest;
@@ -173,7 +181,6 @@ void MeshForwarder::PrepareEmptyFrame(Mac::TxFrame &aFrame, const Mac::Address &
fcf |= (aMacDest.IsShort()) ? Mac::Frame::kFcfDstAddrShort : Mac::Frame::kFcfDstAddrExt;
fcf |= (macSource.IsShort()) ? Mac::Frame::kFcfSrcAddrShort : Mac::Frame::kFcfSrcAddrExt;
Get<Mac::Mac>().UpdateFrameControlField(Get<NeighborTable>().FindNeighbor(aMacDest), false, fcf);
aFrame.InitMacHeader(fcf, Mac::Frame::kKeyIdMode1 | Mac::Frame::kSecEncMic32);
@@ -187,7 +194,10 @@ void MeshForwarder::PrepareEmptyFrame(Mac::TxFrame &aFrame, const Mac::Address &
aFrame.SetSrcAddr(macSource);
aFrame.SetFramePending(false);
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
IgnoreError(Get<Mac::Mac>().AppendHeaderIe(false, aFrame));
if (iePresent)
{
AppendHeaderIe(nullptr, aFrame);
}
#endif
aFrame.SetPayloadLength(0);
}
@@ -585,17 +595,23 @@ uint16_t MeshForwarder::PrepareDataFrame(Mac::TxFrame & aFrame,
uint16_t dstpan;
uint8_t secCtl;
uint16_t nextOffset;
bool iePresent = CalcIePresent(&aMessage);
start:
// Initialize MAC header
fcf = Mac::Frame::kFcfFrameData;
Get<Mac::Mac>().UpdateFrameControlField(Get<NeighborTable>().FindNeighbor(aMacDest), aMessage.IsTimeSync(), fcf);
fcf |= (aMacDest.IsShort()) ? Mac::Frame::kFcfDstAddrShort : Mac::Frame::kFcfDstAddrExt;
fcf |= (aMacSource.IsShort()) ? Mac::Frame::kFcfSrcAddrShort : Mac::Frame::kFcfSrcAddrExt;
if (iePresent)
{
fcf |= Mac::Frame::kFcfIePresent;
}
fcf |= CalcFrameVersion(Get<NeighborTable>().FindNeighbor(aMacDest), iePresent);
// All unicast frames request ACK
if (aMacDest.IsExtended() || !aMacDest.IsBroadcast())
{
@@ -663,7 +679,10 @@ start:
aFrame.SetSrcAddr(aMacSource);
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
IgnoreError(Get<Mac::Mac>().AppendHeaderIe(aMessage.IsTimeSync(), aFrame));
if (iePresent)
{
AppendHeaderIe(&aMessage, aFrame);
}
#endif
payload = aFrame.GetPayload();
@@ -1491,6 +1510,78 @@ exit:
}
#endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
bool MeshForwarder::CalcIePresent(const Message *aMessage)
{
bool iePresent = false;
OT_UNUSED_VARIABLE(aMessage);
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
iePresent |= (aMessage != nullptr && aMessage->IsTimeSync());
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
iePresent |= Get<Mac::Mac>().IsCslEnabled();
#endif
return iePresent;
}
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
void MeshForwarder::AppendHeaderIe(const Message *aMessage, Mac::Frame &aFrame)
{
uint8_t index = 0;
bool iePresent = false;
OT_UNUSED_VARIABLE(aMessage);
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
if (aMessage != nullptr && aMessage->IsTimeSync())
{
IgnoreError(aFrame.AppendHeaderIeAt<Mac::TimeIe>(index));
iePresent = true;
}
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (Get<Mac::Mac>().IsCslEnabled())
{
IgnoreError(aFrame.AppendHeaderIeAt<Mac::CslIe>(index));
iePresent = true;
}
#endif
if (iePresent)
{
IgnoreError(aFrame.AppendHeaderIeAt<Mac::Termination2Ie>(index));
}
}
#endif
uint16_t MeshForwarder::CalcFrameVersion(const Neighbor *aNeighbor, bool aIePresent)
{
uint16_t version = Mac::Frame::kFcfFrameVersion2006;
OT_UNUSED_VARIABLE(aNeighbor);
if (aIePresent)
{
version = Mac::Frame::kFcfFrameVersion2015;
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
else if (aNeighbor != nullptr && !Mle::MleRouter::IsActiveRouter(aNeighbor->GetRloc16()) &&
static_cast<const Child *>(aNeighbor)->IsCslSynchronized())
{
version = Mac::Frame::kFcfFrameVersion2015;
}
#endif
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_ENABLE
else if (aNeighbor != nullptr && aNeighbor->IsEnhAckProbingActive())
{
version = Mac::Frame::kFcfFrameVersion2015; ///< Set version to 2015 to fetch Link Metrics data in Enh-ACK.
}
#endif
return version;
}
// LCOV_EXCL_START
#if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_NOTE) && (OPENTHREAD_CONFIG_LOG_MAC == 1)
+7
View File
@@ -44,6 +44,7 @@
#include "mac/channel_mask.hpp"
#include "mac/data_poll_sender.hpp"
#include "mac/mac.hpp"
#include "mac/mac_frame.hpp"
#include "net/ip6.hpp"
#include "thread/address_resolver.hpp"
#include "thread/indirect_sender.hpp"
@@ -475,6 +476,12 @@ private:
otError GetDestinationRlocByServiceAloc(uint16_t aServiceAloc, uint16_t &aMeshDest);
bool CalcIePresent(const Message *aMessage);
uint16_t CalcFrameVersion(const Neighbor *aNeighbor, bool aIePresent);
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
void AppendHeaderIe(const Message *aMessage, Mac::Frame &aFrame);
#endif
void PauseMessageTransmissions(void) { mTxPaused = true; }
void ResumeMessageTransmissions(void);
+11 -12
View File
@@ -342,29 +342,28 @@ void MeshForwarder::RemoveDataResponseMessages(void)
void MeshForwarder::SendMesh(Message &aMessage, Mac::TxFrame &aFrame)
{
uint16_t fcf;
bool iePresent = CalcIePresent(&aMessage);
// initialize MAC header
fcf = Mac::Frame::kFcfFrameData | Mac::Frame::kFcfPanidCompression | Mac::Frame::kFcfDstAddrShort |
Mac::Frame::kFcfSrcAddrShort | Mac::Frame::kFcfAckRequest | Mac::Frame::kFcfSecurityEnabled;
Get<Mac::Mac>().UpdateFrameControlField(nullptr, aMessage.IsTimeSync(), fcf);
if (iePresent)
{
fcf |= Mac::Frame::kFcfIePresent;
}
fcf |= CalcFrameVersion(Get<NeighborTable>().FindNeighbor(mMacDest), iePresent);
aFrame.InitMacHeader(fcf, Mac::Frame::kKeyIdMode1 | Mac::Frame::kSecEncMic32);
aFrame.SetDstPanId(Get<Mac::Mac>().GetPanId());
aFrame.SetDstAddr(mMacDest.GetShort());
aFrame.SetSrcAddr(mMacSource.GetShort());
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (Get<Mac::Mac>().IsCslEnabled())
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
if (iePresent)
{
Mac::HeaderIe ieList[2]; // CSL + Termination
ieList[0].Init();
ieList[0].SetId(Mac::Frame::kHeaderIeCsl);
ieList[0].SetLength(sizeof(Mac::CslIe));
ieList[1].Init();
ieList[1].SetId(Mac::Frame::kHeaderIeTermination2);
ieList[1].SetLength(0);
IgnoreError(aFrame.AppendHeaderIe(ieList, 2));
AppendHeaderIe(&aMessage, aFrame);
}
#endif
+2 -2
View File
@@ -620,7 +620,7 @@ void TestMacFrameAckGeneration(void)
Mac::CslIe *csl;
IgnoreError(ackFrame.GenerateEnhAck(receivedFrame, false, ie_data, sizeof(ie_data)));
csl = reinterpret_cast<Mac::CslIe *>(ackFrame.GetHeaderIe(Mac::Frame::kHeaderIeCsl) + sizeof(Mac::HeaderIe));
csl = reinterpret_cast<Mac::CslIe *>(ackFrame.GetHeaderIe(Mac::CslIe::kHeaderIeId) + sizeof(Mac::HeaderIe));
VerifyOrQuit(ackFrame.mLength == 23,
"Mac::Frame::GenerateEnhAck() failed, length incorrect\n"); // 23 is the length of the correct ack
VerifyOrQuit(ackFrame.GetType() == Mac::Frame::kFcfFrameAck,
@@ -642,7 +642,7 @@ void TestMacFrameAckGeneration(void)
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
ackFrame.SetCslIe(123, 456);
csl = reinterpret_cast<Mac::CslIe *>(ackFrame.GetHeaderIe(Mac::Frame::kHeaderIeCsl) + sizeof(Mac::HeaderIe));
csl = reinterpret_cast<Mac::CslIe *>(ackFrame.GetHeaderIe(Mac::CslIe::kHeaderIeId) + sizeof(Mac::HeaderIe));
VerifyOrQuit(csl->GetPeriod() == 123 && csl->GetPhase() == 456, "Mac::Frame::SetCslIe failed, CslIe incorrect\n");
#endif
#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)