[simulation] use the CSL receiver's peer address to include CSL IE (#11905)

The description of the method `otPlatRadioEnableCsl()` requires the platform
to include the CSL IE in the enhanced ACK when the received data frame's source
address matches the CSL receiver's peer address. This commit implements this
requirement in the simulation radio.
This commit is contained in:
Zhanglong Xia
2025-09-30 09:24:38 +08:00
committed by GitHub
parent e72d19387e
commit fab01a7f0f
3 changed files with 74 additions and 11 deletions
+24 -8
View File
@@ -98,7 +98,9 @@ static void radioSendMessage(otInstance *aInstance);
static void radioSendAck(void);
static void radioProcessFrame(otInstance *aInstance);
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
static uint8_t generateAckIeData(uint8_t *aLinkMetricsIeData, uint8_t aLinkMetricsIeDataLen);
static uint8_t generateAckIeData(uint8_t *aLinkMetricsIeData,
uint8_t aLinkMetricsIeDataLen,
const struct otRadioFrame *aReceivedFrame);
#endif
static otRadioState sState = OT_RADIO_STATE_DISABLED;
@@ -643,6 +645,7 @@ void radioSendMessage(otInstance *aInstance)
{
uint64_t sfdTxTime = otPlatTimeGet();
sRadioContext.mCslPresent = sTransmitFrame.mInfo.mTxInfo.mCslPresent;
otEXPECT(otMacFrameProcessTxSfd(&sTransmitFrame, sfdTxTime, &sRadioContext) == OT_ERROR_NONE);
}
@@ -802,7 +805,7 @@ void radioSendAck(void)
}
#endif
sAckIeDataLength = generateAckIeData(dataPtr, linkMetricsDataLen);
sAckIeDataLength = generateAckIeData(dataPtr, linkMetricsDataLen, &sReceiveFrame);
otEXPECT(otMacFrameGenerateEnhAck(&sReceiveFrame, sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending,
sAckIeData, sAckIeDataLength, &sAckFrame) == OT_ERROR_NONE);
@@ -1047,15 +1050,21 @@ uint64_t otPlatRadioGetNow(otInstance *aInstance)
}
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
static uint8_t generateAckIeData(uint8_t *aLinkMetricsIeData, uint8_t aLinkMetricsIeDataLen)
static uint8_t generateAckIeData(uint8_t *aLinkMetricsIeData,
uint8_t aLinkMetricsIeDataLen,
const struct otRadioFrame *aReceivedFrame)
{
OT_UNUSED_VARIABLE(aLinkMetricsIeData);
OT_UNUSED_VARIABLE(aLinkMetricsIeDataLen);
OT_UNUSED_VARIABLE(aReceivedFrame);
uint8_t offset = 0;
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (sRadioContext.mCslPeriod > 0)
sRadioContext.mCslPresent =
(sRadioContext.mCslPeriod > 0) && otMacFrameSrcAddrMatchCslReceiverPeer(aReceivedFrame, &sRadioContext);
if (sRadioContext.mCslPresent)
{
offset += otMacFrameGenerateCslIeTemplate(sAckIeData);
}
@@ -1079,13 +1088,20 @@ otError otPlatRadioEnableCsl(otInstance *aInstance,
const otExtAddress *aExtAddr)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aShortAddr);
OT_UNUSED_VARIABLE(aExtAddr);
otError error = OT_ERROR_NONE;
assert(aCslPeriod < UINT16_MAX);
sRadioContext.mCslPeriod = (uint16_t)aCslPeriod;
otEXPECT_ACTION((aShortAddr != OT_RADIO_BROADCAST_SHORT_ADDR) && (aShortAddr != OT_RADIO_INVALID_SHORT_ADDR),
error = OT_ERROR_FAILED);
otEXPECT_ACTION(aExtAddr != NULL, error = OT_ERROR_FAILED);
return OT_ERROR_NONE;
sRadioContext.mCslPeriod = (uint16_t)aCslPeriod;
sRadioContext.mCslShortAddress = aShortAddr;
ReverseExtAddress(&sRadioContext.mCslExtAddress, aExtAddr);
exit:
return error;
}
otError otPlatRadioResetCsl(otInstance *aInstance)
+33 -1
View File
@@ -404,7 +404,7 @@ exit:
otError otMacFrameProcessTxSfd(otRadioFrame *aFrame, uint64_t aRadioTime, otRadioContext *aRadioContext)
{
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (aRadioContext->mCslPeriod > 0) // CSL IE should be filled for every transmit attempt
if (aRadioContext->mCslPresent) // CSL IE should be filled for every transmit attempt
{
otMacFrameSetCslIe(aFrame, aRadioContext->mCslPeriod, ComputeCslPhase(aRadioTime, aRadioContext));
}
@@ -415,3 +415,35 @@ otError otMacFrameProcessTxSfd(otRadioFrame *aFrame, uint64_t aRadioTime, otRadi
aFrame->mInfo.mTxInfo.mTimestamp = aRadioTime;
return otMacFrameProcessTransmitSecurity(aFrame, aRadioContext);
}
bool otMacFrameSrcAddrMatchCslReceiverPeer(const otRadioFrame *aFrame, const otRadioContext *aRadioContext)
{
const Mac::Frame &frame = *static_cast<const Mac::Frame *>(aFrame);
bool matches = false;
Mac::Address src;
VerifyOrExit(frame.GetSrcAddr(src) == kErrorNone);
switch (src.GetType())
{
case Mac::Address::kTypeShort:
VerifyOrExit(aRadioContext->mCslShortAddress != Mac::kShortAddrBroadcast &&
aRadioContext->mCslShortAddress != Mac::kShortAddrInvalid);
VerifyOrExit(src.GetShort() == aRadioContext->mCslShortAddress);
matches = true;
break;
case Mac::Address::kTypeExtended:
VerifyOrExit(*reinterpret_cast<const uint64_t *>(aRadioContext->mCslExtAddress.m8) != 0);
VerifyOrExit(src.GetExtended() == *static_cast<const Mac::ExtAddress *>(&aRadioContext->mCslExtAddress));
matches = true;
break;
case Mac::Address::kTypeNone:
matches = false;
break;
}
exit:
return matches;
}
+17 -2
View File
@@ -345,8 +345,11 @@ typedef struct otRadioContext
otExtAddress mExtAddress; ///< In little-endian byte order.
uint32_t mMacFrameCounter;
uint32_t mPrevMacFrameCounter;
uint32_t mCslSampleTime; ///< The sample time based on the microsecond timer.
uint16_t mCslPeriod; ///< In unit of 10 symbols.
uint32_t mCslSampleTime; ///< The sample time based on the microsecond timer.
uint16_t mCslPeriod; ///< In unit of 10 symbols.
otShortAddress mCslShortAddress; ///< The short address of the CSL receiver's peer.
otExtAddress mCslExtAddress; ///< The extended address of the CSL receiver's peer.
bool mCslPresent : 1; ///< Indicates whether the CSL header IE is present.
otShortAddress mShortAddress;
otShortAddress mAlternateShortAddress;
otRadioKeyType mKeyType;
@@ -386,6 +389,18 @@ otError otMacFrameProcessTxSfd(otRadioFrame *aFrame, uint64_t aRadioTime, otRadi
*/
otError otMacFrameProcessTransmitSecurity(otRadioFrame *aFrame, otRadioContext *aRadioContext);
/**
* Indicates whether the 15.4 frame's source address matches the short or extended address of the CSL receiver's peer.
*
* @param[in] aFrame The target 15.4 frame. MUST NOT be `NULL`.
* @param[in] aRadioContext The radio context accessible in ISR.
*
* @retval TRUE The source address of the frame matches the short or extended address of the CSL receiver's peer.
* @retval FALSE The source address of the frame does not match the short or extended address of the CSL receiver's
* peer.
*/
bool otMacFrameSrcAddrMatchCslReceiverPeer(const otRadioFrame *aFrame, const otRadioContext *aRadioContext);
#ifdef __cplusplus
} // extern "C"
#endif