From 005c5cefc22aaf0396e4327ee7f2e0ad32a7733b Mon Sep 17 00:00:00 2001 From: Yakun Xu Date: Tue, 29 Oct 2024 05:19:44 +0800 Subject: [PATCH] [mac] apply RxChannelAfterTxDone only if RxOnWhenIdle (#10826) This commit updates the implementation to apply RxChannelAfterTxDone only if RxOnWhenIdle. --- include/openthread/instance.h | 2 +- include/openthread/link.h | 11 +++++++ src/core/api/link_raw_api.cpp | 22 ++++++++++++-- src/core/mac/sub_mac.cpp | 2 +- src/core/radio/radio_platform.cpp | 13 ++++----- src/ncp/ncp_base.cpp | 2 +- tests/gtest/radio_spinel_rcp_test.cpp | 41 +++++++++++++++++++++++++++ 7 files changed, 80 insertions(+), 13 deletions(-) diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 3dfe84fdd28..aab7045d44d 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -52,7 +52,7 @@ extern "C" { * * @note This number versions both OpenThread platform and user APIs. */ -#define OPENTHREAD_API_VERSION (457) +#define OPENTHREAD_API_VERSION (458) /** * @addtogroup api-instance diff --git a/include/openthread/link.h b/include/openthread/link.h index a9cc1906e8b..d74a710379f 100644 --- a/include/openthread/link.h +++ b/include/openthread/link.h @@ -1180,6 +1180,17 @@ void otLinkGetWakeupListenParameters(otInstance *aInstance, uint32_t *aInterval, */ otError otLinkSetWakeupListenParameters(otInstance *aInstance, uint32_t aInterval, uint32_t aDuration); +/** + * Sets the rx-on-when-idle state. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * @param[in] aRxOnWhenIdle TRUE to keep radio in Receive state, FALSE to put to Sleep state during idle periods. + * + * @retval OT_ERROR_NONE If successful. + * @retval OT_ERROR_INVALID_STATE If the raw link-layer isn't enabled. + */ +otError otLinkSetRxOnWhenIdle(otInstance *aInstance, bool aRxOnWhenIdle); + /** * @} */ diff --git a/src/core/api/link_raw_api.cpp b/src/core/api/link_raw_api.cpp index ff1eb72a20f..4eb4712148e 100644 --- a/src/core/api/link_raw_api.cpp +++ b/src/core/api/link_raw_api.cpp @@ -33,14 +33,14 @@ #include "openthread-core-config.h" -#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE - #include #include "instance/instance.hpp" using namespace ot; +#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE + otError otLinkRawSetReceiveDone(otInstance *aInstance, otLinkRawReceiveDone aCallback) { return AsCoreType(aInstance).Get().SetReceiveDone(aCallback); @@ -276,3 +276,21 @@ void otLinkGetFactoryAssignedIeeeEui64(otInstance *aInstance, otExtAddress *aEui #endif // OPENTHREAD_RADIO #endif // OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE + +otError otLinkSetRxOnWhenIdle(otInstance *aInstance, bool aRxOnWhenIdle) +{ + Error error = OT_ERROR_NONE; + +#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE + VerifyOrExit(AsCoreType(aInstance).Get().IsEnabled(), error = kErrorInvalidState); +#else + VerifyOrExit(AsCoreType(aInstance).Get().IsEnabled() && + AsCoreType(aInstance).Get().IsDisabled(), + error = kErrorInvalidState); +#endif + + AsCoreType(aInstance).Get().SetRxOnWhenIdle(aRxOnWhenIdle); + +exit: + return error; +} diff --git a/src/core/mac/sub_mac.cpp b/src/core/mac/sub_mac.cpp index 66399866624..0d1a6557097 100644 --- a/src/core/mac/sub_mac.cpp +++ b/src/core/mac/sub_mac.cpp @@ -591,7 +591,7 @@ void SubMac::HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aErro SetState(kStateReceive); #if OPENTHREAD_RADIO - if (aFrame.GetChannel() != aFrame.GetRxChannelAfterTxDone()) + if (aFrame.GetChannel() != aFrame.GetRxChannelAfterTxDone() && mRxOnWhenIdle) { // On RCP build, we switch immediately to the specified RX // channel if it is different from the channel on which frame diff --git a/src/core/radio/radio_platform.cpp b/src/core/radio/radio_platform.cpp index ea7d207ccae..e3fd35d9d76 100644 --- a/src/core/radio/radio_platform.cpp +++ b/src/core/radio/radio_platform.cpp @@ -85,12 +85,6 @@ extern "C" void otPlatRadioTxDone(otInstance *aInstance, otRadioFrame *aFrame, o Instance &instance = AsCoreType(aInstance); Mac::TxFrame &txFrame = *static_cast(aFrame); Mac::RxFrame *ackFrame = static_cast(aAckFrame); -#if OPENTHREAD_RADIO - uint8_t channel = txFrame.mInfo.mTxInfo.mRxChannelAfterTxDone; - - OT_ASSERT((otPlatRadioGetSupportedChannelMask(aInstance) & (1UL << channel)) != 0); - IgnoreError(otPlatRadioReceive(aInstance, channel)); -#endif VerifyOrExit(instance.IsInitialized()); @@ -152,8 +146,11 @@ extern "C" void otPlatDiagRadioTransmitDone(otInstance *aInstance, otRadioFrame #if OPENTHREAD_RADIO uint8_t channel = txFrame.mInfo.mTxInfo.mRxChannelAfterTxDone; - OT_ASSERT((otPlatRadioGetSupportedChannelMask(aInstance) & (1UL << channel)) != 0); - IgnoreError(otPlatRadioReceive(aInstance, channel)); + if (channel != aFrame->mChannel) + { + OT_ASSERT((otPlatRadioGetSupportedChannelMask(aInstance) & (1UL << channel)) != 0); + IgnoreError(otPlatRadioReceive(aInstance, channel)); + } #endif #if OPENTHREAD_CONFIG_MULTI_RADIO txFrame.SetRadioType(Mac::kRadioTypeIeee802154); diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index d85591b6c03..9307685d962 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -1599,7 +1599,7 @@ template <> otError NcpBase::HandlePropertySet