From 90224407f0c27b265d30248597383ba4b20ec3d2 Mon Sep 17 00:00:00 2001 From: Yakun Xu Date: Sat, 10 Oct 2026 14:21:19 +0800 Subject: [PATCH] [radio] fix alternate short address initialization and matching (#13700) When a router-eligible Child transitions to Router (e.g. during TestCoapObserve when Leader notifies an upgraded child at its former child RLOC16), OpenThread calls otPlatRadioSetAlternateShortAddress(), which stores the previous short address in mRadioContext.mAlternateShortAddress. Fix alternate short address handling consistently across Nexus, simulation radio, and MAC frame utils: - Advertise OT_RADIO_CAPS_ALT_SHORT_ADDR in both Nexus otPlatRadioGetCaps() and simulation gRadioCaps. - Initialize mCslShortAddress, mShortAddress, and mAlternateShortAddress in otRadioContext to OT_RADIO_INVALID_SHORT_ADDR in both Nexus::Radio::Reset() and simulation platformRadioInit(). - Drop duplicate Radio::mShortAddress and Radio::mExtAddress from Nexus::Radio and use mRadioContext consistently. - Simplify Nexus::Radio::Radio(void) to call Reset(). - Guard against Mac::kShortAddrInvalid and match both short addresses in Nexus::Radio::Matches() and otMacFrameDoesAddrMatchAny(). --- examples/platforms/simulation/radio.c | 8 +++-- examples/platforms/utils/mac_frame.cpp | 10 +++--- tests/nexus/platform/nexus_radio.cpp | 42 +++++++++----------------- tests/nexus/platform/nexus_radio.hpp | 2 -- 4 files changed, 27 insertions(+), 35 deletions(-) diff --git a/examples/platforms/simulation/radio.c b/examples/platforms/simulation/radio.c index 3f8e5409a..93f2283d8 100644 --- a/examples/platforms/simulation/radio.c +++ b/examples/platforms/simulation/radio.c @@ -144,9 +144,9 @@ static bool sRadioCoexEnabled = true; otRadioCaps gRadioCaps = #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 - OT_RADIO_CAPS_TRANSMIT_SEC; + OT_RADIO_CAPS_ALT_SHORT_ADDR | OT_RADIO_CAPS_TRANSMIT_SEC; #else - OT_RADIO_CAPS_NONE; + OT_RADIO_CAPS_ALT_SHORT_ADDR; #endif static otRadioContext sRadioContext; @@ -417,6 +417,10 @@ void platformRadioInit(void) sTransmitFrame.mPsdu = sTransmitMessage.mPsdu; sAckFrame.mPsdu = sAckMessage.mPsdu; + sRadioContext.mCslShortAddress = OT_RADIO_INVALID_SHORT_ADDR; + sRadioContext.mShortAddress = OT_RADIO_INVALID_SHORT_ADDR; + sRadioContext.mAlternateShortAddress = OT_RADIO_INVALID_SHORT_ADDR; + #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT sTransmitFrame.mInfo.mTxInfo.mIeInfo = &sTransmitIeInfo; #else diff --git a/examples/platforms/utils/mac_frame.cpp b/examples/platforms/utils/mac_frame.cpp index 91e88880e..c2e0ef5eb 100644 --- a/examples/platforms/utils/mac_frame.cpp +++ b/examples/platforms/utils/mac_frame.cpp @@ -108,12 +108,14 @@ bool otMacFrameDoesAddrMatchAny(const otRadioFrame *aFrame, switch (frameInfo.mAddrs.mDestination.GetType()) { case Mac::Address::kTypeShort: - VerifyOrExit(frameInfo.mAddrs.mDestination.GetShort() == Mac::kShortAddrBroadcast || - frameInfo.mAddrs.mDestination.GetShort() == aShortAddress || - (aAltShortAddress != Mac::kShortAddrInvalid && - frameInfo.mAddrs.mDestination.GetShort() == aAltShortAddress), + { + Mac::ShortAddress dstAddr = frameInfo.mAddrs.mDestination.GetShort(); + + VerifyOrExit(dstAddr != Mac::kShortAddrInvalid, rval = false); + VerifyOrExit(dstAddr == Mac::kShortAddrBroadcast || dstAddr == aShortAddress || dstAddr == aAltShortAddress, rval = false); break; + } case Mac::Address::kTypeExtended: VerifyOrExit(frameInfo.mAddrs.mDestination.GetExtended() == *static_cast(aExtAddress), diff --git a/tests/nexus/platform/nexus_radio.cpp b/tests/nexus/platform/nexus_radio.cpp index 4d49220ee..606754e52 100644 --- a/tests/nexus/platform/nexus_radio.cpp +++ b/tests/nexus/platform/nexus_radio.cpp @@ -42,7 +42,7 @@ extern "C" { otRadioCaps otPlatRadioGetCaps(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return OT_RADIO_CAPS_TRANSMIT_SEC; + return OT_RADIO_CAPS_TRANSMIT_SEC | OT_RADIO_CAPS_ALT_SHORT_ADDR; } int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance) @@ -65,18 +65,13 @@ void otPlatRadioSetPanId(otInstance *aInstance, otPanId aPanId) { AsNode(aInstan void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aExtAddress) { - Radio &radio = AsNode(aInstance).mRadio; - - radio.mExtAddress.Set(aExtAddress->m8, Mac::ExtAddress::kReverseByteOrder); - AsCoreType(&radio.mRadioContext.mExtAddress).Set(aExtAddress->m8, Mac::ExtAddress::kReverseByteOrder); + AsCoreType(&AsNode(aInstance).mRadio.mRadioContext.mExtAddress) + .Set(aExtAddress->m8, Mac::ExtAddress::kReverseByteOrder); } void otPlatRadioSetShortAddress(otInstance *aInstance, otShortAddress aShortAddress) { - Radio &radio = AsNode(aInstance).mRadio; - - radio.mShortAddress = aShortAddress; - radio.mRadioContext.mShortAddress = aShortAddress; + AsNode(aInstance).mRadio.mRadioContext.mShortAddress = aShortAddress; } void otPlatRadioSetAlternateShortAddress(otInstance *aInstance, otShortAddress aShortAddress) @@ -362,19 +357,7 @@ otError otPlatRadioConfigureEnhAckProbing(otInstance *aInstance, //--------------------------------------------------------------------------------------------------------------------- // Radio -Radio::Radio(void) - : mState(kStateDisabled) - , mPromiscuous(false) - , mSrcMatchEnabled(false) - , mMacFrameCounterReset(false) - , mChannel(0) - , mPanId(0) - , mShortAddress(Mac::kShortAddrInvalid) -{ - mExtAddress.Clear(); - ClearAllBytes(mRadioContext); - mTxFrame.mInfo.mTxInfo.mIeInfo = &mTxIeInfo; -} +Radio::Radio(void) { Reset(); } void Radio::Reset(void) { @@ -384,13 +367,14 @@ void Radio::Reset(void) mMacFrameCounterReset = false; mChannel = 0; mPanId = 0; - mShortAddress = Mac::kShortAddrInvalid; - mExtAddress.Clear(); mSrcMatchShortEntries.Clear(); mSrcMatchExtEntries.Clear(); mLinkMetricsEntries.Clear(); ClearAllBytes(mRadioContext); - mTxFrame.mInfo.mTxInfo.mIeInfo = &mTxIeInfo; + mRadioContext.mCslShortAddress = Mac::kShortAddrInvalid; + mRadioContext.mShortAddress = Mac::kShortAddrInvalid; + mRadioContext.mAlternateShortAddress = Mac::kShortAddrInvalid; + mTxFrame.mInfo.mTxInfo.mIeInfo = &mTxIeInfo; } Error Radio::ConfigureEnhAckProbing(Mac::ShortAddress aShortAddress, @@ -506,11 +490,15 @@ bool Radio::Matches(const Mac::Address &aAddress, Mac::PanId aPanId) const if (aAddress.IsShort()) { - VerifyOrExit(aAddress.IsBroadcast() || aAddress.GetShort() == mShortAddress); + Mac::ShortAddress shortAddr = aAddress.GetShort(); + + VerifyOrExit(shortAddr != Mac::kShortAddrInvalid); + VerifyOrExit(aAddress.IsBroadcast() || (shortAddr == mRadioContext.mShortAddress) || + (shortAddr == mRadioContext.mAlternateShortAddress)); } else if (aAddress.IsExtended()) { - VerifyOrExit(aAddress.GetExtended() == mExtAddress); + VerifyOrExit(aAddress.GetExtended() == AsCoreType(&mRadioContext.mExtAddress)); } if ((aPanId != Mac::kPanIdBroadcast) && (mPanId != Mac::kPanIdBroadcast)) diff --git a/tests/nexus/platform/nexus_radio.hpp b/tests/nexus/platform/nexus_radio.hpp index 0c7dcef0e..b0c0d0e5c 100644 --- a/tests/nexus/platform/nexus_radio.hpp +++ b/tests/nexus/platform/nexus_radio.hpp @@ -96,8 +96,6 @@ struct Radio bool mMacFrameCounterReset : 1; uint8_t mChannel; Mac::PanId mPanId; - Mac::ShortAddress mShortAddress; - Mac::ExtAddress mExtAddress; Frame mTxFrame; otRadioIeInfo mTxIeInfo; otRadioContext mRadioContext;