From 6d93c7fc9646514267d6c04bd93c99995f7b6cac Mon Sep 17 00:00:00 2001 From: francoismichel Date: Fri, 3 Oct 2025 14:45:17 -0400 Subject: [PATCH] [rcp] add support for OTNS (#11637) This commit allows compiling the OpenThread RCP in OTNS mode. This allows OTBR to attach seamlessly to OTNS. * Add the mOtns attribute to Instance::Instance when compiled with OPENTHREAD_RADIO=1 * Add src/core/utils/otns.cpp to the RCP build. Only the necessary functions are compiled in RCP mode. Other functions such as EmitPingRequest and EmitPingReply that require IPv6 stack support are not compiled in RCP and are therefore moved into adequate `#if OPENTHREAD_MTD || OPENTHREAD_FTD` guards. * Ensure the RCP emits the needed events in src/core/radio/radio.cpp when compiled with OTNS support. --- src/core/CMakeLists.txt | 1 + src/core/instance/instance.cpp | 6 +-- src/core/instance/instance.hpp | 16 +++---- src/core/radio/radio.cpp | 6 +-- src/core/utils/otns.cpp | 76 +++++++++++++++++----------------- src/core/utils/otns.hpp | 36 +++++++++------- 6 files changed, 76 insertions(+), 65 deletions(-) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 43a534b0a..fb697fa72 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -315,6 +315,7 @@ set(RADIO_COMMON_SOURCES radio/radio_callbacks.cpp radio/radio_platform.cpp thread/link_quality.cpp + utils/otns.cpp utils/parse_cmdline.cpp utils/power_calibration.cpp ) diff --git a/src/core/instance/instance.cpp b/src/core/instance/instance.cpp index a61e25e86..ff6939a37 100644 --- a/src/core/instance/instance.cpp +++ b/src/core/instance/instance.cpp @@ -84,6 +84,9 @@ Instance::Instance(void) #if OPENTHREAD_CONFIG_UPTIME_ENABLE , mUptime(*this) #endif +#if OPENTHREAD_CONFIG_OTNS_ENABLE + , mOtns(*this) +#endif #if OPENTHREAD_MTD || OPENTHREAD_FTD , mNotifier(*this) , mTimeTicker(*this) @@ -259,9 +262,6 @@ Instance::Instance(void) #if OPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE , mAnnounceSender(*this) #endif -#if OPENTHREAD_CONFIG_OTNS_ENABLE - , mOtns(*this) -#endif #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE , mRoutingManager(*this) #if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE diff --git a/src/core/instance/instance.hpp b/src/core/instance/instance.hpp index 08f001a69..eede9f422 100644 --- a/src/core/instance/instance.hpp +++ b/src/core/instance/instance.hpp @@ -471,6 +471,10 @@ private: Uptime mUptime; #endif +#if OPENTHREAD_CONFIG_OTNS_ENABLE + Utils::Otns mOtns; +#endif + #if OPENTHREAD_MTD || OPENTHREAD_FTD // Notifier, TimeTicker, Settings, and MessagePool are initialized // before other member variables since other classes/objects from @@ -699,10 +703,6 @@ private: AnnounceSender mAnnounceSender; #endif -#if OPENTHREAD_CONFIG_OTNS_ENABLE - Utils::Otns mOtns; -#endif - #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE BorderRouter::RoutingManager mRoutingManager; #if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE @@ -758,6 +758,10 @@ template <> inline Radio::Statistics &Instance::Get(void) { return mRadio.mStati template <> inline Uptime &Instance::Get(void) { return mUptime; } #endif +#if OPENTHREAD_CONFIG_OTNS_ENABLE +template <> inline Utils::Otns &Instance::Get(void) { return mOtns; } +#endif + #if OPENTHREAD_MTD || OPENTHREAD_FTD template <> inline Notifier &Instance::Get(void) { return mNotifier; } @@ -1078,10 +1082,6 @@ template <> inline LinkMetrics::Subject &Instance::Get(void) { return mSubject; #endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) -#if OPENTHREAD_CONFIG_OTNS_ENABLE -template <> inline Utils::Otns &Instance::Get(void) { return mOtns; } -#endif - #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE template <> inline BorderRouter::RoutingManager &Instance::Get(void) { return mRoutingManager; } template <> inline BorderRouter::InfraIf &Instance::Get(void) { return mRoutingManager.mInfraIf; } diff --git a/src/core/radio/radio.cpp b/src/core/radio/radio.cpp index f3f980e0f..05ed0c1dd 100644 --- a/src/core/radio/radio.cpp +++ b/src/core/radio/radio.cpp @@ -88,7 +88,7 @@ void Radio::SetExtendedAddress(const Mac::ExtAddress &aExtAddress) address.Set(aExtAddress.m8, Mac::ExtAddress::kReverseByteOrder); otPlatRadioSetExtendedAddress(GetInstancePtr(), &address); -#if (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_OTNS_ENABLE +#if OPENTHREAD_CONFIG_OTNS_ENABLE Get().EmitExtendedAddress(address); #endif } @@ -97,7 +97,7 @@ void Radio::SetShortAddress(Mac::ShortAddress aShortAddress) { otPlatRadioSetShortAddress(GetInstancePtr(), aShortAddress); -#if (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_OTNS_ENABLE +#if OPENTHREAD_CONFIG_OTNS_ENABLE Get().EmitShortAddress(aShortAddress); #endif } @@ -120,7 +120,7 @@ Error Radio::ClearSrcMatchExtEntry(const Mac::ExtAddress &aExtAddress) Error Radio::Transmit(Mac::TxFrame &aFrame) { -#if (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_OTNS_ENABLE +#if OPENTHREAD_CONFIG_OTNS_ENABLE Get().EmitTransmit(aFrame); #endif diff --git a/src/core/utils/otns.cpp b/src/core/utils/otns.cpp index f9f0fe766..3d5559f37 100644 --- a/src/core/utils/otns.cpp +++ b/src/core/utils/otns.cpp @@ -33,7 +33,7 @@ #include "otns.hpp" -#if (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_OTNS_ENABLE +#if OPENTHREAD_CONFIG_OTNS_ENABLE #include "instance/instance.hpp" @@ -52,6 +52,42 @@ void Otns::EmitExtendedAddress(const Mac::ExtAddress &aExtAddress) const EmitStatus("extaddr=%s", revExtAddress.ToString().AsCString()); } +void Otns::EmitStatus(const char *aFmt, ...) const +{ + StatusString string; + va_list args; + + va_start(args, aFmt); + string.AppendVarArgs(aFmt, args); + va_end(args); + + EmitStatus(string); +} + +void Otns::EmitStatus(const StatusString &aString) const { otPlatOtnsStatus(aString.AsCString()); } + +void Otns::EmitTransmit(const Mac::TxFrame &aFrame) const +{ + StatusString string; + Mac::Address dst; + + IgnoreError(aFrame.GetDstAddr(dst)); + + string.Append("transmit=%d,%04x,%d", aFrame.GetChannel(), aFrame.GetFrameControlField(), aFrame.GetSequence()); + + if (dst.IsShort()) + { + string.Append(",%04x", dst.GetShort()); + } + else if (dst.IsExtended()) + { + string.Append(",%s", dst.ToString().AsCString()); + } + + EmitStatus(string); +} + +#if OPENTHREAD_MTD || OPENTHREAD_FTD void Otns::EmitPingRequest(const Ip6::Address &aPeerAddress, uint16_t aPingLength, uint32_t aTimestamp, @@ -70,20 +106,6 @@ void Otns::EmitPingReply(const Ip6::Address &aPeerAddress, aHopLimit); } -void Otns::EmitStatus(const char *aFmt, ...) const -{ - StatusString string; - va_list args; - - va_start(args, aFmt); - string.AppendVarArgs(aFmt, args); - va_end(args); - - EmitStatus(string); -} - -void Otns::EmitStatus(const StatusString &aString) const { otPlatOtnsStatus(aString.AsCString()); } - void Otns::HandleNotifierEvents(Events aEvents) const { if (aEvents.Contains(kEventThreadRoleChanged)) @@ -133,27 +155,6 @@ exit: return; } -void Otns::EmitTransmit(const Mac::TxFrame &aFrame) const -{ - StatusString string; - Mac::Address dst; - - IgnoreError(aFrame.GetDstAddr(dst)); - - string.Append("transmit=%d,%04x,%d", aFrame.GetChannel(), aFrame.GetFrameControlField(), aFrame.GetSequence()); - - if (dst.IsShort()) - { - string.Append(",%04x", dst.GetShort()); - } - else if (dst.IsExtended()) - { - string.Append(",%s", dst.ToString().AsCString()); - } - - EmitStatus(string); -} - void Otns::EmitDeviceMode(Mle::DeviceMode aMode) const { StatusString string; @@ -217,8 +218,9 @@ void Otns::EmitCoapStatus(const char *aAction, exit: LogWarnOnError(error, "EmitCoapStatus"); } +#endif // OPENTHREAD_MTD || OPENTHREAD_FTD } // namespace Utils } // namespace ot -#endif // (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_OTNS_ENABLE +#endif // OPENTHREAD_CONFIG_OTNS_ENABLE diff --git a/src/core/utils/otns.hpp b/src/core/utils/otns.hpp index ddf854e4e..ca8625386 100644 --- a/src/core/utils/otns.hpp +++ b/src/core/utils/otns.hpp @@ -36,22 +36,24 @@ #include "openthread-core-config.h" -#if (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_OTNS_ENABLE +#if OPENTHREAD_CONFIG_OTNS_ENABLE #include #include #include - -#include "coap/coap_message.hpp" #include "common/locator.hpp" #include "common/non_copyable.hpp" -#include "common/notifier.hpp" #include "common/string.hpp" #include "mac/mac_frame.hpp" #include "mac/mac_types.hpp" + +#if OPENTHREAD_MTD || OPENTHREAD_FTD +#include "coap/coap_message.hpp" +#include "common/notifier.hpp" #include "net/ip6_address.hpp" #include "thread/neighbor.hpp" #include "thread/neighbor_table.hpp" +#endif namespace ot { namespace Utils { @@ -61,7 +63,9 @@ namespace Utils { */ class Otns : public InstanceLocator, private NonCopyable { +#if OPENTHREAD_MTD || OPENTHREAD_FTD friend class ot::Notifier; +#endif public: /** @@ -88,6 +92,14 @@ public: */ void EmitExtendedAddress(const Mac::ExtAddress &aExtAddress) const; + /** + * Emits a transmit event to OTNS. + * + * @param[in] aFrame The frame of the transmission. + */ + void EmitTransmit(const Mac::TxFrame &aFrame) const; + +#if OPENTHREAD_MTD || OPENTHREAD_FTD /** * Emits ping request information to OTNS when sending. * @@ -122,13 +134,6 @@ public: */ void EmitNeighborChange(NeighborTable::Event aEvent, const Neighbor &aNeighbor) const; - /** - * Emits a transmit event to OTNS. - * - * @param[in] aFrame The frame of the transmission. - */ - void EmitTransmit(const Mac::TxFrame &aFrame) const; - /** * Emits the device mode to OTNS. * @@ -159,8 +164,9 @@ public: * @param[in] aMessage The received COAP message. * @param[in] aMessageInfo The message info. */ - void EmitCoapReceive(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) const; + void EmitCoapReceive(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) const; +#endif // OPENTHREAD_MTD || OPENTHREAD_FTD private: static constexpr uint16_t kStatusStringLength = 128; @@ -168,17 +174,19 @@ private: void EmitStatus(const StatusString &aString) const; void EmitStatus(const char *aFmt, ...) const OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK(2, 3); + +#if OPENTHREAD_FTD || OPENTHREAD_MTD void EmitCoapStatus(const char *aAction, const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Error *aError = nullptr) const; - void HandleNotifierEvents(Events aEvents) const; +#endif }; } // namespace Utils } // namespace ot -#endif //(OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_OTNS_ENABLE +#endif // OPENTHREAD_CONFIG_OTNS_ENABLE #endif // UTILS_OTNS_HPP_