mirror of
https://github.com/espressif/openthread.git
synced 2026-08-06 02:37:47 +00:00
[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:
+40
-78
@@ -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
@@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user