aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhanglong Xia <zhanglongxia@google.com>2023-10-16 03:29:27 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2023-10-16 03:29:27 +0000
commitff54b9bee2fc06819bd459c9931fba2fd4becd97 (patch)
tree9dcd308137d1419abaa3cc3c6eb8f913d83d7245
parent0e548bab831ea05f78a37382a4aad82a815527af (diff)
parent79f3ce8ee3b502ed9b95e213a9c485beee068852 (diff)
downloadopenthread-ff54b9bee2fc06819bd459c9931fba2fd4becd97.tar.gz
Merge "[spinel] create spinel interface based on the radio url protocol (#9393)" into main
-rw-r--r--etc/cmake/options.cmake1
-rwxr-xr-xscript/check-posix-build-cmake4
-rw-r--r--src/lib/hdlc/hdlc.cpp25
-rw-r--r--src/lib/hdlc/hdlc.hpp10
-rw-r--r--src/lib/spinel/BUILD.gn3
-rw-r--r--src/lib/spinel/CMakeLists.txt1
-rw-r--r--src/lib/spinel/openthread-spinel-config.h12
-rw-r--r--src/lib/spinel/radio_spinel.cpp (renamed from src/lib/spinel/radio_spinel_impl.hpp)539
-rw-r--r--src/lib/spinel/radio_spinel.hpp128
-rw-r--r--src/lib/spinel/radio_spinel_metrics.h16
-rw-r--r--src/lib/spinel/spinel_interface.hpp29
-rw-r--r--src/lib/url/url.cpp8
-rw-r--r--src/lib/url/url.hpp2
-rw-r--r--src/ncp/ncp_hdlc.cpp2
-rw-r--r--src/posix/platform/CMakeLists.txt20
-rw-r--r--src/posix/platform/hdlc_interface.cpp61
-rw-r--r--src/posix/platform/hdlc_interface.hpp42
-rw-r--r--src/posix/platform/include/openthread/openthread-system.h16
-rw-r--r--src/posix/platform/openthread-posix-config.h47
-rw-r--r--src/posix/platform/radio.cpp257
-rw-r--r--src/posix/platform/radio.hpp51
-rw-r--r--src/posix/platform/radio_url.cpp48
-rw-r--r--src/posix/platform/spi_interface.cpp62
-rw-r--r--src/posix/platform/spi_interface.hpp41
-rw-r--r--src/posix/platform/trel.cpp1
-rw-r--r--src/posix/platform/vendor.cmake2
-rw-r--r--src/posix/platform/vendor_interface.hpp34
-rw-r--r--src/posix/platform/vendor_interface_example.cpp31
-rwxr-xr-xtests/scripts/expect/cli-region.exp1
-rw-r--r--tests/toranj/openthread-core-toranj-config-posix.h2
-rw-r--r--tests/unit/test_hdlc.cpp6
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();