diff options
author | Zhanglong Xia <zhanglongxia@google.com> | 2023-10-16 03:29:27 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2023-10-16 03:29:27 +0000 |
commit | ff54b9bee2fc06819bd459c9931fba2fd4becd97 (patch) | |
tree | 9dcd308137d1419abaa3cc3c6eb8f913d83d7245 | |
parent | 0e548bab831ea05f78a37382a4aad82a815527af (diff) | |
parent | 79f3ce8ee3b502ed9b95e213a9c485beee068852 (diff) | |
download | openthread-ff54b9bee2fc06819bd459c9931fba2fd4becd97.tar.gz |
Merge "[spinel] create spinel interface based on the radio url protocol (#9393)" into main
31 files changed, 823 insertions, 679 deletions
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 @@ -141,6 +141,12 @@ public: typedef void (*FrameHandler)(void *aContext, otError aError); /** + * Initializes the object. + * + */ + Decoder(void); + + /** * Initializes the decoder. * * @param[in] aFrameWritePointer The `FrameWritePointer` used by `Decoder` to write the decoded frames. @@ -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 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 <assert.h> #include <errno.h> #include <stdarg.h> @@ -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<otError>(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 <typename InterfaceType> void RadioSpinel<InterfaceType>::HandleReceivedFrame(void *aContext) -{ - static_cast<RadioSpinel *>(aContext)->HandleReceivedFrame(); -} - -template <typename InterfaceType> -RadioSpinel<InterfaceType>::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<InterfaceType>::RadioSpinel(void) memset(&mRadioSpinelMetrics, 0, sizeof(mRadioSpinelMetrics)); } -template <typename InterfaceType> -void RadioSpinel<InterfaceType>::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<InterfaceType>::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 <typename InterfaceType> void RadioSpinel<InterfaceType>::ResetRcp(bool aResetRadio) +void RadioSpinel::ResetRcp(bool aResetRadio) { bool hardwareReset; bool resetDone = false; @@ -256,7 +147,7 @@ template <typename InterfaceType> void RadioSpinel<InterfaceType>::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 <typename InterfaceType> otError RadioSpinel<InterfaceType>::CheckSpinelVersion(void) +otError RadioSpinel::CheckSpinelVersion(void) { otError error = OT_ERROR_NONE; unsigned int versionMajor; @@ -304,8 +195,7 @@ exit: return error; } -template <typename InterfaceType> -bool RadioSpinel<InterfaceType>::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<InterfaceType>::IsRcp(bool &aSupportsRcpApiVersion, bool &aSupp return isRcp; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::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 <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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 <typename InterfaceType> void RadioSpinel<InterfaceType>::Deinit(void) +void RadioSpinel::Deinit(void) { - mSpinelInterface.Deinit(); + if (mSpinelInterface != nullptr) + { + mSpinelInterface->Deinit(); + mSpinelInterface = nullptr; + } + // This allows implementing pseudo reset. new (this) RadioSpinel(); } -template <typename InterfaceType> void RadioSpinel<InterfaceType>::HandleReceivedFrame(void) +void RadioSpinel::HandleReceivedFrame(void *aContext) { static_cast<RadioSpinel *>(aContext)->HandleReceivedFrame(); } + +void RadioSpinel::HandleReceivedFrame(void) { otError error = OT_ERROR_NONE; uint8_t header; @@ -490,8 +386,7 @@ exit: UpdateParseErrorCount(error); } -template <typename InterfaceType> -void RadioSpinel<InterfaceType>::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 <typename InterfaceType> -void RadioSpinel<InterfaceType>::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 <typename InterfaceType> -void RadioSpinel<InterfaceType>::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 <typename InterfaceType> -void RadioSpinel<InterfaceType>::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 <typename InterfaceType> -void RadioSpinel<InterfaceType>::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 <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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 <typename InterfaceType> void RadioSpinel<InterfaceType>::ProcessFrameQueue(void) +void RadioSpinel::ProcessFrameQueue(void) { uint8_t *frame = nullptr; uint16_t length; @@ -879,7 +769,7 @@ template <typename InterfaceType> void RadioSpinel<InterfaceType>::ProcessFrameQ mRxFrameBuffer.ClearSavedFrames(); } -template <typename InterfaceType> void RadioSpinel<InterfaceType>::RadioReceive(void) +void RadioSpinel::RadioReceive(void) { if (!mIsPromiscuous) { @@ -911,8 +801,7 @@ exit: return; } -template <typename InterfaceType> -void RadioSpinel<InterfaceType>::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<InterfaceType>::TransmitDone(otRadioFrame *aFrame, otRadioFrame } } -template <typename InterfaceType> void RadioSpinel<InterfaceType>::ProcessRadioStateMachine(void) +void RadioSpinel::ProcessRadioStateMachine(void) { if (mState == kStateTransmitDone) { @@ -937,13 +826,13 @@ template <typename InterfaceType> void RadioSpinel<InterfaceType>::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 <typename InterfaceType> void RadioSpinel<InterfaceType>::Process(const void *aContext) +void RadioSpinel::Process(const void *aContext) { if (mRxFrameBuffer.HasSavedFrame()) { @@ -951,7 +840,7 @@ template <typename InterfaceType> void RadioSpinel<InterfaceType>::Process(const RecoverFromRcpFailure(); } - GetSpinelInterface().Process(aContext); + mSpinelInterface->Process(aContext); RecoverFromRcpFailure(); if (mRxFrameBuffer.HasSavedFrame()) @@ -965,7 +854,7 @@ template <typename InterfaceType> void RadioSpinel<InterfaceType>::Process(const CalcRcpTimeOffset(); } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::SetPromiscuous(bool aEnable) +otError RadioSpinel::SetPromiscuous(bool aEnable) { otError error; @@ -977,7 +866,7 @@ exit: return error; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::SetShortAddress(uint16_t aAddress) +otError RadioSpinel::SetShortAddress(uint16_t aAddress) { otError error = OT_ERROR_NONE; @@ -989,12 +878,11 @@ exit: return error; } -template <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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 <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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 <typename InterfaceType> otError RadioSpinel<InterfaceType>::GetIeeeEui64(uint8_t *aIeeeEui64) +otError RadioSpinel::GetIeeeEui64(uint8_t *aIeeeEui64) { memcpy(aIeeeEui64, mIeeeEui64.m8, sizeof(mIeeeEui64.m8)); return OT_ERROR_NONE; } -template <typename InterfaceType> -otError RadioSpinel<InterfaceType>::SetExtendedAddress(const otExtAddress &aExtAddress) +otError RadioSpinel::SetExtendedAddress(const otExtAddress &aExtAddress) { otError error; @@ -1068,7 +953,7 @@ exit: return error; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::SetPanId(uint16_t aPanId) +otError RadioSpinel::SetPanId(uint16_t aPanId) { otError error = OT_ERROR_NONE; @@ -1080,12 +965,12 @@ exit: return error; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::EnableSrcMatch(bool aEnable) +otError RadioSpinel::EnableSrcMatch(bool aEnable) { return Set(SPINEL_PROP_MAC_SRC_MATCH_ENABLED, SPINEL_DATATYPE_BOOL_S, aEnable); } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::AddSrcMatchShortEntry(uint16_t aShortAddress) +otError RadioSpinel::AddSrcMatchShortEntry(uint16_t aShortAddress) { otError error; @@ -1109,8 +994,7 @@ exit: return error; } -template <typename InterfaceType> -otError RadioSpinel<InterfaceType>::AddSrcMatchExtEntry(const otExtAddress &aExtAddress) +otError RadioSpinel::AddSrcMatchExtEntry(const otExtAddress &aExtAddress) { otError error; @@ -1135,7 +1019,7 @@ exit: return error; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::ClearSrcMatchShortEntry(uint16_t aShortAddress) +otError RadioSpinel::ClearSrcMatchShortEntry(uint16_t aShortAddress) { otError error; @@ -1157,8 +1041,7 @@ exit: return error; } -template <typename InterfaceType> -otError RadioSpinel<InterfaceType>::ClearSrcMatchExtEntry(const otExtAddress &aExtAddress) +otError RadioSpinel::ClearSrcMatchExtEntry(const otExtAddress &aExtAddress) { otError error; @@ -1181,7 +1064,7 @@ exit: return error; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::ClearSrcMatchShortEntries(void) +otError RadioSpinel::ClearSrcMatchShortEntries(void) { otError error; @@ -1195,7 +1078,7 @@ exit: return error; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::ClearSrcMatchExtEntries(void) +otError RadioSpinel::ClearSrcMatchExtEntries(void) { otError error; @@ -1209,7 +1092,7 @@ exit: return error; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::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 <typename InterfaceType> otError RadioSpinel<InterfaceType>::GetTransmi return error; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::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 <typename InterfaceType> otError RadioSpinel<InterfaceType>::GetCcaEner return error; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::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 <typename InterfaceType> otError RadioSpinel<InterfaceType>::GetFemLnaG return error; } -template <typename InterfaceType> int8_t RadioSpinel<InterfaceType>::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 <typename InterfaceType> int8_t RadioSpinel<InterfaceType>::GetRssi(voi } #if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::SetCoexEnabled(bool aEnabled) +otError RadioSpinel::SetCoexEnabled(bool aEnabled) { otError error; @@ -1258,7 +1141,7 @@ exit: return error; } -template <typename InterfaceType> bool RadioSpinel<InterfaceType>::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 <typename InterfaceType> bool RadioSpinel<InterfaceType>::IsCoexEnabled return enabled; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::GetCoexMetrics(otRadioCoexMetrics &aCoexMetrics) +otError RadioSpinel::GetCoexMetrics(otRadioCoexMetrics &aCoexMetrics) { otError error; @@ -1307,7 +1190,7 @@ template <typename InterfaceType> otError RadioSpinel<InterfaceType>::GetCoexMet } #endif -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::SetTransmitPower(int8_t aPower) +otError RadioSpinel::SetTransmitPower(int8_t aPower) { otError error; @@ -1323,7 +1206,7 @@ exit: return error; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::SetCcaEnergyDetectThreshold(int8_t aThreshold) +otError RadioSpinel::SetCcaEnergyDetectThreshold(int8_t aThreshold) { otError error; @@ -1339,7 +1222,7 @@ exit: return error; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::SetFemLnaGain(int8_t aGain) +otError RadioSpinel::SetFemLnaGain(int8_t aGain) { otError error; @@ -1355,8 +1238,7 @@ exit: return error; } -template <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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 <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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<InterfaceType>::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 <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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<InterfaceType>::GetWithParam(spinel_prop_key_t aKey, return error; } -template <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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<InterfaceType>::Set(spinel_prop_key_t aKey, const char *aFor return error; } -template <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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<InterfaceType>::Insert(spinel_prop_key_t aKey, const char *a return error; } -template <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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<InterfaceType>::Remove(spinel_prop_key_t aKey, const char *a return error; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::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 <typename InterfaceType> otError RadioSpinel<InterfaceType>::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 <typename InterfaceType> spinel_tid_t RadioSpinel<InterfaceType>::GetNextTid(void) +spinel_tid_t RadioSpinel::GetNextTid(void) { spinel_tid_t tid = mCmdNextTid; @@ -1551,7 +1428,7 @@ exit: return tid; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::SendReset(uint8_t aResetType) +otError RadioSpinel::SendReset(uint8_t aResetType) { otError error = OT_ERROR_NONE; uint8_t buffer[kMaxSpinelFrame]; @@ -1563,19 +1440,18 @@ template <typename InterfaceType> otError RadioSpinel<InterfaceType>::SendReset( VerifyOrExit(packed > 0 && static_cast<size_t>(packed) <= sizeof(buffer), error = OT_ERROR_NO_BUFS); - SuccessOrExit(error = mSpinelInterface.SendFrame(buffer, static_cast<uint16_t>(packed))); + SuccessOrExit(error = mSpinelInterface->SendFrame(buffer, static_cast<uint16_t>(packed))); LogSpinelFrame(buffer, static_cast<uint16_t>(packed), true); exit: return error; } -template <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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<InterfaceType>::SendCommand(uint32_t aCommand, offset += static_cast<uint16_t>(packed); } - SuccessOrExit(error = mSpinelInterface.SendFrame(buffer, offset)); + SuccessOrExit(error = mSpinelInterface->SendFrame(buffer, offset)); LogSpinelFrame(buffer, offset, true); exit: return error; } -template <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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 <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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<InterfaceType>::Request(uint32_t aCommand, spinel_prop_key_t return status; } -template <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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<InterfaceType>::RequestWithPropertyFormat(const char * return error; } -template <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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<InterfaceType>::RequestWithPropertyFormatV(const char return error; } -template <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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<InterfaceType>::RequestWithExpectedCommandV(uint32_t return error; } -template <typename InterfaceType> -void RadioSpinel<InterfaceType>::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 <typename InterfaceType> otError RadioSpinel<InterfaceType>::Transmit(otRadioFrame &aFrame) +otError RadioSpinel::Transmit(otRadioFrame &aFrame) { otError error = OT_ERROR_INVALID_STATE; @@ -1802,7 +1669,7 @@ template <typename InterfaceType> otError RadioSpinel<InterfaceType>::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 <typename InterfaceType> otError RadioSpinel<InterfaceType>::Receive(uint8_t aChannel) +otError RadioSpinel::Receive(uint8_t aChannel) { otError error = OT_ERROR_NONE; @@ -1841,7 +1708,7 @@ exit: return error; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::Sleep(void) +otError RadioSpinel::Sleep(void) { otError error = OT_ERROR_NONE; @@ -1866,7 +1733,7 @@ exit: return error; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::Enable(otInstance *aInstance) +otError RadioSpinel::Enable(otInstance *aInstance) { otError error = OT_ERROR_NONE; @@ -1891,7 +1758,7 @@ exit: return error; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::Disable(void) +otError RadioSpinel::Disable(void) { otError error = OT_ERROR_NONE; @@ -1907,8 +1774,7 @@ exit: } #if OPENTHREAD_CONFIG_DIAG_ENABLE -template <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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<InterfaceType>::PlatDiagProcess(const char *aString, char *a } #endif -template <typename InterfaceType> uint32_t RadioSpinel<InterfaceType>::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 <typename InterfaceType> otRadioState RadioSpinel<InterfaceType>::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 <typename InterfaceType> otRadioState RadioSpinel<InterfaceType>::GetSt return sOtRadioStateMap[mState]; } -template <typename InterfaceType> void RadioSpinel<InterfaceType>::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 <typename InterfaceType> void RadioSpinel<InterfaceType>::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 <typename InterfaceType> uint64_t RadioSpinel<InterfaceType>::GetNow(void) -{ - return (mIsTimeSynced) ? (otPlatTimeGet() + mRadioTimeOffset) : UINT64_MAX; -} +uint64_t RadioSpinel::GetNow(void) { return (mIsTimeSynced) ? (otPlatTimeGet() + mRadioTimeOffset) : UINT64_MAX; } -template <typename InterfaceType> uint32_t RadioSpinel<InterfaceType>::GetBusSpeed(void) const -{ - return mSpinelInterface.GetBusSpeed(); -} +uint32_t RadioSpinel::GetBusSpeed(void) const { return mSpinelInterface->GetBusSpeed(); } -template <typename InterfaceType> void RadioSpinel<InterfaceType>::HandleRcpUnexpectedReset(spinel_status_t aStatus) +void RadioSpinel::HandleRcpUnexpectedReset(spinel_status_t aStatus) { OT_UNUSED_VARIABLE(aStatus); @@ -2054,7 +1914,7 @@ template <typename InterfaceType> void RadioSpinel<InterfaceType>::HandleRcpUnex #endif } -template <typename InterfaceType> void RadioSpinel<InterfaceType>::HandleRcpTimeout(void) +void RadioSpinel::HandleRcpTimeout(void) { mRadioSpinelMetrics.mRcpTimeoutCount++; @@ -2073,7 +1933,7 @@ template <typename InterfaceType> void RadioSpinel<InterfaceType>::HandleRcpTime #endif } -template <typename InterfaceType> void RadioSpinel<InterfaceType>::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 <typename InterfaceType> void RadioSpinel<InterfaceType>::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 <typename InterfaceType> void RadioSpinel<InterfaceType>::RestoreProper } #endif // OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0 -template <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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 <typename InterfaceType> otError RadioSpinel<InterfaceType>::SetRadioRegion(uint16_t aRegionCode) +otError RadioSpinel::SetRadioRegion(uint16_t aRegionCode) { otError error; @@ -2265,7 +2124,7 @@ template <typename InterfaceType> otError RadioSpinel<InterfaceType>::SetRadioRe return error; } -template <typename InterfaceType> otError RadioSpinel<InterfaceType>::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 <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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<InterfaceType>::ConfigureEnhAckProbing(otLinkMetrics #endif #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE -template <typename InterfaceType> uint8_t RadioSpinel<InterfaceType>::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 <typename InterfaceType> uint8_t RadioSpinel<InterfaceType>::GetCslAccu #endif #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE -template <typename InterfaceType> uint8_t RadioSpinel<InterfaceType>::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 <typename InterfaceType> uint8_t RadioSpinel<InterfaceType>::GetCslUnce #endif #if OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE -template <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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 <typename InterfaceType> otError RadioSpinel<InterfaceType>::ClearCalibratedPowers(void) -{ - return Set(SPINEL_PROP_PHY_CALIBRATED_POWER, nullptr); -} +otError RadioSpinel::ClearCalibratedPowers(void) { return Set(SPINEL_PROP_PHY_CALIBRATED_POWER, nullptr); } -template <typename InterfaceType> -otError RadioSpinel<InterfaceType>::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 <typename InterfaceType> -uint32_t RadioSpinel<InterfaceType>::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<InterfaceType>::Snprintf(char *aDest, uint32_t aSize, const return (len < 0) ? 0 : Min(static_cast<uint32_t>(len), aSize - 1); } -template <typename InterfaceType> -void RadioSpinel<InterfaceType>::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<InterfaceType>::LogSpinelFrame(const uint8_t *aFrame, uint16_t VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE); start += Snprintf(start, static_cast<uint32_t>(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<InterfaceType>::LogSpinelFrame(const uint8_t *aFrame, uint16_t start += Snprintf(start, static_cast<uint32_t>(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<InterfaceType>::LogSpinelFrame(const uint8_t *aFrame, uint16_t VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE); start += Snprintf(start, static_cast<uint32_t>(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<uint32_t>(end - start), "%u ", channels[i]); } @@ -2978,7 +2831,7 @@ void RadioSpinel<InterfaceType>::LogSpinelFrame(const uint8_t *aFrame, uint16_t start += Snprintf(start, static_cast<uint32_t>(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<uint32_t>(end - start), "%02x", rawPowerSetting[i]); } @@ -3000,16 +2853,102 @@ void RadioSpinel<InterfaceType>::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<otError>(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 <openthread/platform/radio.h> #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 <typename InterfaceType> class RadioSpinel +class RadioSpinel { public: /** @@ -111,13 +61,20 @@ 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. @@ -140,12 +142,27 @@ 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. * */ 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<useconds_t>(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 @@ -86,22 +86,6 @@ typedef struct otPlatformConfig } 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 @@ -86,33 +86,54 @@ #endif /** - * RCP bus UART. + * @def OPENTHREAD_POSIX_CONFIG_RCP_BUS * - * @note This value is also for simulated UART bus. + * This setting configures what type of RCP bus to use. * */ -#define OT_POSIX_RCP_BUS_UART 1 +#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 /** - * RCP bus SPI. + * @def OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE + * + * Define as 1 to enable the spinel HDLC interface. * */ -#define OT_POSIX_RCP_BUS_SPI 2 +#ifndef OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE +#define OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE 1 +#endif /** - * RCP bus defined by vendors. + * @def OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE + * + * Define as 1 to enable the spinel SPI interface. * */ -#define OT_POSIX_RCP_BUS_VENDOR 3 +#ifndef OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE +#define OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE 0 +#endif /** - * @def OPENTHREAD_POSIX_CONFIG_RCP_BUS + * @def OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE * - * This setting configures what type of RCP bus to use. + * 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_RCP_BUS -#define OPENTHREAD_POSIX_CONFIG_RCP_BUS OT_POSIX_RCP_BUS_UART +#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 <string.h> #include <openthread/logging.h> +#include <openthread/platform/diag.h> #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<ot::Posix::HdlcInterface> sRadioSpinel; -#elif OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI -#include "spi_interface.hpp" - -static ot::Spinel::RadioSpinel<ot::Posix::SpiInterface> sRadioSpinel; -#elif OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_VENDOR -#include "vendor_interface.hpp" - -static ot::Spinel::RadioSpinel<ot::Posix::VendorInterface> 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<int8_t>(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<size_t>(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<bool>(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<int>(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. * + */ + Radio(void); + + /** + * Initialize the Thread radio. + * * @param[in] aUrl A pointer to the null-terminated URL. * */ - explicit Radio(const char *aUrl); + void Init(const char *aUrl); /** - * Initialize the Thread radio. + * Acts as an accessor to the spinel interface instance used by the radio. + * + * @returns A reference to the radio's spinel interface instance. * */ - void Init(void); + Spinel::SpinelInterface &GetSpinelInterface(void) + { + OT_ASSERT(mSpinelInterface != nullptr); + return *mSpinelInterface; + } /** - * Acts as an accessor to the spinel instance used by the radio. + * Acts as an accessor to the radio spinel instance used by the radio. * - * @returns A pointer to the radio's spinel interface instance. + * @returns A reference to the radio spinel instance. * */ - static void *GetSpinelInstance(void); + 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 <sys/types.h> #include <sys/ucontext.h> -#if OPENTHREAD_POSIX_CONFIG_RCP_BUS == OT_POSIX_RCP_BUS_SPI +#if OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE #include <linux/gpio.h> #include <linux/ioctl.h> #include <linux/spi/spidev.h> @@ -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<kBufferSize> 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<kBufferSize> 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(); |