mirror of
https://github.com/espressif/openthread.git
synced 2026-07-30 07:37:46 +00:00
[mac] apply RxChannelAfterTxDone only if RxOnWhenIdle (#10826)
This commit updates the implementation to apply RxChannelAfterTxDone only if RxOnWhenIdle.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -33,14 +33,14 @@
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
|
||||
|
||||
#include <openthread/platform/time.h>
|
||||
|
||||
#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<Mac::LinkRaw>().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<Mac::LinkRaw>().IsEnabled(), error = kErrorInvalidState);
|
||||
#else
|
||||
VerifyOrExit(AsCoreType(aInstance).Get<Mac::Mac>().IsEnabled() &&
|
||||
AsCoreType(aInstance).Get<Mle::Mle>().IsDisabled(),
|
||||
error = kErrorInvalidState);
|
||||
#endif
|
||||
|
||||
AsCoreType(aInstance).Get<Mac::SubMac>().SetRxOnWhenIdle(aRxOnWhenIdle);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -85,12 +85,6 @@ extern "C" void otPlatRadioTxDone(otInstance *aInstance, otRadioFrame *aFrame, o
|
||||
Instance &instance = AsCoreType(aInstance);
|
||||
Mac::TxFrame &txFrame = *static_cast<Mac::TxFrame *>(aFrame);
|
||||
Mac::RxFrame *ackFrame = static_cast<Mac::RxFrame *>(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);
|
||||
|
||||
@@ -1599,7 +1599,7 @@ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_RX_ON_WHEN_IDLE_M
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadBool(enabled));
|
||||
otPlatRadioSetRxOnWhenIdle(mInstance, enabled);
|
||||
SuccessOrExit(error = otLinkSetRxOnWhenIdle(mInstance, enabled));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
@@ -244,3 +244,44 @@ TEST(RadioSpinelTransmit, shouldPerformCsmaCaWhenEnabled)
|
||||
|
||||
platform.GoInMs(1000);
|
||||
}
|
||||
|
||||
TEST(RadioSpinelTransmit, shouldNotCauseSwitchingToRxAfterTxDoneIfNotRxOnWhenIdle)
|
||||
{
|
||||
FakeCoprocessorPlatform platform;
|
||||
|
||||
constexpr Mac::PanId kSrcPanId = 0x1234;
|
||||
constexpr Mac::PanId kDstPanId = 0x4321;
|
||||
constexpr uint8_t kDstAddr[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
|
||||
constexpr uint16_t kSrcAddr = 0xac00;
|
||||
constexpr int8_t kTxPower = 100;
|
||||
|
||||
uint8_t frameBuffer[OT_RADIO_FRAME_MAX_SIZE];
|
||||
Mac::TxFrame txFrame;
|
||||
|
||||
txFrame.mPsdu = frameBuffer;
|
||||
|
||||
{
|
||||
Mac::TxFrame::Info frameInfo;
|
||||
|
||||
frameInfo.mType = Mac::Frame::kTypeData;
|
||||
frameInfo.mVersion = Mac::Frame::kVersion2006;
|
||||
frameInfo.mAddrs.mSource.SetShort(kSrcAddr);
|
||||
frameInfo.mAddrs.mDestination.SetExtended(kDstAddr);
|
||||
frameInfo.mPanIds.SetSource(kSrcPanId);
|
||||
frameInfo.mPanIds.SetDestination(kDstPanId);
|
||||
frameInfo.mSecurityLevel = Mac::Frame::kSecurityEncMic32;
|
||||
|
||||
frameInfo.PrepareHeadersIn(txFrame);
|
||||
}
|
||||
|
||||
txFrame.mInfo.mTxInfo.mTxPower = kTxPower;
|
||||
txFrame.mChannel = 11;
|
||||
txFrame.mInfo.mTxInfo.mRxChannelAfterTxDone = 25;
|
||||
|
||||
ASSERT_EQ(platform.mRadioSpinel.Enable(FakePlatform::CurrentInstance()), kErrorNone);
|
||||
ASSERT_EQ(platform.mRadioSpinel.Receive(11), kErrorNone);
|
||||
ASSERT_EQ(platform.mRadioSpinel.SetRxOnWhenIdle(false), kErrorNone);
|
||||
ASSERT_EQ(platform.mRadioSpinel.Transmit(txFrame), kErrorNone);
|
||||
platform.GoInMs(1000);
|
||||
EXPECT_EQ(platform.GetReceiveChannel(), 11);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user