/*
 *  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 "radio_spinel_metrics.h"
#include "spinel.h"
#include "spinel_interface.hpp"
#include "core/radio/max_power_table.hpp"
#include "ncp/ncp_config.h"

namespace ot {
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:
 *
 * 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
{
public:
    /**
     * Initializes the spinel based OpenThread transceiver.
     *
     */
    RadioSpinel(void);

    /**
     * Initialize this radio transceiver.
     *
     * @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);

    /**
     * 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 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 &aAddress);

    /**
     * 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 mVersion; }

    /**
     * Returns the radio capabilities.
     *
     * @returns The radio capability bit vector.
     *
     */
    otRadioCaps GetRadioCaps(void) const { return mRadioCaps; }

    /**
     * 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

    /**
     * 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);

    /**
     * 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.
     *
     * @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] aPower      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);

    /**
     * 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 or SPINEL_RESET_STACK.
     *
     * @retval  OT_ERROR_NONE               Successfully removed item from the property.
     * @retval  OT_ERROR_BUSY               Failed due to another operation is on going.
     *
     */
    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

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.
    };

    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 aSupportsMinHostRcpApiVersion);

    /**
     * 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);
    }

    void HandleNotification(SpinelInterface::RxFrameBuffer &aFrameBuffer);
    void HandleNotification(const uint8_t *aBuffer, 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);

#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
    void RestoreProperties(void);
#endif
    void UpdateParseErrorCount(otError aError)
    {
        mRadioSpinelMetrics.mSpinelParseErrorCount += (aError == OT_ERROR_PARSE) ? 1 : 0;
    }

    uint32_t Snprintf(char *aDest, uint32_t aSize, const char *aFormat, ...);
    void     LogSpinelFrame(const uint8_t *aFrame, uint16_t aLength, bool aTx);

    otInstance *mInstance;

    SpinelInterface::RxFrameBuffer mRxFrameBuffer;

    InterfaceType mSpinelInterface;

    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.

    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;
    otRadioCaps  mRadioCaps;
    uint8_t      mChannel;
    int8_t       mRxSensitivity;
    otError      mTxError;
    char         mVersion[kVersionStringSize];
    otExtAddress mIeeeEui64;

    State mState;
    bool  mIsPromiscuous : 1;     ///< Promiscuous mode.
    bool  mIsReady : 1;           ///< NCP ready.
    bool  mSupportsLogStream : 1; ///< RCP supports `LOG_STREAM` property with OpenThread log meta-data format.
    bool  mIsTimeSynced : 1;      ///< Host has calculated the time difference between host and RCP.

#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0

    bool    mResetRadioOnStartup : 1; ///< Whether should send reset command when init.
    int16_t mRcpFailureCount;         ///< Count of consecutive RCP failures.

    // 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 mRcpFailed : 1;                   ///< RCP failure happened, should recover and retry operation.
    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;
};

} // namespace Spinel
} // namespace ot

#include "radio_spinel_impl.hpp"

#endif // RADIO_SPINEL_HPP_
