[mac] simplify preparation of header IE entries (#10692)

This commit updates `TxFrame::Info` and `PrepareHeadersIn()` to
prepare header IE entries along with MAC and security headers. New
boolean fields in `TxFrame::Info` indicate whether CSL or Time IE
entries should be appended to the frame. This simplifies the code,
particularly `MeshForwarder::PrepareMacHeader()`, which now just sets
these flags on `TxFrame::Info`. It also allows for the removal of
`AppendHeaderIe<>()` and its related methods.

This commit also updates `GenerateWakeupFrame()` to use the new
model for appending `RendezvousTimeIe` and `ConnectionIe` fields.
This commit is contained in:
Abtin Keshavarzian
2024-10-10 08:10:58 -07:00
committed by GitHub
parent e7ca8b1aa1
commit 2dbaaa5cfd
4 changed files with 111 additions and 197 deletions
+40 -78
View File
@@ -168,6 +168,15 @@ void TxFrame::Info::PrepareHeadersIn(TxFrame &aTxFrame) const
fcf |= kFcfSequenceSuppression;
}
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
fcf |= (mAppendTimeIe ? kFcfIePresent : 0);
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
fcf |= (mAppendCslIe ? kFcfIePresent : 0);
#endif
#endif
builder.Init(aTxFrame.mPsdu, aTxFrame.GetMtu());
IgnoreError(builder.AppendLittleEndianUint16(fcf));
@@ -202,6 +211,31 @@ void TxFrame::Info::PrepareHeadersIn(TxFrame &aTxFrame) const
micSize = CalculateMicSize(secCtl);
}
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
if (mAppendTimeIe)
{
builder.Append<HeaderIe>()->Init(TimeIe::kHeaderIeId, sizeof(TimeIe));
builder.Append<TimeIe>()->Init();
}
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (mAppendCslIe)
{
builder.Append<HeaderIe>()->Init(CslIe::kHeaderIeId, sizeof(CslIe));
builder.Append<CslIe>();
}
#endif
if ((fcf & kFcfIePresent) && ((mType == kTypeMacCmd) || !mEmptyPayload))
{
builder.Append<HeaderIe>()->Init(Termination2Ie::kHeaderIeId, Termination2Ie::kIeContentSize);
}
#endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
if (mType == kTypeMacCmd)
{
builder.Append<uint8_t>(); // Placeholder for Command ID
@@ -1098,65 +1132,6 @@ exit:
return index;
}
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
template <typename IeType> Error Frame::AppendHeaderIeAt(uint8_t &aIndex)
{
Error error = kErrorNone;
SuccessOrExit(error = InitIeHeaderAt(aIndex, IeType::kHeaderIeId, IeType::kIeContentSize));
InitIeContentAt<IeType>(aIndex);
exit:
return error;
}
Error Frame::InitIeHeaderAt(uint8_t &aIndex, uint8_t ieId, uint8_t ieContentSize)
{
Error error = kErrorNone;
SetIePresent(true);
if (aIndex == 0)
{
aIndex = FindHeaderIeIndex();
}
VerifyOrExit(aIndex != kInvalidIndex, error = kErrorNotFound);
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_WAKEUP_COORDINATOR_ENABLE
template <> void Frame::InitIeContentAt<RendezvousTimeIe>(uint8_t &aIndex) { aIndex += sizeof(RendezvousTimeIe); }
template <> void Frame::InitIeContentAt<ConnectionIe>(uint8_t &aIndex)
{
reinterpret_cast<ConnectionIe *>(mPsdu + aIndex)->Init();
aIndex += sizeof(ConnectionIe);
}
#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();
@@ -1338,21 +1313,6 @@ uint16_t Frame::GetMtu(void) const { return Trel::Link::kMtuSize; }
uint8_t Frame::GetFcsSize(void) const { return Trel::Link::kFcsSize; }
#endif
// Explicit instantiation
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
template Error Frame::AppendHeaderIeAt<TimeIe>(uint8_t &aIndex);
#endif
#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE
template Error Frame::AppendHeaderIeAt<RendezvousTimeIe>(uint8_t &aIndex);
template Error Frame::AppendHeaderIeAt<ConnectionIe>(uint8_t &aIndex);
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
template Error Frame::AppendHeaderIeAt<CslIe>(uint8_t &aIndex);
#endif
template Error Frame::AppendHeaderIeAt<Termination2Ie>(uint8_t &aIndex);
#endif
void TxFrame::CopyFrom(const TxFrame &aFromFrame)
{
uint8_t *psduBuffer = mPsdu;
@@ -1532,7 +1492,6 @@ Error TxFrame::GenerateWakeupFrame(PanId aPanId, const Address &aDest, const Add
Error error = kErrorNone;
uint16_t fcf;
uint8_t secCtl;
uint8_t index = 0;
FrameBuilder builder;
fcf = kTypeMultipurpose | kMpFcfLongFrame | kMpFcfPanidPresent | kMpFcfSecurityEnabled | kMpFcfSequenceSuppression |
@@ -1554,13 +1513,16 @@ Error TxFrame::GenerateWakeupFrame(PanId aPanId, const Address &aDest, const Add
IgnoreError(builder.AppendUint8(secCtl));
builder.AppendLength(CalculateSecurityHeaderSize(secCtl) - sizeof(secCtl));
builder.Append<HeaderIe>()->Init(RendezvousTimeIe::kHeaderIeId, sizeof(RendezvousTimeIe));
builder.Append<RendezvousTimeIe>();
builder.Append<HeaderIe>()->Init(ConnectionIe::kHeaderIeId, sizeof(ConnectionIe));
builder.Append<ConnectionIe>()->Init();
builder.AppendLength(CalculateMicSize(secCtl) + GetFcsSize());
mLength = builder.GetLength();
SuccessOrExit(error = AppendHeaderIeAt<RendezvousTimeIe>(index));
SuccessOrExit(error = AppendHeaderIeAt<ConnectionIe>(index));
exit:
return error;
}
+15 -24
View File
@@ -627,25 +627,6 @@ public:
#endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
/**
* Appends an Header IE at specified index in this frame.
*
* 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
* appended at `aIndex` on input. And on output, `aIndex` will be set to the end of the
* IE just appended.
*
* @tparam IeType The Header IE type, it MUST contain a constant `kHeaderIeId` equal to the IE's Id
* and a constant `kIeContentSize` indicating the IE body's size.
*
* @retval kErrorNone Successfully appended the Header IE.
* @retval kErrorNotFound The position for first IE is not found.
*/
template <typename IeType> Error AppendHeaderIeAt(uint8_t &aIndex);
/**
* Returns a pointer to the Header IE.
*
@@ -884,9 +865,6 @@ protected:
uint8_t FindPayloadIndex(void) const;
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
uint8_t FindHeaderIeIndex(void) const;
Error 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);
@@ -1071,8 +1049,11 @@ public:
* - The destination address is not the broadcast address
* - The frame type is not an ACK frame
*
* The Frame Pending and IE Present flags in the FCF are not set. They may need to be set separately depending
* on the specific requirements of the frame being transmitted.
* The header IE entries are prepared based on `mAppendTimeIe` and `mAppendCslIe` flags and the IE Present
* flag in FCF is determined accordingly.
*
* The Frame Pending flag in FCF is not set. It may need to be set separately depending on the specific
* requirements of the frame being transmitted.
*
* @param[in,out] aTxFrame The `TxFrame` instance in which to prepare and append the MAC headers.
*/
@@ -1085,6 +1066,16 @@ public:
SecurityLevel mSecurityLevel; ///< Frame security level.
KeyIdMode mKeyIdMode; ///< Frame security key ID mode.
bool mSuppressSequence : 1; ///< Whether to suppress seq number.
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
bool mAppendTimeIe : 1; ///< Whether to append Time IE.
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
bool mAppendCslIe : 1; ///< Whether to append CSL IE.
#endif
bool mEmptyPayload : 1; ///< Whether payload is empty (to decide about appending Termination2 IE).
#endif
};
/**
+56 -89
View File
@@ -840,20 +840,66 @@ exit:
void MeshForwarder::PrepareMacHeaders(Mac::TxFrame &aTxFrame, Mac::TxFrame::Info &aTxFrameInfo, const Message *aMessage)
{
bool iePresent;
aTxFrameInfo.mVersion = Mac::Frame::kVersion2006;
iePresent = CalcIePresent(aMessage);
aTxFrameInfo.mVersion =
CalcFrameVersion(Get<NeighborTable>().FindNeighbor(aTxFrameInfo.mAddrs.mDestination), iePresent);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Determine Header IE entries
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
if ((aMessage != nullptr) && aMessage->IsTimeSync())
{
aTxFrameInfo.mAppendTimeIe = true;
aTxFrameInfo.mVersion = Mac::Frame::kVersion2015;
}
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (Get<Mac::Mac>().IsCslEnabled() &&
!(aMessage != nullptr && aMessage->GetSubType() == Message::kSubTypeMleDiscoverRequest))
{
aTxFrameInfo.mAppendCslIe = true;
aTxFrameInfo.mVersion = Mac::Frame::kVersion2015;
}
#endif
aTxFrameInfo.mEmptyPayload = (aMessage == nullptr) || (aMessage->GetLength() == 0);
#endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
#if (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE) || \
OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Determine frame version
if (aTxFrameInfo.mVersion == Mac::Frame::kVersion2006)
{
const Neighbor *neighbor = Get<NeighborTable>().FindNeighbor(aTxFrameInfo.mAddrs.mDestination);
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
if ((neighbor != nullptr) && Get<ChildTable>().Contains(*neighbor) &&
static_cast<const Child *>(neighbor)->IsCslSynchronized())
{
aTxFrameInfo.mVersion = Mac::Frame::kVersion2015;
}
#endif
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
if ((neighbor != nullptr) && neighbor->IsEnhAckProbingActive())
{
aTxFrameInfo.mVersion = Mac::Frame::kVersion2015;
}
#endif
}
#endif // OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Prepare MAC headers
aTxFrameInfo.PrepareHeadersIn(aTxFrame);
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
if (iePresent)
{
AppendHeaderIe(aMessage, aTxFrame);
}
#endif
OT_UNUSED_VARIABLE(aMessage);
}
// This method constructs a MAC data from from a given IPv6 message.
@@ -1718,85 +1764,6 @@ exit:
}
#endif
bool MeshForwarder::CalcIePresent(const Message *aMessage)
{
bool iePresent = false;
OT_UNUSED_VARIABLE(aMessage);
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
iePresent |= (aMessage != nullptr && aMessage->IsTimeSync());
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (!(aMessage != nullptr && aMessage->GetSubType() == Message::kSubTypeMleDiscoverRequest))
{
iePresent |= Get<Mac::Mac>().IsCslEnabled();
}
#endif
#endif
return iePresent;
}
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
void MeshForwarder::AppendHeaderIe(const Message *aMessage, Mac::TxFrame &aFrame)
{
uint8_t index = 0;
bool iePresent = false;
bool payloadPresent =
(aFrame.GetType() == Mac::Frame::kTypeMacCmd) || (aMessage != nullptr && aMessage->GetLength() != 0);
#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));
aFrame.SetCslIePresent(true);
iePresent = true;
}
#endif
if (iePresent && payloadPresent)
{
// Assume no Payload IE in current implementation
IgnoreError(aFrame.AppendHeaderIeAt<Mac::Termination2Ie>(index));
}
}
#endif
Mac::Frame::Version MeshForwarder::CalcFrameVersion(const Neighbor *aNeighbor, bool aIePresent) const
{
Mac::Frame::Version version = Mac::Frame::kVersion2006;
OT_UNUSED_VARIABLE(aNeighbor);
if (aIePresent)
{
version = Mac::Frame::kVersion2015;
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
else if ((aNeighbor != nullptr) && Get<ChildTable>().Contains(*aNeighbor) &&
static_cast<const Child *>(aNeighbor)->IsCslSynchronized())
{
version = Mac::Frame::kVersion2015;
}
#endif
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
else if (aNeighbor != nullptr && aNeighbor->IsEnhAckProbingActive())
{
version = Mac::Frame::kVersion2015; ///< Set version to 2015 to fetch Link Metrics data in Enh-ACK.
}
#endif
return version;
}
// LCOV_EXCL_START
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE)
-6
View File
@@ -560,12 +560,6 @@ private:
void GetForwardFramePriority(RxInfo &aRxInfo, Message::Priority &aPriority);
#endif
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
void PauseMessageTransmissions(void) { mTxPaused = true; }
void ResumeMessageTransmissions(void);