blob: 5f55c7588f98a0b757f8063235004877b2753e40 [file]
/*
* Copyright (c) 2018, 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.
*/
/**
* @file
* This file includes definitions for the spinel based radio transceiver.
*/
#ifndef RADIO_SPINEL_HPP_
#define RADIO_SPINEL_HPP_
#include <openthread/platform/radio.h>
#include "openthread-spinel-config.h"
#include "core/radio/max_power_table.hpp"
#include "lib/spinel/logger.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 {
namespace Spinel {
/**
* Maximum number of Spinel Interface IDs.
*
*/
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
static constexpr uint8_t kSpinelHeaderMaxNumIid = 4;
#else
static constexpr uint8_t kSpinelHeaderMaxNumIid = 1;
#endif
struct RadioSpinelCallbacks
{
/**
* This callback notifies user of `RadioSpinel` of a received frame.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aFrame A pointer to the received frame or nullptr if the receive operation failed.
* @param[in] aError kErrorNone when successfully received a frame,
* kErrorAbort when reception was aborted and a frame was not received,
* kErrorNoBufs when a frame could not be received due to lack of rx buffer space.
*
*/
void (*mReceiveDone)(otInstance *aInstance, otRadioFrame *aFrame, Error aError);
/**
* The callback notifies user of `RadioSpinel` that the transmit operation has completed, providing, if
* applicable, the received ACK frame.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aFrame The transmitted frame.
* @param[in] aAckFrame A pointer to the ACK frame, nullptr if no ACK was received.
* @param[in] aError kErrorNone when the frame was transmitted,
* kErrorNoAck when the frame was transmitted but no ACK was received,
* kErrorChannelAccessFailure tx failed due to activity on the channel,
* kErrorAbort when transmission was aborted for other reasons.
*
*/
void (*mTransmitDone)(otInstance *aInstance, otRadioFrame *aFrame, otRadioFrame *aAckFrame, Error aError);
/**
* This callback notifies user of `RadioSpinel` that energy scan is complete.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aMaxRssi Maximum RSSI seen on the channel, or `SubMac::kInvalidRssiValue` if failed.
*
*/
void (*mEnergyScanDone)(otInstance *aInstance, int8_t aMaxRssi);
/**
* This callback notifies user of `RadioSpinel` that the transmission has started.
*
* @param[in] aInstance A pointer to the OpenThread instance structure.
* @param[in] aFrame A pointer to the frame that is being transmitted.
*
*/
void (*mTxStarted)(otInstance *aInstance, otRadioFrame *aFrame);
/**
* This callback notifies user of `RadioSpinel` that the radio interface switchover has completed.
*
* @param[in] aInstance A pointer to the OpenThread instance structure.
* @param[in] aSuccess A value indicating if the switchover was successful or not.
*
*/
void (*mSwitchoverDone)(otInstance *aInstance, bool aSuccess);
#if OPENTHREAD_CONFIG_DIAG_ENABLE
/**
* This callback notifies diagnostics module using `RadioSpinel` of a received frame.
*
* This callback is used when diagnostics is enabled.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aFrame A pointer to the received frame or NULL if the receive operation failed.
* @param[in] aError OT_ERROR_NONE when successfully received a frame,
* OT_ERROR_ABORT when reception was aborted and a frame was not received,
* OT_ERROR_NO_BUFS when a frame could not be received due to lack of rx buffer space.
*
*/
void (*mDiagReceiveDone)(otInstance *aInstance, otRadioFrame *aFrame, Error aError);
/**
* This callback notifies diagnostics module using `RadioSpinel` that the transmission has completed.
*
* This callback is used when diagnostics is enabled.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aFrame A pointer to the frame that was transmitted.
* @param[in] aError OT_ERROR_NONE when the frame was transmitted,
* OT_ERROR_CHANNEL_ACCESS_FAILURE tx could not take place due to activity on the
* channel, OT_ERROR_ABORT when transmission was aborted for other reasons.
*
*/
void (*mDiagTransmitDone)(otInstance *aInstance, otRadioFrame *aFrame, Error aError);
#endif // OPENTHREAD_CONFIG_DIAG_ENABLE
};
/**
* The class for providing a OpenThread radio interface by talking with a radio-only
* co-processor(RCP).
*
*/
class RadioSpinel : private Logger
{
public:
/**
* Initializes the spinel based OpenThread transceiver.
*
*/
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.
* @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.
*
*/
void Init(SpinelInterface &aSpinelInterface,
bool aResetRadio,
bool aSkipRcpCompatibilityCheck,
const spinel_iid_t *aIidList,
uint8_t aIidListLength);
/**
* This method sets the notification callbacks.
*
* @param[in] aCallbacks A pointer to structure with notification callbacks.
*
*/
void SetCallbacks(const struct RadioSpinelCallbacks &aCallbacks);
/**
* Deinitialize this radio transceiver.
*
*/
void Deinit(void);
/**
* Gets the status of promiscuous mode.
*
* @retval true Promiscuous mode is enabled.
* @retval false Promiscuous mode is disabled.
*
*/
bool IsPromiscuous(void) const { return mIsPromiscuous; }
/**
* Sets the status of promiscuous mode.
*
* @param[in] aEnable Whether to enable or disable promiscuous mode.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError SetPromiscuous(bool aEnable);
/**
* Sets the status of RxOnWhenIdle mode.
*
* @param[in] aEnable Whether to enable or disable RxOnWhenIdle mode.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError SetRxOnWhenIdle(bool aEnable);
/**
* Sets the Short Address for address filtering.
*
* @param[in] aShortAddress The IEEE 802.15.4 Short Address.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError SetShortAddress(uint16_t aAddress);
/**
* Gets the factory-assigned IEEE EUI-64 for this transceiver.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[out] aIeeeEui64 A pointer to the factory-assigned IEEE EUI-64.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError GetIeeeEui64(uint8_t *aIeeeEui64);
/**
* Sets the Extended Address for address filtering.
*
* @param[in] aExtAddress A pointer to the IEEE 802.15.4 Extended Address stored in little-endian byte order.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError SetExtendedAddress(const otExtAddress &aExtAddress);
/**
* Sets the PAN ID for address filtering.
*
* @param[in] aPanId The IEEE 802.15.4 PAN ID.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError SetPanId(uint16_t aPanId);
/**
* Gets the radio's transmit power in dBm.
*
* @param[out] aPower The transmit power in dBm.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError GetTransmitPower(int8_t &aPower);
/**
* Sets the radio's transmit power in dBm.
*
* @param[in] aPower The transmit power in dBm.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError SetTransmitPower(int8_t aPower);
/**
* Gets the radio's CCA ED threshold in dBm.
*
* @param[out] aThreshold The CCA ED threshold in dBm.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError GetCcaEnergyDetectThreshold(int8_t &aThreshold);
/**
* Sets the radio's CCA ED threshold in dBm.
*
* @param[in] aThreshold The CCA ED threshold in dBm.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError SetCcaEnergyDetectThreshold(int8_t aThreshold);
/**
* Gets the FEM's Rx LNA gain in dBm.
*
* @param[out] aGain The FEM's Rx LNA gain in dBm.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError GetFemLnaGain(int8_t &aGain);
/**
* Sets the FEM's Rx LNA gain in dBm.
*
* @param[in] aGain The FEM's Rx LNA gain in dBm.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError SetFemLnaGain(int8_t aGain);
/**
* Returns the radio sw version string.
*
* @returns A pointer to the radio version string.
*
*/
const char *GetVersion(void) const { return sVersion; }
/**
* Returns the radio capabilities.
*
* @returns The radio capability bit vector.
*
*/
otRadioCaps GetRadioCaps(void) const { return sRadioCaps; }
/**
* Gets the most recent RSSI measurement.
*
* @returns The RSSI in dBm when it is valid. 127 when RSSI is invalid.
*/
int8_t GetRssi(void);
/**
* Returns the radio receive sensitivity value.
*
* @returns The radio receive sensitivity value in dBm.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
int8_t GetReceiveSensitivity(void) const { return mRxSensitivity; }
/**
* Gets current state of the radio.
*
* @return Current state of the radio.
*
*/
otRadioState GetState(void) const;
/**
* Gets the current receiving channel.
*
* @returns Current receiving channel.
*
*/
uint8_t GetChannel(void) const { return mChannel; }
#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
/**
* Enable the radio coex.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aEnabled TRUE to enable the radio coex, FALSE otherwise.
*
* @retval OT_ERROR_NONE Successfully enabled.
* @retval OT_ERROR_FAILED The radio coex could not be enabled.
*
*/
otError SetCoexEnabled(bool aEnabled);
/**
* Check whether radio coex is enabled or not.
*
* @param[in] aInstance The OpenThread instance structure.
*
* @returns TRUE if the radio coex is enabled, FALSE otherwise.
*
*/
bool IsCoexEnabled(void);
/**
* Retrieves the radio coexistence metrics.
*
* @param[out] aCoexMetrics A reference to the coexistence metrics structure.
*
* @retval OT_ERROR_NONE Successfully retrieved the coex metrics.
* @retval OT_ERROR_INVALID_ARGS @p aCoexMetrics was nullptr.
*
*/
otError GetCoexMetrics(otRadioCoexMetrics &aCoexMetrics);
#endif // OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
/**
* Get currently active interface.
*
* @param[out] aIid IID of the interface that owns the radio.
*
* @retval OT_ERROR_NONE Successfully got the property.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
* @retval OT_ERROR_NOT_IMPLEMENTED Failed due to lack of the support in radio
* @retval OT_ERROR_INVALID_COMMAND Platform supports all interfaces simultaneously.
* (i.e. no active/inactive interface concept in the platform level)
*
*/
otError GetMultipanActiveInterface(spinel_iid_t *aIid);
/**
* Sets specified radio interface active
*
* This function allows selecting currently active radio interface on platforms that do not support parallel
* communication on multiple interfaces. I.e. if more than one interface is in receive state calling
* SetMultipanActiveInterface guarantees that specified interface will not be losing frames. This function
* returns if the request was received properly. After interface switching is complete SwitchoverDone callback is
* Invoked. Switching interfaces may take longer if aCompletePending is set true.
*
* @param[in] aIid IID of the interface to set active.
* @param[in] aCompletePending Set true if pending radio operation should complete first(Soft switch) or false if
* ongoing operations should be interrupted (Force switch).
*
* @retval OT_ERROR_NONE Successfully requested interface switch.
* @retval OT_ERROR_BUSY Failed due to another operation on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
* @retval OT_ERROR_NOT_IMPLEMENTED Failed due to lack of support in radio for the given interface id or
* @retval OT_ERROR_INVALID_COMMAND Platform supports all interfaces simultaneously
* (i.e. no active/inactive interface concept in the platform level)
* @retval OT_ERROR_ALREADY Given interface is already active.
*
*/
otError SetMultipanActiveInterface(spinel_iid_t aIid, bool aCompletePending);
/**
* Returns a reference to the transmit buffer.
*
* The caller forms the IEEE 802.15.4 frame in this buffer then calls otPlatRadioTransmit() to request transmission.
*
* @returns A reference to the transmit buffer.
*
*/
otRadioFrame &GetTransmitFrame(void) { return mTxRadioFrame; }
/**
* Enables or disables source address match feature.
*
* @param[in] aEnable Enable/disable source address match feature.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError EnableSrcMatch(bool aEnable);
/**
* Adds a short address to the source address match table.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aShortAddress The short address to be added.
*
* @retval OT_ERROR_NONE Successfully added short address to the source match table.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
* @retval OT_ERROR_NO_BUFS No available entry in the source match table.
*/
otError AddSrcMatchShortEntry(uint16_t aShortAddress);
/**
* Removes a short address from the source address match table.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aShortAddress The short address to be removed.
*
* @retval OT_ERROR_NONE Successfully removed short address from the source match table.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
* @retval OT_ERROR_NO_ADDRESS The short address is not in source address match table.
*/
otError ClearSrcMatchShortEntry(uint16_t aShortAddress);
/**
* Clear all short addresses from the source address match table.
*
* @param[in] aInstance The OpenThread instance structure.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError ClearSrcMatchShortEntries(void);
/**
* Add an extended address to the source address match table.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aExtAddress The extended address to be added stored in little-endian byte order.
*
* @retval OT_ERROR_NONE Successfully added extended address to the source match table.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
* @retval OT_ERROR_NO_BUFS No available entry in the source match table.
*/
otError AddSrcMatchExtEntry(const otExtAddress &aExtAddress);
/**
* Remove an extended address from the source address match table.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aExtAddress The extended address to be removed stored in little-endian byte order.
*
* @retval OT_ERROR_NONE Successfully removed the extended address from the source match table.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
* @retval OT_ERROR_NO_ADDRESS The extended address is not in source address match table.
*/
otError ClearSrcMatchExtEntry(const otExtAddress &aExtAddress);
/**
* Clear all the extended/long addresses from source address match table.
*
* @param[in] aInstance The OpenThread instance structure.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError ClearSrcMatchExtEntries(void);
/**
* Begins the energy scan sequence on the radio.
*
* @param[in] aScanChannel The channel to perform the energy scan on.
* @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration);
/**
* Switches the radio state from Receive to Transmit.
*
* @param[in] aFrame A reference to the transmitted frame.
*
* @retval OT_ERROR_NONE Successfully transitioned to Transmit.
* @retval OT_ERROR_BUSY Failed due to another transmission is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
* @retval OT_ERROR_INVALID_STATE The radio was not in the Receive state.
*/
otError Transmit(otRadioFrame &aFrame);
/**
* Switches the radio state from Sleep to Receive.
*
* @param[in] aChannel The channel to use for receiving.
*
* @retval OT_ERROR_NONE Successfully transitioned to Receive.
* @retval OT_ERROR_INVALID_STATE The radio was disabled or transmitting.
*
*/
otError Receive(uint8_t aChannel);
/**
* Switches the radio state from Receive to Sleep.
*
* @retval OT_ERROR_NONE Successfully transitioned to Sleep.
* @retval OT_ERROR_BUSY The radio was transmitting
* @retval OT_ERROR_INVALID_STATE The radio was disabled
*
*/
otError Sleep(void);
/**
* Enable the radio.
*
* @param[in] aInstance A pointer to the OpenThread instance.
*
* @retval OT_ERROR_NONE Successfully enabled.
* @retval OT_ERROR_FAILED The radio could not be enabled.
*
*/
otError Enable(otInstance *aInstance);
/**
* Disable the radio.
*
* @retval OT_ERROR_NONE Successfully transitioned to Disabled.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError Disable(void);
/**
* Checks whether radio is enabled or not.
*
* @returns TRUE if the radio is enabled, FALSE otherwise.
*
*/
bool IsEnabled(void) const { return mState != kStateDisabled; }
/**
* Indicates whether there is a pending transmission.
*
* @retval TRUE There is a pending transmission.
* @retval FALSE There is no pending transmission.
*
*/
bool IsTransmitting(void) const { return mState == kStateTransmitting; }
/**
* Indicates whether a transmit has just finished.
*
* @retval TRUE The transmission is done.
* @retval FALSE The transmission is not done.
*
*/
bool IsTransmitDone(void) const { return mState == kStateTransmitDone; }
/**
* Returns the timeout timepoint for the pending transmission.
*
* @returns The timeout timepoint for the pending transmission.
*
*/
uint64_t GetTxRadioEndUs(void) const { return mTxRadioEndUs; }
/**
* Processes any pending the I/O data.
*
* @param[in] aContext The process context.
*
*/
void Process(const void *aContext);
#if OPENTHREAD_CONFIG_DIAG_ENABLE
/**
* Enables/disables the factory diagnostics mode.
*
* @param[in] aMode TRUE to enable diagnostics mode, FALSE otherwise.
*
*/
void SetDiagEnabled(bool aMode) { mDiagMode = aMode; }
/**
* Indicates whether or not factory diagnostics mode is enabled.
*
* @returns TRUE if factory diagnostics mode is enabled, FALSE otherwise.
*
*/
bool IsDiagEnabled(void) const { return mDiagMode; }
/**
* Processes platform diagnostics commands.
*
* @param[in] aString A null-terminated input string.
* @param[out] aOutput The diagnostics execution result.
* @param[in] aOutputMaxLen The output buffer size.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError PlatDiagProcess(const char *aString, char *aOutput, size_t aOutputMaxLen);
#endif
/**
* Returns the radio channel mask.
*
* @param[in] aPreferred TRUE to get preferred channel mask, FALSE to get supported channel mask.
*
* @returns The radio channel mask according to @aPreferred:
* The radio supported channel mask that the device is allowed to be on.
* The radio preferred channel mask that the device prefers to form on.
*
*/
uint32_t GetRadioChannelMask(bool aPreferred);
/**
* Processes a received Spinel frame.
*
* The newly received frame is available in `RxFrameBuffer` from `SpinelInterface::GetRxFrameBuffer()`.
*
*/
void HandleReceivedFrame(void);
/**
* Sets MAC key and key index to RCP.
*
* @param[in] aKeyIdMode The key ID mode.
* @param[in] aKeyId The key index.
* @param[in] aPrevKey Pointer to previous MAC key.
* @param[in] aCurrKey Pointer to current MAC key.
* @param[in] aNextKey Pointer to next MAC key.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_INVALID_ARGS One of the keys passed is invalid..
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError SetMacKey(uint8_t aKeyIdMode,
uint8_t aKeyId,
const otMacKeyMaterial *aPrevKey,
const otMacKeyMaterial *aCurrKey,
const otMacKeyMaterial *aNextKey);
/**
* Sets the current MAC Frame Counter value.
*
* @param[in] aMacFrameCounter The MAC Frame Counter value.
* @param[in] aSetIfLarger If `true`, set only if the new value is larger than the current value.
* If `false`, set the new value independent of the current value.
*
*/
otError SetMacFrameCounter(uint32_t aMacFrameCounter, bool aSetIfLarger);
/**
* Sets the radio region code.
*
* @param[in] aRegionCode The radio region code.
*
* @retval OT_ERROR_NONE Successfully set region code.
* @retval OT_ERROR_FAILED Other platform specific errors.
*
*/
otError SetRadioRegion(uint16_t aRegionCode);
/**
* Gets the radio region code.
*
* @param[out] aRegionCode The radio region code.
*
* @retval OT_ERROR_INVALID_ARGS @p aRegionCode is nullptr.
* @retval OT_ERROR_NONE Successfully got region code.
* @retval OT_ERROR_FAILED Other platform specific errors.
*
*/
otError GetRadioRegion(uint16_t *aRegionCode);
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
/**
* Enable/disable or update Enhanced-ACK Based Probing in radio for a specific Initiator.
*
* After Enhanced-ACK Based Probing is configured by a specific Probing Initiator, the Enhanced-ACK sent to that
* node should include Vendor-Specific IE containing Link Metrics data. This method informs the radio to start/stop
* to collect Link Metrics data and include Vendor-Specific IE that containing the data in Enhanced-ACK sent to that
* Probing Initiator.
*
* @param[in] aLinkMetrics This parameter specifies what metrics to query. Per spec 4.11.3.4.4.6, at most 2
* metrics can be specified. The probing would be disabled if @p aLinkMetrics is
* bitwise 0.
* @param[in] aShortAddress The short address of the Probing Initiator.
* @param[in] aExtAddress The extended source address of the Probing Initiator. @p aExtAddress MUST NOT be
* nullptr.
*
* @retval OT_ERROR_NONE Successfully configured the Enhanced-ACK Based Probing.
* @retval OT_ERROR_INVALID_ARGS @p aExtAddress is nullptr.
* @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);
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
/**
* Get the current accuracy, in units of ± ppm, of the clock used for scheduling CSL operations.
*
* @note Platforms may optimize this value based on operational conditions (i.e.: temperature).
*
* @retval The current CSL rx/tx scheduling drift, in units of ± ppm.
*
*/
uint8_t GetCslAccuracy(void);
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
/**
* Get the current uncertainty, in units of 10 us, of the clock used for scheduling CSL operations.
*
* @retval The current CSL Clock Uncertainty in units of 10 us.
*
*/
uint8_t GetCslUncertainty(void);
#endif
/**
* Checks whether the spinel interface is radio-only.
*
* @param[out] aSupportsRcpApiVersion A reference to a boolean variable to update whether the list of
* spinel capabilities includes `SPINEL_CAP_RCP_API_VERSION`.
* @param[out] aSupportsRcpMinHostApiVersion A reference to a boolean variable to update whether the list of
* spinel capabilities includes `SPINEL_CAP_RCP_MIN_HOST_API_VERSION`.
*
* @retval TRUE The radio chip is in radio-only mode.
* @retval FALSE Otherwise.
*
*/
bool IsRcp(bool &aSupportsRcpApiVersion, bool &aSupportsRcpMinHostApiVersion);
/**
* Checks whether there is pending frame in the buffer.
*
* @returns Whether there is pending frame in the buffer.
*
*/
bool HasPendingFrame(void) const { return mRxFrameBuffer.HasSavedFrame(); }
/**
* Returns the next timepoint to recalculate RCP time offset.
*
* @returns The timepoint to start the recalculation of RCP time offset.
*
*/
uint64_t GetNextRadioTimeRecalcStart(void) const { return mRadioTimeRecalcStart; }
/**
* Gets the current estimated time on RCP.
*
* @returns The current estimated RCP time in microseconds.
*
*/
uint64_t GetNow(void);
/**
* Returns the bus speed between the host and the radio.
*
* @returns bus speed in bits/second.
*
*/
uint32_t GetBusSpeed(void) const;
/**
* Sets the max transmit power.
*
* @param[in] aChannel The radio channel.
* @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 aMaxPower);
/**
* Tries to retrieve a spinel property from OpenThread transceiver.
*
* @param[in] aKey Spinel property key.
* @param[in] aFormat Spinel formatter to unpack property value.
* @param[out] ... Variable arguments list.
*
* @retval OT_ERROR_NONE Successfully got the property.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError Get(spinel_prop_key_t aKey, const char *aFormat, ...);
/**
* Tries to retrieve a spinel property from OpenThread transceiver with parameter appended.
*
* @param[in] aKey Spinel property key.
* @param[in] aParam Parameter appended to spinel command.
* @param[in] aParamSize Size of parameter appended to spinel command
* @param[in] aFormat Spinel formatter to unpack property value.
* @param[out] ... Variable arguments list.
*
* @retval OT_ERROR_NONE Successfully got the property.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError GetWithParam(spinel_prop_key_t aKey,
const uint8_t *aParam,
spinel_size_t aParamSize,
const char *aFormat,
...);
/**
* Tries to update a spinel property of OpenThread transceiver.
*
* @param[in] aKey Spinel property key.
* @param[in] aFormat Spinel formatter to pack property value.
* @param[in] ... Variable arguments list.
*
* @retval OT_ERROR_NONE Successfully set the property.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError Set(spinel_prop_key_t aKey, const char *aFormat, ...);
/**
* Tries to insert a item into a spinel list property of OpenThread transceiver.
*
* @param[in] aKey Spinel property key.
* @param[in] aFormat Spinel formatter to pack the item.
* @param[in] ... Variable arguments list.
*
* @retval OT_ERROR_NONE Successfully insert item into the property.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError Insert(spinel_prop_key_t aKey, const char *aFormat, ...);
/**
* Tries to remove a item from a spinel list property of OpenThread transceiver.
*
* @param[in] aKey Spinel property key.
* @param[in] aFormat Spinel formatter to pack the item.
* @param[in] ... Variable arguments list.
*
* @retval OT_ERROR_NONE Successfully removed item from the property.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError Remove(spinel_prop_key_t aKey, const char *aFormat, ...);
/**
* Tries to reset the co-processor.
*
* @prarm[in] aResetType The reset type, SPINEL_RESET_PLATFORM, SPINEL_RESET_STACK, or SPINEL_RESET_BOOTLOADER.
*
* @retval OT_ERROR_NONE Successfully removed item from the property.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_NOT_CAPABLE Requested reset type is not supported by the co-processor
*
*/
otError SendReset(uint8_t aResetType);
/**
* Returns the radio Spinel metrics.
*
* @returns The radio Spinel metrics.
*
*/
const otRadioSpinelMetrics *GetRadioSpinelMetrics(void) const { return &mRadioSpinelMetrics; }
#if OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
/**
* Add a calibrated power of the specified channel to the power calibration table.
*
* @param[in] aChannel The radio channel.
* @param[in] aActualPower The actual power in 0.01dBm.
* @param[in] aRawPowerSetting A pointer to the raw power setting byte array.
* @param[in] aRawPowerSettingLength The length of the @p aRawPowerSetting.
*
* @retval OT_ERROR_NONE Successfully added the calibrated power to the power calibration table.
* @retval OT_ERROR_NO_BUFS No available entry in the power calibration table.
* @retval OT_ERROR_INVALID_ARGS The @p aChannel, @p aActualPower or @p aRawPowerSetting is invalid.
* @retval OT_ERROR_NOT_IMPLEMENTED This feature is not implemented.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError AddCalibratedPower(uint8_t aChannel,
int16_t aActualPower,
const uint8_t *aRawPowerSetting,
uint16_t aRawPowerSettingLength);
/**
* Clear all calibrated powers from the power calibration table.
*
* @retval OT_ERROR_NONE Successfully cleared all calibrated powers from the power calibration table.
* @retval OT_ERROR_NOT_IMPLEMENTED This feature is not implemented.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError ClearCalibratedPowers(void);
/**
* Set the target power for the given channel.
*
* @param[in] aChannel The radio channel.
* @param[in] aTargetPower The target power in 0.01dBm. Passing `INT16_MAX` will disable this channel.
*
* @retval OT_ERROR_NONE Successfully set the target power.
* @retval OT_ERROR_INVALID_ARGS The @p aChannel or @p aTargetPower is invalid..
* @retval OT_ERROR_NOT_IMPLEMENTED The feature is not implemented.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
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);
#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
/**
* Restore the properties of Radio Co-processor (RCP).
*
*/
void RestoreProperties(void);
#endif
#if OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
/**
* Defines a vendor "set property handler" hook to process vendor spinel properties.
*
* The vendor handler should return `OT_ERROR_NOT_FOUND` status if it does not support "set" operation for the
* given property key. Otherwise, the vendor handler should behave like other property set handlers, i.e., it
* should first decode the value from the input spinel frame and then perform the corresponding set operation. The
* handler should not prepare the spinel response and therefore should not write anything to the NCP buffer. The
* `otError` returned from handler (other than `OT_ERROR_NOT_FOUND`) indicates the error in either parsing of the
* input or the error of the set operation. In case of a successful "set", `NcpBase` set command handler will call
* the `VendorGetPropertyHandler()` for the same property key to prepare the response.
*
* @param[in] aPropKey The spinel property key.
*
* @returns OT_ERROR_NOT_FOUND if it does not support the given property key, otherwise the error in either parsing
* of the input or the "set" operation.
*
*/
otError VendorHandleValueIs(spinel_prop_key_t aPropKey);
/**
* A callback type for restoring vendor properties.
*
*/
typedef void (*otRadioSpinelVendorRestorePropertiesCallback)(void *context);
/**
* Registers a callback to restore vendor properties.
*
* This function is used to register a callback for vendor properties recovery. When an event which needs to restore
* properties occurs (such as an unexpected RCP reset), the user can restore the vendor properties via the callback.
*
* @param[in] aCallback The callback.
* @param[in] aContext The context.
*
*/
void SetVendorRestorePropertiesCallback(otRadioSpinelVendorRestorePropertiesCallback aCallback, void *aContext);
#endif
private:
enum
{
kMaxSpinelFrame = SPINEL_FRAME_MAX_SIZE,
kMaxWaitTime = 2000, ///< Max time to wait for response in milliseconds.
kVersionStringSize = 128, ///< Max size of version string.
kCapsBufferSize = 100, ///< Max buffer size used to store `SPINEL_PROP_CAPS` value.
kChannelMaskBufferSize = 32, ///< Max buffer size used to store `SPINEL_PROP_PHY_CHAN_SUPPORTED` value.
};
enum State
{
kStateDisabled, ///< Radio is disabled.
kStateSleep, ///< Radio is sleep.
kStateReceive, ///< Radio is in receive mode.
kStateTransmitting, ///< Frame passed to radio for transmission, waiting for done event from radio.
kStateTransmitDone, ///< Radio indicated frame transmission is done.
};
static constexpr uint32_t kUsPerMs = 1000; ///< Microseconds per millisecond.
static constexpr uint32_t kMsPerSec = 1000; ///< Milliseconds per second.
static constexpr uint32_t kUsPerSec = kUsPerMs * kMsPerSec; ///< Microseconds per second.
static constexpr uint64_t kTxWaitUs =
OPENTHREAD_SPINEL_CONFIG_RCP_TX_WAIT_TIME_SECS *
kUsPerSec; ///< 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);
void ResetRcp(bool aResetRadio);
otError CheckSpinelVersion(void);
otError CheckRadioCapabilities(void);
otError CheckRcpApiVersion(bool aSupportsRcpApiVersion, bool aSupportsRcpMinHostApiVersion);
/**
* Triggers a state transfer of the state machine.
*
*/
void ProcessRadioStateMachine(void);
/**
* Processes the frame queue.
*
*/
void ProcessFrameQueue(void);
spinel_tid_t GetNextTid(void);
void FreeTid(spinel_tid_t tid) { mCmdTidsInUse &= ~(1 << tid); }
otError RequestV(uint32_t aCommand, spinel_prop_key_t aKey, const char *aFormat, va_list aArgs);
otError Request(uint32_t aCommand, spinel_prop_key_t aKey, const char *aFormat, ...);
otError RequestWithPropertyFormat(const char *aPropertyFormat,
uint32_t aCommand,
spinel_prop_key_t aKey,
const char *aFormat,
...);
otError RequestWithPropertyFormatV(const char *aPropertyFormat,
uint32_t aCommand,
spinel_prop_key_t aKey,
const char *aFormat,
va_list aArgs);
otError RequestWithExpectedCommandV(uint32_t aExpectedCommand,
uint32_t aCommand,
spinel_prop_key_t aKey,
const char *aFormat,
va_list aArgs);
otError WaitResponse(bool aHandleRcpTimeout = true);
otError SendCommand(uint32_t aCommand,
spinel_prop_key_t aKey,
spinel_tid_t aTid,
const char *aFormat,
va_list aArgs);
otError ParseRadioFrame(otRadioFrame &aFrame, const uint8_t *aBuffer, uint16_t aLength, spinel_ssize_t &aUnpacked);
/**
* Returns if the property changed event is safe to be handled now.
*
* If a property handler will go up to core stack, it may cause reentrant issue of `Hdlc::Decode()` and
* `WaitResponse()`.
*
* @param[in] aKey The identifier of the property.
*
* @returns Whether this property is safe to be handled now.
*
*/
bool IsSafeToHandleNow(spinel_prop_key_t aKey) const
{
return !(aKey == SPINEL_PROP_STREAM_RAW || aKey == SPINEL_PROP_MAC_ENERGY_SCAN_RESULT);
}
/**
* Checks whether given interface ID is part of list of IIDs to be allowed.
*
* @param[in] aIid Spinel Interface ID.
*
* @retval TRUE Given IID present in allow list.
* @retval FALSE Otherwise.
*
*/
inline bool IsFrameForUs(spinel_iid_t aIid);
void HandleNotification(SpinelInterface::RxFrameBuffer &aFrameBuffer);
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);
void HandleTransmitDone(uint32_t aCommand, spinel_prop_key_t aKey, const uint8_t *aBuffer, uint16_t aLength);
void HandleWaitingResponse(uint32_t aCommand, spinel_prop_key_t aKey, const uint8_t *aBuffer, uint16_t aLength);
void RadioReceive(void);
void TransmitDone(otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError);
void CalcRcpTimeOffset(void);
void HandleRcpUnexpectedReset(spinel_status_t aStatus);
void HandleRcpTimeout(void);
void RecoverFromRcpFailure(void);
void UpdateParseErrorCount(otError aError)
{
mRadioSpinelMetrics.mSpinelParseErrorCount += (aError == OT_ERROR_PARSE) ? 1 : 0;
}
otError SetMacKey(uint8_t aKeyIdMode,
uint8_t aKeyId,
const otMacKey &aPrevKey,
const otMacKey &aCurrKey,
const otMacKey &NextKey);
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
static otError ReadMacKey(const otMacKeyMaterial &aKeyMaterial, otMacKey &aKey);
#endif
otInstance *mInstance;
SpinelInterface::RxFrameBuffer mRxFrameBuffer;
SpinelInterface *mSpinelInterface;
RadioSpinelCallbacks mCallbacks; ///< Callbacks for notifications of higher layer.
uint16_t mCmdTidsInUse; ///< Used transaction ids.
spinel_tid_t mCmdNextTid; ///< Next available transaction id.
spinel_tid_t mTxRadioTid; ///< The transaction id used to send a radio frame.
spinel_tid_t mWaitingTid; ///< The transaction id of current transaction.
spinel_prop_key_t mWaitingKey; ///< The property key of current transaction.
const char *mPropertyFormat; ///< The spinel property format of current transaction.
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
otExtAddress mExtendedAddress;
uint16_t mShortAddress;
uint16_t mPanId;
uint8_t mChannel;
int8_t mRxSensitivity;
otError mTxError;
static char sVersion[kVersionStringSize];
static otExtAddress sIeeeEui64;
static otRadioCaps sRadioCaps;
State mState;
bool mIsPromiscuous : 1; ///< Promiscuous mode.
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.
#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
enum {
kRcpFailureNone,
kRcpFailureTimeout,
kRcpFailureUnexpectedReset,
};
bool mResetRadioOnStartup : 1; ///< Whether should send reset command when init.
int16_t mRcpFailureCount; ///< Count of consecutive RCP failures.
uint8_t mRcpFailure : 2; ///< RCP failure reason, should recover and retry operation.
// Properties set by core.
uint8_t mKeyIdMode;
uint8_t mKeyId;
otMacKey mPrevKey;
otMacKey mCurrKey;
otMacKey mNextKey;
uint16_t mSrcMatchShortEntries[OPENTHREAD_CONFIG_MLE_MAX_CHILDREN];
int16_t mSrcMatchShortEntryCount;
otExtAddress mSrcMatchExtEntries[OPENTHREAD_CONFIG_MLE_MAX_CHILDREN];
int16_t mSrcMatchExtEntryCount;
uint8_t mScanChannel;
uint16_t mScanDuration;
int8_t mCcaEnergyDetectThreshold;
int8_t mTransmitPower;
int8_t mFemLnaGain;
uint32_t mMacFrameCounter;
bool mCoexEnabled : 1;
bool mMacKeySet : 1; ///< Whether MAC key has been set.
bool mCcaEnergyDetectThresholdSet : 1; ///< Whether CCA energy detect threshold has been set.
bool mTransmitPowerSet : 1; ///< Whether transmit power has been set.
bool mCoexEnabledSet : 1; ///< Whether coex enabled has been set.
bool mFemLnaGainSet : 1; ///< Whether FEM LNA gain has been set.
bool mEnergyScanning : 1; ///< If fails while scanning, restarts scanning.
bool mMacFrameCounterSet : 1; ///< Whether the MAC frame counter has been set.
#endif // OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
#if OPENTHREAD_CONFIG_DIAG_ENABLE
bool mDiagMode;
char *mDiagOutput;
size_t mDiagOutputMaxLen;
#endif
uint64_t mTxRadioEndUs;
uint64_t mRadioTimeRecalcStart; ///< When to recalculate RCP time offset.
uint64_t mRadioTimeOffset; ///< Time difference with estimated RCP time minus host time.
MaxPowerTable mMaxPowerTable;
otRadioSpinelMetrics mRadioSpinelMetrics;
#if OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE
otRadioSpinelVendorRestorePropertiesCallback mVendorRestorePropertiesCallback;
void *mVendorRestorePropertiesContext;
#endif
};
} // namespace Spinel
} // namespace ot
#endif // RADIO_SPINEL_HPP_