From 7568e31c0831fcf90fdbe40680f82dc462bde33f Mon Sep 17 00:00:00 2001 From: Zhanglong Xia Date: Wed, 11 Oct 2023 01:15:32 +0800 Subject: [PATCH] [spinel] create spinel interface based on the radio url protocol (#9393) The posix platform is able to support the HDLC, SPI and vendor spinel interfaces, but the spinel interface type can't be changed dynamically. It is inconvenient to use different spinel interfaces for Thread stack in Android. This commit enables the posix platform to support the HDLC, SPI and vendor interface at the same time, and the final spinel interface type is determined by the radio url protocol. Some other changes: 1. Not use CRTP style for the radio spinel. 2. Deprecate the OT_POSIX_CONFIG_RCP_BUS and OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL. --- etc/cmake/options.cmake | 1 + script/check-posix-build-cmake | 4 +- src/lib/hdlc/hdlc.cpp | 25 +- src/lib/hdlc/hdlc.hpp | 10 +- src/lib/spinel/BUILD.gn | 3 +- src/lib/spinel/CMakeLists.txt | 1 + src/lib/spinel/openthread-spinel-config.h | 12 + ...radio_spinel_impl.hpp => radio_spinel.cpp} | 539 ++++++++---------- src/lib/spinel/radio_spinel.hpp | 128 ++--- src/lib/spinel/radio_spinel_metrics.h | 16 + src/lib/spinel/spinel_interface.hpp | 29 +- src/lib/url/url.cpp | 8 + src/lib/url/url.hpp | 2 + src/ncp/ncp_hdlc.cpp | 2 +- src/posix/platform/CMakeLists.txt | 20 +- src/posix/platform/hdlc_interface.cpp | 61 +- src/posix/platform/hdlc_interface.hpp | 42 +- .../include/openthread/openthread-system.h | 16 - src/posix/platform/openthread-posix-config.h | 69 ++- src/posix/platform/radio.cpp | 257 +++++---- src/posix/platform/radio.hpp | 53 +- src/posix/platform/radio_url.cpp | 48 +- src/posix/platform/spi_interface.cpp | 62 +- src/posix/platform/spi_interface.hpp | 41 +- src/posix/platform/trel.cpp | 1 + src/posix/platform/vendor.cmake | 2 +- src/posix/platform/vendor_interface.hpp | 34 +- .../platform/vendor_interface_example.cpp | 31 +- tests/scripts/expect/cli-region.exp | 1 + .../openthread-core-toranj-config-posix.h | 2 +- tests/unit/test_hdlc.cpp | 6 +- 31 files changed, 835 insertions(+), 691 deletions(-) rename src/lib/spinel/{radio_spinel_impl.hpp => radio_spinel.cpp} (86%) diff --git a/etc/cmake/options.cmake b/etc/cmake/options.cmake index a03af2013..0c667d0ee 100644 --- a/etc/cmake/options.cmake +++ b/etc/cmake/options.cmake @@ -354,3 +354,4 @@ endmacro() ot_removed_option(OT_MTD_NETDIAG "- Use OT_NETDIAG_CLIENT instead - note that server function is always supported") ot_removed_option(OT_EXCLUDE_TCPLP_LIB "- Use OT_TCP instead, OT_EXCLUDE_TCPLP_LIB is deprecated") +ot_removed_option(OT_POSIX_CONFIG_RCP_BUS "- Use OT_POSIX_RCP_HDLC_BUS, OT_POSIX_RCP_SPI_BUS or OT_POSIX_RCP_VENDOR_BUS instead, OT_POSIX_CONFIG_RCP_BUS is deprecated") diff --git a/script/check-posix-build-cmake b/script/check-posix-build-cmake index 253ab2863..63f67c683 100755 --- a/script/check-posix-build-cmake +++ b/script/check-posix-build-cmake @@ -72,11 +72,11 @@ main() if [[ $OSTYPE != "darwin"* ]]; then reset_source - build -DOT_RCP_RESTORATION_MAX_COUNT=2 -DOT_POSIX_CONFIG_RCP_BUS=SPI "$@" + build -DOT_RCP_RESTORATION_MAX_COUNT=2 -DOT_POSIX_RCP_SPI_BUS=ON "$@" fi reset_source - build -DOT_POSIX_CONFIG_RCP_BUS=VENDOR "$@" + build -DOT_POSIX_RCP_VENDOR_BUS=ON "$@" } main "$@" diff --git a/src/lib/hdlc/hdlc.cpp b/src/lib/hdlc/hdlc.cpp index 26b1bd5ca..cde7ce8d5 100644 --- a/src/lib/hdlc/hdlc.cpp +++ b/src/lib/hdlc/hdlc.cpp @@ -199,16 +199,23 @@ exit: return error; } -Decoder::Decoder(Spinel::FrameWritePointer &aFrameWritePointer, FrameHandler aFrameHandler, void *aContext) +Decoder::Decoder(void) : mState(kStateNoSync) - , mWritePointer(aFrameWritePointer) - , mFrameHandler(aFrameHandler) - , mContext(aContext) + , mWritePointer(nullptr) + , mFrameHandler(nullptr) + , mContext(nullptr) , mFcs(0) , mDecodedLength(0) { } +void Decoder::Init(Spinel::FrameWritePointer &aFrameWritePointer, FrameHandler aFrameHandler, void *aContext) +{ + mWritePointer = &aFrameWritePointer; + mFrameHandler = aFrameHandler; + mContext = aContext; +} + void Decoder::Reset(void) { mState = kStateNoSync; @@ -254,7 +261,7 @@ void Decoder::Decode(const uint8_t *aData, uint16_t aLength) ) { // Remove the FCS from the frame. - mWritePointer.UndoLastWrites(kFcsSize); + mWritePointer->UndoLastWrites(kFcsSize); error = OT_ERROR_NONE; } @@ -266,10 +273,10 @@ void Decoder::Decode(const uint8_t *aData, uint16_t aLength) break; default: - if (mWritePointer.CanWrite(sizeof(uint8_t))) + if (mWritePointer->CanWrite(sizeof(uint8_t))) { mFcs = UpdateFcs(mFcs, byte); - IgnoreError(mWritePointer.WriteByte(byte)); + IgnoreError(mWritePointer->WriteByte(byte)); mDecodedLength++; } else @@ -284,11 +291,11 @@ void Decoder::Decode(const uint8_t *aData, uint16_t aLength) break; case kStateEscaped: - if (mWritePointer.CanWrite(sizeof(uint8_t))) + if (mWritePointer->CanWrite(sizeof(uint8_t))) { byte ^= 0x20; mFcs = UpdateFcs(mFcs, byte); - IgnoreError(mWritePointer.WriteByte(byte)); + IgnoreError(mWritePointer->WriteByte(byte)); mDecodedLength++; mState = kStateSync; } diff --git a/src/lib/hdlc/hdlc.hpp b/src/lib/hdlc/hdlc.hpp index 37ebb324c..dd2860115 100644 --- a/src/lib/hdlc/hdlc.hpp +++ b/src/lib/hdlc/hdlc.hpp @@ -140,6 +140,12 @@ public: */ typedef void (*FrameHandler)(void *aContext, otError aError); + /** + * Initializes the object. + * + */ + Decoder(void); + /** * Initializes the decoder. * @@ -148,7 +154,7 @@ public: * @param[in] aContext A pointer to arbitrary context information. * */ - Decoder(Spinel::FrameWritePointer &aFrameWritePointer, FrameHandler aFrameHandler, void *aContext); + void Init(Spinel::FrameWritePointer &aFrameWritePointer, FrameHandler aFrameHandler, void *aContext); /** * Feeds a block of data into the decoder. @@ -179,7 +185,7 @@ private: }; State mState; - Spinel::FrameWritePointer &mWritePointer; + Spinel::FrameWritePointer *mWritePointer; FrameHandler mFrameHandler; void *mContext; uint16_t mFcs; diff --git a/src/lib/spinel/BUILD.gn b/src/lib/spinel/BUILD.gn index 13ca106c4..f03d945dd 100644 --- a/src/lib/spinel/BUILD.gn +++ b/src/lib/spinel/BUILD.gn @@ -34,8 +34,9 @@ declare_args() { spinel_sources = [ "openthread-spinel-config.h", + "multi_frame_buffer.hpp", + "radio_spinel.cpp", "radio_spinel.hpp", - "radio_spinel_impl.hpp", "spi_frame.hpp", "spinel.c", "spinel_buffer.cpp", diff --git a/src/lib/spinel/CMakeLists.txt b/src/lib/spinel/CMakeLists.txt index 0e41c8798..de68fc25a 100644 --- a/src/lib/spinel/CMakeLists.txt +++ b/src/lib/spinel/CMakeLists.txt @@ -61,6 +61,7 @@ set(COMMON_INCLUDES ) set(COMMON_SOURCES + radio_spinel.cpp spinel.c spinel_buffer.cpp spinel_decoder.cpp diff --git a/src/lib/spinel/openthread-spinel-config.h b/src/lib/spinel/openthread-spinel-config.h index d8dec50ba..086a75842 100644 --- a/src/lib/spinel/openthread-spinel-config.h +++ b/src/lib/spinel/openthread-spinel-config.h @@ -66,4 +66,16 @@ #ifndef OPENTHREAD_SPINEL_CONFIG_ABORT_ON_UNEXPECTED_RCP_RESET_ENABLE #define OPENTHREAD_SPINEL_CONFIG_ABORT_ON_UNEXPECTED_RCP_RESET_ENABLE 0 #endif + +/** + * @def OPENTHREAD_SPINEL_CONFIG_RCP_TIME_SYNC_INTERVAL + * + * This setting configures the interval (in units of microseconds) for host-rcp + * time sync. The host will recalculate the time offset between host and RCP + * every interval. + * + */ +#ifndef OPENTHREAD_SPINEL_CONFIG_RCP_TIME_SYNC_INTERVAL +#define OPENTHREAD_SPINEL_CONFIG_RCP_TIME_SYNC_INTERVAL (60 * 1000 * 1000) +#endif #endif // OPENTHREAD_SPINEL_CONFIG_H_ diff --git a/src/lib/spinel/radio_spinel_impl.hpp b/src/lib/spinel/radio_spinel.cpp similarity index 86% rename from src/lib/spinel/radio_spinel_impl.hpp rename to src/lib/spinel/radio_spinel.cpp index 30d16bd43..e933874e7 100644 --- a/src/lib/spinel/radio_spinel_impl.hpp +++ b/src/lib/spinel/radio_spinel.cpp @@ -31,6 +31,8 @@ * This file implements the spinel based radio transceiver. */ +#include "radio_spinel.hpp" + #include #include #include @@ -44,127 +46,14 @@ #include "common/encoding.hpp" #include "common/new.hpp" #include "lib/platform/exit_code.h" -#include "lib/spinel/radio_spinel.hpp" -#include "lib/spinel/spinel.h" #include "lib/spinel/spinel_decoder.hpp" -#ifndef MS_PER_S -#define MS_PER_S 1000 -#endif -#ifndef US_PER_MS -#define US_PER_MS 1000 -#endif -#ifndef US_PER_S -#define US_PER_S (MS_PER_S * US_PER_MS) -#endif - -#ifndef TX_WAIT_US -#define TX_WAIT_US (5 * US_PER_S) -#endif - -using ot::Spinel::Decoder; - namespace ot { namespace Spinel { -static inline otError SpinelStatusToOtError(spinel_status_t aError) -{ - otError ret; - - switch (aError) - { - case SPINEL_STATUS_OK: - ret = OT_ERROR_NONE; - break; - - case SPINEL_STATUS_FAILURE: - ret = OT_ERROR_FAILED; - break; - - case SPINEL_STATUS_DROPPED: - ret = OT_ERROR_DROP; - break; - - case SPINEL_STATUS_NOMEM: - ret = OT_ERROR_NO_BUFS; - break; - - case SPINEL_STATUS_BUSY: - ret = OT_ERROR_BUSY; - break; - - case SPINEL_STATUS_PARSE_ERROR: - ret = OT_ERROR_PARSE; - break; - - case SPINEL_STATUS_INVALID_ARGUMENT: - ret = OT_ERROR_INVALID_ARGS; - break; - - case SPINEL_STATUS_UNIMPLEMENTED: - ret = OT_ERROR_NOT_IMPLEMENTED; - break; - - case SPINEL_STATUS_INVALID_STATE: - ret = OT_ERROR_INVALID_STATE; - break; - - case SPINEL_STATUS_NO_ACK: - ret = OT_ERROR_NO_ACK; - break; - - case SPINEL_STATUS_CCA_FAILURE: - ret = OT_ERROR_CHANNEL_ACCESS_FAILURE; - break; - - case SPINEL_STATUS_ALREADY: - ret = OT_ERROR_ALREADY; - break; - - case SPINEL_STATUS_PROP_NOT_FOUND: - ret = OT_ERROR_NOT_IMPLEMENTED; - break; - - case SPINEL_STATUS_ITEM_NOT_FOUND: - ret = OT_ERROR_NOT_FOUND; - break; - - default: - if (aError >= SPINEL_STATUS_STACK_NATIVE__BEGIN && aError <= SPINEL_STATUS_STACK_NATIVE__END) - { - ret = static_cast(aError - SPINEL_STATUS_STACK_NATIVE__BEGIN); - } - else - { - ret = OT_ERROR_FAILED; - } - break; - } - - return ret; -} - -static inline void LogIfFail(const char *aText, otError aError) -{ - OT_UNUSED_VARIABLE(aText); - OT_UNUSED_VARIABLE(aError); - - if (aError != OT_ERROR_NONE && aError != OT_ERROR_NO_ACK) - { - otLogWarnPlat("%s: %s", aText, otThreadErrorToString(aError)); - } -} - -template void RadioSpinel::HandleReceivedFrame(void *aContext) -{ - static_cast(aContext)->HandleReceivedFrame(); -} - -template -RadioSpinel::RadioSpinel(void) +RadioSpinel::RadioSpinel(void) : mInstance(nullptr) - , mRxFrameBuffer() - , mSpinelInterface(HandleReceivedFrame, this, mRxFrameBuffer) + , mSpinelInterface(nullptr) , mCmdTidsInUse(0) , mCmdNextTid(1) , mTxRadioTid(0) @@ -210,8 +99,7 @@ RadioSpinel::RadioSpinel(void) memset(&mRadioSpinelMetrics, 0, sizeof(mRadioSpinelMetrics)); } -template -void RadioSpinel::Init(bool aResetRadio, bool aSkipRcpCompatibilityCheck) +void RadioSpinel::Init(SpinelInterface &aSpinelInterface, bool aResetRadio, bool aSkipRcpCompatibilityCheck) { otError error = OT_ERROR_NONE; bool supportsRcpApiVersion; @@ -221,6 +109,9 @@ void RadioSpinel::Init(bool aResetRadio, bool aSkipRcpCompatibili mResetRadioOnStartup = aResetRadio; #endif + mSpinelInterface = &aSpinelInterface; + SuccessOrDie(mSpinelInterface->Init(HandleReceivedFrame, this, mRxFrameBuffer)); + ResetRcp(aResetRadio); SuccessOrExit(error = CheckSpinelVersion()); SuccessOrExit(error = Get(SPINEL_PROP_NCP_VERSION, SPINEL_DATATYPE_UTF8_S, mVersion, sizeof(mVersion))); @@ -242,7 +133,7 @@ exit: SuccessOrDie(error); } -template void RadioSpinel::ResetRcp(bool aResetRadio) +void RadioSpinel::ResetRcp(bool aResetRadio) { bool hardwareReset; bool resetDone = false; @@ -256,7 +147,7 @@ template void RadioSpinel::ResetRcp(bool ExitNow(resetDone = true); } - hardwareReset = (mSpinelInterface.HardwareReset() == OT_ERROR_NONE); + hardwareReset = (mSpinelInterface->HardwareReset() == OT_ERROR_NONE); if (hardwareReset) { @@ -282,7 +173,7 @@ exit: } } -template otError RadioSpinel::CheckSpinelVersion(void) +otError RadioSpinel::CheckSpinelVersion(void) { otError error = OT_ERROR_NONE; unsigned int versionMajor; @@ -304,8 +195,7 @@ exit: return error; } -template -bool RadioSpinel::IsRcp(bool &aSupportsRcpApiVersion, bool &aSupportsRcpMinHostApiVersion) +bool RadioSpinel::IsRcp(bool &aSupportsRcpApiVersion, bool &aSupportsRcpMinHostApiVersion) { uint8_t capsBuffer[kCapsBufferSize]; const uint8_t *capsData = capsBuffer; @@ -364,7 +254,7 @@ bool RadioSpinel::IsRcp(bool &aSupportsRcpApiVersion, bool &aSupp return isRcp; } -template otError RadioSpinel::CheckRadioCapabilities(void) +otError RadioSpinel::CheckRadioCapabilities(void) { const otRadioCaps kRequiredRadioCaps = #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 @@ -400,8 +290,7 @@ exit: return error; } -template -otError RadioSpinel::CheckRcpApiVersion(bool aSupportsRcpApiVersion, bool aSupportsRcpMinHostApiVersion) +otError RadioSpinel::CheckRcpApiVersion(bool aSupportsRcpApiVersion, bool aSupportsRcpMinHostApiVersion) { otError error = OT_ERROR_NONE; @@ -450,14 +339,21 @@ exit: return error; } -template void RadioSpinel::Deinit(void) +void RadioSpinel::Deinit(void) { - mSpinelInterface.Deinit(); + if (mSpinelInterface != nullptr) + { + mSpinelInterface->Deinit(); + mSpinelInterface = nullptr; + } + // This allows implementing pseudo reset. new (this) RadioSpinel(); } -template void RadioSpinel::HandleReceivedFrame(void) +void RadioSpinel::HandleReceivedFrame(void *aContext) { static_cast(aContext)->HandleReceivedFrame(); } + +void RadioSpinel::HandleReceivedFrame(void) { otError error = OT_ERROR_NONE; uint8_t header; @@ -490,8 +386,7 @@ exit: UpdateParseErrorCount(error); } -template -void RadioSpinel::HandleNotification(SpinelInterface::RxFrameBuffer &aFrameBuffer) +void RadioSpinel::HandleNotification(SpinelInterface::RxFrameBuffer &aFrameBuffer) { spinel_prop_key_t key; spinel_size_t len = 0; @@ -546,8 +441,7 @@ exit: LogIfFail("Error processing notification", error); } -template -void RadioSpinel::HandleNotification(const uint8_t *aFrame, uint16_t aLength) +void RadioSpinel::HandleNotification(const uint8_t *aFrame, uint16_t aLength) { spinel_prop_key_t key; spinel_size_t len = 0; @@ -568,8 +462,7 @@ exit: LogIfFail("Error processing saved notification", error); } -template -void RadioSpinel::HandleResponse(const uint8_t *aBuffer, uint16_t aLength) +void RadioSpinel::HandleResponse(const uint8_t *aBuffer, uint16_t aLength) { spinel_prop_key_t key; uint8_t *data = nullptr; @@ -610,11 +503,10 @@ exit: LogIfFail("Error processing response", error); } -template -void RadioSpinel::HandleWaitingResponse(uint32_t aCommand, - spinel_prop_key_t aKey, - const uint8_t *aBuffer, - uint16_t aLength) +void RadioSpinel::HandleWaitingResponse(uint32_t aCommand, + spinel_prop_key_t aKey, + const uint8_t *aBuffer, + uint16_t aLength) { if (aKey == SPINEL_PROP_LAST_STATUS) { @@ -679,8 +571,7 @@ exit: LogIfFail("Error processing result", mError); } -template -void RadioSpinel::HandleValueIs(spinel_prop_key_t aKey, const uint8_t *aBuffer, uint16_t aLength) +void RadioSpinel::HandleValueIs(spinel_prop_key_t aKey, const uint8_t *aBuffer, uint16_t aLength) { otError error = OT_ERROR_NONE; spinel_ssize_t unpacked; @@ -785,11 +676,10 @@ exit: LogIfFail("Failed to handle ValueIs", error); } -template -otError RadioSpinel::ParseRadioFrame(otRadioFrame &aFrame, - const uint8_t *aBuffer, - uint16_t aLength, - spinel_ssize_t &aUnpacked) +otError RadioSpinel::ParseRadioFrame(otRadioFrame &aFrame, + const uint8_t *aBuffer, + uint16_t aLength, + spinel_ssize_t &aUnpacked) { otError error = OT_ERROR_NONE; uint16_t flags = 0; @@ -866,7 +756,7 @@ exit: return error; } -template void RadioSpinel::ProcessFrameQueue(void) +void RadioSpinel::ProcessFrameQueue(void) { uint8_t *frame = nullptr; uint16_t length; @@ -879,7 +769,7 @@ template void RadioSpinel::ProcessFrameQ mRxFrameBuffer.ClearSavedFrames(); } -template void RadioSpinel::RadioReceive(void) +void RadioSpinel::RadioReceive(void) { if (!mIsPromiscuous) { @@ -911,8 +801,7 @@ exit: return; } -template -void RadioSpinel::TransmitDone(otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError) +void RadioSpinel::TransmitDone(otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError) { #if OPENTHREAD_CONFIG_DIAG_ENABLE if (otPlatDiagModeGet()) @@ -926,7 +815,7 @@ void RadioSpinel::TransmitDone(otRadioFrame *aFrame, otRadioFrame } } -template void RadioSpinel::ProcessRadioStateMachine(void) +void RadioSpinel::ProcessRadioStateMachine(void) { if (mState == kStateTransmitDone) { @@ -937,13 +826,13 @@ template void RadioSpinel::ProcessRadioS } else if (mState == kStateTransmitting && otPlatTimeGet() >= mTxRadioEndUs) { - // Frame has been successfully passed to radio, but no `TransmitDone` event received within TX_WAIT_US. + // Frame has been successfully passed to radio, but no `TransmitDone` event received within kTxWaitUs. otLogWarnPlat("radio tx timeout"); HandleRcpTimeout(); } } -template void RadioSpinel::Process(const void *aContext) +void RadioSpinel::Process(const void *aContext) { if (mRxFrameBuffer.HasSavedFrame()) { @@ -951,7 +840,7 @@ template void RadioSpinel::Process(const RecoverFromRcpFailure(); } - GetSpinelInterface().Process(aContext); + mSpinelInterface->Process(aContext); RecoverFromRcpFailure(); if (mRxFrameBuffer.HasSavedFrame()) @@ -965,7 +854,7 @@ template void RadioSpinel::Process(const CalcRcpTimeOffset(); } -template otError RadioSpinel::SetPromiscuous(bool aEnable) +otError RadioSpinel::SetPromiscuous(bool aEnable) { otError error; @@ -977,7 +866,7 @@ exit: return error; } -template otError RadioSpinel::SetShortAddress(uint16_t aAddress) +otError RadioSpinel::SetShortAddress(uint16_t aAddress) { otError error = OT_ERROR_NONE; @@ -989,12 +878,11 @@ exit: return error; } -template -otError RadioSpinel::SetMacKey(uint8_t aKeyIdMode, - uint8_t aKeyId, - const otMacKeyMaterial *aPrevKey, - const otMacKeyMaterial *aCurrKey, - const otMacKeyMaterial *aNextKey) +otError RadioSpinel::SetMacKey(uint8_t aKeyIdMode, + uint8_t aKeyId, + const otMacKeyMaterial *aPrevKey, + const otMacKeyMaterial *aCurrKey, + const otMacKeyMaterial *aNextKey) { otError error; size_t aKeySize; @@ -1032,14 +920,12 @@ exit: return error; } -template -otError RadioSpinel::SetMacFrameCounter(uint32_t aMacFrameCounter, bool aSetIfLarger) +otError RadioSpinel::SetMacFrameCounter(uint32_t aMacFrameCounter, bool aSetIfLarger) { otError error; SuccessOrExit(error = Set(SPINEL_PROP_RCP_MAC_FRAME_COUNTER, SPINEL_DATATYPE_UINT32_S SPINEL_DATATYPE_BOOL_S, aMacFrameCounter, aSetIfLarger)); - #if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0 mMacFrameCounterSet = true; mMacFrameCounter = aMacFrameCounter; @@ -1049,15 +935,14 @@ exit: return error; } -template otError RadioSpinel::GetIeeeEui64(uint8_t *aIeeeEui64) +otError RadioSpinel::GetIeeeEui64(uint8_t *aIeeeEui64) { memcpy(aIeeeEui64, mIeeeEui64.m8, sizeof(mIeeeEui64.m8)); return OT_ERROR_NONE; } -template -otError RadioSpinel::SetExtendedAddress(const otExtAddress &aExtAddress) +otError RadioSpinel::SetExtendedAddress(const otExtAddress &aExtAddress) { otError error; @@ -1068,7 +953,7 @@ exit: return error; } -template otError RadioSpinel::SetPanId(uint16_t aPanId) +otError RadioSpinel::SetPanId(uint16_t aPanId) { otError error = OT_ERROR_NONE; @@ -1080,12 +965,12 @@ exit: return error; } -template otError RadioSpinel::EnableSrcMatch(bool aEnable) +otError RadioSpinel::EnableSrcMatch(bool aEnable) { return Set(SPINEL_PROP_MAC_SRC_MATCH_ENABLED, SPINEL_DATATYPE_BOOL_S, aEnable); } -template otError RadioSpinel::AddSrcMatchShortEntry(uint16_t aShortAddress) +otError RadioSpinel::AddSrcMatchShortEntry(uint16_t aShortAddress) { otError error; @@ -1109,8 +994,7 @@ exit: return error; } -template -otError RadioSpinel::AddSrcMatchExtEntry(const otExtAddress &aExtAddress) +otError RadioSpinel::AddSrcMatchExtEntry(const otExtAddress &aExtAddress) { otError error; @@ -1135,7 +1019,7 @@ exit: return error; } -template otError RadioSpinel::ClearSrcMatchShortEntry(uint16_t aShortAddress) +otError RadioSpinel::ClearSrcMatchShortEntry(uint16_t aShortAddress) { otError error; @@ -1157,8 +1041,7 @@ exit: return error; } -template -otError RadioSpinel::ClearSrcMatchExtEntry(const otExtAddress &aExtAddress) +otError RadioSpinel::ClearSrcMatchExtEntry(const otExtAddress &aExtAddress) { otError error; @@ -1181,7 +1064,7 @@ exit: return error; } -template otError RadioSpinel::ClearSrcMatchShortEntries(void) +otError RadioSpinel::ClearSrcMatchShortEntries(void) { otError error; @@ -1195,7 +1078,7 @@ exit: return error; } -template otError RadioSpinel::ClearSrcMatchExtEntries(void) +otError RadioSpinel::ClearSrcMatchExtEntries(void) { otError error; @@ -1209,7 +1092,7 @@ exit: return error; } -template otError RadioSpinel::GetTransmitPower(int8_t &aPower) +otError RadioSpinel::GetTransmitPower(int8_t &aPower) { otError error = Get(SPINEL_PROP_PHY_TX_POWER, SPINEL_DATATYPE_INT8_S, &aPower); @@ -1217,7 +1100,7 @@ template otError RadioSpinel::GetTransmi return error; } -template otError RadioSpinel::GetCcaEnergyDetectThreshold(int8_t &aThreshold) +otError RadioSpinel::GetCcaEnergyDetectThreshold(int8_t &aThreshold) { otError error = Get(SPINEL_PROP_PHY_CCA_THRESHOLD, SPINEL_DATATYPE_INT8_S, &aThreshold); @@ -1225,7 +1108,7 @@ template otError RadioSpinel::GetCcaEner return error; } -template otError RadioSpinel::GetFemLnaGain(int8_t &aGain) +otError RadioSpinel::GetFemLnaGain(int8_t &aGain) { otError error = Get(SPINEL_PROP_PHY_FEM_LNA_GAIN, SPINEL_DATATYPE_INT8_S, &aGain); @@ -1233,7 +1116,7 @@ template otError RadioSpinel::GetFemLnaG return error; } -template int8_t RadioSpinel::GetRssi(void) +int8_t RadioSpinel::GetRssi(void) { int8_t rssi = OT_RADIO_RSSI_INVALID; otError error = Get(SPINEL_PROP_PHY_RSSI, SPINEL_DATATYPE_INT8_S, &rssi); @@ -1243,7 +1126,7 @@ template int8_t RadioSpinel::GetRssi(voi } #if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE -template otError RadioSpinel::SetCoexEnabled(bool aEnabled) +otError RadioSpinel::SetCoexEnabled(bool aEnabled) { otError error; @@ -1258,7 +1141,7 @@ exit: return error; } -template bool RadioSpinel::IsCoexEnabled(void) +bool RadioSpinel::IsCoexEnabled(void) { bool enabled; otError error = Get(SPINEL_PROP_RADIO_COEX_ENABLE, SPINEL_DATATYPE_BOOL_S, &enabled); @@ -1267,7 +1150,7 @@ template bool RadioSpinel::IsCoexEnabled return enabled; } -template otError RadioSpinel::GetCoexMetrics(otRadioCoexMetrics &aCoexMetrics) +otError RadioSpinel::GetCoexMetrics(otRadioCoexMetrics &aCoexMetrics) { otError error; @@ -1307,7 +1190,7 @@ template otError RadioSpinel::GetCoexMet } #endif -template otError RadioSpinel::SetTransmitPower(int8_t aPower) +otError RadioSpinel::SetTransmitPower(int8_t aPower) { otError error; @@ -1323,7 +1206,7 @@ exit: return error; } -template otError RadioSpinel::SetCcaEnergyDetectThreshold(int8_t aThreshold) +otError RadioSpinel::SetCcaEnergyDetectThreshold(int8_t aThreshold) { otError error; @@ -1339,7 +1222,7 @@ exit: return error; } -template otError RadioSpinel::SetFemLnaGain(int8_t aGain) +otError RadioSpinel::SetFemLnaGain(int8_t aGain) { otError error; @@ -1355,8 +1238,7 @@ exit: return error; } -template -otError RadioSpinel::EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration) +otError RadioSpinel::EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration) { otError error; @@ -1378,8 +1260,7 @@ exit: return error; } -template -otError RadioSpinel::Get(spinel_prop_key_t aKey, const char *aFormat, ...) +otError RadioSpinel::Get(spinel_prop_key_t aKey, const char *aFormat, ...) { otError error; @@ -1401,12 +1282,11 @@ otError RadioSpinel::Get(spinel_prop_key_t aKey, const char *aFor } // This is not a normal use case for VALUE_GET command and should be only used to get RCP timestamp with dummy payload -template -otError RadioSpinel::GetWithParam(spinel_prop_key_t aKey, - const uint8_t *aParam, - spinel_size_t aParamSize, - const char *aFormat, - ...) +otError RadioSpinel::GetWithParam(spinel_prop_key_t aKey, + const uint8_t *aParam, + spinel_size_t aParamSize, + const char *aFormat, + ...) { otError error; @@ -1428,8 +1308,7 @@ otError RadioSpinel::GetWithParam(spinel_prop_key_t aKey, return error; } -template -otError RadioSpinel::Set(spinel_prop_key_t aKey, const char *aFormat, ...) +otError RadioSpinel::Set(spinel_prop_key_t aKey, const char *aFormat, ...) { otError error; @@ -1451,8 +1330,7 @@ otError RadioSpinel::Set(spinel_prop_key_t aKey, const char *aFor return error; } -template -otError RadioSpinel::Insert(spinel_prop_key_t aKey, const char *aFormat, ...) +otError RadioSpinel::Insert(spinel_prop_key_t aKey, const char *aFormat, ...) { otError error; @@ -1474,8 +1352,7 @@ otError RadioSpinel::Insert(spinel_prop_key_t aKey, const char *a return error; } -template -otError RadioSpinel::Remove(spinel_prop_key_t aKey, const char *aFormat, ...) +otError RadioSpinel::Remove(spinel_prop_key_t aKey, const char *aFormat, ...) { otError error; @@ -1497,9 +1374,9 @@ otError RadioSpinel::Remove(spinel_prop_key_t aKey, const char *a return error; } -template otError RadioSpinel::WaitResponse(bool aHandleRcpTimeout) +otError RadioSpinel::WaitResponse(bool aHandleRcpTimeout) { - uint64_t end = otPlatTimeGet() + kMaxWaitTime * US_PER_MS; + uint64_t end = otPlatTimeGet() + kMaxWaitTime * kUsPerMs; otLogDebgPlat("Wait response: tid=%u key=%lu", mWaitingTid, ToUlong(mWaitingKey)); @@ -1508,7 +1385,7 @@ template otError RadioSpinel::WaitRespon uint64_t now; now = otPlatTimeGet(); - if ((end <= now) || (mSpinelInterface.WaitForFrame(end - now) != OT_ERROR_NONE)) + if ((end <= now) || (mSpinelInterface->WaitForFrame(end - now) != OT_ERROR_NONE)) { otLogWarnPlat("Wait for response timeout"); if (aHandleRcpTimeout) @@ -1527,7 +1404,7 @@ exit: return mError; } -template spinel_tid_t RadioSpinel::GetNextTid(void) +spinel_tid_t RadioSpinel::GetNextTid(void) { spinel_tid_t tid = mCmdNextTid; @@ -1551,7 +1428,7 @@ exit: return tid; } -template otError RadioSpinel::SendReset(uint8_t aResetType) +otError RadioSpinel::SendReset(uint8_t aResetType) { otError error = OT_ERROR_NONE; uint8_t buffer[kMaxSpinelFrame]; @@ -1563,19 +1440,18 @@ template otError RadioSpinel::SendReset( VerifyOrExit(packed > 0 && static_cast(packed) <= sizeof(buffer), error = OT_ERROR_NO_BUFS); - SuccessOrExit(error = mSpinelInterface.SendFrame(buffer, static_cast(packed))); + SuccessOrExit(error = mSpinelInterface->SendFrame(buffer, static_cast(packed))); LogSpinelFrame(buffer, static_cast(packed), true); exit: return error; } -template -otError RadioSpinel::SendCommand(uint32_t aCommand, - spinel_prop_key_t aKey, - spinel_tid_t tid, - const char *aFormat, - va_list args) +otError RadioSpinel::SendCommand(uint32_t aCommand, + spinel_prop_key_t aKey, + spinel_tid_t tid, + const char *aFormat, + va_list args) { otError error = OT_ERROR_NONE; uint8_t buffer[kMaxSpinelFrame]; @@ -1599,18 +1475,14 @@ otError RadioSpinel::SendCommand(uint32_t aCommand, offset += static_cast(packed); } - SuccessOrExit(error = mSpinelInterface.SendFrame(buffer, offset)); + SuccessOrExit(error = mSpinelInterface->SendFrame(buffer, offset)); LogSpinelFrame(buffer, offset, true); exit: return error; } -template -otError RadioSpinel::RequestV(uint32_t command, - spinel_prop_key_t aKey, - const char *aFormat, - va_list aArgs) +otError RadioSpinel::RequestV(uint32_t command, spinel_prop_key_t aKey, const char *aFormat, va_list aArgs) { otError error = OT_ERROR_NONE; spinel_tid_t tid = GetNextTid(); @@ -1638,8 +1510,7 @@ exit: return error; } -template -otError RadioSpinel::Request(uint32_t aCommand, spinel_prop_key_t aKey, const char *aFormat, ...) +otError RadioSpinel::Request(uint32_t aCommand, spinel_prop_key_t aKey, const char *aFormat, ...) { va_list args; va_start(args, aFormat); @@ -1648,12 +1519,11 @@ otError RadioSpinel::Request(uint32_t aCommand, spinel_prop_key_t return status; } -template -otError RadioSpinel::RequestWithPropertyFormat(const char *aPropertyFormat, - uint32_t aCommand, - spinel_prop_key_t aKey, - const char *aFormat, - ...) +otError RadioSpinel::RequestWithPropertyFormat(const char *aPropertyFormat, + uint32_t aCommand, + spinel_prop_key_t aKey, + const char *aFormat, + ...) { otError error; va_list args; @@ -1665,12 +1535,11 @@ otError RadioSpinel::RequestWithPropertyFormat(const char * return error; } -template -otError RadioSpinel::RequestWithPropertyFormatV(const char *aPropertyFormat, - uint32_t aCommand, - spinel_prop_key_t aKey, - const char *aFormat, - va_list aArgs) +otError RadioSpinel::RequestWithPropertyFormatV(const char *aPropertyFormat, + uint32_t aCommand, + spinel_prop_key_t aKey, + const char *aFormat, + va_list aArgs) { otError error; @@ -1681,12 +1550,11 @@ otError RadioSpinel::RequestWithPropertyFormatV(const char return error; } -template -otError RadioSpinel::RequestWithExpectedCommandV(uint32_t aExpectedCommand, - uint32_t aCommand, - spinel_prop_key_t aKey, - const char *aFormat, - va_list aArgs) +otError RadioSpinel::RequestWithExpectedCommandV(uint32_t aExpectedCommand, + uint32_t aCommand, + spinel_prop_key_t aKey, + const char *aFormat, + va_list aArgs) { otError error; @@ -1697,11 +1565,10 @@ otError RadioSpinel::RequestWithExpectedCommandV(uint32_t return error; } -template -void RadioSpinel::HandleTransmitDone(uint32_t aCommand, - spinel_prop_key_t aKey, - const uint8_t *aBuffer, - uint16_t aLength) +void RadioSpinel::HandleTransmitDone(uint32_t aCommand, + spinel_prop_key_t aKey, + const uint8_t *aBuffer, + uint16_t aLength) { otError error = OT_ERROR_NONE; spinel_status_t status = SPINEL_STATUS_OK; @@ -1768,7 +1635,7 @@ exit: LogIfFail("Handle transmit done failed", error); } -template otError RadioSpinel::Transmit(otRadioFrame &aFrame) +otError RadioSpinel::Transmit(otRadioFrame &aFrame) { otError error = OT_ERROR_INVALID_STATE; @@ -1802,7 +1669,7 @@ template otError RadioSpinel::Transmit(o { // Waiting for `TransmitDone` event. mState = kStateTransmitting; - mTxRadioEndUs = otPlatTimeGet() + TX_WAIT_US; + mTxRadioEndUs = otPlatTimeGet() + kTxWaitUs; mChannel = mTransmitFrame->mChannel; } @@ -1810,7 +1677,7 @@ exit: return error; } -template otError RadioSpinel::Receive(uint8_t aChannel) +otError RadioSpinel::Receive(uint8_t aChannel) { otError error = OT_ERROR_NONE; @@ -1841,7 +1708,7 @@ exit: return error; } -template otError RadioSpinel::Sleep(void) +otError RadioSpinel::Sleep(void) { otError error = OT_ERROR_NONE; @@ -1866,7 +1733,7 @@ exit: return error; } -template otError RadioSpinel::Enable(otInstance *aInstance) +otError RadioSpinel::Enable(otInstance *aInstance) { otError error = OT_ERROR_NONE; @@ -1891,7 +1758,7 @@ exit: return error; } -template otError RadioSpinel::Disable(void) +otError RadioSpinel::Disable(void) { otError error = OT_ERROR_NONE; @@ -1907,8 +1774,7 @@ exit: } #if OPENTHREAD_CONFIG_DIAG_ENABLE -template -otError RadioSpinel::PlatDiagProcess(const char *aString, char *aOutput, size_t aOutputMaxLen) +otError RadioSpinel::PlatDiagProcess(const char *aString, char *aOutput, size_t aOutputMaxLen) { otError error; @@ -1924,7 +1790,7 @@ otError RadioSpinel::PlatDiagProcess(const char *aString, char *a } #endif -template uint32_t RadioSpinel::GetRadioChannelMask(bool aPreferred) +uint32_t RadioSpinel::GetRadioChannelMask(bool aPreferred) { uint8_t maskBuffer[kChannelMaskBufferSize]; otError error = OT_ERROR_NONE; @@ -1957,7 +1823,7 @@ exit: return channelMask; } -template otRadioState RadioSpinel::GetState(void) const +otRadioState RadioSpinel::GetState(void) const { static const otRadioState sOtRadioStateMap[] = { OT_RADIO_STATE_DISABLED, OT_RADIO_STATE_SLEEP, OT_RADIO_STATE_RECEIVE, @@ -1967,7 +1833,7 @@ template otRadioState RadioSpinel::GetSt return sOtRadioStateMap[mState]; } -template void RadioSpinel::CalcRcpTimeOffset(void) +void RadioSpinel::CalcRcpTimeOffset(void) { #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 otError error = OT_ERROR_NONE; @@ -2021,24 +1887,18 @@ template void RadioSpinel::CalcRcpTimeOf mRadioTimeOffset = (remoteTimestamp - ((localRxTimestamp / 2) + (localTxTimestamp / 2))); mIsTimeSynced = true; - mRadioTimeRecalcStart = localRxTimestamp + OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL; + mRadioTimeRecalcStart = localRxTimestamp + OPENTHREAD_SPINEL_CONFIG_RCP_TIME_SYNC_INTERVAL; exit: LogIfFail("Error calculating RCP time offset: %s", error); #endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 } -template uint64_t RadioSpinel::GetNow(void) -{ - return (mIsTimeSynced) ? (otPlatTimeGet() + mRadioTimeOffset) : UINT64_MAX; -} +uint64_t RadioSpinel::GetNow(void) { return (mIsTimeSynced) ? (otPlatTimeGet() + mRadioTimeOffset) : UINT64_MAX; } -template uint32_t RadioSpinel::GetBusSpeed(void) const -{ - return mSpinelInterface.GetBusSpeed(); -} +uint32_t RadioSpinel::GetBusSpeed(void) const { return mSpinelInterface->GetBusSpeed(); } -template void RadioSpinel::HandleRcpUnexpectedReset(spinel_status_t aStatus) +void RadioSpinel::HandleRcpUnexpectedReset(spinel_status_t aStatus) { OT_UNUSED_VARIABLE(aStatus); @@ -2054,7 +1914,7 @@ template void RadioSpinel::HandleRcpUnex #endif } -template void RadioSpinel::HandleRcpTimeout(void) +void RadioSpinel::HandleRcpTimeout(void) { mRadioSpinelMetrics.mRcpTimeoutCount++; @@ -2073,7 +1933,7 @@ template void RadioSpinel::HandleRcpTime #endif } -template void RadioSpinel::RecoverFromRcpFailure(void) +void RadioSpinel::RecoverFromRcpFailure(void) { #if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0 constexpr int16_t kMaxFailureCount = OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT; @@ -2145,7 +2005,7 @@ exit: } #if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0 -template void RadioSpinel::RestoreProperties(void) +void RadioSpinel::RestoreProperties(void) { SuccessOrDie(Set(SPINEL_PROP_MAC_15_4_PANID, SPINEL_DATATYPE_UINT16_S, mPanId)); SuccessOrDie(Set(SPINEL_PROP_MAC_15_4_SADDR, SPINEL_DATATYPE_UINT16_S, mShortAddress)); @@ -2233,8 +2093,7 @@ template void RadioSpinel::RestoreProper } #endif // OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0 -template -otError RadioSpinel::SetChannelMaxTransmitPower(uint8_t aChannel, int8_t aMaxPower) +otError RadioSpinel::SetChannelMaxTransmitPower(uint8_t aChannel, int8_t aMaxPower) { otError error = OT_ERROR_NONE; VerifyOrExit(aChannel >= Radio::kChannelMin && aChannel <= Radio::kChannelMax, error = OT_ERROR_INVALID_ARGS); @@ -2245,7 +2104,7 @@ exit: return error; } -template otError RadioSpinel::SetRadioRegion(uint16_t aRegionCode) +otError RadioSpinel::SetRadioRegion(uint16_t aRegionCode) { otError error; @@ -2265,7 +2124,7 @@ template otError RadioSpinel::SetRadioRe return error; } -template otError RadioSpinel::GetRadioRegion(uint16_t *aRegionCode) +otError RadioSpinel::GetRadioRegion(uint16_t *aRegionCode) { otError error = OT_ERROR_NONE; @@ -2277,10 +2136,9 @@ exit: } #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE -template -otError RadioSpinel::ConfigureEnhAckProbing(otLinkMetrics aLinkMetrics, - const otShortAddress aShortAddress, - const otExtAddress &aExtAddress) +otError RadioSpinel::ConfigureEnhAckProbing(otLinkMetrics aLinkMetrics, + const otShortAddress &aShortAddress, + const otExtAddress &aExtAddress) { otError error = OT_ERROR_NONE; uint8_t flags = 0; @@ -2314,7 +2172,7 @@ otError RadioSpinel::ConfigureEnhAckProbing(otLinkMetrics #endif #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE -template uint8_t RadioSpinel::GetCslAccuracy(void) +uint8_t RadioSpinel::GetCslAccuracy(void) { uint8_t accuracy = UINT8_MAX; otError error = Get(SPINEL_PROP_RCP_CSL_ACCURACY, SPINEL_DATATYPE_UINT8_S, &accuracy); @@ -2325,7 +2183,7 @@ template uint8_t RadioSpinel::GetCslAccu #endif #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE -template uint8_t RadioSpinel::GetCslUncertainty(void) +uint8_t RadioSpinel::GetCslUncertainty(void) { uint8_t uncertainty = UINT8_MAX; otError error = Get(SPINEL_PROP_RCP_CSL_UNCERTAINTY, SPINEL_DATATYPE_UINT8_S, &uncertainty); @@ -2336,11 +2194,10 @@ template uint8_t RadioSpinel::GetCslUnce #endif #if OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE -template -otError RadioSpinel::AddCalibratedPower(uint8_t aChannel, - int16_t aActualPower, - const uint8_t *aRawPowerSetting, - uint16_t aRawPowerSettingLength) +otError RadioSpinel::AddCalibratedPower(uint8_t aChannel, + int16_t aActualPower, + const uint8_t *aRawPowerSetting, + uint16_t aRawPowerSettingLength) { otError error; @@ -2353,13 +2210,9 @@ exit: return error; } -template otError RadioSpinel::ClearCalibratedPowers(void) -{ - return Set(SPINEL_PROP_PHY_CALIBRATED_POWER, nullptr); -} +otError RadioSpinel::ClearCalibratedPowers(void) { return Set(SPINEL_PROP_PHY_CALIBRATED_POWER, nullptr); } -template -otError RadioSpinel::SetChannelTargetPower(uint8_t aChannel, int16_t aTargetPower) +otError RadioSpinel::SetChannelTargetPower(uint8_t aChannel, int16_t aTargetPower) { otError error = OT_ERROR_NONE; VerifyOrExit(aChannel >= Radio::kChannelMin && aChannel <= Radio::kChannelMax, error = OT_ERROR_INVALID_ARGS); @@ -2371,8 +2224,7 @@ exit: } #endif // OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE -template -uint32_t RadioSpinel::Snprintf(char *aDest, uint32_t aSize, const char *aFormat, ...) +uint32_t RadioSpinel::Snprintf(char *aDest, uint32_t aSize, const char *aFormat, ...) { int len; va_list args; @@ -2384,8 +2236,7 @@ uint32_t RadioSpinel::Snprintf(char *aDest, uint32_t aSize, const return (len < 0) ? 0 : Min(static_cast(len), aSize - 1); } -template -void RadioSpinel::LogSpinelFrame(const uint8_t *aFrame, uint16_t aLength, bool aTx) +void RadioSpinel::LogSpinelFrame(const uint8_t *aFrame, uint16_t aLength, bool aTx) { otError error = OT_ERROR_NONE; char buf[OPENTHREAD_CONFIG_LOG_MAX_SIZE] = {0}; @@ -2719,6 +2570,7 @@ void RadioSpinel::LogSpinelFrame(const uint8_t *aFrame, uint16_t VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE); start += Snprintf(start, static_cast(end - start), ", len:%u, rssi:%d ...", frame.mLength, frame.mInfo.mRxInfo.mRssi); + OT_UNUSED_VARIABLE(start); // Avoid static analysis error otLogDebgPlat("%s", buf); start = buf; @@ -2754,6 +2606,7 @@ void RadioSpinel::LogSpinelFrame(const uint8_t *aFrame, uint16_t start += Snprintf(start, static_cast(end - start), ", len:%u, channel:%u, maxbackoffs:%u, maxretries:%u ...", frame.mLength, frame.mChannel, frame.mInfo.mTxInfo.mMaxCsmaBackoffs, frame.mInfo.mTxInfo.mMaxFrameRetries); + OT_UNUSED_VARIABLE(start); // Avoid static analysis error otLogDebgPlat("%s", buf); start = buf; @@ -2939,7 +2792,7 @@ void RadioSpinel::LogSpinelFrame(const uint8_t *aFrame, uint16_t VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE); start += Snprintf(start, static_cast(end - start), ", channels:"); - for (uint8_t i = 0; i < size; i++) + for (spinel_size_t i = 0; i < size; i++) { start += Snprintf(start, static_cast(end - start), "%u ", channels[i]); } @@ -2978,7 +2831,7 @@ void RadioSpinel::LogSpinelFrame(const uint8_t *aFrame, uint16_t start += Snprintf(start, static_cast(end - start), ", ch:%u, actualPower:%d, rawPowerSetting:", channel, actualPower); - for (uint16_t i = 0; i < rawPowerSettingLength; i++) + for (unsigned int i = 0; i < rawPowerSettingLength; i++) { start += Snprintf(start, static_cast(end - start), "%02x", rawPowerSetting[i]); } @@ -3000,16 +2853,102 @@ void RadioSpinel::LogSpinelFrame(const uint8_t *aFrame, uint16_t } exit: + OT_UNUSED_VARIABLE(start); // Avoid static analysis error if (error == OT_ERROR_NONE) { otLogDebgPlat("%s", buf); } - else + else if (prefix != nullptr) { otLogDebgPlat("%s, failed to parse spinel frame !", prefix); } +} - return; +otError RadioSpinel::SpinelStatusToOtError(spinel_status_t aStatus) +{ + otError ret; + + switch (aStatus) + { + case SPINEL_STATUS_OK: + ret = OT_ERROR_NONE; + break; + + case SPINEL_STATUS_FAILURE: + ret = OT_ERROR_FAILED; + break; + + case SPINEL_STATUS_DROPPED: + ret = OT_ERROR_DROP; + break; + + case SPINEL_STATUS_NOMEM: + ret = OT_ERROR_NO_BUFS; + break; + + case SPINEL_STATUS_BUSY: + ret = OT_ERROR_BUSY; + break; + + case SPINEL_STATUS_PARSE_ERROR: + ret = OT_ERROR_PARSE; + break; + + case SPINEL_STATUS_INVALID_ARGUMENT: + ret = OT_ERROR_INVALID_ARGS; + break; + + case SPINEL_STATUS_UNIMPLEMENTED: + ret = OT_ERROR_NOT_IMPLEMENTED; + break; + + case SPINEL_STATUS_INVALID_STATE: + ret = OT_ERROR_INVALID_STATE; + break; + + case SPINEL_STATUS_NO_ACK: + ret = OT_ERROR_NO_ACK; + break; + + case SPINEL_STATUS_CCA_FAILURE: + ret = OT_ERROR_CHANNEL_ACCESS_FAILURE; + break; + + case SPINEL_STATUS_ALREADY: + ret = OT_ERROR_ALREADY; + break; + + case SPINEL_STATUS_PROP_NOT_FOUND: + ret = OT_ERROR_NOT_IMPLEMENTED; + break; + + case SPINEL_STATUS_ITEM_NOT_FOUND: + ret = OT_ERROR_NOT_FOUND; + break; + + default: + if (aStatus >= SPINEL_STATUS_STACK_NATIVE__BEGIN && aStatus <= SPINEL_STATUS_STACK_NATIVE__END) + { + ret = static_cast(aStatus - SPINEL_STATUS_STACK_NATIVE__BEGIN); + } + else + { + ret = OT_ERROR_FAILED; + } + break; + } + + return ret; +} + +void RadioSpinel::LogIfFail(const char *aText, otError aError) +{ + OT_UNUSED_VARIABLE(aText); + + if (aError != OT_ERROR_NONE && aError != OT_ERROR_NO_ACK) + { + otLogWarnPlat("%s: %s", aText, otThreadErrorToString(aError)); + } } } // namespace Spinel diff --git a/src/lib/spinel/radio_spinel.hpp b/src/lib/spinel/radio_spinel.hpp index 5dbb80cd4..dac40d5c0 100644 --- a/src/lib/spinel/radio_spinel.hpp +++ b/src/lib/spinel/radio_spinel.hpp @@ -37,10 +37,10 @@ #include #include "openthread-spinel-config.h" -#include "radio_spinel_metrics.h" -#include "spinel.h" -#include "spinel_interface.hpp" #include "core/radio/max_power_table.hpp" +#include "lib/spinel/radio_spinel_metrics.h" +#include "lib/spinel/spinel.h" +#include "lib/spinel/spinel_interface.hpp" #include "ncp/ncp_config.h" namespace ot { @@ -48,60 +48,10 @@ namespace Spinel { /** * The class for providing a OpenThread radio interface by talking with a radio-only - * co-processor(RCP). The InterfaceType template parameter should provide the following - * methods: + * co-processor(RCP). * - * class InterfaceType { - * - * // This constructor initializes the object. - * - * // @param[in] aCallback Callback on frame received - * // @param[in] aCallbackContext Callback context - * // @param[in] aFrameBuffer A reference to a `RxFrameBuffer` object. - * - * InterfaceType(Spinel::SpinelInterface::ReceiveFrameCallback aCallback, - * void * aCallbackContext, - * Spinel::SpinelInterface::RxFrameBuffer & aFrameBuffer); - * - * - * // This method encodes and sends a spinel frame to Radio Co-processor (RCP) over the socket. - * - * // This is blocking call, i.e., if the socket is not writable, this method waits for it to become writable for - * // up to `kMaxWaitTime` interval. - * - * // @param[in] aFrame A pointer to buffer containing the spinel frame to send. - * // @param[in] aLength The length (number of bytes) in the frame. - * - * // @retval OT_ERROR_NONE Successfully encoded and sent the spinel frame. - * // @retval OT_ERROR_NO_BUFS Insufficient buffer space available to encode the frame. - * // @retval OT_ERROR_FAILED Failed to send due to socket not becoming writable within `kMaxWaitTime`. - * - * otError SendFrame(const uint8_t *aFrame, uint16_t aLength); - * - * - * // This method waits for receiving part or all of spinel frame within specified interval. - * - * // @param[in] aTimeout The timeout value in microseconds. - * - * // @retval OT_ERROR_NONE Part or all of spinel frame is received. - * // @retval OT_ERROR_RESPONSE_TIMEOUT No spinel frame is received within @p aTimeout. - * - * otError WaitForFrame(uint64_t& aTimeoutUs); - * - * - * // This method performs radio driver processing. - * - * // @param[in] aContext The process context. - * - * void Process(const void *aContext); - * - * - * // This method deinitializes the interface to the RCP. - * - * void Deinit(void); - * }; */ -template class RadioSpinel +class RadioSpinel { public: /** @@ -110,14 +60,21 @@ public: */ RadioSpinel(void); + /** + * Deinitializes the spinel based OpenThread transceiver. + * + */ + ~RadioSpinel(void) { Deinit(); } + /** * Initialize this radio transceiver. * + * @param[in] aSpinelInterface A reference to the Spinel interface. * @param[in] aResetRadio TRUE to reset on init, FALSE to not reset on init. * @param[in] aSkipRcpCompatibilityCheck TRUE to skip RCP compatibility check, FALSE to perform the check. * */ - void Init(bool aResetRadio, bool aSkipRcpCompatibilityCheck); + void Init(SpinelInterface &aSpinelInterface, bool aResetRadio, bool aSkipRcpCompatibilityCheck); /** * Deinitialize this radio transceiver. @@ -181,7 +138,7 @@ public: * @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver. * */ - otError SetExtendedAddress(const otExtAddress &aAddress); + otError SetExtendedAddress(const otExtAddress &aExtAddress); /** * Sets the PAN ID for address filtering. @@ -560,14 +517,6 @@ public: */ void Process(const void *aContext); - /** - * Returns the underlying spinel interface. - * - * @returns The underlying spinel interface. - * - */ - InterfaceType &GetSpinelInterface(void) { return mSpinelInterface; } - #if OPENTHREAD_CONFIG_DIAG_ENABLE /** * Enables/disables the factory diagnostics mode. @@ -695,9 +644,9 @@ public: * @retval OT_ERROR_NOT_FOUND The Initiator indicated by @p aShortAddress is not found when trying to clear. * @retval OT_ERROR_NO_BUFS No more Initiator can be supported. */ - otError ConfigureEnhAckProbing(otLinkMetrics aLinkMetrics, - const otShortAddress aShortAddress, - const otExtAddress &aExtAddress); + otError ConfigureEnhAckProbing(otLinkMetrics aLinkMetrics, + const otShortAddress &aShortAddress, + const otExtAddress &aExtAddress); #endif #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE @@ -772,13 +721,13 @@ public: * Sets the max transmit power. * * @param[in] aChannel The radio channel. - * @param[in] aPower The max transmit power in dBm. + * @param[in] aMaxPower The max transmit power in dBm. * * @retval OT_ERROR_NONE Successfully set the max transmit power. * @retval OT_ERROR_INVALID_ARGS Channel is not in valid range. * */ - otError SetChannelMaxTransmitPower(uint8_t aChannel, int8_t aPower); + otError SetChannelMaxTransmitPower(uint8_t aChannel, int8_t aMaxPower); /** * Tries to retrieve a spinel property from OpenThread transceiver. @@ -924,6 +873,28 @@ public: otError SetChannelTargetPower(uint8_t aChannel, int16_t aTargetPower); #endif + /** + * Convert the Spinel status code to OpenThread error code. + * + * @param[in] aStatus The Spinel status code. + * + * @retval OT_ERROR_NONE The operation has completed successfully. + * @retval OT_ERROR_DROP The packet was dropped. + * @retval OT_ERROR_NO_BUFS The operation has been prevented due to memory pressure. + * @retval OT_ERROR_BUSY The device is currently performing a mutuallyexclusive operation. + * @retval OT_ERROR_PARSE An error has occurred while parsing the command. + * @retval OT_ERROR_INVALID_ARGS An argument to the given operation is invalid. + * @retval OT_ERROR_NOT_IMPLEMENTED The given operation has not been implemented. + * @retval OT_ERROR_INVALID_STATE The given operation is invalid for the current state of the device. + * @retval OT_ERROR_NO_ACK The packet was not acknowledged. + * @retval OT_ERROR_NOT_FOUND The given property is not recognized. + * @retval OT_ERROR_FAILED The given operation has failed for some undefined reason. + * @retval OT_ERROR_CHANNEL_ACCESS_FAILURE The packet was not sent due to a CCA failure. + * @retval OT_ERROR_ALREADY The operation is already in progress or the property was already set + * to the given value. + */ + static otError SpinelStatusToOtError(spinel_status_t aStatus); + private: enum { @@ -943,6 +914,12 @@ private: kStateTransmitDone, ///< Radio indicated frame transmission is done. }; + enum + { + kUsPerMs = 1000, ///< Microseconds per millisecond. + kTxWaitUs = 5000000, ///< Maximum time of waiting for `TransmitDone` event, in microseconds. + }; + typedef otError (RadioSpinel::*ResponseHandler)(const uint8_t *aBuffer, uint16_t aLength); static void HandleReceivedFrame(void *aContext); @@ -950,7 +927,7 @@ private: void ResetRcp(bool aResetRadio); otError CheckSpinelVersion(void); otError CheckRadioCapabilities(void); - otError CheckRcpApiVersion(bool aSupportsRcpApiVersion, bool aSupportsMinHostRcpApiVersion); + otError CheckRcpApiVersion(bool aSupportsRcpApiVersion, bool aSupportsRcpMinHostApiVersion); /** * Triggers a state transfer of the state machine. @@ -1009,7 +986,7 @@ private: } void HandleNotification(SpinelInterface::RxFrameBuffer &aFrameBuffer); - void HandleNotification(const uint8_t *aBuffer, uint16_t aLength); + void HandleNotification(const uint8_t *aFrame, uint16_t aLength); void HandleValueIs(spinel_prop_key_t aKey, const uint8_t *aBuffer, uint16_t aLength); void HandleResponse(const uint8_t *aBuffer, uint16_t aLength); @@ -1037,11 +1014,12 @@ private: uint32_t Snprintf(char *aDest, uint32_t aSize, const char *aFormat, ...); void LogSpinelFrame(const uint8_t *aFrame, uint16_t aLength, bool aTx); + void LogIfFail(const char *aText, otError aError); + otInstance *mInstance; SpinelInterface::RxFrameBuffer mRxFrameBuffer; - - InterfaceType mSpinelInterface; + SpinelInterface *mSpinelInterface; uint16_t mCmdTidsInUse; ///< Used transaction ids. spinel_tid_t mCmdNextTid; ///< Next available transaction id. @@ -1129,6 +1107,4 @@ private: } // namespace Spinel } // namespace ot -#include "radio_spinel_impl.hpp" - #endif // RADIO_SPINEL_HPP_ diff --git a/src/lib/spinel/radio_spinel_metrics.h b/src/lib/spinel/radio_spinel_metrics.h index e2500879e..452520566 100644 --- a/src/lib/spinel/radio_spinel_metrics.h +++ b/src/lib/spinel/radio_spinel_metrics.h @@ -51,6 +51,22 @@ typedef struct otRadioSpinelMetrics uint32_t mSpinelParseErrorCount; ///< The number of spinel frame parse errors. } otRadioSpinelMetrics; +/** + * Represents RCP interface metrics. + * + */ +typedef struct otRcpInterfaceMetrics +{ + uint8_t mRcpInterfaceType; ///< The RCP interface type. + uint64_t mTransferredFrameCount; ///< The number of transferred frames. + uint64_t mTransferredValidFrameCount; ///< The number of transferred valid frames. + uint64_t mTransferredGarbageFrameCount; ///< The number of transferred garbage frames. + uint64_t mRxFrameCount; ///< The number of received frames. + uint64_t mRxFrameByteCount; ///< The number of received bytes. + uint64_t mTxFrameCount; ///< The number of transmitted frames. + uint64_t mTxFrameByteCount; ///< The number of transmitted bytes. +} otRcpInterfaceMetrics; + #ifdef __cplusplus } // end of extern "C" #endif diff --git a/src/lib/spinel/spinel_interface.hpp b/src/lib/spinel/spinel_interface.hpp index 344de7e43..432b8b7ee 100644 --- a/src/lib/spinel/spinel_interface.hpp +++ b/src/lib/spinel/spinel_interface.hpp @@ -36,8 +36,8 @@ #define SPINEL_SPINEL_INTERFACE_HPP_ #include "lib/spinel/multi_frame_buffer.hpp" +#include "lib/spinel/radio_spinel_metrics.h" #include "lib/spinel/spinel.h" -#include "lib/url/url.hpp" namespace ot { namespace Spinel { @@ -66,14 +66,16 @@ public: * * @note This method should be called before reading and sending spinel frames to the interface. * - * @param[in] aRadioUrl RadioUrl parsed from radio url. + * @param[in] aCallback Callback on frame received + * @param[in] aCallbackContext Callback context + * @param[in] aFrameBuffer A reference to a `RxFrameBuffer` object. * - * @retval OT_ERROR_NONE The interface is initialized successfully - * @retval OT_ERROR_ALREADY The interface is already initialized. - * @retval OT_ERROR_INVALID_ARGS The UART device or executable cannot be found or failed to open/run. + * @retval OT_ERROR_NONE The interface is initialized successfully + * @retval OT_ERROR_ALREADY The interface is already initialized. + * @retval OT_ERROR_FAILED Failed to initialize the interface. * */ - virtual otError Init(const Url::Url &aRadioUrl) = 0; + virtual otError Init(ReceiveFrameCallback aCallback, void *aCallbackContext, RxFrameBuffer &aFrameBuffer) = 0; /** * Deinitializes the interface to the RCP. @@ -139,6 +141,14 @@ public: */ virtual otError HardwareReset(void) = 0; + /** + * Returns the RCP interface metrics. + * + * @returns The RCP interface metrics. + * + */ + virtual const otRcpInterfaceMetrics *GetRcpInterfaceMetrics(void) const = 0; + /** * Marks destructor virtual method. * @@ -146,6 +156,13 @@ public: virtual ~SpinelInterface() = default; protected: + enum : uint8_t + { + kSpinelInterfaceTypeHdlc = 1, ///< The type of Spinel HDLC interface. + kSpinelInterfaceTypeSpi = 2, ///< The type of Spinel SPI interface. + kSpinelInterfaceTypeVendor = 3, ///< The type of Spinel Vendor interface. + }; + /** * Indicates whether or not the frame is the Spinel SPINEL_CMD_RESET frame. * diff --git a/src/lib/url/url.cpp b/src/lib/url/url.cpp index 0d1250ba0..040f6cdba 100644 --- a/src/lib/url/url.cpp +++ b/src/lib/url/url.cpp @@ -37,6 +37,14 @@ namespace ot { namespace Url { +Url::Url(void) +{ + mProtocol = nullptr; + mPath = nullptr; + mQuery = nullptr; + mEnd = nullptr; +} + otError Url::Init(char *aUrl) { otError error = OT_ERROR_NONE; diff --git a/src/lib/url/url.hpp b/src/lib/url/url.hpp index ee6ec1883..a74d18a47 100644 --- a/src/lib/url/url.hpp +++ b/src/lib/url/url.hpp @@ -56,6 +56,8 @@ namespace Url { class Url : public otUrl { public: + Url(void); + /** * Initializes the URL. * diff --git a/src/ncp/ncp_hdlc.cpp b/src/ncp/ncp_hdlc.cpp index 2020d157d..a18c345cb 100644 --- a/src/ncp/ncp_hdlc.cpp +++ b/src/ncp/ncp_hdlc.cpp @@ -83,7 +83,6 @@ NcpHdlc::NcpHdlc(Instance *aInstance, otNcpHdlcSendCallback aSendCallback) : NcpBase(aInstance) , mSendCallback(aSendCallback) , mFrameEncoder(mHdlcBuffer) - , mFrameDecoder(mRxBuffer, &NcpHdlc::HandleFrame, this) , mState(kStartingFrame) , mByte(0) , mHdlcSendImmediate(false) @@ -92,6 +91,7 @@ NcpHdlc::NcpHdlc(Instance *aInstance, otNcpHdlcSendCallback aSendCallback) , mTxFrameBufferEncrypterReader(mTxFrameBuffer) #endif // OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER { + mFrameDecoder.Init(mRxBuffer, &NcpHdlc::HandleFrame, this); mTxFrameBuffer.SetFrameAddedCallback(HandleFrameAddedToNcpBuffer, this); } diff --git a/src/posix/platform/CMakeLists.txt b/src/posix/platform/CMakeLists.txt index 88e8f7e73..b367d8758 100644 --- a/src/posix/platform/CMakeLists.txt +++ b/src/posix/platform/CMakeLists.txt @@ -77,10 +77,24 @@ if (OT_POSIX_SECURE_SETTINGS) ) endif() -set(OT_POSIX_CONFIG_RCP_BUS "" CACHE STRING "RCP bus type") -if(OT_POSIX_CONFIG_RCP_BUS) +option(OT_POSIX_RCP_HDLC_BUS "enable RCP HDLC bus" OFF) +if(OT_POSIX_RCP_HDLC_BUS) target_compile_definitions(ot-posix-config - INTERFACE "OPENTHREAD_POSIX_CONFIG_RCP_BUS=OT_POSIX_RCP_BUS_${OT_POSIX_CONFIG_RCP_BUS}" + INTERFACE "OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE=1" + ) +endif() + +option(OT_POSIX_RCP_SPI_BUS "enable RCP SPI bus" OFF) +if(OT_POSIX_RCP_SPI_BUS) + target_compile_definitions(ot-posix-config + INTERFACE "OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE=1" + ) +endif() + +option(OT_POSIX_RCP_VENDOR_BUS "enable RCP vendor bus" OFF) +if(OT_POSIX_RCP_VENDOR_BUS) + target_compile_definitions(ot-posix-config + INTERFACE "OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE=1" ) endif() diff --git a/src/posix/platform/hdlc_interface.cpp b/src/posix/platform/hdlc_interface.cpp index edc58c494..d2c45e433 100644 --- a/src/posix/platform/hdlc_interface.cpp +++ b/src/posix/platform/hdlc_interface.cpp @@ -123,52 +123,55 @@ #endif // __APPLE__ -#if OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_UART +#if OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE namespace ot { namespace Posix { -HdlcInterface::HdlcInterface(ReceiveFrameCallback aCallback, void *aCallbackContext, RxFrameBuffer &aFrameBuffer) - : mReceiveFrameCallback(aCallback) - , mReceiveFrameContext(aCallbackContext) - , mReceiveFrameBuffer(aFrameBuffer) +HdlcInterface::HdlcInterface(const Url::Url &aRadioUrl) + : mReceiveFrameCallback(nullptr) + , mReceiveFrameContext(nullptr) + , mReceiveFrameBuffer(nullptr) , mSockFd(-1) , mBaudRate(0) - , mHdlcDecoder(aFrameBuffer, HandleHdlcFrame, this) - , mRadioUrl(nullptr) + , mHdlcDecoder() + , mRadioUrl(aRadioUrl) { memset(&mInterfaceMetrics, 0, sizeof(mInterfaceMetrics)); - mInterfaceMetrics.mRcpInterfaceType = OT_POSIX_RCP_BUS_UART; + mInterfaceMetrics.mRcpInterfaceType = kSpinelInterfaceTypeHdlc; } -otError HdlcInterface::Init(const Url::Url &aRadioUrl) +otError HdlcInterface::Init(ReceiveFrameCallback aCallback, void *aCallbackContext, RxFrameBuffer &aFrameBuffer) { otError error = OT_ERROR_NONE; struct stat st; VerifyOrExit(mSockFd == -1, error = OT_ERROR_ALREADY); - VerifyOrDie(stat(aRadioUrl.GetPath(), &st) == 0, OT_EXIT_INVALID_ARGUMENTS); + VerifyOrDie(stat(mRadioUrl.GetPath(), &st) == 0, OT_EXIT_ERROR_ERRNO); if (S_ISCHR(st.st_mode)) { - mSockFd = OpenFile(aRadioUrl); - VerifyOrExit(mSockFd != -1, error = OT_ERROR_INVALID_ARGS); + mSockFd = OpenFile(mRadioUrl); + VerifyOrExit(mSockFd != -1, error = OT_ERROR_FAILED); } #if OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE else if (S_ISREG(st.st_mode)) { - mSockFd = ForkPty(aRadioUrl); - VerifyOrExit(mSockFd != -1, error = OT_ERROR_INVALID_ARGS); + mSockFd = ForkPty(mRadioUrl); + VerifyOrExit(mSockFd != -1, error = OT_ERROR_FAILED); } #endif // OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE else { - otLogCritPlat("Radio file '%s' not supported", aRadioUrl.GetPath()); - ExitNow(error = OT_ERROR_INVALID_ARGS); + otLogCritPlat("Radio file '%s' not supported", mRadioUrl.GetPath()); + ExitNow(error = OT_ERROR_FAILED); } - mRadioUrl = &aRadioUrl; + mHdlcDecoder.Init(aFrameBuffer, HandleHdlcFrame, this); + mReceiveFrameCallback = aCallback; + mReceiveFrameContext = aCallbackContext; + mReceiveFrameBuffer = &aFrameBuffer; exit: return error; @@ -176,7 +179,14 @@ exit: HdlcInterface::~HdlcInterface(void) { Deinit(); } -void HdlcInterface::Deinit(void) { CloseFile(); } +void HdlcInterface::Deinit(void) +{ + CloseFile(); + + mReceiveFrameCallback = nullptr; + mReceiveFrameContext = nullptr; + mReceiveFrameBuffer = nullptr; +} void HdlcInterface::Read(void) { @@ -689,21 +699,26 @@ void HdlcInterface::HandleHdlcFrame(void *aContext, otError aError) void HdlcInterface::HandleHdlcFrame(otError aError) { + VerifyOrExit((mReceiveFrameCallback != nullptr) && (mReceiveFrameBuffer != nullptr)); + mInterfaceMetrics.mTransferredFrameCount++; if (aError == OT_ERROR_NONE) { mInterfaceMetrics.mRxFrameCount++; - mInterfaceMetrics.mRxFrameByteCount += mReceiveFrameBuffer.GetLength(); + mInterfaceMetrics.mRxFrameByteCount += mReceiveFrameBuffer->GetLength(); mInterfaceMetrics.mTransferredValidFrameCount++; mReceiveFrameCallback(mReceiveFrameContext); } else { mInterfaceMetrics.mTransferredGarbageFrameCount++; - mReceiveFrameBuffer.DiscardFrame(); + mReceiveFrameBuffer->DiscardFrame(); otLogWarnPlat("Error decoding hdlc frame: %s", otThreadErrorToString(aError)); } + +exit: + return; } otError HdlcInterface::ResetConnection(void) @@ -711,7 +726,7 @@ otError HdlcInterface::ResetConnection(void) otError error = OT_ERROR_NONE; uint64_t end; - if (mRadioUrl->HasParam("uart-reset")) + if (mRadioUrl.HasParam("uart-reset")) { usleep(static_cast(kRemoveRcpDelay) * US_PER_MS); CloseFile(); @@ -719,7 +734,7 @@ otError HdlcInterface::ResetConnection(void) end = otPlatTimeGet() + kResetTimeout * US_PER_MS; do { - mSockFd = OpenFile(*mRadioUrl); + mSockFd = OpenFile(mRadioUrl); if (mSockFd != -1) { ExitNow(); @@ -737,4 +752,4 @@ exit: } // namespace Posix } // namespace ot -#endif // OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_UART +#endif // OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE diff --git a/src/posix/platform/hdlc_interface.hpp b/src/posix/platform/hdlc_interface.hpp index bc2b899ac..6078135d5 100644 --- a/src/posix/platform/hdlc_interface.hpp +++ b/src/posix/platform/hdlc_interface.hpp @@ -31,8 +31,8 @@ * This file includes definitions for the HDLC interface to radio (RCP). */ -#ifndef POSIX_APP_HDLC_INTERFACE_HPP_ -#define POSIX_APP_HDLC_INTERFACE_HPP_ +#ifndef POSIX_PLATFORM_HDLC_INTERFACE_HPP_ +#define POSIX_PLATFORM_HDLC_INTERFACE_HPP_ #include "openthread-posix-config.h" #include "platform-posix.h" @@ -54,12 +54,10 @@ public: /** * Initializes the object. * - * @param[in] aCallback Callback on frame received - * @param[in] aCallbackContext Callback context - * @param[in] aFrameBuffer A reference to a `RxFrameBuffer` object. + * @param[in] aRadioUrl RadioUrl parsed from radio url. * */ - HdlcInterface(ReceiveFrameCallback aCallback, void *aCallbackContext, RxFrameBuffer &aFrameBuffer); + HdlcInterface(const Url::Url &aRadioUrl); /** * This destructor deinitializes the object. @@ -72,14 +70,16 @@ public: * * @note This method should be called before reading and sending spinel frames to the interface. * - * @param[in] aRadioUrl RadioUrl parsed from radio url. + * @param[in] aCallback Callback on frame received + * @param[in] aCallbackContext Callback context + * @param[in] aFrameBuffer A reference to a `RxFrameBuffer` object. * - * @retval OT_ERROR_NONE The interface is initialized successfully - * @retval OT_ERROR_ALREADY The interface is already initialized. - * @retval OT_ERROR_INVALID_ARGS The UART device or executable cannot be found or failed to open/run. + * @retval OT_ERROR_NONE The interface is initialized successfully + * @retval OT_ERROR_ALREADY The interface is already initialized. + * @retval OT_ERROR_FAILED Failed to initialize the interface. * */ - otError Init(const Url::Url &aRadioUrl); + otError Init(ReceiveFrameCallback aCallback, void *aCallbackContext, RxFrameBuffer &aFrameBuffer); /** * Deinitializes the interface to the RCP. @@ -155,6 +155,20 @@ public: */ const otRcpInterfaceMetrics *GetRcpInterfaceMetrics(void) const { return &mInterfaceMetrics; } + /** + * Indicates whether or not the given interface matches this interface name. + * + * @param[in] aInterfaceName A pointer to the interface name. + * + * @retval TRUE The given interface name matches this interface name. + * @retval FALSE The given interface name doesn't match this interface name. + */ + static bool IsInterfaceNameMatch(const char *aInterfaceName) + { + static const char kInterfaceName[] = "spinel+hdlc"; + return (strncmp(aInterfaceName, kInterfaceName, strlen(kInterfaceName)) == 0); + } + private: /** * Is called when RCP is reset to recreate the connection with it. @@ -242,12 +256,12 @@ private: ReceiveFrameCallback mReceiveFrameCallback; void *mReceiveFrameContext; - RxFrameBuffer &mReceiveFrameBuffer; + RxFrameBuffer *mReceiveFrameBuffer; int mSockFd; uint32_t mBaudRate; Hdlc::Decoder mHdlcDecoder; - const Url::Url *mRadioUrl; + const Url::Url &mRadioUrl; otRcpInterfaceMetrics mInterfaceMetrics; @@ -258,4 +272,4 @@ private: } // namespace Posix } // namespace ot -#endif // POSIX_APP_HDLC_INTERFACE_HPP_ +#endif // POSIX_PLATFORM_HDLC_INTERFACE_HPP_ diff --git a/src/posix/platform/include/openthread/openthread-system.h b/src/posix/platform/include/openthread/openthread-system.h index e3b02fc5a..7fe2e0ea0 100644 --- a/src/posix/platform/include/openthread/openthread-system.h +++ b/src/posix/platform/include/openthread/openthread-system.h @@ -85,22 +85,6 @@ typedef struct otPlatformConfig ///< directly after initialization. } otPlatformConfig; -/** - * Represents RCP interface metrics. - * - */ -typedef struct otRcpInterfaceMetrics -{ - uint8_t mRcpInterfaceType; ///< The RCP interface type. - uint64_t mTransferredFrameCount; ///< The number of transferred frames. - uint64_t mTransferredValidFrameCount; ///< The number of transferred valid frames. - uint64_t mTransferredGarbageFrameCount; ///< The number of transferred garbage frames. - uint64_t mRxFrameCount; ///< The number of received frames. - uint64_t mRxFrameByteCount; ///< The number of received bytes. - uint64_t mTxFrameCount; ///< The number of transmitted frames. - uint64_t mTxFrameByteCount; ///< The number of transmitted bytes. -} otRcpInterfaceMetrics; - /** * Performs all platform-specific initialization of OpenThread's drivers and initializes the OpenThread * instance. diff --git a/src/posix/platform/openthread-posix-config.h b/src/posix/platform/openthread-posix-config.h index eb7fbf6f7..262d37ca0 100644 --- a/src/posix/platform/openthread-posix-config.h +++ b/src/posix/platform/openthread-posix-config.h @@ -85,34 +85,55 @@ #define OPENTHREAD_POSIX_CONFIG_DAEMON_CLI_ENABLE 1 #endif -/** - * RCP bus UART. - * - * @note This value is also for simulated UART bus. - * - */ -#define OT_POSIX_RCP_BUS_UART 1 - -/** - * RCP bus SPI. - * - */ -#define OT_POSIX_RCP_BUS_SPI 2 - -/** - * RCP bus defined by vendors. - * - */ -#define OT_POSIX_RCP_BUS_VENDOR 3 - /** * @def OPENTHREAD_POSIX_CONFIG_RCP_BUS * * This setting configures what type of RCP bus to use. * */ -#ifndef OPENTHREAD_POSIX_CONFIG_RCP_BUS -#define OPENTHREAD_POSIX_CONFIG_RCP_BUS OT_POSIX_RCP_BUS_UART +#ifdef OPENTHREAD_POSIX_CONFIG_RCP_BUS +#error "OPENTHREAD_POSIX_CONFIG_RCP_BUS was replaced by OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE,"\ + "OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE and OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE" +#endif + +/** + * @def OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE + * + * Define as 1 to enable the spinel HDLC interface. + * + */ +#ifndef OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE +#define OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE 1 +#endif + +/** + * @def OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE + * + * Define as 1 to enable the spinel SPI interface. + * + */ +#ifndef OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE +#define OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE 0 +#endif + +/** + * @def OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE + * + * Define as 1 to enable the spinel vendor interface. + * + */ +#ifndef OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE +#define OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE 0 +#endif + +/** + * @def OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_URL_PROTOCOL_NAME + * + * Define the URL protocol name of the vendor Spinel interface. + * + */ +#ifndef OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_URL_PROTOCOL_NAME +#define OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_URL_PROTOCOL_NAME "spinel+vendor" #endif /** @@ -417,7 +438,7 @@ * every interval. * */ -#ifndef OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL -#define OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL (60 * 1000 * 1000) +#ifdef OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL +#error "OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL was replaced by OPENTHREAD_SPINEL_CONFIG_RCP_TIME_SYNC_INTERVAL" #endif #endif // OPENTHREAD_PLATFORM_CONFIG_H_ diff --git a/src/posix/platform/radio.cpp b/src/posix/platform/radio.cpp index 32cd9e618..aafe9b502 100644 --- a/src/posix/platform/radio.cpp +++ b/src/posix/platform/radio.cpp @@ -36,66 +36,52 @@ #include #include +#include #include "common/code_utils.hpp" #include "common/new.hpp" -#include "lib/spinel/radio_spinel.hpp" #include "posix/platform/radio.hpp" #include "utils/parse_cmdline.hpp" -#if OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_UART -#include "hdlc_interface.hpp" - -static ot::Spinel::RadioSpinel sRadioSpinel; -#elif OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI -#include "spi_interface.hpp" - -static ot::Spinel::RadioSpinel sRadioSpinel; -#elif OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_VENDOR -#include "vendor_interface.hpp" - -static ot::Spinel::RadioSpinel sRadioSpinel; -#else -#error "OPENTHREAD_POSIX_CONFIG_RCP_BUS only allows OT_POSIX_RCP_BUS_UART, OT_POSIX_RCP_BUS_SPI and " \ - "OT_POSIX_RCP_BUS_VENDOR!" -#endif - #if OPENTHREAD_POSIX_CONFIG_CONFIGURATION_FILE_ENABLE #include "configuration.hpp" static ot::Posix::Configuration sConfig; #endif +static ot::Posix::Radio sRadio; + namespace ot { namespace Posix { namespace { -alignas(alignof(ot::Posix::Radio)) char sRadioRaw[sizeof(ot::Posix::Radio)]; - -extern "C" void platformRadioInit(const char *aUrl) -{ - Radio &radio = *(new (&sRadioRaw) Radio(aUrl)); - - radio.Init(); -} +extern "C" void platformRadioInit(const char *aUrl) { sRadio.Init(aUrl); } } // namespace -Radio::Radio(const char *aUrl) - : mRadioUrl(aUrl) +Radio::Radio(void) + : mRadioUrl(nullptr) + , mRadioSpinel() + , mSpinelInterface(nullptr) { - VerifyOrDie(mRadioUrl.GetPath() != nullptr, OT_EXIT_INVALID_ARGUMENTS); } -void Radio::Init(void) +void Radio::Init(const char *aUrl) { - bool resetRadio = !mRadioUrl.HasParam("no-reset"); - bool skipCompatibilityCheck = mRadioUrl.HasParam("skip-rcp-compatibility-check"); + bool resetRadio; + bool skipCompatibilityCheck; + + mRadioUrl = aUrl; + VerifyOrDie(mRadioUrl.GetPath() != nullptr, OT_EXIT_INVALID_ARGUMENTS); #if OPENTHREAD_POSIX_VIRTUAL_TIME VirtualTimeInit(); #endif - SuccessOrDie(sRadioSpinel.GetSpinelInterface().Init(mRadioUrl)); - sRadioSpinel.Init(resetRadio, skipCompatibilityCheck); + mSpinelInterface = CreateSpinelInterface(mRadioUrl.GetProtocol()); + VerifyOrDie(mSpinelInterface != nullptr, OT_EXIT_FAILURE); + + resetRadio = !mRadioUrl.HasParam("no-reset"); + skipCompatibilityCheck = mRadioUrl.HasParam("skip-rcp-compatibility-check"); + mRadioSpinel.Init(*mSpinelInterface, resetRadio, skipCompatibilityCheck); ProcessRadioUrl(mRadioUrl); } @@ -114,6 +100,41 @@ void Radio::VirtualTimeInit(void) } #endif +Spinel::SpinelInterface *Radio::CreateSpinelInterface(const char *aInterfaceName) +{ + Spinel::SpinelInterface *interface; + + if (aInterfaceName == nullptr) + { + DieNow(OT_ERROR_FAILED); + } +#if OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE + else if (HdlcInterface::IsInterfaceNameMatch(aInterfaceName)) + { + interface = new (&mSpinelInterfaceRaw) HdlcInterface(mRadioUrl); + } +#endif +#if OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE + else if (Posix::SpiInterface::IsInterfaceNameMatch(aInterfaceName)) + { + interface = new (&mSpinelInterfaceRaw) SpiInterface(mRadioUrl); + } +#endif +#if OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE + else if (VendorInterface::IsInterfaceNameMatch(aInterfaceName)) + { + interface = new (&mSpinelInterfaceRaw) VendorInterface(mRadioUrl); + } +#endif + else + { + otLogCritPlat("The Spinel interface name \"%s\" is not supported!", aInterfaceName); + DieNow(OT_ERROR_FAILED); + } + + return interface; +} + void Radio::ProcessRadioUrl(const RadioUrl &aRadioUrl) { const char *region; @@ -128,13 +149,13 @@ void Radio::ProcessRadioUrl(const RadioUrl &aRadioUrl) if (aRadioUrl.HasParam("fem-lnagain")) { SuccessOrDie(aRadioUrl.ParseInt8("fem-lnagain", value)); - SuccessOrDie(sRadioSpinel.SetFemLnaGain(value)); + SuccessOrDie(mRadioSpinel.SetFemLnaGain(value)); } if (aRadioUrl.HasParam("cca-threshold")) { SuccessOrDie(aRadioUrl.ParseInt8("cca-threshold", value)); - SuccessOrDie(sRadioSpinel.SetCcaEnergyDetectThreshold(value)); + SuccessOrDie(mRadioSpinel.SetCcaEnergyDetectThreshold(value)); } if ((region = aRadioUrl.GetValue("region")) != nullptr) @@ -153,7 +174,7 @@ void Radio::ProcessRadioUrl(const RadioUrl &aRadioUrl) const char *enableCoex = aRadioUrl.GetValue("enable-coex"); if (enableCoex != nullptr) { - SuccessOrDie(sRadioSpinel.SetCoexEnabled(enableCoex[0] != '0')); + SuccessOrDie(mRadioSpinel.SetCoexEnabled(enableCoex[0] != '0')); } } #endif // OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE @@ -178,7 +199,7 @@ void Radio::ProcessMaxPowerTable(const RadioUrl &aRadioUrl) str != nullptr && channel <= ot::Radio::kChannelMax; str = strtok_r(nullptr, ",", &pSave)) { power = static_cast(strtol(str, nullptr, 0)); - error = sRadioSpinel.SetChannelMaxTransmitPower(channel, power); + error = mRadioSpinel.SetChannelMaxTransmitPower(channel, power); VerifyOrDie((error == OT_ERROR_NONE) || (error == OT_ERROR_NOT_IMPLEMENTED), OT_EXIT_FAILURE); if (error == OT_ERROR_NOT_IMPLEMENTED) { @@ -191,7 +212,7 @@ void Radio::ProcessMaxPowerTable(const RadioUrl &aRadioUrl) // Use the last power if omitted. while (channel <= ot::Radio::kChannelMax) { - error = sRadioSpinel.SetChannelMaxTransmitPower(channel, power); + error = mRadioSpinel.SetChannelMaxTransmitPower(channel, power); VerifyOrDie((error == OT_ERROR_NONE) || (error == OT_ERROR_NOT_IMPLEMENTED), OT_ERROR_FAILED); if (error == OT_ERROR_NOT_IMPLEMENTED) { @@ -208,23 +229,23 @@ exit: #endif // OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE } -void *Radio::GetSpinelInstance(void) { return &sRadioSpinel; } - } // namespace Posix } // namespace ot -void platformRadioDeinit(void) { sRadioSpinel.Deinit(); } +static ot::Spinel::RadioSpinel &GetRadioSpinel(void) { return sRadio.GetRadioSpinel(); } + +void platformRadioDeinit(void) { GetRadioSpinel().Deinit(); } void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64) { OT_UNUSED_VARIABLE(aInstance); - SuccessOrDie(sRadioSpinel.GetIeeeEui64(aIeeeEui64)); + SuccessOrDie(GetRadioSpinel().GetIeeeEui64(aIeeeEui64)); } void otPlatRadioSetPanId(otInstance *aInstance, uint16_t panid) { OT_UNUSED_VARIABLE(aInstance); - SuccessOrDie(sRadioSpinel.SetPanId(panid)); + SuccessOrDie(GetRadioSpinel().SetPanId(panid)); } void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aAddress) @@ -237,39 +258,39 @@ void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aA addr.m8[i] = aAddress->m8[sizeof(addr) - 1 - i]; } - SuccessOrDie(sRadioSpinel.SetExtendedAddress(addr)); + SuccessOrDie(GetRadioSpinel().SetExtendedAddress(addr)); } void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aAddress) { OT_UNUSED_VARIABLE(aInstance); - SuccessOrDie(sRadioSpinel.SetShortAddress(aAddress)); + SuccessOrDie(GetRadioSpinel().SetShortAddress(aAddress)); } void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable) { OT_UNUSED_VARIABLE(aInstance); - SuccessOrDie(sRadioSpinel.SetPromiscuous(aEnable)); + SuccessOrDie(GetRadioSpinel().SetPromiscuous(aEnable)); } bool otPlatRadioIsEnabled(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.IsEnabled(); + return GetRadioSpinel().IsEnabled(); } -otError otPlatRadioEnable(otInstance *aInstance) { return sRadioSpinel.Enable(aInstance); } +otError otPlatRadioEnable(otInstance *aInstance) { return GetRadioSpinel().Enable(aInstance); } otError otPlatRadioDisable(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.Disable(); + return GetRadioSpinel().Disable(); } otError otPlatRadioSleep(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.Sleep(); + return GetRadioSpinel().Sleep(); } otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel) @@ -278,7 +299,7 @@ otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel) otError error; - SuccessOrExit(error = sRadioSpinel.Receive(aChannel)); + SuccessOrExit(error = GetRadioSpinel().Receive(aChannel)); exit: return error; @@ -287,47 +308,47 @@ exit: otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.Transmit(*aFrame); + return GetRadioSpinel().Transmit(*aFrame); } otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return &sRadioSpinel.GetTransmitFrame(); + return &GetRadioSpinel().GetTransmitFrame(); } int8_t otPlatRadioGetRssi(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.GetRssi(); + return GetRadioSpinel().GetRssi(); } otRadioCaps otPlatRadioGetCaps(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.GetRadioCaps(); + return GetRadioSpinel().GetRadioCaps(); } const char *otPlatRadioGetVersionString(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.GetVersion(); + return GetRadioSpinel().GetVersion(); } bool otPlatRadioGetPromiscuous(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.IsPromiscuous(); + return GetRadioSpinel().IsPromiscuous(); } void platformRadioUpdateFdSet(otSysMainloopContext *aContext) { uint64_t now = otPlatTimeGet(); - uint64_t deadline = sRadioSpinel.GetNextRadioTimeRecalcStart(); + uint64_t deadline = GetRadioSpinel().GetNextRadioTimeRecalcStart(); - if (sRadioSpinel.IsTransmitting()) + if (GetRadioSpinel().IsTransmitting()) { - uint64_t txRadioEndUs = sRadioSpinel.GetTxRadioEndUs(); + uint64_t txRadioEndUs = GetRadioSpinel().GetTxRadioEndUs(); if (txRadioEndUs < deadline) { @@ -352,9 +373,9 @@ void platformRadioUpdateFdSet(otSysMainloopContext *aContext) aContext->mTimeout.tv_usec = 0; } - sRadioSpinel.GetSpinelInterface().UpdateFdSet(aContext); + sRadio.GetSpinelInterface().UpdateFdSet(aContext); - if (sRadioSpinel.HasPendingFrame() || sRadioSpinel.IsTransmitDone()) + if (GetRadioSpinel().HasPendingFrame() || GetRadioSpinel().IsTransmitDone()) { aContext->mTimeout.tv_sec = 0; aContext->mTimeout.tv_usec = 0; @@ -365,27 +386,27 @@ void platformRadioUpdateFdSet(otSysMainloopContext *aContext) void virtualTimeRadioSpinelProcess(otInstance *aInstance, const struct VirtualTimeEvent *aEvent) { OT_UNUSED_VARIABLE(aInstance); - sRadioSpinel.Process(aEvent); + GetRadioSpinel().Process(aEvent); } #else void platformRadioProcess(otInstance *aInstance, const otSysMainloopContext *aContext) { OT_UNUSED_VARIABLE(aInstance); - sRadioSpinel.Process(aContext); + GetRadioSpinel().Process(aContext); } #endif // OPENTHREAD_POSIX_VIRTUAL_TIME void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable) { OT_UNUSED_VARIABLE(aInstance); - SuccessOrDie(sRadioSpinel.EnableSrcMatch(aEnable)); + SuccessOrDie(GetRadioSpinel().EnableSrcMatch(aEnable)); } otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.AddSrcMatchShortEntry(aShortAddress); + return GetRadioSpinel().AddSrcMatchShortEntry(aShortAddress); } otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress) @@ -398,13 +419,13 @@ otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress addr.m8[i] = aExtAddress->m8[sizeof(addr) - 1 - i]; } - return sRadioSpinel.AddSrcMatchExtEntry(addr); + return GetRadioSpinel().AddSrcMatchExtEntry(addr); } otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.ClearSrcMatchShortEntry(aShortAddress); + return GetRadioSpinel().ClearSrcMatchShortEntry(aShortAddress); } otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress) @@ -417,83 +438,83 @@ otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddre addr.m8[i] = aExtAddress->m8[sizeof(addr) - 1 - i]; } - return sRadioSpinel.ClearSrcMatchExtEntry(addr); + return GetRadioSpinel().ClearSrcMatchExtEntry(addr); } void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - SuccessOrDie(sRadioSpinel.ClearSrcMatchShortEntries()); + SuccessOrDie(GetRadioSpinel().ClearSrcMatchShortEntries()); } void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - SuccessOrDie(sRadioSpinel.ClearSrcMatchExtEntries()); + SuccessOrDie(GetRadioSpinel().ClearSrcMatchExtEntries()); } otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.EnergyScan(aScanChannel, aScanDuration); + return GetRadioSpinel().EnergyScan(aScanChannel, aScanDuration); } otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower) { OT_UNUSED_VARIABLE(aInstance); assert(aPower != nullptr); - return sRadioSpinel.GetTransmitPower(*aPower); + return GetRadioSpinel().GetTransmitPower(*aPower); } otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.SetTransmitPower(aPower); + return GetRadioSpinel().SetTransmitPower(aPower); } otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aThreshold) { OT_UNUSED_VARIABLE(aInstance); assert(aThreshold != nullptr); - return sRadioSpinel.GetCcaEnergyDetectThreshold(*aThreshold); + return GetRadioSpinel().GetCcaEnergyDetectThreshold(*aThreshold); } otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.SetCcaEnergyDetectThreshold(aThreshold); + return GetRadioSpinel().SetCcaEnergyDetectThreshold(aThreshold); } otError otPlatRadioGetFemLnaGain(otInstance *aInstance, int8_t *aGain) { OT_UNUSED_VARIABLE(aInstance); assert(aGain != nullptr); - return sRadioSpinel.GetFemLnaGain(*aGain); + return GetRadioSpinel().GetFemLnaGain(*aGain); } otError otPlatRadioSetFemLnaGain(otInstance *aInstance, int8_t aGain) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.SetFemLnaGain(aGain); + return GetRadioSpinel().SetFemLnaGain(aGain); } int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.GetReceiveSensitivity(); + return GetRadioSpinel().GetReceiveSensitivity(); } #if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE otError otPlatRadioSetCoexEnabled(otInstance *aInstance, bool aEnabled) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.SetCoexEnabled(aEnabled); + return GetRadioSpinel().SetCoexEnabled(aEnabled); } bool otPlatRadioIsCoexEnabled(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.IsCoexEnabled(); + return GetRadioSpinel().IsCoexEnabled(); } otError otPlatRadioGetCoexMetrics(otInstance *aInstance, otRadioCoexMetrics *aCoexMetrics) @@ -504,7 +525,7 @@ otError otPlatRadioGetCoexMetrics(otInstance *aInstance, otRadioCoexMetrics *aCo VerifyOrExit(aCoexMetrics != nullptr, error = OT_ERROR_INVALID_ARGS); - error = sRadioSpinel.GetCoexMetrics(*aCoexMetrics); + error = GetRadioSpinel().GetCoexMetrics(*aCoexMetrics); exit: return error; @@ -529,26 +550,26 @@ otError otPlatDiagProcess(otInstance *aInstance, cur += snprintf(cur, static_cast(end - cur), "%s ", aArgs[index]); } - return sRadioSpinel.PlatDiagProcess(cmd, aOutput, aOutputMaxLen); + return GetRadioSpinel().PlatDiagProcess(cmd, aOutput, aOutputMaxLen); } void otPlatDiagModeSet(bool aMode) { - SuccessOrExit(sRadioSpinel.PlatDiagProcess(aMode ? "start" : "stop", nullptr, 0)); - sRadioSpinel.SetDiagEnabled(aMode); + SuccessOrExit(GetRadioSpinel().PlatDiagProcess(aMode ? "start" : "stop", nullptr, 0)); + GetRadioSpinel().SetDiagEnabled(aMode); exit: return; } -bool otPlatDiagModeGet(void) { return sRadioSpinel.IsDiagEnabled(); } +bool otPlatDiagModeGet(void) { return GetRadioSpinel().IsDiagEnabled(); } void otPlatDiagTxPowerSet(int8_t aTxPower) { char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE]; snprintf(cmd, sizeof(cmd), "power %d", aTxPower); - SuccessOrExit(sRadioSpinel.PlatDiagProcess(cmd, nullptr, 0)); + SuccessOrExit(GetRadioSpinel().PlatDiagProcess(cmd, nullptr, 0)); exit: return; @@ -559,7 +580,7 @@ void otPlatDiagChannelSet(uint8_t aChannel) char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE]; snprintf(cmd, sizeof(cmd), "channel %d", aChannel); - SuccessOrExit(sRadioSpinel.PlatDiagProcess(cmd, nullptr, 0)); + SuccessOrExit(GetRadioSpinel().PlatDiagProcess(cmd, nullptr, 0)); exit: return; @@ -571,7 +592,7 @@ otError otPlatDiagGpioSet(uint32_t aGpio, bool aValue) char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE]; snprintf(cmd, sizeof(cmd), "gpio set %d %d", aGpio, aValue); - SuccessOrExit(error = sRadioSpinel.PlatDiagProcess(cmd, nullptr, 0)); + SuccessOrExit(error = GetRadioSpinel().PlatDiagProcess(cmd, nullptr, 0)); exit: return error; @@ -585,7 +606,7 @@ otError otPlatDiagGpioGet(uint32_t aGpio, bool *aValue) char *str; snprintf(cmd, sizeof(cmd), "gpio get %d", aGpio); - SuccessOrExit(error = sRadioSpinel.PlatDiagProcess(cmd, output, sizeof(output))); + SuccessOrExit(error = GetRadioSpinel().PlatDiagProcess(cmd, output, sizeof(output))); VerifyOrExit((str = strtok(output, "\r")) != nullptr, error = OT_ERROR_FAILED); *aValue = static_cast(atoi(str)); @@ -599,7 +620,7 @@ otError otPlatDiagGpioSetMode(uint32_t aGpio, otGpioMode aMode) char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE]; snprintf(cmd, sizeof(cmd), "gpio mode %d %s", aGpio, aMode == OT_GPIO_MODE_INPUT ? "in" : "out"); - SuccessOrExit(error = sRadioSpinel.PlatDiagProcess(cmd, nullptr, 0)); + SuccessOrExit(error = GetRadioSpinel().PlatDiagProcess(cmd, nullptr, 0)); exit: return error; @@ -613,7 +634,7 @@ otError otPlatDiagGpioGetMode(uint32_t aGpio, otGpioMode *aMode) char *str; snprintf(cmd, sizeof(cmd), "gpio mode %d", aGpio); - SuccessOrExit(error = sRadioSpinel.PlatDiagProcess(cmd, output, sizeof(output))); + SuccessOrExit(error = GetRadioSpinel().PlatDiagProcess(cmd, output, sizeof(output))); VerifyOrExit((str = strtok(output, "\r")) != nullptr, error = OT_ERROR_FAILED); if (strcmp(str, "in") == 0) @@ -656,7 +677,7 @@ otError otPlatDiagRadioGetPowerSettings(otInstance *aInstance, (aRawPowerSettingLength != nullptr)); snprintf(cmd, sizeof(cmd), "powersettings %d", aChannel); - SuccessOrExit(error = sRadioSpinel.PlatDiagProcess(cmd, output, sizeof(output))); + SuccessOrExit(error = GetRadioSpinel().PlatDiagProcess(cmd, output, sizeof(output))); snprintf(fmt, sizeof(fmt), "TargetPower(0.01dBm): %%d\r\nActualPower(0.01dBm): %%d\r\nRawPowerSetting: %%%us\r\n", kRawPowerStringSize); VerifyOrExit(sscanf(output, fmt, &targetPower, &actualPower, rawPowerSetting) == 3, error = OT_ERROR_FAILED); @@ -689,7 +710,7 @@ otError otPlatDiagRadioSetRawPowerSetting(otInstance *aInstance, VerifyOrExit(nbytes < static_cast(sizeof(cmd)), error = OT_ERROR_INVALID_ARGS); } - SuccessOrExit(error = sRadioSpinel.PlatDiagProcess(cmd, nullptr, 0)); + SuccessOrExit(error = GetRadioSpinel().PlatDiagProcess(cmd, nullptr, 0)); exit: return error; @@ -708,7 +729,7 @@ otError otPlatDiagRadioGetRawPowerSetting(otInstance *aInstance, assert((aRawPowerSetting != nullptr) && (aRawPowerSettingLength != nullptr)); snprintf(cmd, sizeof(cmd), "rawpowersetting"); - SuccessOrExit(error = sRadioSpinel.PlatDiagProcess(cmd, output, sizeof(output))); + SuccessOrExit(error = GetRadioSpinel().PlatDiagProcess(cmd, output, sizeof(output))); VerifyOrExit((str = strtok(output, "\r")) != nullptr, error = OT_ERROR_FAILED); SuccessOrExit(error = ot::Utils::CmdLineParser::ParseAsHexString(str, *aRawPowerSettingLength, aRawPowerSetting)); @@ -724,7 +745,7 @@ otError otPlatDiagRadioRawPowerSettingEnable(otInstance *aInstance, bool aEnable char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE]; snprintf(cmd, sizeof(cmd), "rawpowersetting %s", aEnable ? "enable" : "disable"); - SuccessOrExit(error = sRadioSpinel.PlatDiagProcess(cmd, nullptr, 0)); + SuccessOrExit(error = GetRadioSpinel().PlatDiagProcess(cmd, nullptr, 0)); exit: return error; @@ -738,7 +759,7 @@ otError otPlatDiagRadioTransmitCarrier(otInstance *aInstance, bool aEnable) char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE]; snprintf(cmd, sizeof(cmd), "cw %s", aEnable ? "start" : "stop"); - SuccessOrExit(error = sRadioSpinel.PlatDiagProcess(cmd, nullptr, 0)); + SuccessOrExit(error = GetRadioSpinel().PlatDiagProcess(cmd, nullptr, 0)); exit: return error; @@ -751,7 +772,7 @@ otError otPlatDiagRadioTransmitStream(otInstance *aInstance, bool aEnable) char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE]; snprintf(cmd, sizeof(cmd), "stream %s", aEnable ? "start" : "stop"); - return sRadioSpinel.PlatDiagProcess(cmd, nullptr, 0); + return GetRadioSpinel().PlatDiagProcess(cmd, nullptr, 0); } void otPlatDiagRadioReceived(otInstance *aInstance, otRadioFrame *aFrame, otError aError) @@ -778,7 +799,7 @@ uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance) else #endif { - channelMask = sRadioSpinel.GetRadioChannelMask(false); + channelMask = GetRadioSpinel().GetRadioChannelMask(false); } return channelMask; @@ -798,7 +819,7 @@ uint32_t otPlatRadioGetPreferredChannelMask(otInstance *aInstance) else #endif { - channelMask = sRadioSpinel.GetRadioChannelMask(true); + channelMask = GetRadioSpinel().GetRadioChannelMask(true); } return channelMask; @@ -807,7 +828,7 @@ uint32_t otPlatRadioGetPreferredChannelMask(otInstance *aInstance) otRadioState otPlatRadioGetState(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.GetState(); + return GetRadioSpinel().GetState(); } void otPlatRadioSetMacKey(otInstance *aInstance, @@ -818,33 +839,33 @@ void otPlatRadioSetMacKey(otInstance *aInstance, const otMacKeyMaterial *aNextKey, otRadioKeyType aKeyType) { - SuccessOrDie(sRadioSpinel.SetMacKey(aKeyIdMode, aKeyId, aPrevKey, aCurrKey, aNextKey)); + SuccessOrDie(GetRadioSpinel().SetMacKey(aKeyIdMode, aKeyId, aPrevKey, aCurrKey, aNextKey)); OT_UNUSED_VARIABLE(aInstance); OT_UNUSED_VARIABLE(aKeyType); } void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter) { - SuccessOrDie(sRadioSpinel.SetMacFrameCounter(aMacFrameCounter, /* aSetIfLarger */ false)); + SuccessOrDie(GetRadioSpinel().SetMacFrameCounter(aMacFrameCounter, /* aSetIfLarger */ false)); OT_UNUSED_VARIABLE(aInstance); } void otPlatRadioSetMacFrameCounterIfLarger(otInstance *aInstance, uint32_t aMacFrameCounter) { - SuccessOrDie(sRadioSpinel.SetMacFrameCounter(aMacFrameCounter, /* aSetIfLarger */ true)); + SuccessOrDie(GetRadioSpinel().SetMacFrameCounter(aMacFrameCounter, /* aSetIfLarger */ true)); OT_UNUSED_VARIABLE(aInstance); } uint64_t otPlatRadioGetNow(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.GetNow(); + return GetRadioSpinel().GetNow(); } uint32_t otPlatRadioGetBusSpeed(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.GetBusSpeed(); + return GetRadioSpinel().GetBusSpeed(); } #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE @@ -852,7 +873,7 @@ uint8_t otPlatRadioGetCslAccuracy(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.GetCslAccuracy(); + return GetRadioSpinel().GetCslAccuracy(); } #endif @@ -861,14 +882,14 @@ uint8_t otPlatRadioGetCslUncertainty(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.GetCslUncertainty(); + return GetRadioSpinel().GetCslUncertainty(); } #endif otError otPlatRadioSetChannelMaxTransmitPower(otInstance *aInstance, uint8_t aChannel, int8_t aMaxPower) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.SetChannelMaxTransmitPower(aChannel, aMaxPower); + return GetRadioSpinel().SetChannelMaxTransmitPower(aChannel, aMaxPower); } #if OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE @@ -879,19 +900,19 @@ otError otPlatRadioAddCalibratedPower(otInstance *aInstance, uint16_t aRawPowerSettingLength) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.AddCalibratedPower(aChannel, aActualPower, aRawPowerSetting, aRawPowerSettingLength); + return GetRadioSpinel().AddCalibratedPower(aChannel, aActualPower, aRawPowerSetting, aRawPowerSettingLength); } otError otPlatRadioClearCalibratedPowers(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.ClearCalibratedPowers(); + return GetRadioSpinel().ClearCalibratedPowers(); } otError otPlatRadioSetChannelTargetPower(otInstance *aInstance, uint8_t aChannel, int16_t aTargetPower) { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.SetChannelTargetPower(aChannel, aTargetPower); + return GetRadioSpinel().SetChannelTargetPower(aChannel, aTargetPower); } #endif @@ -909,7 +930,7 @@ otError otPlatRadioSetRegion(otInstance *aInstance, uint16_t aRegionCode) else #endif { - error = sRadioSpinel.SetRadioRegion(aRegionCode); + error = GetRadioSpinel().SetRadioRegion(aRegionCode); } return error; @@ -930,7 +951,7 @@ otError otPlatRadioGetRegion(otInstance *aInstance, uint16_t *aRegionCode) else #endif { - error = sRadioSpinel.GetRadioRegion(aRegionCode); + error = GetRadioSpinel().GetRadioRegion(aRegionCode); } return error; @@ -944,7 +965,7 @@ otError otPlatRadioConfigureEnhAckProbing(otInstance *aInstance, { OT_UNUSED_VARIABLE(aInstance); - return sRadioSpinel.ConfigureEnhAckProbing(aLinkMetrics, aShortAddress, *aExtAddress); + return GetRadioSpinel().ConfigureEnhAckProbing(aLinkMetrics, aShortAddress, *aExtAddress); } #endif @@ -957,9 +978,9 @@ otError otPlatRadioReceiveAt(otInstance *aInstance, uint8_t aChannel, uint32_t a return OT_ERROR_NOT_IMPLEMENTED; } -const otRadioSpinelMetrics *otSysGetRadioSpinelMetrics(void) { return sRadioSpinel.GetRadioSpinelMetrics(); } +const otRadioSpinelMetrics *otSysGetRadioSpinelMetrics(void) { return GetRadioSpinel().GetRadioSpinelMetrics(); } const otRcpInterfaceMetrics *otSysGetRcpInterfaceMetrics(void) { - return sRadioSpinel.GetSpinelInterface().GetRcpInterfaceMetrics(); + return sRadio.GetSpinelInterface().GetRcpInterfaceMetrics(); } diff --git a/src/posix/platform/radio.hpp b/src/posix/platform/radio.hpp index 5e8d81cf9..ae0626614 100644 --- a/src/posix/platform/radio.hpp +++ b/src/posix/platform/radio.hpp @@ -29,7 +29,12 @@ #ifndef POSIX_PLATFORM_RADIO_HPP_ #define POSIX_PLATFORM_RADIO_HPP_ +#include "common/code_utils.hpp" +#include "lib/spinel/radio_spinel.hpp" +#include "posix/platform/hdlc_interface.hpp" #include "posix/platform/radio_url.hpp" +#include "posix/platform/spi_interface.hpp" +#include "posix/platform/vendor_interface.hpp" namespace ot { namespace Posix { @@ -44,24 +49,36 @@ public: /** * Creates the radio manager. * - * @param[in] aUrl A pointer to the null-terminated URL. - * */ - explicit Radio(const char *aUrl); + Radio(void); /** * Initialize the Thread radio. * + * @param[in] aUrl A pointer to the null-terminated URL. + * */ - void Init(void); + void Init(const char *aUrl); /** - * Acts as an accessor to the spinel instance used by the radio. + * Acts as an accessor to the spinel interface instance used by the radio. * - * @returns A pointer to the radio's spinel interface instance. + * @returns A reference to the radio's spinel interface instance. * */ - static void *GetSpinelInstance(void); + Spinel::SpinelInterface &GetSpinelInterface(void) + { + OT_ASSERT(mSpinelInterface != nullptr); + return *mSpinelInterface; + } + + /** + * Acts as an accessor to the radio spinel instance used by the radio. + * + * @returns A reference to the radio spinel instance. + * + */ + Spinel::RadioSpinel &GetRadioSpinel(void) { return mRadioSpinel; } private: #if OPENTHREAD_POSIX_VIRTUAL_TIME @@ -70,7 +87,27 @@ private: void ProcessRadioUrl(const RadioUrl &aRadioUrl); void ProcessMaxPowerTable(const RadioUrl &aRadioUrl); - RadioUrl mRadioUrl; + Spinel::SpinelInterface *CreateSpinelInterface(const char *aInterfaceName); + +#if OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE && OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE + static constexpr size_t kSpinelInterfaceRawSize = sizeof(ot::Posix::SpiInterface) > sizeof(ot::Posix::HdlcInterface) + ? sizeof(ot::Posix::SpiInterface) + : sizeof(ot::Posix::HdlcInterface); +#elif OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE + static constexpr size_t kSpinelInterfaceRawSize = sizeof(ot::Posix::HdlcInterface); +#elif OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE + static constexpr size_t kSpinelInterfaceRawSize = sizeof(ot::Posix::SpiInterface); +#elif OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE + static constexpr size_t kSpinelInterfaceRawSize = sizeof(ot::Posix::VendorInterface); +#else +#error "No Spinel interface is specified!" +#endif + + RadioUrl mRadioUrl; + Spinel::RadioSpinel mRadioSpinel; + Spinel::SpinelInterface *mSpinelInterface; + + OT_DEFINE_ALIGNED_VAR(mSpinelInterfaceRaw, kSpinelInterfaceRawSize, uint64_t); }; } // namespace Posix diff --git a/src/posix/platform/radio_url.cpp b/src/posix/platform/radio_url.cpp index a8513f326..b57e29f81 100644 --- a/src/posix/platform/radio_url.cpp +++ b/src/posix/platform/radio_url.cpp @@ -37,8 +37,14 @@ const char *otSysGetRadioUrlHelpString(void) { -#if OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI -#define OT_RADIO_URL_HELP_BUS \ +#define OT_RADIO_URL_HELP_BUS \ + "Radio Url format:" \ + " {Protocol}://${PATH_TO_DEVICE}?${Parameters}\n" \ + "\n" + +#if OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE +#define OT_SPINEL_SPI_RADIO_URL_HELP_BUS \ + "Protocol=[spinel+spi*] Specify the Spinel interface as the Spinel SPI interface\n" \ " spinel+spi://${PATH_TO_SPI_DEVICE}?${Parameters}\n" \ "Parameters:\n" \ " gpio-int-device[=gpio-device-path]\n" \ @@ -61,10 +67,15 @@ const char *otSysGetRadioUrlHelpString(void) " spi-align-allowance[=n] Specify the maximum number of 0xFF bytes to clip from start of\n" \ " MISO frame. Max value is 16.\n" \ " spi-small-packet=[n] Specify the smallest packet we can receive in a single transaction.\n" \ - " (larger packets will require two transactions). Default value is 32.\n" + " (larger packets will require two transactions). Default value is 32.\n" \ + "\n" +#else +#define OT_SPINEL_SPI_RADIO_URL_HELP_BUS +#endif // OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE -#elif OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_UART -#define OT_RADIO_URL_HELP_BUS \ +#if OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE +#define OT_SPINEL_HDLC_RADIO_URL_HELP_BUS \ + "Protocol=[spinel+hdlc*] Specify the Spinel interface as the Spinel HDLC interface\n" \ " forkpty-arg[=argument string] Command line arguments for subprocess, can be repeated.\n" \ " spinel+hdlc+uart://${PATH_TO_UART_DEVICE}?${Parameters} for real uart device\n" \ " spinel+hdlc+forkpty://${PATH_TO_UART_DEVICE}?${Parameters} for forking a pty subprocess.\n" \ @@ -73,17 +84,22 @@ const char *otSysGetRadioUrlHelpString(void) " uart-stop[=number-of-bits] Uart stop bit, default is 1.\n" \ " uart-baudrate[=baudrate] Uart baud rate, default is 115200.\n" \ " uart-flow-control Enable flow control, disabled by default.\n" \ - " uart-reset Reset connection after hard resetting RCP(USB CDC ACM).\n" + " uart-reset Reset connection after hard resetting RCP(USB CDC ACM).\n" \ + "\n" +#else +#define OT_SPINEL_HDLC_RADIO_URL_HELP_BUS +#endif // OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE -#elif OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_VENDOR +#if OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE #ifndef OT_VENDOR_RADIO_URL_HELP_BUS #define OT_VENDOR_RADIO_URL_HELP_BUS "\n" #endif // OT_VENDOR_RADIO_URL_HELP_BUS -#define OT_RADIO_URL_HELP_BUS OT_VENDOR_RADIO_URL_HELP_BUS - -#endif // OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI +#define OT_SPINEL_VENDOR_RADIO_URL_HELP_BUS OT_VENDOR_RADIO_URL_HELP_BUS +#else +#define OT_SPINEL_VENDOR_RADIO_URL_HELP_BUS +#endif // OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE #if OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE #define OT_RADIO_URL_HELP_MAX_POWER_TABLE \ @@ -95,7 +111,8 @@ const char *otSysGetRadioUrlHelpString(void) #define OT_RADIO_URL_HELP_MAX_POWER_TABLE #endif - return "RadioURL:\n" OT_RADIO_URL_HELP_BUS OT_RADIO_URL_HELP_MAX_POWER_TABLE + return "RadioURL:\n" OT_RADIO_URL_HELP_BUS OT_SPINEL_SPI_RADIO_URL_HELP_BUS OT_SPINEL_HDLC_RADIO_URL_HELP_BUS + OT_SPINEL_VENDOR_RADIO_URL_HELP_BUS OT_RADIO_URL_HELP_MAX_POWER_TABLE " region[=region-code] Set the radio's region code. The region code must be an\n" " ISO 3166 alpha-2 code.\n" " cca-threshold[=dbm] Set the radio's CCA ED threshold in dBm measured at antenna connector.\n" @@ -111,9 +128,12 @@ namespace Posix { RadioUrl::RadioUrl(const char *aUrl) { - VerifyOrDie(strnlen(aUrl, sizeof(mUrl)) < sizeof(mUrl), OT_EXIT_INVALID_ARGUMENTS); - strncpy(mUrl, aUrl, sizeof(mUrl) - 1); - SuccessOrDie(Url::Url::Init(mUrl)); + if (aUrl != nullptr) + { + VerifyOrDie(strnlen(aUrl, sizeof(mUrl)) < sizeof(mUrl), OT_EXIT_INVALID_ARGUMENTS); + strncpy(mUrl, aUrl, sizeof(mUrl) - 1); + SuccessOrDie(Url::Url::Init(mUrl)); + } } } // namespace Posix diff --git a/src/posix/platform/spi_interface.cpp b/src/posix/platform/spi_interface.cpp index af6ee369e..54e889a7b 100644 --- a/src/posix/platform/spi_interface.cpp +++ b/src/posix/platform/spi_interface.cpp @@ -54,7 +54,7 @@ #include #include -#if OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI +#if OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE #include #include #include @@ -62,10 +62,11 @@ namespace ot { namespace Posix { -SpiInterface::SpiInterface(ReceiveFrameCallback aCallback, void *aCallbackContext, RxFrameBuffer &aFrameBuffer) - : mReceiveFrameCallback(aCallback) - , mReceiveFrameContext(aCallbackContext) - , mRxFrameBuffer(aFrameBuffer) +SpiInterface::SpiInterface(const Url::Url &aRadioUrl) + : mReceiveFrameCallback(nullptr) + , mReceiveFrameContext(nullptr) + , mRxFrameBuffer(nullptr) + , mRadioUrl(aRadioUrl) , mSpiDevFd(-1) , mResetGpioValueFd(-1) , mIntGpioValueFd(-1) @@ -90,7 +91,7 @@ void SpiInterface::ResetStates(void) mSpiSlaveDataLen = 0; memset(mSpiTxFrameBuffer, 0, sizeof(mSpiTxFrameBuffer)); memset(&mInterfaceMetrics, 0, sizeof(mInterfaceMetrics)); - mInterfaceMetrics.mRcpInterfaceType = OT_POSIX_RCP_BUS_SPI; + mInterfaceMetrics.mRcpInterfaceType = kSpinelInterfaceTypeSpi; } otError SpiInterface::HardwareReset(void) @@ -107,7 +108,7 @@ otError SpiInterface::HardwareReset(void) return OT_ERROR_NONE; } -otError SpiInterface::Init(const Url::Url &aRadioUrl) +otError SpiInterface::Init(ReceiveFrameCallback aCallback, void *aCallbackContext, RxFrameBuffer &aFrameBuffer) { const char *spiGpioIntDevice; const char *spiGpioResetDevice; @@ -120,23 +121,23 @@ otError SpiInterface::Init(const Url::Url &aRadioUrl) uint8_t spiAlignAllowance = OT_PLATFORM_CONFIG_SPI_DEFAULT_ALIGN_ALLOWANCE; uint8_t spiSmallPacketSize = OT_PLATFORM_CONFIG_SPI_DEFAULT_SMALL_PACKET_SIZE; - spiGpioIntDevice = aRadioUrl.GetValue("gpio-int-device"); - spiGpioResetDevice = aRadioUrl.GetValue("gpio-reset-device"); + spiGpioIntDevice = mRadioUrl.GetValue("gpio-int-device"); + spiGpioResetDevice = mRadioUrl.GetValue("gpio-reset-device"); if (!spiGpioIntDevice || !spiGpioResetDevice) { DieNow(OT_EXIT_INVALID_ARGUMENTS); } - SuccessOrDie(aRadioUrl.ParseUint8("gpio-int-line", spiGpioIntLine)); - SuccessOrDie(aRadioUrl.ParseUint8("gpio-reset-line", spiGpioResetLine)); - VerifyOrDie(aRadioUrl.ParseUint8("spi-mode", spiMode) != OT_ERROR_INVALID_ARGS, OT_EXIT_INVALID_ARGUMENTS); - VerifyOrDie(aRadioUrl.ParseUint32("spi-speed", spiSpeed) != OT_ERROR_INVALID_ARGS, OT_EXIT_INVALID_ARGUMENTS); - VerifyOrDie(aRadioUrl.ParseUint32("spi-reset-delay", spiResetDelay) != OT_ERROR_INVALID_ARGS, + SuccessOrDie(mRadioUrl.ParseUint8("gpio-int-line", spiGpioIntLine)); + SuccessOrDie(mRadioUrl.ParseUint8("gpio-reset-line", spiGpioResetLine)); + VerifyOrDie(mRadioUrl.ParseUint8("spi-mode", spiMode) != OT_ERROR_INVALID_ARGS, OT_EXIT_INVALID_ARGUMENTS); + VerifyOrDie(mRadioUrl.ParseUint32("spi-speed", spiSpeed) != OT_ERROR_INVALID_ARGS, OT_EXIT_INVALID_ARGUMENTS); + VerifyOrDie(mRadioUrl.ParseUint32("spi-reset-delay", spiResetDelay) != OT_ERROR_INVALID_ARGS, OT_EXIT_INVALID_ARGUMENTS); - VerifyOrDie(aRadioUrl.ParseUint16("spi-cs-delay", spiCsDelay) != OT_ERROR_INVALID_ARGS, OT_EXIT_INVALID_ARGUMENTS); - VerifyOrDie(aRadioUrl.ParseUint8("spi-align-allowance", spiAlignAllowance) != OT_ERROR_INVALID_ARGS, + VerifyOrDie(mRadioUrl.ParseUint16("spi-cs-delay", spiCsDelay) != OT_ERROR_INVALID_ARGS, OT_EXIT_INVALID_ARGUMENTS); + VerifyOrDie(mRadioUrl.ParseUint8("spi-align-allowance", spiAlignAllowance) != OT_ERROR_INVALID_ARGS, OT_EXIT_INVALID_ARGUMENTS); - VerifyOrDie(aRadioUrl.ParseUint8("spi-small-packet", spiSmallPacketSize) != OT_ERROR_INVALID_ARGS, + VerifyOrDie(mRadioUrl.ParseUint8("spi-small-packet", spiSmallPacketSize) != OT_ERROR_INVALID_ARGS, OT_EXIT_INVALID_ARGUMENTS); VerifyOrDie(spiAlignAllowance <= kSpiAlignAllowanceMax, OT_EXIT_INVALID_ARGUMENTS); @@ -156,7 +157,11 @@ otError SpiInterface::Init(const Url::Url &aRadioUrl) } InitResetPin(spiGpioResetDevice, spiGpioResetLine); - InitSpiDev(aRadioUrl.GetPath(), spiMode, spiSpeed); + InitSpiDev(mRadioUrl.GetPath(), spiMode, spiSpeed); + + mReceiveFrameCallback = aCallback; + mReceiveFrameContext = aCallbackContext; + mRxFrameBuffer = &aFrameBuffer; return OT_ERROR_NONE; } @@ -182,6 +187,10 @@ void SpiInterface::Deinit(void) close(mIntGpioValueFd); mIntGpioValueFd = -1; } + + mReceiveFrameCallback = nullptr; + mReceiveFrameContext = nullptr; + mRxFrameBuffer = nullptr; } int SpiInterface::SetupGpioHandle(int aFd, uint8_t aLine, uint32_t aHandleFlags, const char *aLabel) @@ -382,6 +391,8 @@ otError SpiInterface::PushPullSpi(void) Spinel::SpiFrame txFrame(mSpiTxFrameBuffer); uint16_t skipAlignAllowanceLength; + VerifyOrExit((mReceiveFrameCallback != nullptr) && (mRxFrameBuffer != nullptr), error = OT_ERROR_INVALID_STATE); + if (mInterfaceMetrics.mTransferredValidFrameCount == 0) { // Set the reset flag to indicate to our slave that we are coming up from scratch. @@ -426,13 +437,13 @@ otError SpiInterface::PushPullSpi(void) txFrame.SetHeaderAcceptLen(spiTransferBytes); // Set skip length to make MultiFrameBuffer to reserve a space in front of the frame buffer. - SuccessOrExit(error = mRxFrameBuffer.SetSkipLength(kSpiFrameHeaderSize)); + SuccessOrExit(error = mRxFrameBuffer->SetSkipLength(kSpiFrameHeaderSize)); // Check whether the remaining frame buffer has enough space to store the data to be received. - VerifyOrExit(mRxFrameBuffer.GetFrameMaxLength() >= spiTransferBytes + mSpiAlignAllowance); + VerifyOrExit(mRxFrameBuffer->GetFrameMaxLength() >= spiTransferBytes + mSpiAlignAllowance); // Point to the start of the reserved buffer. - spiRxFrameBuffer = mRxFrameBuffer.GetFrame() - kSpiFrameHeaderSize; + spiRxFrameBuffer = mRxFrameBuffer->GetFrame() - kSpiFrameHeaderSize; // Set the total number of bytes to be transmitted. spiTransferBytes += kSpiFrameHeaderSize + mSpiAlignAllowance; @@ -534,9 +545,9 @@ otError SpiInterface::PushPullSpi(void) successfulExchanges++; // Set the skip length to skip align bytes and SPI frame header. - SuccessOrExit(error = mRxFrameBuffer.SetSkipLength(skipAlignAllowanceLength + kSpiFrameHeaderSize)); + SuccessOrExit(error = mRxFrameBuffer->SetSkipLength(skipAlignAllowanceLength + kSpiFrameHeaderSize)); // Set the received frame length. - SuccessOrExit(error = mRxFrameBuffer.SetLength(rxFrame.GetHeaderDataLen())); + SuccessOrExit(error = mRxFrameBuffer->SetLength(rxFrame.GetHeaderDataLen())); // Upper layer will free the frame buffer. discardRxFrame = false; @@ -583,7 +594,7 @@ otError SpiInterface::PushPullSpi(void) exit: if (discardRxFrame) { - mRxFrameBuffer.DiscardFrame(); + mRxFrameBuffer->DiscardFrame(); } return error; @@ -809,5 +820,4 @@ void SpiInterface::LogStats(void) } } // namespace Posix } // namespace ot - -#endif // OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI +#endif // OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE diff --git a/src/posix/platform/spi_interface.hpp b/src/posix/platform/spi_interface.hpp index cd0ee2033..095214a79 100644 --- a/src/posix/platform/spi_interface.hpp +++ b/src/posix/platform/spi_interface.hpp @@ -31,8 +31,8 @@ * This file includes definitions for the SPI interface to radio (RCP). */ -#ifndef POSIX_APP_SPI_INTERFACE_HPP_ -#define POSIX_APP_SPI_INTERFACE_HPP_ +#ifndef POSIX_PLATFORM_SPI_INTERFACE_HPP_ +#define POSIX_PLATFORM_SPI_INTERFACE_HPP_ #include "openthread-posix-config.h" @@ -57,12 +57,10 @@ public: /** * Initializes the object. * - * @param[in] aCallback A reference to a `Callback` object. - * @param[in] aCallbackContext The context pointer passed to the callback. - * @param[in] aFrameBuffer A reference to a `RxFrameBuffer` object. + * @param[in] aRadioUrl RadioUrl parsed from radio url. * */ - SpiInterface(ReceiveFrameCallback aCallback, void *aCallbackContext, RxFrameBuffer &aFrameBuffer); + SpiInterface(const Url::Url &aRadioUrl); /** * This destructor deinitializes the object. @@ -75,14 +73,16 @@ public: * * @note This method should be called before reading and sending spinel frames to the interface. * - * @param[in] aRadioUrl Arguments parsed from radio url. + * @param[in] aCallback Callback on frame received + * @param[in] aCallbackContext Callback context + * @param[in] aFrameBuffer A reference to a `RxFrameBuffer` object. * - * @retval OT_ERROR_NONE The interface is initialized successfully. - * @retval OT_ERROR_ALREADY The interface is already initialized. - * @retval OT_ERROR_INVALID_ARGS The UART device or executable cannot be found or failed to open/run. + * @retval OT_ERROR_NONE The interface is initialized successfully + * @retval OT_ERROR_ALREADY The interface is already initialized. + * @retval OT_ERROR_FAILED Failed to initialize the interface. * */ - otError Init(const Url::Url &aRadioUrl); + otError Init(ReceiveFrameCallback aCallback, void *aCallbackContext, RxFrameBuffer &aFrameBuffer); /** * Deinitializes the interface to the RCP. @@ -156,6 +156,20 @@ public: */ const otRcpInterfaceMetrics *GetRcpInterfaceMetrics(void) const { return &mInterfaceMetrics; } + /** + * Indicates whether or not the given interface matches this interface name. + * + * @param[in] aInterfaceName A pointer to the interface name. + * + * @retval TRUE The given interface name matches this interface name. + * @retval FALSE The given interface name doesn't match this interface name. + */ + static bool IsInterfaceNameMatch(const char *aInterfaceName) + { + static const char kInterfaceName[] = "spinel+spi"; + return (strncmp(aInterfaceName, kInterfaceName, strlen(kInterfaceName)) == 0); + } + private: void ResetStates(void); int SetupGpioHandle(int aFd, uint8_t aLine, uint32_t aHandleFlags, const char *aLabel); @@ -206,7 +220,8 @@ private: ReceiveFrameCallback mReceiveFrameCallback; void *mReceiveFrameContext; - RxFrameBuffer &mRxFrameBuffer; + RxFrameBuffer *mRxFrameBuffer; + const Url::Url &mRadioUrl; int mSpiDevFd; int mResetGpioValueFd; @@ -243,4 +258,4 @@ private: } // namespace Posix } // namespace ot -#endif // POSIX_APP_SPI_INTERFACE_HPP_ +#endif // POSIX_PLATFORM_SPI_INTERFACE_HPP_ diff --git a/src/posix/platform/trel.cpp b/src/posix/platform/trel.cpp index 2ddab4bdc..a925cb84c 100644 --- a/src/posix/platform/trel.cpp +++ b/src/posix/platform/trel.cpp @@ -498,6 +498,7 @@ void platformTrelInit(const char *aTrelUrl) if (aTrelUrl != nullptr) { ot::Posix::RadioUrl url(aTrelUrl); + strncpy(sInterfaceName, url.GetPath(), sizeof(sInterfaceName) - 1); sInterfaceName[sizeof(sInterfaceName) - 1] = '\0'; } diff --git a/src/posix/platform/vendor.cmake b/src/posix/platform/vendor.cmake index ad33f1192..4e0f0be9d 100644 --- a/src/posix/platform/vendor.cmake +++ b/src/posix/platform/vendor.cmake @@ -35,7 +35,7 @@ set(OT_POSIX_CONFIG_RCP_VENDOR_DEPS_PACKAGE "" CACHE STRING set(OT_POSIX_RCP_VENDOR_TARGET "" CACHE STRING "name of vendor extension CMake target to link with posix library") -if(OT_POSIX_CONFIG_RCP_BUS STREQUAL "VENDOR") +if(OT_POSIX_RCP_VENDOR_BUS) add_library(rcp-vendor-intf ${OT_POSIX_CONFIG_RCP_VENDOR_INTERFACE}) target_link_libraries(rcp-vendor-intf PUBLIC ot-posix-config) diff --git a/src/posix/platform/vendor_interface.hpp b/src/posix/platform/vendor_interface.hpp index 75bc794dc..4ee7a1ae8 100644 --- a/src/posix/platform/vendor_interface.hpp +++ b/src/posix/platform/vendor_interface.hpp @@ -54,14 +54,10 @@ public: /** * Initializes the object. * - * @param[in] aCallback A reference to a `Callback` object. - * @param[in] aCallbackContext The context pointer passed to the callback. - * @param[in] aFrameBuffer A reference to a `RxFrameBuffer` object. + * @param[in] aRadioUrl RadioUrl parsed from radio url. * */ - VendorInterface(Spinel::SpinelInterface::ReceiveFrameCallback aCallback, - void *aCallbackContext, - Spinel::SpinelInterface::RxFrameBuffer &aFrameBuffer); + VendorInterface(const Url::Url &aRadioUrl); /** * This destructor deinitializes the object. @@ -74,14 +70,16 @@ public: * * @note This method should be called before reading and sending spinel frames to the interface. * - * @param[in] aRadioUrl Arguments parsed from radio url. + * @param[in] aCallback Callback on frame received + * @param[in] aCallbackContext Callback context + * @param[in] aFrameBuffer A reference to a `RxFrameBuffer` object. * - * @retval OT_ERROR_NONE The interface is initialized successfully. - * @retval OT_ERROR_ALREADY The interface is already initialized. - * @retval OT_ERROR_INVALID_ARGS The UART device or executable cannot be found or failed to open/run. + * @retval OT_ERROR_NONE The interface is initialized successfully + * @retval OT_ERROR_ALREADY The interface is already initialized. + * @retval OT_ERROR_FAILED Failed to initialize the interface. * */ - otError Init(const Url::Url &aRadioUrl); + otError Init(ReceiveFrameCallback aCallback, void *aCallbackContext, RxFrameBuffer &aFrameBuffer); /** * Deinitializes the interface to the RCP. @@ -154,6 +152,20 @@ public: * */ const otRcpInterfaceMetrics *GetRcpInterfaceMetrics(void) const; + + /** + * Indicates whether or not the given interface matches this interface name. + * + * @param[in] aInterfaceName A pointer to the interface name. + * + * @retval TRUE The given interface name matches this interface name. + * @retval FALSE The given interface name doesn't match this interface name. + */ + static bool IsInterfaceNameMatch(const char *aInterfaceName) + { + static const char *kInterfaceName = OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_URL_PROTOCOL_NAME; + return (strncmp(aInterfaceName, kInterfaceName, strlen(kInterfaceName)) == 0); + } }; } // namespace Posix diff --git a/src/posix/platform/vendor_interface_example.cpp b/src/posix/platform/vendor_interface_example.cpp index 2b03c5dc3..da026b590 100644 --- a/src/posix/platform/vendor_interface_example.cpp +++ b/src/posix/platform/vendor_interface_example.cpp @@ -33,7 +33,7 @@ #include "openthread-posix-config.h" -#if OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_VENDOR +#if OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE #include "vendor_interface.hpp" #include "common/new.hpp" @@ -49,24 +49,15 @@ using ot::Spinel::SpinelInterface; class VendorInterfaceImpl { public: - explicit VendorInterfaceImpl(SpinelInterface::ReceiveFrameCallback aCallback, - void *aCallbackContext, - SpinelInterface::RxFrameBuffer &aFrameBuffer) - : mReceiveFrameCallback(aCallback) - , mReceiveFrameContext(aCallbackContext) - , mRxFrameBuffer(aFrameBuffer) + explicit VendorInterfaceImpl(const Url::Url &aRadioUrl) + : mRadioUrl(aRadioUrl) { - OT_UNUSED_VARIABLE(mReceiveFrameCallback); - OT_UNUSED_VARIABLE(mReceiveFrameContext); - OT_UNUSED_VARIABLE(mRxFrameBuffer); } // TODO: Add vendor code (add methods and/or member variables). private: - SpinelInterface::ReceiveFrameCallback mReceiveFrameCallback; - void *mReceiveFrameContext; - SpinelInterface::RxFrameBuffer &mRxFrameBuffer; + const Url::Url &mRadioUrl; }; // ---------------------------------------------------------------------------- @@ -75,19 +66,19 @@ private: static OT_DEFINE_ALIGNED_VAR(sVendorInterfaceImplRaw, sizeof(VendorInterfaceImpl), uint64_t); -VendorInterface::VendorInterface(SpinelInterface::ReceiveFrameCallback aCallback, - void *aCallbackContext, - SpinelInterface::RxFrameBuffer &aFrameBuffer) +VendorInterface::VendorInterface(const Url::Url &aRadioUrl) { - new (&sVendorInterfaceImplRaw) VendorInterfaceImpl(aCallback, aCallbackContext, aFrameBuffer); + new (&sVendorInterfaceImplRaw) VendorInterfaceImpl(aRadioUrl); OT_UNUSED_VARIABLE(sVendorInterfaceImplRaw); } VendorInterface::~VendorInterface(void) { Deinit(); } -otError VendorInterface::Init(const Url::Url &aRadioUrl) +otError VendorInterface::Init(ReceiveFrameCallback aCallback, void *aCallbackContext, RxFrameBuffer &aFrameBuffer) { - OT_UNUSED_VARIABLE(aRadioUrl); + OT_UNUSED_VARIABLE(aCallback); + OT_UNUSED_VARIABLE(aCallbackContext); + OT_UNUSED_VARIABLE(aFrameBuffer); // TODO: Implement vendor code here. @@ -150,4 +141,4 @@ const otRcpInterfaceMetrics *VendorInterface::GetRcpInterfaceMetrics(void) const } // namespace Posix } // namespace ot -#endif // OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_VENDOR +#endif // OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE diff --git a/tests/scripts/expect/cli-region.exp b/tests/scripts/expect/cli-region.exp index 3c75c40ab..16cef5a55 100755 --- a/tests/scripts/expect/cli-region.exp +++ b/tests/scripts/expect/cli-region.exp @@ -38,3 +38,4 @@ expect_line "Done" send "region\n" expect "US" expect_line "Done" +dispose_node 1 diff --git a/tests/toranj/openthread-core-toranj-config-posix.h b/tests/toranj/openthread-core-toranj-config-posix.h index 6b2f02876..95cf37ac3 100644 --- a/tests/toranj/openthread-core-toranj-config-posix.h +++ b/tests/toranj/openthread-core-toranj-config-posix.h @@ -45,6 +45,6 @@ #define OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE 1 -#define OPENTHREAD_POSIX_CONFIG_RCP_BUS OT_POSIX_RCP_BUS_UART +#define OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE 1 #endif /* OPENTHREAD_CORE_TORANJ_CONFIG_POSIX_H_ */ diff --git a/tests/unit/test_hdlc.cpp b/tests/unit/test_hdlc.cpp index 9a2fc0f70..c4c707cb1 100644 --- a/tests/unit/test_hdlc.cpp +++ b/tests/unit/test_hdlc.cpp @@ -454,13 +454,14 @@ void TestEncoderDecoder(void) Spinel::MultiFrameBuffer decoderBuffer; DecoderContext decoderContext; Hdlc::Encoder encoder(encoderBuffer); - Hdlc::Decoder decoder(decoderBuffer, ProcessDecodedFrame, &decoderContext); + Hdlc::Decoder decoder; uint8_t *frame; uint16_t length; uint8_t badShortFrame[3] = {kFlagSequence, 0xaa, kFlagSequence}; printf("Testing Hdlc::Encoder and Hdlc::Decoder"); + decoder.Init(decoderBuffer, ProcessDecodedFrame, &decoderContext); SuccessOrQuit(encoder.BeginFrame()); SuccessOrQuit(encoder.Encode(sOpenThreadText, sizeof(sOpenThreadText) - 1)); SuccessOrQuit(encoder.EndFrame()); @@ -602,10 +603,11 @@ void TestFuzzEncoderDecoder(void) Spinel::FrameBuffer decoderBuffer; DecoderContext decoderContext; Hdlc::Encoder encoder(encoderBuffer); - Hdlc::Decoder decoder(decoderBuffer, ProcessDecodedFrame, &decoderContext); + Hdlc::Decoder decoder; printf("Testing Hdlc::Encoder and Hdlc::Decoder with randomly generated frames"); + decoder.Init(decoderBuffer, ProcessDecodedFrame, &decoderContext); for (uint32_t iter = 0; iter < kFuzzTestIteration; iter++) { encoderBuffer.Clear();