Skip to content

Commit

Permalink
[csl] add Mac::Frame methods to process the CSL IE (openthread#10651)
Browse files Browse the repository at this point in the history
This commit provides unified methods for checking whether the CSL IE
is present and getting the CSL IE.
  • Loading branch information
zhanglongxia authored Sep 3, 2024
1 parent 5b33afd commit aed9cd1
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 81 deletions.
10 changes: 4 additions & 6 deletions src/core/mac/data_poll_sender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,16 +255,14 @@ void DataPollSender::HandlePollSent(Mac::TxFrame &aFrame, Error aError)

#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
LogInfo("Failed to send data poll, error:%s, retx:%d/%d", ErrorToString(aError), mPollTxFailureCounter,
(aFrame.GetHeaderIe(Mac::CslIe::kHeaderIeId) != nullptr) ? kMaxCslPollRetxAttempts
: kMaxPollRetxAttempts);
aFrame.HasCslIe() ? kMaxCslPollRetxAttempts : kMaxPollRetxAttempts);
#else
LogInfo("Failed to send data poll, error:%s, retx:%d/%d", ErrorToString(aError), mPollTxFailureCounter,
kMaxPollRetxAttempts);
#endif

#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (mPollTxFailureCounter <
((aFrame.GetHeaderIe(Mac::CslIe::kHeaderIeId) != nullptr) ? kMaxCslPollRetxAttempts : kMaxPollRetxAttempts))
if (mPollTxFailureCounter < (aFrame.HasCslIe() ? kMaxCslPollRetxAttempts : kMaxPollRetxAttempts))
#else
if (mPollTxFailureCounter < kMaxPollRetxAttempts)
#endif
Expand Down Expand Up @@ -344,7 +342,7 @@ void DataPollSender::ProcessTxDone(const Mac::TxFrame &aFrame, const Mac::RxFram
VerifyOrExit(aFrame.GetSecurityEnabled());

#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
sendDataPoll = true;
Expand Down Expand Up @@ -583,7 +581,7 @@ Mac::TxFrame *DataPollSender::PrepareDataRequest(Mac::TxFrames &aTxFrames)
Mac::Frame::kSecurityEncMic32, Mac::Frame::kKeyIdMode1, nullptr);

#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
aTxFrames.SetMaxFrameRetries(0);
Expand Down
12 changes: 5 additions & 7 deletions src/core/mac/mac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1316,7 +1316,7 @@ void Mac::HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError)
ProcessCsl(*aAckFrame, dstAddr);
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (!mRxOnWhenIdle && aFrame.GetHeaderIe(CslIe::kHeaderIeId) != nullptr)
if (!mRxOnWhenIdle && aFrame.HasCslIe())
{
Get<DataPollSender>().ResetKeepAliveTimer();
}
Expand Down Expand Up @@ -2356,19 +2356,17 @@ bool Mac::IsCslSupported(void) const
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
void Mac::ProcessCsl(const RxFrame &aFrame, const Address &aSrcAddr)
{
const uint8_t *cur;
Child *child;
const CslIe *csl;
Child *child;
const CslIe *csl;

VerifyOrExit(aFrame.IsVersion2015() && aFrame.GetSecurityEnabled());

cur = aFrame.GetHeaderIe(CslIe::kHeaderIeId);
VerifyOrExit(cur != nullptr);
csl = aFrame.GetCslIe();
VerifyOrExit(csl != nullptr);

child = Get<ChildTable>().FindChild(aSrcAddr, Child::kInStateAnyExceptInvalid);
VerifyOrExit(child != nullptr);

csl = reinterpret_cast<const CslIe *>(cur + sizeof(HeaderIe));
VerifyOrExit(csl->GetPeriod() >= kMinCslIePeriod);

child->SetCslPeriod(csl->GetPeriod());
Expand Down
25 changes: 20 additions & 5 deletions src/core/mac/mac_frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1232,19 +1232,34 @@ const uint8_t *Frame::GetThreadIe(uint8_t aSubType) const
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
void Frame::SetCslIe(uint16_t aCslPeriod, uint16_t aCslPhase)
{
uint8_t *cur = GetHeaderIe(CslIe::kHeaderIeId);
CslIe *csl;
CslIe *csl = GetCslIe();

VerifyOrExit(cur != nullptr);

csl = reinterpret_cast<CslIe *>(cur + sizeof(HeaderIe));
VerifyOrExit(csl != nullptr);
csl->SetPeriod(aCslPeriod);
csl->SetPhase(aCslPhase);

exit:
return;
}

bool Frame::HasCslIe(void) const { return GetHeaderIe(CslIe::kHeaderIeId) != nullptr; }
#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
void Frame::SetEnhAckProbingIe(const uint8_t *aValue, uint8_t aLen)
{
Expand Down
149 changes: 88 additions & 61 deletions src/core/mac/mac_frame.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,67 @@ class HeaderIe

} 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 || \
OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
/**
Expand Down Expand Up @@ -1023,8 +1084,35 @@ class Frame : public otRadioFrame
*
*/
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

#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
/**
* Finds Enhanced ACK Probing (Vendor Specific) IE and set its value.
Expand Down Expand Up @@ -1766,67 +1854,6 @@ class BeaconPayload
otExtendedPanId mExtendedPanId;
} 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;
};

/**
* @}
*
Expand Down
2 changes: 1 addition & 1 deletion src/core/mac/sub_mac_csl_receiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
// 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());
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/thread/mesh_forwarder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1138,7 +1138,7 @@ Neighbor *MeshForwarder::UpdateNeighborOnSentFrame(Mac::TxFrame &aFrame,
#endif // OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE

#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if ((aFrame.GetHeaderIe(Mac::CslIe::kHeaderIeId) != nullptr) && aIsDataPoll)
if (aFrame.HasCslIe() && aIsDataPoll)
{
failLimit = kFailedCslDataPollTransmissions;
}
Expand Down

0 comments on commit aed9cd1

Please sign in to comment.