[spinel] breakdown posix radio module (#10051)

This commit breaks down current posix radio module into `Radio` and
`SpinelManager`. The static instance of `SpinelDriver` is moved from
`Radio` to `SpinelManager`. The `platformRadioXXX` methods are also
broken down into `platformSpinelXXX` and `platformRadioXXX`. The
purpose is to make `platformSpinelXXX` resuable under both NCP and RCP
cases. And to use `platformSpinelInit` to detect to co-processor type
during initialization.
This commit is contained in:
Li Cao
2024-05-01 22:00:34 -07:00
committed by GitHub
parent 3bf281d32d
commit 9e4cbb8c60
13 changed files with 565 additions and 209 deletions
+31 -40
View File
@@ -53,12 +53,8 @@
namespace ot {
namespace Spinel {
char RadioSpinel::sVersion[kVersionStringSize] = "";
otExtAddress RadioSpinel::sIeeeEui64;
bool RadioSpinel::sIsReady = false; ///< NCP ready.
bool RadioSpinel::sSupportsLogStream =
false; ///< RCP supports `LOG_STREAM` property with OpenThread log meta-data format.
@@ -71,7 +67,6 @@ otRadioCaps RadioSpinel::sRadioCaps = OT_RADIO_CAPS_NONE;
RadioSpinel::RadioSpinel(void)
: Logger("RadioSpinel")
, mInstance(nullptr)
, mSpinelInterface(nullptr)
, mCmdTidsInUse(0)
, mCmdNextTid(1)
, mTxRadioTid(0)
@@ -80,7 +75,6 @@ RadioSpinel::RadioSpinel(void)
, mPropertyFormat(nullptr)
, mExpectedCommand(0)
, mError(OT_ERROR_NONE)
, mIid(SPINEL_HEADER_INVALID_IID)
, mTransmitFrame(nullptr)
, mShortAddress(0)
, mPanId(0xffff)
@@ -117,35 +111,32 @@ RadioSpinel::RadioSpinel(void)
, mVendorRestorePropertiesCallback(nullptr)
, mVendorRestorePropertiesContext(nullptr)
#endif
, mSpinelDriver(nullptr)
{
memset(&mRadioSpinelMetrics, 0, sizeof(mRadioSpinelMetrics));
memset(&mCallbacks, 0, sizeof(mCallbacks));
}
void RadioSpinel::Init(SpinelInterface &aSpinelInterface,
bool aResetRadio,
bool aSkipRcpCompatibilityCheck,
const spinel_iid_t *aIidList,
uint8_t aIidListLength)
void RadioSpinel::Init(bool aSkipRcpCompatibilityCheck, bool aSoftwareReset, SpinelDriver *aSpinelDriver)
{
otError error = OT_ERROR_NONE;
bool supportsRcpApiVersion;
bool supportsRcpMinHostApiVersion;
OT_UNUSED_VARIABLE(aSoftwareReset);
#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
mResetRadioOnStartup = aResetRadio;
mResetRadioOnStartup = aSoftwareReset;
#endif
mSpinelInterface = &aSpinelInterface;
mSpinelDriver = aSpinelDriver;
mSpinelDriver->SetFrameHandler(&HandleReceivedFrame, &HandleSavedFrame, this);
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT && OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
memset(&mTxIeInfo, 0, sizeof(otRadioIeInfo));
mTxRadioFrame.mInfo.mTxInfo.mIeInfo = &mTxIeInfo;
#endif
mSpinelDriver.Init(aSpinelInterface, aResetRadio, aIidList, aIidListLength);
mSpinelDriver.SetFrameHandler(&HandleReceivedFrame, &HandleSavedFrame, this);
SuccessOrExit(error = Get(SPINEL_PROP_HWADDR, SPINEL_DATATYPE_EUI64_S, sIeeeEui64.m8));
InitializeCaps(supportsRcpApiVersion, supportsRcpMinHostApiVersion);
@@ -207,22 +198,23 @@ exit:
void RadioSpinel::InitializeCaps(bool &aSupportsRcpApiVersion, bool &aSupportsRcpMinHostApiVersion)
{
if (!mSpinelDriver.CoprocessorHasCap(SPINEL_CAP_CONFIG_RADIO))
if (!GetSpinelDriver().CoprocessorHasCap(SPINEL_CAP_CONFIG_RADIO))
{
LogCrit("The co-processor isn't a RCP!");
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
}
if (!mSpinelDriver.CoprocessorHasCap(SPINEL_CAP_MAC_RAW))
if (!GetSpinelDriver().CoprocessorHasCap(SPINEL_CAP_MAC_RAW))
{
LogCrit("RCP capability list does not include support for radio/raw mode");
DieNow(OT_EXIT_RADIO_SPINEL_INCOMPATIBLE);
}
sSupportsLogStream = mSpinelDriver.CoprocessorHasCap(SPINEL_CAP_OPENTHREAD_LOG_METADATA);
aSupportsRcpApiVersion = mSpinelDriver.CoprocessorHasCap(SPINEL_CAP_RCP_API_VERSION);
aSupportsRcpMinHostApiVersion = mSpinelDriver.CoprocessorHasCap(SPINEL_CAP_RCP_MIN_HOST_API_VERSION);
sSupportsResetToBootloader = mSpinelDriver.CoprocessorHasCap(SPINEL_CAP_RCP_RESET_TO_BOOTLOADER);
sSupportsLogCrashDump = mSpinelDriver.CoprocessorHasCap(SPINEL_CAP_RCP_LOG_CRASH_DUMP);
sSupportsLogStream = GetSpinelDriver().CoprocessorHasCap(SPINEL_CAP_OPENTHREAD_LOG_METADATA);
aSupportsRcpApiVersion = GetSpinelDriver().CoprocessorHasCap(SPINEL_CAP_RCP_API_VERSION);
sSupportsResetToBootloader = GetSpinelDriver().CoprocessorHasCap(SPINEL_CAP_RCP_RESET_TO_BOOTLOADER);
aSupportsRcpMinHostApiVersion = GetSpinelDriver().CoprocessorHasCap(SPINEL_PROP_RCP_MIN_HOST_API_VERSION);
sSupportsLogCrashDump = GetSpinelDriver().CoprocessorHasCap(SPINEL_CAP_RCP_LOG_CRASH_DUMP);
}
otError RadioSpinel::CheckRadioCapabilities(void)
@@ -312,12 +304,6 @@ exit:
void RadioSpinel::Deinit(void)
{
if (mSpinelInterface != nullptr)
{
mSpinelInterface->Deinit();
mSpinelInterface = nullptr;
}
// This allows implementing pseudo reset.
new (this) RadioSpinel();
}
@@ -525,11 +511,10 @@ void RadioSpinel::HandleValueIs(spinel_prop_key_t aKey, const uint8_t *aBuffer,
}
// this clear is necessary in case the RCP has sent messages between disable and reset
mSpinelDriver.ClearRxBuffer();
mSpinelDriver.SetCoprocessorReady();
mSpinelDriver->ClearRxBuffer();
mSpinelDriver->SetCoprocessorReady();
LogInfo("RCP reset: %s", spinel_status_to_cstr(status));
sIsReady = true;
}
else if (status == SPINEL_STATUS_SWITCHOVER_DONE || status == SPINEL_STATUS_SWITCHOVER_FAILED)
{
@@ -630,6 +615,12 @@ void RadioSpinel::SetVendorRestorePropertiesCallback(otRadioSpinelVendorRestoreP
}
#endif
SpinelDriver &RadioSpinel::GetSpinelDriver(void) const
{
OT_ASSERT(mSpinelDriver != nullptr);
return *mSpinelDriver;
}
otError RadioSpinel::SendReset(uint8_t aResetType)
{
otError error;
@@ -638,7 +629,7 @@ otError RadioSpinel::SendReset(uint8_t aResetType)
{
ExitNow(error = OT_ERROR_NOT_CAPABLE);
}
error = mSpinelDriver.SendReset(aResetType);
error = GetSpinelDriver().SendReset(aResetType);
exit:
return error;
@@ -788,7 +779,7 @@ void RadioSpinel::ProcessRadioStateMachine(void)
void RadioSpinel::Process(const void *aContext)
{
mSpinelDriver.Process(aContext);
OT_UNUSED_VARIABLE(aContext);
ProcessRadioStateMachine();
RecoverFromRcpFailure();
@@ -1383,7 +1374,7 @@ otError RadioSpinel::WaitResponse(bool aHandleRcpTimeout)
uint64_t now;
now = otPlatTimeGet();
if ((end <= now) || (mSpinelInterface->WaitForFrame(end - now) != OT_ERROR_NONE))
if ((end <= now) || (GetSpinelDriver().GetSpinelInterface()->WaitForFrame(end - now) != OT_ERROR_NONE))
{
LogWarn("Wait for response timeout");
if (aHandleRcpTimeout)
@@ -1433,7 +1424,7 @@ otError RadioSpinel::RequestV(uint32_t command, spinel_prop_key_t aKey, const ch
VerifyOrExit(tid > 0, error = OT_ERROR_BUSY);
error = mSpinelDriver.SendCommand(command, aKey, tid, aFormat, aArgs);
error = GetSpinelDriver().SendCommand(command, aKey, tid, aFormat, aArgs);
SuccessOrExit(error);
if (aKey == SPINEL_PROP_STREAM_RAW)
@@ -1887,7 +1878,7 @@ exit:
uint64_t RadioSpinel::GetNow(void) { return (mIsTimeSynced) ? (otPlatTimeGet() + mRadioTimeOffset) : UINT64_MAX; }
uint32_t RadioSpinel::GetBusSpeed(void) const { return mSpinelInterface->GetBusSpeed(); }
uint32_t RadioSpinel::GetBusSpeed(void) const { return GetSpinelDriver().GetSpinelInterface()->GetBusSpeed(); }
void RadioSpinel::HandleRcpUnexpectedReset(spinel_status_t aStatus)
{
@@ -1953,14 +1944,14 @@ void RadioSpinel::RecoverFromRcpFailure(void)
mState = kStateDisabled;
mSpinelDriver.ClearRxBuffer();
GetSpinelDriver().ClearRxBuffer();
if (skipReset)
{
mSpinelDriver.SetCoprocessorReady();
GetSpinelDriver().SetCoprocessorReady();
}
else
{
mSpinelDriver.ResetCoprocessor(mResetRadioOnStartup);
GetSpinelDriver().ResetCoprocessor(mResetRadioOnStartup);
}
mCmdTidsInUse = 0;
+16 -28
View File
@@ -158,19 +158,13 @@ public:
/**
* 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.
* @param[in] aIidList A Pointer to the list of IIDs to receive spinel frame from.
* First entry must be the IID of the Host Application.
* @param[in] aIidListLength The Length of the @p aIidList.
* @param[in] aSoftwareReset When doing RCP recovery, TRUE to try software reset first, FALSE to
* directly do a hardware reset.
* @param[in] aSpinelDriver A pointer to the spinel driver instance that this object depends on.
*
*/
void Init(SpinelInterface &aSpinelInterface,
bool aResetRadio,
bool aSkipRcpCompatibilityCheck,
const spinel_iid_t *aIidList,
uint8_t aIidListLength);
void Init(bool aSkipRcpCompatibilityCheck, bool aSoftwareReset, SpinelDriver *aSpinelDriver);
/**
* This method sets the notification callbacks.
@@ -815,7 +809,7 @@ public:
* @returns Whether there is pending frame in the buffer.
*
*/
bool HasPendingFrame(void) const { return mSpinelDriver.HasPendingFrame(); }
bool HasPendingFrame(void) const { return mSpinelDriver->HasPendingFrame(); }
/**
* Returns the next timepoint to recalculate RCP time offset.
@@ -847,7 +841,7 @@ public:
* @returns A pointer to the co-processor version string.
*
*/
const char *GetVersion(void) const { return mSpinelDriver.GetVersion(); }
const char *GetVersion(void) const { return mSpinelDriver->GetVersion(); }
/**
* Sets the max transmit power.
@@ -1101,6 +1095,8 @@ private:
typedef otError (RadioSpinel::*ResponseHandler)(const uint8_t *aBuffer, uint16_t aLength);
SpinelDriver &GetSpinelDriver(void) const;
otError CheckSpinelVersion(void);
otError CheckRadioCapabilities(void);
otError CheckRcpApiVersion(bool aSupportsRcpApiVersion, bool aSupportsRcpMinHostApiVersion);
@@ -1200,9 +1196,6 @@ private:
otInstance *mInstance;
SpinelInterface::RxFrameBuffer mRxFrameBuffer;
SpinelInterface *mSpinelInterface;
RadioSpinelCallbacks mCallbacks; ///< Callbacks for notifications of higher layer.
uint16_t mCmdTidsInUse; ///< Used transaction ids.
@@ -1214,16 +1207,13 @@ private:
va_list mPropertyArgs; ///< The arguments pack or unpack spinel property of current transaction.
uint32_t mExpectedCommand; ///< Expected response command of current transaction.
otError mError; ///< The result of current transaction.
spinel_iid_t mIid; ///< The spinel interface id used by this process.
spinel_iid_t mIidList[kSpinelHeaderMaxNumIid]; ///< Array of interface ids to accept the incoming spinel frames.
uint8_t mRxPsdu[OT_RADIO_FRAME_MAX_SIZE];
uint8_t mTxPsdu[OT_RADIO_FRAME_MAX_SIZE];
uint8_t mAckPsdu[OT_RADIO_FRAME_MAX_SIZE];
otRadioFrame mRxRadioFrame;
otRadioFrame mTxRadioFrame;
otRadioFrame mAckRadioFrame;
otRadioFrame *mTransmitFrame; ///< Points to the frame to send
uint8_t mRxPsdu[OT_RADIO_FRAME_MAX_SIZE];
uint8_t mTxPsdu[OT_RADIO_FRAME_MAX_SIZE];
uint8_t mAckPsdu[OT_RADIO_FRAME_MAX_SIZE];
otRadioFrame mRxRadioFrame;
otRadioFrame mTxRadioFrame;
otRadioFrame mAckRadioFrame;
otRadioFrame *mTransmitFrame; ///< Points to the frame to send
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT && OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
otRadioIeInfo mTxIeInfo;
@@ -1235,7 +1225,6 @@ private:
uint8_t mChannel;
int8_t mRxSensitivity;
otError mTxError;
static char sVersion[kVersionStringSize];
static otExtAddress sIeeeEui64;
static otRadioCaps sRadioCaps;
@@ -1244,7 +1233,6 @@ private:
bool mRxOnWhenIdle : 1; ///< RxOnWhenIdle mode.
bool mIsTimeSynced : 1; ///< Host has calculated the time difference between host and RCP.
static bool sIsReady; ///< NCP ready.
static bool sSupportsLogStream; ///< RCP supports `LOG_STREAM` property with OpenThread log meta-data format.
static bool sSupportsResetToBootloader; ///< RCP supports resetting into bootloader mode.
static bool sSupportsLogCrashDump; ///< RCP supports logging a crash dump.
@@ -1311,7 +1299,7 @@ private:
void *mVendorRestorePropertiesContext;
#endif
SpinelDriver mSpinelDriver;
SpinelDriver *mSpinelDriver;
};
} // namespace Spinel
+31 -4
View File
@@ -59,11 +59,13 @@ SpinelDriver::SpinelDriver(void)
mFrameHandlerContext = this;
}
void SpinelDriver::Init(SpinelInterface &aSpinelInterface,
bool aSoftwareReset,
const spinel_iid_t *aIidList,
uint8_t aIidListLength)
CoprocessorType SpinelDriver::Init(SpinelInterface &aSpinelInterface,
bool aSoftwareReset,
const spinel_iid_t *aIidList,
uint8_t aIidListLength)
{
CoprocessorType coprocessorType;
mSpinelInterface = &aSpinelInterface;
mRxFrameBuffer.Clear();
SuccessOrDie(mSpinelInterface->Init(HandleReceivedFrame, this, mRxFrameBuffer));
@@ -81,6 +83,15 @@ void SpinelDriver::Init(SpinelInterface &aSpinelInterface,
SuccessOrDie(CheckSpinelVersion());
SuccessOrDie(GetCoprocessorVersion());
SuccessOrDie(GetCoprocessorCaps());
coprocessorType = GetCoprocessorType();
if (coprocessorType == OT_COPROCESSOR_UNKNOWN)
{
LogCrit("The coprocessor mode is unknown!");
DieNow(OT_EXIT_FAILURE);
}
return coprocessorType;
}
void SpinelDriver::Deinit(void)
@@ -447,6 +458,22 @@ exit:
return error;
}
CoprocessorType SpinelDriver::GetCoprocessorType(void)
{
CoprocessorType type = OT_COPROCESSOR_UNKNOWN;
if (CoprocessorHasCap(SPINEL_CAP_CONFIG_RADIO))
{
type = OT_COPROCESSOR_RCP;
}
else if (CoprocessorHasCap(SPINEL_CAP_CONFIG_FTD) || CoprocessorHasCap(SPINEL_CAP_CONFIG_MTD))
{
type = OT_COPROCESSOR_NCP;
}
return type;
}
void SpinelDriver::ProcessFrameQueue(void)
{
uint8_t *frame = nullptr;
+13 -7
View File
@@ -34,6 +34,7 @@
#include "lib/spinel/logger.hpp"
#include "lib/spinel/spinel.h"
#include "lib/spinel/spinel_interface.hpp"
#include "posix/platform/coprocessor_type.h"
namespace ot {
namespace Spinel {
@@ -70,11 +71,15 @@ public:
* First entry must be the IID of the Host Application.
* @param[in] aIidListLength The Length of the @p aIidList.
*
* @retval OT_COPROCESSOR_UNKNOWN The initialization fails.
* @retval OT_COPROCESSOR_RCP The Co-processor is a RCP.
* @retval OT_COPROCESSOR_NCP The Co-processor is a NCP.
*
*/
void Init(SpinelInterface &aSpinelInterface,
bool aSoftwareReset,
const spinel_iid_t *aIidList,
uint8_t aIidListLength);
CoprocessorType Init(SpinelInterface &aSpinelInterface,
bool aSoftwareReset,
const spinel_iid_t *aIidList,
uint8_t aIidListLength);
/**
* Deinitialize this SpinelDriver Instance.
@@ -272,9 +277,10 @@ private:
otError SendCommand(uint32_t aCommand, spinel_prop_key_t aKey, spinel_tid_t aTid);
otError CheckSpinelVersion(void);
otError GetCoprocessorVersion(void);
otError GetCoprocessorCaps(void);
otError CheckSpinelVersion(void);
otError GetCoprocessorVersion(void);
otError GetCoprocessorCaps(void);
CoprocessorType GetCoprocessorType(void);
void ProcessFrameQueue(void);
+1
View File
@@ -145,6 +145,7 @@ add_library(openthread-posix
radio_url.cpp
resolver.cpp
settings.cpp
spinel_manager.cpp
spi_interface.cpp
system.cpp
trel.cpp
+50
View File
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2024, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OT_PLATFORM_COPROCESSOR_MODE_H_
#define OT_PLATFORM_COPROCESSOR_MODE_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* Represents the mode of the co-processor.
* A co-processor could be either a RCP or NCP.
*/
typedef enum CoprocessorType
{
OT_COPROCESSOR_UNKNOWN = 0,
OT_COPROCESSOR_RCP = 1,
OT_COPROCESSOR_NCP = 2,
} CoprocessorType;
#ifdef __cplusplus
}
#endif
#endif // OT_PLATFORM_COPROCESSOR_MODE_H_
+46 -2
View File
@@ -52,6 +52,7 @@
#include <openthread/openthread-system.h>
#include <openthread/platform/time.h>
#include "coprocessor_type.h"
#include "lib/platform/exit_code.h"
#include "lib/url/url.hpp"
@@ -338,13 +339,22 @@ void virtualTimeReceiveEvent(struct VirtualTimeEvent *aEvent);
void virtualTimeSendSleepEvent(const struct timeval *aTimeout);
/**
* Performs radio spinel processing of virtual time simulation.
* Performs radio processing of virtual time simulation.
*
* @param[in] aInstance A pointer to the OpenThread instance.
* @param[in] aEvent A pointer to the current event.
*
*/
void virtualTimeRadioSpinelProcess(otInstance *aInstance, const struct VirtualTimeEvent *aEvent);
void virtualTimeRadioProcess(otInstance *aInstance, const struct VirtualTimeEvent *aEvent);
/**
* Performs radio processing of virtual time simulation.
*
* @param[in] aInstance A pointer to the OpenThread instance.
* @param[in] aEvent A pointer to the current event.
*
*/
void virtualTimeSpinelProcess(otInstance *aInstance, const struct VirtualTimeEvent *aEvent);
enum SocketBlockOption
{
@@ -421,6 +431,40 @@ extern otInstance *gInstance;
*/
void platformBacktraceInit(void);
/**
* Initializes the spinel service used by OpenThread.
*
* @param[in] aUrl A pointer to the null-terminated spinel URL.
*
* @retval OT_COPROCESSOR_UNKNOWN The initialization fails.
* @retval OT_COPROCESSOR_RCP The Co-processor is a RCP.
* @retval OT_COPROCESSOR_NCP The Co-processor is a NCP.
*/
CoprocessorType platformSpinelManagerInit(const char *aUrl);
/**
* Shuts down the spinel service used by OpenThread.
*
*/
void platformSpinelManagerDeinit(void);
/**
* Performs spinel driver processing.
*
* @param[in] aInstance A pointer to the OT instance.
* @param[in] aContext A pointer to the mainloop context.
*
*/
void platformSpinelManagerProcess(otInstance *aInstance, const otSysMainloopContext *aContext);
/**
* Updates the file descriptor sets with file descriptors used by the spinel driver.
*
* @param[in] aContext A pointer to the mainloop context.
*
*/
void platformSpinelManagerUpdateFdSet(otSysMainloopContext *aContext);
#ifdef __cplusplus
}
#endif
+4 -113
View File
@@ -41,6 +41,7 @@
#include "common/code_utils.hpp"
#include "common/new.hpp"
#include "posix/platform/radio.hpp"
#include "posix/platform/spinel_manager.hpp"
#include "utils/parse_cmdline.hpp"
#if OPENTHREAD_POSIX_CONFIG_CONFIGURATION_FILE_ENABLE
@@ -62,7 +63,6 @@ const char Radio::kLogModuleName[] = "Radio";
Radio::Radio(void)
: mRadioUrl(nullptr)
, mRadioSpinel()
, mSpinelInterface(nullptr)
{
}
@@ -70,7 +70,6 @@ void Radio::Init(const char *aUrl)
{
bool resetRadio;
bool skipCompatibilityCheck;
spinel_iid_t iidList[Spinel::kSpinelHeaderMaxNumIid];
struct ot::Spinel::RadioSpinelCallbacks callbacks;
mRadioUrl.Init(aUrl);
@@ -86,74 +85,15 @@ void Radio::Init(const char *aUrl)
callbacks.mTransmitDone = otPlatRadioTxDone;
callbacks.mTxStarted = otPlatRadioTxStarted;
GetIidListFromRadioUrl(iidList);
#if OPENTHREAD_POSIX_VIRTUAL_TIME
VirtualTimeInit();
#endif
mSpinelInterface = CreateSpinelInterface(mRadioUrl.GetProtocol());
VerifyOrDie(mSpinelInterface != nullptr, OT_EXIT_FAILURE);
resetRadio = !mRadioUrl.HasParam("no-reset");
skipCompatibilityCheck = mRadioUrl.HasParam("skip-rcp-compatibility-check");
mRadioSpinel.SetCallbacks(callbacks);
mRadioSpinel.Init(*mSpinelInterface, resetRadio, skipCompatibilityCheck, iidList, OT_ARRAY_LENGTH(iidList));
LogDebg("instance init:%p - iid = %d", (void *)&mRadioSpinel, iidList[0]);
mRadioSpinel.Init(skipCompatibilityCheck, resetRadio, &SpinelManager::GetSpinelDriver());
ProcessRadioUrl(mRadioUrl);
}
#if OPENTHREAD_POSIX_VIRTUAL_TIME
void Radio::VirtualTimeInit(void)
{
// The last argument must be the node id
const char *nodeId = nullptr;
for (const char *arg = nullptr; (arg = mRadioUrl.GetValue("forkpty-arg", arg)) != nullptr; nodeId = arg)
{
}
virtualTimeInit(static_cast<uint16_t>(atoi(nodeId)));
}
#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
{
LogCrit("The Spinel interface name \"%s\" is not supported!", aInterfaceName);
DieNow(OT_ERROR_FAILED);
}
return interface;
}
void Radio::ProcessRadioUrl(const RadioUrl &aRadioUrl)
{
const char *region;
@@ -248,53 +188,6 @@ exit:
#endif // OPENTHREAD_POSIX_CONFIG_MAX_POWER_TABLE_ENABLE
}
void Radio::GetIidListFromRadioUrl(spinel_iid_t (&aIidList)[Spinel::kSpinelHeaderMaxNumIid])
{
const char *iidString;
const char *iidListString;
memset(aIidList, SPINEL_HEADER_INVALID_IID, sizeof(aIidList));
iidString = (mRadioUrl.GetValue("iid"));
iidListString = (mRadioUrl.GetValue("iid-list"));
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
// First entry to the aIidList must be the IID of the host application.
VerifyOrDie(iidString != nullptr, OT_EXIT_INVALID_ARGUMENTS);
aIidList[0] = static_cast<spinel_iid_t>(atoi(iidString));
if (iidListString != nullptr)
{
// Convert string to an array of integers.
// Integer i is for traverse the iidListString.
// Integer j is for aIidList array offset location.
// First entry of aIidList is for host application iid hence j start from 1.
for (uint8_t i = 0, j = 1; iidListString[i] != '\0' && j < Spinel::kSpinelHeaderMaxNumIid; i++)
{
if (iidListString[i] == ',')
{
j++;
continue;
}
if (iidListString[i] < '0' || iidListString[i] > '9')
{
DieNow(OT_EXIT_INVALID_ARGUMENTS);
}
else
{
aIidList[j] = iidListString[i] - '0';
VerifyOrDie(aIidList[j] < Spinel::kSpinelHeaderMaxNumIid, OT_EXIT_INVALID_ARGUMENTS);
}
}
}
#else // !OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
VerifyOrDie(iidString == nullptr, OT_EXIT_INVALID_ARGUMENTS);
VerifyOrDie(iidListString == nullptr, OT_EXIT_INVALID_ARGUMENTS);
aIidList[0] = 0;
#endif // OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
}
} // namespace Posix
} // namespace ot
@@ -439,9 +332,7 @@ void platformRadioUpdateFdSet(otSysMainloopContext *aContext)
aContext->mTimeout.tv_usec = 0;
}
sRadio.GetSpinelInterface().UpdateFdSet(aContext);
if (GetRadioSpinel().HasPendingFrame() || GetRadioSpinel().IsTransmitDone())
if (GetRadioSpinel().IsTransmitDone())
{
aContext->mTimeout.tv_sec = 0;
aContext->mTimeout.tv_usec = 0;
@@ -449,7 +340,7 @@ void platformRadioUpdateFdSet(otSysMainloopContext *aContext)
}
#if OPENTHREAD_POSIX_VIRTUAL_TIME
void virtualTimeRadioSpinelProcess(otInstance *aInstance, const struct VirtualTimeEvent *aEvent)
void virtualTimeRadioProcess(otInstance *aInstance, const struct VirtualTimeEvent *aEvent)
{
OT_UNUSED_VARIABLE(aInstance);
GetRadioSpinel().Process(aEvent);
+3 -14
View File
@@ -33,9 +33,11 @@
#include "logger.hpp"
#include "radio_url.hpp"
#include "spi_interface.hpp"
#include "spinel_manager.hpp"
#include "vendor_interface.hpp"
#include "common/code_utils.hpp"
#include "lib/spinel/radio_spinel.hpp"
#include "lib/spinel/spinel_driver.hpp"
#if OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
#ifdef OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_HEADER
#include OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_HEADER
@@ -74,11 +76,7 @@ public:
* @returns A reference to the radio's spinel interface instance.
*
*/
Spinel::SpinelInterface &GetSpinelInterface(void)
{
OT_ASSERT(mSpinelInterface != nullptr);
return *mSpinelInterface;
}
Spinel::SpinelInterface &GetSpinelInterface(void) { return SpinelManager::GetSpinelManager().GetSpinelInterface(); }
/**
* Acts as an accessor to the radio spinel instance used by the radio.
@@ -89,15 +87,9 @@ public:
Spinel::RadioSpinel &GetRadioSpinel(void) { return mRadioSpinel; }
private:
#if OPENTHREAD_POSIX_VIRTUAL_TIME
void VirtualTimeInit(void);
#endif
void ProcessRadioUrl(const RadioUrl &aRadioUrl);
void ProcessMaxPowerTable(const RadioUrl &aRadioUrl);
Spinel::SpinelInterface *CreateSpinelInterface(const char *aInterfaceName);
void GetIidListFromRadioUrl(spinel_iid_t (&aIidList)[Spinel::kSpinelHeaderMaxNumIid]);
#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)
@@ -118,9 +110,6 @@ private:
#else
Spinel::RadioSpinel mRadioSpinel;
#endif
Spinel::SpinelInterface *mSpinelInterface;
OT_DEFINE_ALIGNED_VAR(mSpinelInterfaceRaw, kSpinelInterfaceRawSize, uint64_t);
};
} // namespace Posix
+224
View File
@@ -0,0 +1,224 @@
/*
* Copyright (c) 2024, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "platform-posix.h"
#include "posix/platform/spinel_manager.hpp"
#include "common/code_utils.hpp"
#include "common/new.hpp"
#include "lib/spinel/spinel_driver.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"
static ot::Posix::SpinelManager sSpinelManager;
namespace ot {
namespace Posix {
SpinelManager &SpinelManager::GetSpinelManager(void) { return sSpinelManager; }
Spinel::SpinelDriver &SpinelManager::GetSpinelDriver(void) { return sSpinelManager.mSpinelDriver; }
SpinelManager::SpinelManager(void)
: mUrl(nullptr)
, mSpinelDriver()
, mSpinelInterface(nullptr)
{
}
SpinelManager::~SpinelManager(void) { Deinit(); }
CoprocessorType SpinelManager::Init(const char *aUrl)
{
bool swReset;
spinel_iid_t iidList[Spinel::kSpinelHeaderMaxNumIid];
CoprocessorType mode;
mUrl.Init(aUrl);
VerifyOrDie(mUrl.GetPath() != nullptr, OT_EXIT_INVALID_ARGUMENTS);
GetIidListFromUrl(iidList);
#if OPENTHREAD_POSIX_VIRTUAL_TIME
VirtualTimeInit();
#endif
mSpinelInterface = CreateSpinelInterface(mUrl.GetProtocol());
VerifyOrDie(mSpinelInterface != nullptr, OT_EXIT_FAILURE);
swReset = !mUrl.HasParam("no-reset");
mode = mSpinelDriver.Init(*mSpinelInterface, swReset, iidList, OT_ARRAY_LENGTH(iidList));
otLogDebgPlat("instance init:%p - iid = %d", (void *)&mSpinelDriver, iidList[0]);
return mode;
}
void SpinelManager::Deinit(void)
{
if (mSpinelInterface != nullptr)
{
mSpinelInterface->Deinit();
mSpinelInterface = nullptr;
}
mSpinelDriver.Deinit();
}
Spinel::SpinelInterface *SpinelManager::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(mUrl);
}
#endif
#if OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE
else if (Posix::SpiInterface::IsInterfaceNameMatch(aInterfaceName))
{
interface = new (&mSpinelInterfaceRaw) SpiInterface(mUrl);
}
#endif
#if OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE
else if (VendorInterface::IsInterfaceNameMatch(aInterfaceName))
{
interface = new (&mSpinelInterfaceRaw) VendorInterface(mUrl);
}
#endif
else
{
otLogCritPlat("The Spinel interface name \"%s\" is not supported!", aInterfaceName);
DieNow(OT_ERROR_FAILED);
}
return interface;
}
void SpinelManager::GetIidListFromUrl(spinel_iid_t (&aIidList)[Spinel::kSpinelHeaderMaxNumIid])
{
const char *iidString;
const char *iidListString;
memset(aIidList, SPINEL_HEADER_INVALID_IID, sizeof(aIidList));
iidString = mUrl.GetValue("iid");
iidListString = mUrl.GetValue("iid-list");
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
// First entry to the aIidList must be the IID of the host application.
VerifyOrDie(iidString != nullptr, OT_EXIT_INVALID_ARGUMENTS);
aIidList[0] = static_cast<spinel_iid_t>(atoi(iidString));
if (iidListString != nullptr)
{
// Convert string to an array of integers.
// Integer i is for traverse the iidListString.
// Integer j is for aIidList array offset location.
// First entry of aIidList is for host application iid hence j start from 1.
for (uint8_t i = 0, j = 1; iidListString[i] != '\0' && j < Spinel::kSpinelHeaderMaxNumIid; i++)
{
if (iidListString[i] == ',')
{
j++;
continue;
}
if (iidListString[i] < '0' || iidListString[i] > '9')
{
DieNow(OT_EXIT_INVALID_ARGUMENTS);
}
else
{
aIidList[j] = iidListString[i] - '0';
VerifyOrDie(aIidList[j] < Spinel::kSpinelHeaderMaxNumIid, OT_EXIT_INVALID_ARGUMENTS);
}
}
}
#else // !OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
VerifyOrDie(iidString == nullptr, OT_EXIT_INVALID_ARGUMENTS);
VerifyOrDie(iidListString == nullptr, OT_EXIT_INVALID_ARGUMENTS);
aIidList[0] = 0;
#endif // OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
}
#if OPENTHREAD_POSIX_VIRTUAL_TIME
void SpinelManager::VirtualTimeInit(void)
{
// The last argument must be the node id
const char *nodeId = nullptr;
for (const char *arg = nullptr; (arg = mUrl.GetValue("forkpty-arg", arg)) != nullptr; nodeId = arg)
{
}
virtualTimeInit(static_cast<uint16_t>(atoi(nodeId)));
}
#endif
} // namespace Posix
} // namespace ot
CoprocessorType platformSpinelManagerInit(const char *aUrl) { return sSpinelManager.Init(aUrl); }
void platformSpinelManagerDeinit(void) { return sSpinelManager.Deinit(); }
#if OPENTHREAD_POSIX_VIRTUAL_TIME
void virtualTimeSpinelProcess(otInstance *aInstance, const struct VirtualTimeEvent *aEvent)
{
OT_UNUSED_VARIABLE(aInstance);
ot::Posix::SpinelManager::GetSpinelDriver().Process(aEvent);
}
#else
void platformSpinelManagerProcess(otInstance *aInstance, const otSysMainloopContext *aContext)
{
OT_UNUSED_VARIABLE(aInstance);
ot::Posix::SpinelManager::GetSpinelDriver().Process(aContext);
}
#endif // OPENTHREAD_POSIX_VIRTUAL_TIME
void platformSpinelManagerUpdateFdSet(otSysMainloopContext *aContext)
{
sSpinelManager.GetSpinelInterface().UpdateFdSet(aContext);
if (ot::Posix::SpinelManager::GetSpinelDriver().HasPendingFrame())
{
aContext->mTimeout.tv_sec = 0;
aContext->mTimeout.tv_usec = 0;
}
}
+131
View File
@@ -0,0 +1,131 @@
/*
* Copyright (c) 2024, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef POSIX_PLATFORM_SPINEL_MANAGER_HPP_
#define POSIX_PLATFORM_SPINEL_MANAGER_HPP_
#include "common/code_utils.hpp"
#include "lib/spinel/spinel_driver.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 {
class SpinelManager
{
public:
/**
* Returns the static instance of the SpinelDriver.
*
*/
static Spinel::SpinelDriver &GetSpinelDriver(void);
/**
* Returns the static instance of the SpinelManager.
*
*/
static SpinelManager &GetSpinelManager(void);
/**
* Constructor of the SpinelManager
*
*/
SpinelManager(void);
/**
* Destructor of the SpinelManager
*
*/
~SpinelManager(void);
/**
* Initializes the SpinelManager.
*
* @param[in] aUrl A pointer to the null-terminated spinel URL.
*
* @retval OT_COPROCESSOR_UNKNOWN The initialization fails.
* @retval OT_COPROCESSOR_RCP The Co-processor is a RCP.
* @retval OT_COPROCESSOR_NCP The Co-processor is a NCP.
*
*/
CoprocessorType Init(const char *aUrl);
/**
* Deinitializes the SpinelManager.
*
*/
void Deinit(void);
/**
* Returns the spinel interface.
*
* @returns The spinel interface.
*
*/
Spinel::SpinelInterface &GetSpinelInterface(void)
{
OT_ASSERT(mSpinelInterface != nullptr);
return *mSpinelInterface;
}
private:
#if OPENTHREAD_POSIX_VIRTUAL_TIME
void VirtualTimeInit(void);
#endif
void GetIidListFromUrl(spinel_iid_t (&aIidList)[Spinel::kSpinelHeaderMaxNumIid]);
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(Posix::SpiInterface) > sizeof(Posix::HdlcInterface)
? sizeof(Posix::SpiInterface)
: sizeof(Posix::HdlcInterface);
#elif OPENTHREAD_POSIX_CONFIG_SPINEL_HDLC_INTERFACE_ENABLE
static constexpr size_t kSpinelInterfaceRawSize = sizeof(Posix::HdlcInterface);
#elif OPENTHREAD_POSIX_CONFIG_SPINEL_SPI_INTERFACE_ENABLE
static constexpr size_t kSpinelInterfaceRawSize = sizeof(Posix::SpiInterface);
#elif OPENTHREAD_POSIX_CONFIG_SPINEL_VENDOR_INTERFACE_ENABLE
static constexpr size_t kSpinelInterfaceRawSize = sizeof(Posix::VendorInterface);
#else
#error "No Spinel interface is specified!"
#endif
RadioUrl mUrl;
Spinel::SpinelDriver mSpinelDriver;
Spinel::SpinelInterface *mSpinelInterface;
OT_DEFINE_ALIGNED_VAR(mSpinelInterfaceRaw, kSpinelInterfaceRawSize, uint64_t);
};
} // namespace Posix
} // namespace ot
#endif // POSIX_PLATFORM_SPINEL_MANAGER_HPP_
+13
View File
@@ -129,11 +129,21 @@ void otSysSetInfraNetif(const char *aInfraNetifName, int aIcmp6Socket)
void platformInit(otPlatformConfig *aPlatformConfig)
{
CoprocessorType type;
#if OPENTHREAD_POSIX_CONFIG_BACKTRACE_ENABLE
platformBacktraceInit();
#endif
platformAlarmInit(aPlatformConfig->mSpeedUpFactor, aPlatformConfig->mRealTimeSignal);
type = platformSpinelManagerInit(get802154RadioUrl(aPlatformConfig));
if (type != OT_COPROCESSOR_RCP)
{
printf("Only RCP is supported!\n");
exit(OT_EXIT_FAILURE);
}
platformRadioInit(get802154RadioUrl(aPlatformConfig));
// For Dry-Run option, only init the radio.
@@ -266,6 +276,7 @@ void platformDeinit(void)
virtualTimeDeinit();
#endif
platformRadioDeinit();
platformSpinelManagerDeinit();
// For Dry-Run option, only the radio is initialized.
VerifyOrExit(!gDryRun);
@@ -343,6 +354,7 @@ void otSysMainloopUpdate(otInstance *aInstance, otSysMainloopContext *aMainloop)
#if OPENTHREAD_POSIX_VIRTUAL_TIME
virtualTimeUpdateFdSet(aMainloop);
#else
platformSpinelManagerUpdateFdSet(aMainloop);
platformRadioUpdateFdSet(aMainloop);
#endif
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
@@ -406,6 +418,7 @@ void otSysMainloopProcess(otInstance *aInstance, const otSysMainloopContext *aMa
#if OPENTHREAD_POSIX_VIRTUAL_TIME
virtualTimeProcess(aInstance, aMainloop);
#else
platformSpinelManagerProcess(aInstance, aMainloop);
platformRadioProcess(aInstance, aMainloop);
#endif
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
+2 -1
View File
@@ -181,7 +181,8 @@ void virtualTimeProcess(otInstance *aInstance, const otSysMainloopContext *aCont
virtualTimeReceiveEvent(&event);
}
virtualTimeRadioSpinelProcess(aInstance, &event);
virtualTimeSpinelProcess(aInstance, &event);
virtualTimeRadioProcess(aInstance, &event);
}
uint64_t otPlatTimeGet(void) { return sNow; }