Skip to content

Commit

Permalink
[mac] apply RxChannelAfterTxDone only if RxOnWhenIdle (openthread#10826)
Browse files Browse the repository at this point in the history
This commit updates the implementation to apply RxChannelAfterTxDone
only if RxOnWhenIdle.
  • Loading branch information
bukepo authored Oct 28, 2024
1 parent fb3b265 commit 005c5ce
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 13 deletions.
2 changes: 1 addition & 1 deletion include/openthread/instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 11 additions & 0 deletions include/openthread/link.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/**
* @}
*/
Expand Down
22 changes: 20 additions & 2 deletions src/core/api/link_raw_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
2 changes: 1 addition & 1 deletion src/core/mac/sub_mac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 5 additions & 8 deletions src/core/radio/radio_platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());

Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/ncp/ncp_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
41 changes: 41 additions & 0 deletions tests/gtest/radio_spinel_rcp_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

0 comments on commit 005c5ce

Please sign in to comment.