mirror of
https://github.com/espressif/openthread.git
synced 2026-08-11 05:07:47 +00:00
[spinel] create spinel interface based on the radio url protocol (#9393)
The posix platform is able to support the HDLC, SPI and vendor spinel interfaces, but the spinel interface type can't be changed dynamically. It is inconvenient to use different spinel interfaces for Thread stack in Android. This commit enables the posix platform to support the HDLC, SPI and vendor interface at the same time, and the final spinel interface type is determined by the radio url protocol. Some other changes: 1. Not use CRTP style for the radio spinel. 2. Deprecate the OT_POSIX_CONFIG_RCP_BUS and OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL.
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -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 "$@"
|
||||
|
||||
+16
-9
@@ -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;
|
||||
}
|
||||
|
||||
@@ -140,6 +140,12 @@ public:
|
||||
*/
|
||||
typedef void (*FrameHandler)(void *aContext, otError aError);
|
||||
|
||||
/**
|
||||
* Initializes the object.
|
||||
*
|
||||
*/
|
||||
Decoder(void);
|
||||
|
||||
/**
|
||||
* Initializes the decoder.
|
||||
*
|
||||
@@ -148,7 +154,7 @@ public:
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
*/
|
||||
Decoder(Spinel::FrameWritePointer &aFrameWritePointer, FrameHandler aFrameHandler, void *aContext);
|
||||
void Init(Spinel::FrameWritePointer &aFrameWritePointer, FrameHandler aFrameHandler, void *aContext);
|
||||
|
||||
/**
|
||||
* Feeds a block of data into the decoder.
|
||||
@@ -179,7 +185,7 @@ private:
|
||||
};
|
||||
|
||||
State mState;
|
||||
Spinel::FrameWritePointer &mWritePointer;
|
||||
Spinel::FrameWritePointer *mWritePointer;
|
||||
FrameHandler mFrameHandler;
|
||||
void *mContext;
|
||||
uint16_t mFcs;
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -61,6 +61,7 @@ set(COMMON_INCLUDES
|
||||
)
|
||||
|
||||
set(COMMON_SOURCES
|
||||
radio_spinel.cpp
|
||||
spinel.c
|
||||
spinel_buffer.cpp
|
||||
spinel_decoder.cpp
|
||||
|
||||
@@ -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_
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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:
|
||||
/**
|
||||
@@ -110,14 +60,21 @@ public:
|
||||
*/
|
||||
RadioSpinel(void);
|
||||
|
||||
/**
|
||||
* Deinitializes the spinel based OpenThread transceiver.
|
||||
*
|
||||
*/
|
||||
~RadioSpinel(void) { Deinit(); }
|
||||
|
||||
/**
|
||||
* Initialize this radio transceiver.
|
||||
*
|
||||
* @param[in] aSpinelInterface A reference to the Spinel interface.
|
||||
* @param[in] aResetRadio TRUE to reset on init, FALSE to not reset on init.
|
||||
* @param[in] aSkipRcpCompatibilityCheck TRUE to skip RCP compatibility check, FALSE to perform the check.
|
||||
*
|
||||
*/
|
||||
void Init(bool aResetRadio, bool aSkipRcpCompatibilityCheck);
|
||||
void Init(SpinelInterface &aSpinelInterface, bool aResetRadio, bool aSkipRcpCompatibilityCheck);
|
||||
|
||||
/**
|
||||
* Deinitialize this radio transceiver.
|
||||
@@ -181,7 +138,7 @@ public:
|
||||
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
|
||||
*
|
||||
*/
|
||||
otError SetExtendedAddress(const otExtAddress &aAddress);
|
||||
otError SetExtendedAddress(const otExtAddress &aExtAddress);
|
||||
|
||||
/**
|
||||
* Sets the PAN ID for address filtering.
|
||||
@@ -560,14 +517,6 @@ public:
|
||||
*/
|
||||
void Process(const void *aContext);
|
||||
|
||||
/**
|
||||
* Returns the underlying spinel interface.
|
||||
*
|
||||
* @returns The underlying spinel interface.
|
||||
*
|
||||
*/
|
||||
InterfaceType &GetSpinelInterface(void) { return mSpinelInterface; }
|
||||
|
||||
#if OPENTHREAD_CONFIG_DIAG_ENABLE
|
||||
/**
|
||||
* Enables/disables the factory diagnostics mode.
|
||||
@@ -695,9 +644,9 @@ public:
|
||||
* @retval OT_ERROR_NOT_FOUND The Initiator indicated by @p aShortAddress is not found when trying to clear.
|
||||
* @retval OT_ERROR_NO_BUFS No more Initiator can be supported.
|
||||
*/
|
||||
otError ConfigureEnhAckProbing(otLinkMetrics aLinkMetrics,
|
||||
const otShortAddress aShortAddress,
|
||||
const otExtAddress &aExtAddress);
|
||||
otError ConfigureEnhAckProbing(otLinkMetrics aLinkMetrics,
|
||||
const otShortAddress &aShortAddress,
|
||||
const otExtAddress &aExtAddress);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
|
||||
@@ -772,13 +721,13 @@ public:
|
||||
* Sets the max transmit power.
|
||||
*
|
||||
* @param[in] aChannel The radio channel.
|
||||
* @param[in] aPower The max transmit power in dBm.
|
||||
* @param[in] aMaxPower The max transmit power in dBm.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully set the max transmit power.
|
||||
* @retval OT_ERROR_INVALID_ARGS Channel is not in valid range.
|
||||
*
|
||||
*/
|
||||
otError SetChannelMaxTransmitPower(uint8_t aChannel, int8_t aPower);
|
||||
otError SetChannelMaxTransmitPower(uint8_t aChannel, int8_t aMaxPower);
|
||||
|
||||
/**
|
||||
* Tries to retrieve a spinel property from OpenThread transceiver.
|
||||
@@ -924,6 +873,28 @@ public:
|
||||
otError SetChannelTargetPower(uint8_t aChannel, int16_t aTargetPower);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Convert the Spinel status code to OpenThread error code.
|
||||
*
|
||||
* @param[in] aStatus The Spinel status code.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The operation has completed successfully.
|
||||
* @retval OT_ERROR_DROP The packet was dropped.
|
||||
* @retval OT_ERROR_NO_BUFS The operation has been prevented due to memory pressure.
|
||||
* @retval OT_ERROR_BUSY The device is currently performing a mutuallyexclusive operation.
|
||||
* @retval OT_ERROR_PARSE An error has occurred while parsing the command.
|
||||
* @retval OT_ERROR_INVALID_ARGS An argument to the given operation is invalid.
|
||||
* @retval OT_ERROR_NOT_IMPLEMENTED The given operation has not been implemented.
|
||||
* @retval OT_ERROR_INVALID_STATE The given operation is invalid for the current state of the device.
|
||||
* @retval OT_ERROR_NO_ACK The packet was not acknowledged.
|
||||
* @retval OT_ERROR_NOT_FOUND The given property is not recognized.
|
||||
* @retval OT_ERROR_FAILED The given operation has failed for some undefined reason.
|
||||
* @retval OT_ERROR_CHANNEL_ACCESS_FAILURE The packet was not sent due to a CCA failure.
|
||||
* @retval OT_ERROR_ALREADY The operation is already in progress or the property was already set
|
||||
* to the given value.
|
||||
*/
|
||||
static otError SpinelStatusToOtError(spinel_status_t aStatus);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
@@ -943,6 +914,12 @@ private:
|
||||
kStateTransmitDone, ///< Radio indicated frame transmission is done.
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kUsPerMs = 1000, ///< Microseconds per millisecond.
|
||||
kTxWaitUs = 5000000, ///< Maximum time of waiting for `TransmitDone` event, in microseconds.
|
||||
};
|
||||
|
||||
typedef otError (RadioSpinel::*ResponseHandler)(const uint8_t *aBuffer, uint16_t aLength);
|
||||
|
||||
static void HandleReceivedFrame(void *aContext);
|
||||
@@ -950,7 +927,7 @@ private:
|
||||
void ResetRcp(bool aResetRadio);
|
||||
otError CheckSpinelVersion(void);
|
||||
otError CheckRadioCapabilities(void);
|
||||
otError CheckRcpApiVersion(bool aSupportsRcpApiVersion, bool aSupportsMinHostRcpApiVersion);
|
||||
otError CheckRcpApiVersion(bool aSupportsRcpApiVersion, bool aSupportsRcpMinHostApiVersion);
|
||||
|
||||
/**
|
||||
* Triggers a state transfer of the state machine.
|
||||
@@ -1009,7 +986,7 @@ private:
|
||||
}
|
||||
|
||||
void HandleNotification(SpinelInterface::RxFrameBuffer &aFrameBuffer);
|
||||
void HandleNotification(const uint8_t *aBuffer, uint16_t aLength);
|
||||
void HandleNotification(const uint8_t *aFrame, uint16_t aLength);
|
||||
void HandleValueIs(spinel_prop_key_t aKey, const uint8_t *aBuffer, uint16_t aLength);
|
||||
|
||||
void HandleResponse(const uint8_t *aBuffer, uint16_t aLength);
|
||||
@@ -1037,11 +1014,12 @@ private:
|
||||
uint32_t Snprintf(char *aDest, uint32_t aSize, const char *aFormat, ...);
|
||||
void LogSpinelFrame(const uint8_t *aFrame, uint16_t aLength, bool aTx);
|
||||
|
||||
void LogIfFail(const char *aText, otError aError);
|
||||
|
||||
otInstance *mInstance;
|
||||
|
||||
SpinelInterface::RxFrameBuffer mRxFrameBuffer;
|
||||
|
||||
InterfaceType mSpinelInterface;
|
||||
SpinelInterface *mSpinelInterface;
|
||||
|
||||
uint16_t mCmdTidsInUse; ///< Used transaction ids.
|
||||
spinel_tid_t mCmdNextTid; ///< Next available transaction id.
|
||||
@@ -1129,6 +1107,4 @@ private:
|
||||
} // namespace Spinel
|
||||
} // namespace ot
|
||||
|
||||
#include "radio_spinel_impl.hpp"
|
||||
|
||||
#endif // RADIO_SPINEL_HPP_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
#define SPINEL_SPINEL_INTERFACE_HPP_
|
||||
|
||||
#include "lib/spinel/multi_frame_buffer.hpp"
|
||||
#include "lib/spinel/radio_spinel_metrics.h"
|
||||
#include "lib/spinel/spinel.h"
|
||||
#include "lib/url/url.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Spinel {
|
||||
@@ -66,14 +66,16 @@ public:
|
||||
*
|
||||
* @note This method should be called before reading and sending spinel frames to the interface.
|
||||
*
|
||||
* @param[in] aRadioUrl RadioUrl parsed from radio url.
|
||||
* @param[in] aCallback Callback on frame received
|
||||
* @param[in] aCallbackContext Callback context
|
||||
* @param[in] aFrameBuffer A reference to a `RxFrameBuffer` object.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The interface is initialized successfully
|
||||
* @retval OT_ERROR_ALREADY The interface is already initialized.
|
||||
* @retval OT_ERROR_INVALID_ARGS The UART device or executable cannot be found or failed to open/run.
|
||||
* @retval OT_ERROR_NONE The interface is initialized successfully
|
||||
* @retval OT_ERROR_ALREADY The interface is already initialized.
|
||||
* @retval OT_ERROR_FAILED Failed to initialize the interface.
|
||||
*
|
||||
*/
|
||||
virtual otError Init(const Url::Url &aRadioUrl) = 0;
|
||||
virtual otError Init(ReceiveFrameCallback aCallback, void *aCallbackContext, RxFrameBuffer &aFrameBuffer) = 0;
|
||||
|
||||
/**
|
||||
* Deinitializes the interface to the RCP.
|
||||
@@ -139,6 +141,14 @@ public:
|
||||
*/
|
||||
virtual otError HardwareReset(void) = 0;
|
||||
|
||||
/**
|
||||
* Returns the RCP interface metrics.
|
||||
*
|
||||
* @returns The RCP interface metrics.
|
||||
*
|
||||
*/
|
||||
virtual const otRcpInterfaceMetrics *GetRcpInterfaceMetrics(void) const = 0;
|
||||
|
||||
/**
|
||||
* Marks destructor virtual method.
|
||||
*
|
||||
@@ -146,6 +156,13 @@ public:
|
||||
virtual ~SpinelInterface() = default;
|
||||
|
||||
protected:
|
||||
enum : uint8_t
|
||||
{
|
||||
kSpinelInterfaceTypeHdlc = 1, ///< The type of Spinel HDLC interface.
|
||||
kSpinelInterfaceTypeSpi = 2, ///< The type of Spinel SPI interface.
|
||||
kSpinelInterfaceTypeVendor = 3, ///< The type of Spinel Vendor interface.
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates whether or not the frame is the Spinel SPINEL_CMD_RESET frame.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -56,6 +56,8 @@ namespace Url {
|
||||
class Url : public otUrl
|
||||
{
|
||||
public:
|
||||
Url(void);
|
||||
|
||||
/**
|
||||
* Initializes the URL.
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -85,22 +85,6 @@ typedef struct otPlatformConfig
|
||||
///< directly after initialization.
|
||||
} otPlatformConfig;
|
||||
|
||||
/**
|
||||
* Represents RCP interface metrics.
|
||||
*
|
||||
*/
|
||||
typedef struct otRcpInterfaceMetrics
|
||||
{
|
||||
uint8_t mRcpInterfaceType; ///< The RCP interface type.
|
||||
uint64_t mTransferredFrameCount; ///< The number of transferred frames.
|
||||
uint64_t mTransferredValidFrameCount; ///< The number of transferred valid frames.
|
||||
uint64_t mTransferredGarbageFrameCount; ///< The number of transferred garbage frames.
|
||||
uint64_t mRxFrameCount; ///< The number of received frames.
|
||||
uint64_t mRxFrameByteCount; ///< The number of received bytes.
|
||||
uint64_t mTxFrameCount; ///< The number of transmitted frames.
|
||||
uint64_t mTxFrameByteCount; ///< The number of transmitted bytes.
|
||||
} otRcpInterfaceMetrics;
|
||||
|
||||
/**
|
||||
* Performs all platform-specific initialization of OpenThread's drivers and initializes the OpenThread
|
||||
* instance.
|
||||
|
||||
@@ -85,34 +85,55 @@
|
||||
#define OPENTHREAD_POSIX_CONFIG_DAEMON_CLI_ENABLE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* RCP bus UART.
|
||||
*
|
||||
* @note This value is also for simulated UART bus.
|
||||
*
|
||||
*/
|
||||
#define OT_POSIX_RCP_BUS_UART 1
|
||||
|
||||
/**
|
||||
* RCP bus SPI.
|
||||
*
|
||||
*/
|
||||
#define OT_POSIX_RCP_BUS_SPI 2
|
||||
|
||||
/**
|
||||
* RCP bus defined by vendors.
|
||||
*
|
||||
*/
|
||||
#define OT_POSIX_RCP_BUS_VENDOR 3
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_POSIX_CONFIG_RCP_BUS
|
||||
*
|
||||
* This setting configures what type of RCP bus to use.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_POSIX_CONFIG_RCP_BUS
|
||||
#define OPENTHREAD_POSIX_CONFIG_RCP_BUS OT_POSIX_RCP_BUS_UART
|
||||
#ifdef OPENTHREAD_POSIX_CONFIG_RCP_BUS
|
||||
#error "OPENTHREAD_POSIX_CONFIG_RCP_BUS was replaced by OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE,"\
|
||||
"OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE and OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE
|
||||
*
|
||||
* Define as 1 to enable the spinel HDLC interface.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE
|
||||
#define OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE
|
||||
*
|
||||
* Define as 1 to enable the spinel SPI interface.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE
|
||||
#define OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE
|
||||
*
|
||||
* Define as 1 to enable the spinel vendor interface.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE
|
||||
#define OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_URL_PROTOCOL_NAME
|
||||
*
|
||||
* Define the URL protocol name of the vendor Spinel interface.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_URL_PROTOCOL_NAME
|
||||
#define OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_URL_PROTOCOL_NAME "spinel+vendor"
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -417,7 +438,7 @@
|
||||
* every interval.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL
|
||||
#define OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL (60 * 1000 * 1000)
|
||||
#ifdef OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL
|
||||
#error "OPENTHREAD_POSIX_CONFIG_RCP_TIME_SYNC_INTERVAL was replaced by OPENTHREAD_SPINEL_CONFIG_RCP_TIME_SYNC_INTERVAL"
|
||||
#endif
|
||||
#endif // OPENTHREAD_PLATFORM_CONFIG_H_
|
||||
|
||||
+139
-118
@@ -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();
|
||||
}
|
||||
|
||||
@@ -29,7 +29,12 @@
|
||||
#ifndef POSIX_PLATFORM_RADIO_HPP_
|
||||
#define POSIX_PLATFORM_RADIO_HPP_
|
||||
|
||||
#include "common/code_utils.hpp"
|
||||
#include "lib/spinel/radio_spinel.hpp"
|
||||
#include "posix/platform/hdlc_interface.hpp"
|
||||
#include "posix/platform/radio_url.hpp"
|
||||
#include "posix/platform/spi_interface.hpp"
|
||||
#include "posix/platform/vendor_interface.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Posix {
|
||||
@@ -44,24 +49,36 @@ public:
|
||||
/**
|
||||
* Creates the radio manager.
|
||||
*
|
||||
* @param[in] aUrl A pointer to the null-terminated URL.
|
||||
*
|
||||
*/
|
||||
explicit Radio(const char *aUrl);
|
||||
Radio(void);
|
||||
|
||||
/**
|
||||
* Initialize the Thread radio.
|
||||
*
|
||||
* @param[in] aUrl A pointer to the null-terminated URL.
|
||||
*
|
||||
*/
|
||||
void Init(void);
|
||||
void Init(const char *aUrl);
|
||||
|
||||
/**
|
||||
* Acts as an accessor to the spinel instance used by the radio.
|
||||
* Acts as an accessor to the spinel interface instance used by the radio.
|
||||
*
|
||||
* @returns A pointer to the radio's spinel interface instance.
|
||||
* @returns A reference to the radio's spinel interface instance.
|
||||
*
|
||||
*/
|
||||
static void *GetSpinelInstance(void);
|
||||
Spinel::SpinelInterface &GetSpinelInterface(void)
|
||||
{
|
||||
OT_ASSERT(mSpinelInterface != nullptr);
|
||||
return *mSpinelInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acts as an accessor to the radio spinel instance used by the radio.
|
||||
*
|
||||
* @returns A reference to the radio spinel instance.
|
||||
*
|
||||
*/
|
||||
Spinel::RadioSpinel &GetRadioSpinel(void) { return mRadioSpinel; }
|
||||
|
||||
private:
|
||||
#if OPENTHREAD_POSIX_VIRTUAL_TIME
|
||||
@@ -70,7 +87,27 @@ private:
|
||||
void ProcessRadioUrl(const RadioUrl &aRadioUrl);
|
||||
void ProcessMaxPowerTable(const RadioUrl &aRadioUrl);
|
||||
|
||||
RadioUrl mRadioUrl;
|
||||
Spinel::SpinelInterface *CreateSpinelInterface(const char *aInterfaceName);
|
||||
|
||||
#if OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE && OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE
|
||||
static constexpr size_t kSpinelInterfaceRawSize = sizeof(ot::Posix::SpiInterface) > sizeof(ot::Posix::HdlcInterface)
|
||||
? sizeof(ot::Posix::SpiInterface)
|
||||
: sizeof(ot::Posix::HdlcInterface);
|
||||
#elif OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE
|
||||
static constexpr size_t kSpinelInterfaceRawSize = sizeof(ot::Posix::HdlcInterface);
|
||||
#elif OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE
|
||||
static constexpr size_t kSpinelInterfaceRawSize = sizeof(ot::Posix::SpiInterface);
|
||||
#elif OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE
|
||||
static constexpr size_t kSpinelInterfaceRawSize = sizeof(ot::Posix::VendorInterface);
|
||||
#else
|
||||
#error "No Spinel interface is specified!"
|
||||
#endif
|
||||
|
||||
RadioUrl mRadioUrl;
|
||||
Spinel::RadioSpinel mRadioSpinel;
|
||||
Spinel::SpinelInterface *mSpinelInterface;
|
||||
|
||||
OT_DEFINE_ALIGNED_VAR(mSpinelInterfaceRaw, kSpinelInterfaceRawSize, uint64_t);
|
||||
};
|
||||
|
||||
} // namespace Posix
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -38,3 +38,4 @@ expect_line "Done"
|
||||
send "region\n"
|
||||
expect "US"
|
||||
expect_line "Done"
|
||||
dispose_node 1
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user