[csl] add Mac::Frame methods to process the CSL IE (#10651)

This commit provides unified methods for checking whether the CSL IE
is present and getting the CSL IE.
This commit is contained in:
Zhanglong Xia
2024-09-03 10:36:45 -07:00
committed by GitHub
parent 5b33afd188
commit aed9cd1a30
6 changed files with 119 additions and 81 deletions
+4 -6
View File
@@ -255,16 +255,14 @@ void DataPollSender::HandlePollSent(Mac::TxFrame &aFrame, Error aError)
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
LogInfo("Failed to send data poll, error:%s, retx:%d/%d", ErrorToString(aError), mPollTxFailureCounter, LogInfo("Failed to send data poll, error:%s, retx:%d/%d", ErrorToString(aError), mPollTxFailureCounter,
(aFrame.GetHeaderIe(Mac::CslIe::kHeaderIeId) != nullptr) ? kMaxCslPollRetxAttempts aFrame.HasCslIe() ? kMaxCslPollRetxAttempts : kMaxPollRetxAttempts);
: kMaxPollRetxAttempts);
#else #else
LogInfo("Failed to send data poll, error:%s, retx:%d/%d", ErrorToString(aError), mPollTxFailureCounter, LogInfo("Failed to send data poll, error:%s, retx:%d/%d", ErrorToString(aError), mPollTxFailureCounter,
kMaxPollRetxAttempts); kMaxPollRetxAttempts);
#endif #endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (mPollTxFailureCounter < if (mPollTxFailureCounter < (aFrame.HasCslIe() ? kMaxCslPollRetxAttempts : kMaxPollRetxAttempts))
((aFrame.GetHeaderIe(Mac::CslIe::kHeaderIeId) != nullptr) ? kMaxCslPollRetxAttempts : kMaxPollRetxAttempts))
#else #else
if (mPollTxFailureCounter < kMaxPollRetxAttempts) if (mPollTxFailureCounter < kMaxPollRetxAttempts)
#endif #endif
@@ -344,7 +342,7 @@ void DataPollSender::ProcessTxDone(const Mac::TxFrame &aFrame, const Mac::RxFram
VerifyOrExit(aFrame.GetSecurityEnabled()); VerifyOrExit(aFrame.GetSecurityEnabled());
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (aFrame.mInfo.mTxInfo.mIsARetx && (aFrame.GetHeaderIe(Mac::CslIe::kHeaderIeId) != nullptr)) if (aFrame.mInfo.mTxInfo.mIsARetx && aFrame.HasCslIe())
{ {
// For retransmission frame, use a data poll to resync its parent with correct CSL phase // For retransmission frame, use a data poll to resync its parent with correct CSL phase
sendDataPoll = true; sendDataPoll = true;
@@ -583,7 +581,7 @@ Mac::TxFrame *DataPollSender::PrepareDataRequest(Mac::TxFrames &aTxFrames)
Mac::Frame::kSecurityEncMic32, Mac::Frame::kKeyIdMode1, nullptr); Mac::Frame::kSecurityEncMic32, Mac::Frame::kKeyIdMode1, nullptr);
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT && OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT && OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (frame->GetHeaderIe(Mac::CslIe::kHeaderIeId) != nullptr) if (frame->HasCslIe())
{ {
// Disable frame retransmission when the data poll has CSL IE included // Disable frame retransmission when the data poll has CSL IE included
aTxFrames.SetMaxFrameRetries(0); aTxFrames.SetMaxFrameRetries(0);
+5 -7
View File
@@ -1316,7 +1316,7 @@ void Mac::HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError)
ProcessCsl(*aAckFrame, dstAddr); ProcessCsl(*aAckFrame, dstAddr);
#endif #endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (!mRxOnWhenIdle && aFrame.GetHeaderIe(CslIe::kHeaderIeId) != nullptr) if (!mRxOnWhenIdle && aFrame.HasCslIe())
{ {
Get<DataPollSender>().ResetKeepAliveTimer(); Get<DataPollSender>().ResetKeepAliveTimer();
} }
@@ -2356,19 +2356,17 @@ bool Mac::IsCslSupported(void) const
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
void Mac::ProcessCsl(const RxFrame &aFrame, const Address &aSrcAddr) void Mac::ProcessCsl(const RxFrame &aFrame, const Address &aSrcAddr)
{ {
const uint8_t *cur; Child *child;
Child *child; const CslIe *csl;
const CslIe *csl;
VerifyOrExit(aFrame.IsVersion2015() && aFrame.GetSecurityEnabled()); VerifyOrExit(aFrame.IsVersion2015() && aFrame.GetSecurityEnabled());
cur = aFrame.GetHeaderIe(CslIe::kHeaderIeId); csl = aFrame.GetCslIe();
VerifyOrExit(cur != nullptr); VerifyOrExit(csl != nullptr);
child = Get<ChildTable>().FindChild(aSrcAddr, Child::kInStateAnyExceptInvalid); child = Get<ChildTable>().FindChild(aSrcAddr, Child::kInStateAnyExceptInvalid);
VerifyOrExit(child != nullptr); VerifyOrExit(child != nullptr);
csl = reinterpret_cast<const CslIe *>(cur + sizeof(HeaderIe));
VerifyOrExit(csl->GetPeriod() >= kMinCslIePeriod); VerifyOrExit(csl->GetPeriod() >= kMinCslIePeriod);
child->SetCslPeriod(csl->GetPeriod()); child->SetCslPeriod(csl->GetPeriod());
+20 -5
View File
@@ -1232,19 +1232,34 @@ exit:
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
void Frame::SetCslIe(uint16_t aCslPeriod, uint16_t aCslPhase) void Frame::SetCslIe(uint16_t aCslPeriod, uint16_t aCslPhase)
{ {
uint8_t *cur = GetHeaderIe(CslIe::kHeaderIeId); CslIe *csl = GetCslIe();
CslIe *csl;
VerifyOrExit(cur != nullptr); VerifyOrExit(csl != nullptr);
csl = reinterpret_cast<CslIe *>(cur + sizeof(HeaderIe));
csl->SetPeriod(aCslPeriod); csl->SetPeriod(aCslPeriod);
csl->SetPhase(aCslPhase); csl->SetPhase(aCslPhase);
exit: exit:
return; return;
} }
bool Frame::HasCslIe(void) const { return GetHeaderIe(CslIe::kHeaderIeId) != nullptr; }
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE)
const CslIe *Frame::GetCslIe(void) const
{
const uint8_t *cur;
const CslIe *csl = nullptr;
cur = GetHeaderIe(CslIe::kHeaderIeId);
VerifyOrExit(cur != nullptr);
csl = reinterpret_cast<const CslIe *>(cur + sizeof(HeaderIe));
exit:
return csl;
}
#endif
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
void Frame::SetEnhAckProbingIe(const uint8_t *aValue, uint8_t aLen) void Frame::SetEnhAckProbingIe(const uint8_t *aValue, uint8_t aLen)
{ {
+88 -61
View File
@@ -134,6 +134,67 @@ private:
} OT_TOOL_PACKED_END; } OT_TOOL_PACKED_END;
/**
* Implements CSL IE data structure.
*
*/
OT_TOOL_PACKED_BEGIN
class CslIe
{
public:
static constexpr uint8_t kHeaderIeId = 0x1a;
static constexpr uint8_t kIeContentSize = sizeof(uint16_t) * 2;
/**
* Returns the CSL Period.
*
* @returns the CSL Period.
*
*/
uint16_t GetPeriod(void) const { return LittleEndian::HostSwap16(mPeriod); }
/**
* Sets the CSL Period.
*
* @param[in] aPeriod The CSL Period.
*
*/
void SetPeriod(uint16_t aPeriod) { mPeriod = LittleEndian::HostSwap16(aPeriod); }
/**
* Returns the CSL Phase.
*
* @returns the CSL Phase.
*
*/
uint16_t GetPhase(void) const { return LittleEndian::HostSwap16(mPhase); }
/**
* Sets the CSL Phase.
*
* @param[in] aPhase The CSL Phase.
*
*/
void SetPhase(uint16_t aPhase) { mPhase = LittleEndian::HostSwap16(aPhase); }
private:
uint16_t mPhase;
uint16_t mPeriod;
} OT_TOOL_PACKED_END;
/**
* Implements Termination2 IE.
*
* Is empty for template specialization.
*
*/
class Termination2Ie
{
public:
static constexpr uint8_t kHeaderIeId = 0x7f;
static constexpr uint8_t kIeContentSize = 0;
};
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || \ #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || \
OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
/** /**
@@ -1023,8 +1084,35 @@ public:
* *
*/ */
void SetCslIe(uint16_t aCslPeriod, uint16_t aCslPhase); void SetCslIe(uint16_t aCslPeriod, uint16_t aCslPhase);
/**
* Indicates whether or not the frame contains CSL IE.
*
* @retval TRUE If the frame contains CSL IE.
* @retval FALSE If the frame doesn't contain CSL IE.
*
*/
bool HasCslIe(void) const;
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE)
/**
* Returns a pointer to a CSL IE.
*
* @returns A pointer to the CSL IE, `nullptr` if not found.
*
*/
const CslIe *GetCslIe(void) const;
/**
* Returns a pointer to a CSL IE.
*
* @returns A pointer to the CSL IE, `nullptr` if not found.
*
*/
CslIe *GetCslIe(void) { return AsNonConst(AsConst(this)->GetCslIe()); }
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE)
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
/** /**
* Finds Enhanced ACK Probing (Vendor Specific) IE and set its value. * Finds Enhanced ACK Probing (Vendor Specific) IE and set its value.
@@ -1766,67 +1854,6 @@ private:
otExtendedPanId mExtendedPanId; otExtendedPanId mExtendedPanId;
} OT_TOOL_PACKED_END; } OT_TOOL_PACKED_END;
/**
* Implements CSL IE data structure.
*
*/
OT_TOOL_PACKED_BEGIN
class CslIe
{
public:
static constexpr uint8_t kHeaderIeId = 0x1a;
static constexpr uint8_t kIeContentSize = sizeof(uint16_t) * 2;
/**
* Returns the CSL Period.
*
* @returns the CSL Period.
*
*/
uint16_t GetPeriod(void) const { return LittleEndian::HostSwap16(mPeriod); }
/**
* Sets the CSL Period.
*
* @param[in] aPeriod The CSL Period.
*
*/
void SetPeriod(uint16_t aPeriod) { mPeriod = LittleEndian::HostSwap16(aPeriod); }
/**
* Returns the CSL Phase.
*
* @returns the CSL Phase.
*
*/
uint16_t GetPhase(void) const { return LittleEndian::HostSwap16(mPhase); }
/**
* Sets the CSL Phase.
*
* @param[in] aPhase The CSL Phase.
*
*/
void SetPhase(uint16_t aPhase) { mPhase = LittleEndian::HostSwap16(aPhase); }
private:
uint16_t mPhase;
uint16_t mPeriod;
} OT_TOOL_PACKED_END;
/**
* Implements Termination2 IE.
*
* Is empty for template specialization.
*
*/
class Termination2Ie
{
public:
static constexpr uint8_t kHeaderIeId = 0x7f;
static constexpr uint8_t kIeContentSize = 0;
};
/** /**
* @} * @}
* *
+1 -1
View File
@@ -60,7 +60,7 @@ void SubMac::UpdateCslLastSyncTimestamp(TxFrame &aFrame, RxFrame *aAckFrame)
{ {
// Actual synchronization timestamp should be from the sent frame instead of the current time. // Actual synchronization timestamp should be from the sent frame instead of the current time.
// Assuming the error here since it is bounded and has very small effect on the final window duration. // Assuming the error here since it is bounded and has very small effect on the final window duration.
if (aAckFrame != nullptr && aFrame.GetHeaderIe(CslIe::kHeaderIeId) != nullptr) if (aAckFrame != nullptr && aFrame.HasCslIe())
{ {
mCslLastSync = TimeMicro(GetLocalTime()); mCslLastSync = TimeMicro(GetLocalTime());
} }
+1 -1
View File
@@ -1138,7 +1138,7 @@ Neighbor *MeshForwarder::UpdateNeighborOnSentFrame(Mac::TxFrame &aFrame,
#endif // OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE #endif // OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if ((aFrame.GetHeaderIe(Mac::CslIe::kHeaderIeId) != nullptr) && aIsDataPoll) if (aFrame.HasCslIe() && aIsDataPoll)
{ {
failLimit = kFailedCslDataPollTransmissions; failLimit = kFailedCslDataPollTransmissions;
} }