/*
 *  Copyright (c) 2016-2017, 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
 * @brief
 *  This file defines the OpenThread Thread API (FTD only).
 */

#ifndef OPENTHREAD_THREAD_FTD_H_
#define OPENTHREAD_THREAD_FTD_H_

#include <openthread/link.h>
#include <openthread/message.h>
#include <openthread/thread.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @addtogroup api-thread-router
 *
 * @{
 *
 */

/**
 * This structure holds diagnostic information for a Thread Child
 *
 */
typedef struct
{
    otExtAddress mExtAddress;           ///< IEEE 802.15.4 Extended Address
    uint32_t     mTimeout;              ///< Timeout
    uint32_t     mAge;                  ///< Time last heard
    uint16_t     mRloc16;               ///< RLOC16
    uint16_t     mChildId;              ///< Child ID
    uint8_t      mNetworkDataVersion;   ///< Network Data Version
    uint8_t      mLinkQualityIn;        ///< Link Quality In
    int8_t       mAverageRssi;          ///< Average RSSI
    int8_t       mLastRssi;             ///< Last observed RSSI
    uint16_t     mFrameErrorRate;       ///< Frame error rate (0xffff->100%). Requires error tracking feature.
    uint16_t     mMessageErrorRate;     ///< (IPv6) msg error rate (0xffff->100%). Requires error tracking feature.
    uint16_t     mQueuedMessageCnt;     ///< Number of queued messages for the child.
    uint8_t      mVersion;              ///< MLE version
    bool         mRxOnWhenIdle : 1;     ///< rx-on-when-idle
    bool         mFullThreadDevice : 1; ///< Full Thread Device
    bool         mFullNetworkData : 1;  ///< Full Network Data
    bool         mIsStateRestoring : 1; ///< Is in restoring state
    bool         mIsCslSynced : 1;      ///< Is child CSL synchronized
} otChildInfo;

#define OT_CHILD_IP6_ADDRESS_ITERATOR_INIT 0 ///< Initializer for otChildIP6AddressIterator

typedef uint16_t otChildIp6AddressIterator; ///< Used to iterate through IPv6 addresses of a Thread Child entry.

/**
 * This enumeration defines the EID cache entry state.
 *
 */
typedef enum otCacheEntryState
{
    OT_CACHE_ENTRY_STATE_CACHED      = 0, // Entry is cached and in-use.
    OT_CACHE_ENTRY_STATE_SNOOPED     = 1, // Entry is created by snoop optimization (inspection of received msg).
    OT_CACHE_ENTRY_STATE_QUERY       = 2, // Entry represents an ongoing query for the EID.
    OT_CACHE_ENTRY_STATE_RETRY_QUERY = 3, // Entry is in retry wait mode (a prior query did not get a response).
} otCacheEntryState;

/**
 * This structure represents an EID cache entry.
 *
 */
typedef struct otCacheEntryInfo
{
    otIp6Address      mTarget;             ///< Target EID
    otShortAddress    mRloc16;             ///< RLOC16
    otCacheEntryState mState;              ///< Entry state
    bool              mCanEvict : 1;       ///< Indicates whether the entry can be evicted.
    bool              mValidLastTrans : 1; ///< Indicates whether last transaction time and ML-EID are valid.
    uint32_t          mLastTransTime;      ///< Last transaction time (applicable in cached state).
    otIp6Address      mMeshLocalEid;       ///< Mesh Local EID (applicable if entry in cached state).
    uint16_t          mTimeout;            ///< Timeout in seconds (applicable if in snooped/query/retry-query states).
    uint16_t          mRetryDelay;         ///< Retry delay in seconds (applicable if in query-retry state).
} otCacheEntryInfo;

/**
 * This type represents an iterator used for iterating through the EID cache table entries.
 *
 * To initialize the iterator and start from the first entry in the cache table, set all its fields in the structure to
 * zero (e.g., `memset` the iterator to zero).
 *
 */
typedef struct otCacheEntryIterator
{
    const void *mData[2]; ///< Opaque data used by the core implementation. Should not be changed by user.
} otCacheEntryIterator;

/**
 * Get the maximum number of children currently allowed.
 *
 * @param[in]  aInstance A pointer to an OpenThread instance.
 *
 * @returns The maximum number of children currently allowed.
 *
 * @sa otThreadSetMaxAllowedChildren
 *
 */
uint16_t otThreadGetMaxAllowedChildren(otInstance *aInstance);

/**
 * Set the maximum number of children currently allowed.
 *
 * This parameter can only be set when Thread protocol operation has been stopped.
 *
 * @param[in]  aInstance     A pointer to an OpenThread instance.
 * @param[in]  aMaxChildren  The maximum allowed children.
 *
 * @retval  OT_ERROR_NONE           Successfully set the max.
 * @retval  OT_ERROR_INVALID_ARGS   If @p aMaxChildren is not in the range [1, OPENTHREAD_CONFIG_MLE_MAX_CHILDREN].
 * @retval  OT_ERROR_INVALID_STATE  If Thread isn't stopped.
 *
 * @sa otThreadGetMaxAllowedChildren
 *
 */
otError otThreadSetMaxAllowedChildren(otInstance *aInstance, uint16_t aMaxChildren);

/**
 * This method indicates whether or not the device is router-eligible.
 *
 * @param[in]  aInstance A pointer to an OpenThread instance.
 *
 * @retval TRUE   If device is router-eligible.
 * @retval FALSE  If device is not router-eligible.
 *
 */
bool otThreadIsRouterEligible(otInstance *aInstance);

/**
 * This function sets whether or not the device is router-eligible.
 *
 * If @p aEligible is false and the device is currently operating as a router, this call will cause the device to
 * detach and attempt to reattach as a child.
 *
 * @param[in]  aInstance  A pointer to an OpenThread instance.
 * @param[in]  aEligible  TRUE to configure the device as router-eligible, FALSE otherwise.
 *
 * @retval OT_ERROR_NONE         Successfully set the router-eligible configuration.
 * @retval OT_ERROR_NOT_CAPABLE  The device is not capable of becoming a router.
 *
 */
otError otThreadSetRouterEligible(otInstance *aInstance, bool aEligible);

/**
 * Set the preferred Router Id.
 *
 * Upon becoming a router/leader the node attempts to use this Router Id. If the preferred Router Id is not set or if
 * it can not be used, a randomly generated router id is picked. This property can be set only when the device role is
 * either detached or disabled.
 *
 * @note This API is reserved for testing and demo purposes only. Changing settings with
 * this API will render a production application non-compliant with the Thread Specification.
 *
 * @param[in]  aInstance    A pointer to an OpenThread instance.
 * @param[in]  aRouterId    The preferred Router Id.
 *
 * @retval OT_ERROR_NONE          Successfully set the preferred Router Id.
 * @retval OT_ERROR_INVALID_STATE Could not set (role is not detached or disabled)
 *
 */
otError otThreadSetPreferredRouterId(otInstance *aInstance, uint8_t aRouterId);

/**
 * Get the Thread Leader Weight used when operating in the Leader role.
 *
 * @param[in]  aInstance A pointer to an OpenThread instance.
 *
 * @returns The Thread Leader Weight value.
 *
 * @sa otThreadSetLeaderWeight
 *
 */
uint8_t otThreadGetLocalLeaderWeight(otInstance *aInstance);

/**
 * Set the Thread Leader Weight used when operating in the Leader role.
 *
 * @param[in]  aInstance A pointer to an OpenThread instance.
 * @param[in]  aWeight   The Thread Leader Weight value.
 *
 * @sa otThreadGetLeaderWeight
 *
 */
void otThreadSetLocalLeaderWeight(otInstance *aInstance, uint8_t aWeight);

/**
 * Get the preferred Thread Leader Partition Id used when operating in the Leader role.
 *
 * @param[in]  aInstance A pointer to an OpenThread instance.
 *
 * @returns The Thread Leader Partition Id value.
 *
 */
uint32_t otThreadGetPreferredLeaderPartitionId(otInstance *aInstance);

/**
 * Set the preferred Thread Leader Partition Id used when operating in the Leader role.
 *
 * @param[in]  aInstance     A pointer to an OpenThread instance.
 * @param[in]  aPartitionId  The Thread Leader Partition Id value.
 *
 */
void otThreadSetPreferredLeaderPartitionId(otInstance *aInstance, uint32_t aPartitionId);

/**
 * Get the Joiner UDP Port.
 *
 * @param[in] aInstance A pointer to an OpenThread instance.
 *
 * @returns The Joiner UDP Port number.
 *
 * @sa otThreadSetJoinerUdpPort
 *
 */
uint16_t otThreadGetJoinerUdpPort(otInstance *aInstance);

/**
 * Set the Joiner UDP Port.
 *
 * @param[in]  aInstance       A pointer to an OpenThread instance.
 * @param[in]  aJoinerUdpPort  The Joiner UDP Port number.
 *
 * @retval  OT_ERROR_NONE  Successfully set the Joiner UDP Port.
 *
 * @sa otThreadGetJoinerUdpPort
 *
 */
otError otThreadSetJoinerUdpPort(otInstance *aInstance, uint16_t aJoinerUdpPort);

/**
 * Set Steering data out of band.
 *
 * Configuration option `OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE` should be set to enable setting of steering
 * data out of band.
 *
 * @param[in]  aInstance       A pointer to an OpenThread instance.
 * @param[in]  aExtAddress     Address used to update the steering data.
 *                             All zeros to clear the steering data (no steering data).
 *                             All 0xFFs to set steering data/bloom filter to accept/allow all.
 *                             A specific EUI64 which is then added to current steering data/bloom filter.
 *
 */
void otThreadSetSteeringData(otInstance *aInstance, const otExtAddress *aExtAddress);

/**
 * Get the CONTEXT_ID_REUSE_DELAY parameter used in the Leader role.
 *
 * @param[in]  aInstance A pointer to an OpenThread instance.
 *
 * @returns The CONTEXT_ID_REUSE_DELAY value.
 *
 * @sa otThreadSetContextIdReuseDelay
 *
 */
uint32_t otThreadGetContextIdReuseDelay(otInstance *aInstance);

/**
 * Set the CONTEXT_ID_REUSE_DELAY parameter used in the Leader role.
 *
 * @note This API is reserved for testing and demo purposes only. Changing settings with
 * this API will render a production application non-compliant with the Thread Specification.
 *
 * @param[in]  aInstance A pointer to an OpenThread instance.
 * @param[in]  aDelay    The CONTEXT_ID_REUSE_DELAY value.
 *
 * @sa otThreadGetContextIdReuseDelay
 *
 */
void otThreadSetContextIdReuseDelay(otInstance *aInstance, uint32_t aDelay);

/**
 * Get the NETWORK_ID_TIMEOUT parameter used in the Router role.
 *
 * @note This API is reserved for testing and demo purposes only. Changing settings with
 * this API will render a production application non-compliant with the Thread Specification.
 *
 * @param[in]  aInstance A pointer to an OpenThread instance.
 *
 * @returns The NETWORK_ID_TIMEOUT value.
 *
 * @sa otThreadSetNetworkIdTimeout
 *
 */
uint8_t otThreadGetNetworkIdTimeout(otInstance *aInstance);

/**
 * Set the NETWORK_ID_TIMEOUT parameter used in the Leader role.
 *
 * @param[in]  aInstance A pointer to an OpenThread instance.
 * @param[in]  aTimeout  The NETWORK_ID_TIMEOUT value.
 *
 * @sa otThreadGetNetworkIdTimeout
 *
 */
void otThreadSetNetworkIdTimeout(otInstance *aInstance, uint8_t aTimeout);

/**
 * Get the ROUTER_UPGRADE_THRESHOLD parameter used in the REED role.
 *
 * @param[in]  aInstance A pointer to an OpenThread instance.
 *
 * @returns The ROUTER_UPGRADE_THRESHOLD value.
 *
 * @sa otThreadSetRouterUpgradeThreshold
 *
 */
uint8_t otThreadGetRouterUpgradeThreshold(otInstance *aInstance);

/**
 * Set the ROUTER_UPGRADE_THRESHOLD parameter used in the Leader role.
 *
 * @note This API is reserved for testing and demo purposes only. Changing settings with
 * this API will render a production application non-compliant with the Thread Specification.
 *
 * @param[in]  aInstance   A pointer to an OpenThread instance.
 * @param[in]  aThreshold  The ROUTER_UPGRADE_THRESHOLD value.
 *
 * @sa otThreadGetRouterUpgradeThreshold
 *
 */
void otThreadSetRouterUpgradeThreshold(otInstance *aInstance, uint8_t aThreshold);

/**
 * Release a Router ID that has been allocated by the device in the Leader role.
 *
 * @note This API is reserved for testing and demo purposes only. Changing settings with
 * this API will render a production application non-compliant with the Thread Specification.
 *
 * @param[in]  aInstance  A pointer to an OpenThread instance.
 * @param[in]  aRouterId  The Router ID to release. Valid range is [0, 62].
 *
 * @retval OT_ERROR_NONE           Successfully released the router id.
 * @retval OT_ERROR_INVALID_ARGS   @p aRouterId is not in the range [0, 62].
 * @retval OT_ERROR_INVALID_STATE  The device is not currently operating as a leader.
 * @retval OT_ERROR_NOT_FOUND      The router id is not currently allocated.
 *
 */
otError otThreadReleaseRouterId(otInstance *aInstance, uint8_t aRouterId);

/**
 * Attempt to become a router.
 *
 * @note This API is reserved for testing and demo purposes only. Changing settings with
 * this API will render a production application non-compliant with the Thread Specification.
 *
 * @param[in]  aInstance A pointer to an OpenThread instance.
 *
 * @retval OT_ERROR_NONE           Successfully begin attempt to become a router.
 * @retval OT_ERROR_INVALID_STATE  Thread is disabled.
 */
otError otThreadBecomeRouter(otInstance *aInstance);

/**
 * Become a leader and start a new partition.
 *
 * @note This API is reserved for testing and demo purposes only. Changing settings with
 * this API will render a production application non-compliant with the Thread Specification.
 *
 * @param[in]  aInstance A pointer to an OpenThread instance.
 *
 * @retval OT_ERROR_NONE           Successfully became a leader and started a new partition.
 * @retval OT_ERROR_INVALID_STATE  Thread is disabled.
 */
otError otThreadBecomeLeader(otInstance *aInstance);

/**
 * Get the ROUTER_DOWNGRADE_THRESHOLD parameter used in the Router role.
 *
 * @param[in]  aInstance  A pointer to an OpenThread instance.
 *
 * @returns The ROUTER_DOWNGRADE_THRESHOLD value.
 *
 * @sa otThreadSetRouterDowngradeThreshold
 *
 */
uint8_t otThreadGetRouterDowngradeThreshold(otInstance *aInstance);

/**
 * Set the ROUTER_DOWNGRADE_THRESHOLD parameter used in the Leader role.
 *
 * @note This API is reserved for testing and demo purposes only. Changing settings with
 * this API will render a production application non-compliant with the Thread Specification.
 *
 * @param[in]  aInstance   A pointer to an OpenThread instance.
 * @param[in]  aThreshold  The ROUTER_DOWNGRADE_THRESHOLD value.
 *
 * @sa otThreadGetRouterDowngradeThreshold
 *
 */
void otThreadSetRouterDowngradeThreshold(otInstance *aInstance, uint8_t aThreshold);

/**
 * Get the ROUTER_SELECTION_JITTER parameter used in the REED/Router role.
 *
 * @param[in]  aInstance   A pointer to an OpenThread instance.
 *
 * @returns The ROUTER_SELECTION_JITTER value.
 *
 * @sa otThreadSetRouterSelectionJitter
 *
 */
uint8_t otThreadGetRouterSelectionJitter(otInstance *aInstance);

/**
 * Set the ROUTER_SELECTION_JITTER parameter used in the REED/Router role.
 *
 * @note This API is reserved for testing and demo purposes only. Changing settings with
 * this API will render a production application non-compliant with the Thread Specification.
 *
 * @param[in]  aInstance      A pointer to an OpenThread instance.
 * @param[in]  aRouterJitter  The ROUTER_SELECTION_JITTER value.
 *
 * @sa otThreadGetRouterSelectionJitter
 *
 */
void otThreadSetRouterSelectionJitter(otInstance *aInstance, uint8_t aRouterJitter);

/**
 * The function retains diagnostic information for an attached Child by its Child ID or RLOC16.
 *
 * @param[in]   aInstance   A pointer to an OpenThread instance.
 * @param[in]   aChildId    The Child ID or RLOC16 for the attached child.
 * @param[out]  aChildInfo  A pointer to where the child information is placed.
 *
 * @retval OT_ERROR_NONE          @p aChildInfo was successfully updated with the info for the given ID.
 * @retval OT_ERROR_NOT_FOUND     No valid child with this Child ID.
 * @retval OT_ERROR_INVALID_ARGS  If @p aChildInfo is NULL.
 *
 */
otError otThreadGetChildInfoById(otInstance *aInstance, uint16_t aChildId, otChildInfo *aChildInfo);

/**
 * The function retains diagnostic information for an attached Child by the internal table index.
 *
 * @param[in]   aInstance    A pointer to an OpenThread instance.
 * @param[in]   aChildIndex  The table index.
 * @param[out]  aChildInfo   A pointer to where the child information is placed.
 *
 * @retval OT_ERROR_NONE             @p aChildInfo was successfully updated with the info for the given index.
 * @retval OT_ERROR_NOT_FOUND        No valid child at this index.
 * @retval OT_ERROR_INVALID_ARGS     Either @p aChildInfo is NULL, or @p aChildIndex is out of range (higher
 *                                   than max table index).
 *
 * @sa otGetMaxAllowedChildren
 *
 */
otError otThreadGetChildInfoByIndex(otInstance *aInstance, uint16_t aChildIndex, otChildInfo *aChildInfo);

/**
 * This function gets the next IPv6 address (using an iterator) for a given child.
 *
 * @param[in]      aInstance    A pointer to an OpenThread instance.
 * @param[in]      aChildIndex  The child index.
 * @param[in,out]  aIterator    A pointer to the iterator. On success the iterator will be updated to point to next
 *                              entry in the list. To get the first IPv6 address the iterator should be set to
 *                              OT_CHILD_IP6_ADDRESS_ITERATOR_INIT.
 * @param[out]     aAddress     A pointer to an IPv6 address where the child's next address is placed (on success).
 *
 * @retval OT_ERROR_NONE          Successfully found the next IPv6 address (@p aAddress was successfully updated).
 * @retval OT_ERROR_NOT_FOUND     The child has no subsequent IPv6 address entry.
 * @retval OT_ERROR_INVALID_ARGS  @p aIterator or @p aAddress are NULL, or child at @p aChildIndex is not valid.
 *
 * @sa otThreadGetChildInfoByIndex
 *
 */
otError otThreadGetChildNextIp6Address(otInstance *               aInstance,
                                       uint16_t                   aChildIndex,
                                       otChildIp6AddressIterator *aIterator,
                                       otIp6Address *             aAddress);

/**
 * Get the current Router ID Sequence.
 *
 * @param[in]  aInstance A pointer to an OpenThread instance.
 *
 * @returns The Router ID Sequence.
 *
 */
uint8_t otThreadGetRouterIdSequence(otInstance *aInstance);

/**
 * The function returns the maximum allowed router ID
 *
 * @param[in]   aInstance    A pointer to an OpenThread instance.
 *
 * @returns The maximum allowed router ID.
 *
 */
uint8_t otThreadGetMaxRouterId(otInstance *aInstance);

/**
 * The function retains diagnostic information for a given Thread Router.
 *
 * @param[in]   aInstance    A pointer to an OpenThread instance.
 * @param[in]   aRouterId    The router ID or RLOC16 for a given router.
 * @param[out]  aRouterInfo  A pointer to where the router information is placed.
 *
 * @retval OT_ERROR_NONE          Successfully retrieved the router info for given id.
 * @retval OT_ERROR_NOT_FOUND     No router entry with the given id.
 * @retval OT_ERROR_INVALID_ARGS  @p aRouterInfo is NULL.
 *
 */
otError otThreadGetRouterInfo(otInstance *aInstance, uint16_t aRouterId, otRouterInfo *aRouterInfo);

/**
 * This function gets the next EID cache entry (using an iterator).
 *
 * @param[in]     aInstance   A pointer to an OpenThread instance.
 * @param[out]    aEntryInfo  A pointer to where the EID cache entry information is placed.
 * @param[in,out] aIterator   A pointer to an iterator. It will be updated to point to next entry on success. To get
 *                            the first entry, initialize the iterator by setting all its fields to zero
 *                            (e.g., `memset` the iterator structure to zero).
 *
 * @retval OT_ERROR_NONE          Successfully populated @p aEntryInfo for next EID cache entry.
 * @retval OT_ERROR_NOT_FOUND     No more entries in the address cache table.
 *
 */
otError otThreadGetNextCacheEntry(otInstance *aInstance, otCacheEntryInfo *aEntryInfo, otCacheEntryIterator *aIterator);

/**
 * Get the Thread PSKc
 *
 * @param[in]   aInstance   A pointer to an OpenThread instance.
 * @param[out]  aPskc       A pointer to an `otPskc` to return the retrieved Thread PSKc.
 *
 * @sa otThreadSetPskc
 *
 */
void otThreadGetPskc(otInstance *aInstance, otPskc *aPskc);

/**
 * Get Key Reference to Thread PSKc stored
 *
 * This function requires the build-time feature `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` to be enabled.
 *
 * @param[in]   aInstance   A pointer to an OpenThread instance.
 *
 * @returns Key Reference to PSKc
 *
 * @sa otThreadSetPskcRef
 *
 */
otPskcRef otThreadGetPskcRef(otInstance *aInstance);

/**
 * Set the Thread PSKc
 *
 * This function will only succeed when Thread protocols are disabled.  A successful
 * call to this function will also invalidate the Active and Pending Operational Datasets in
 * non-volatile memory.
 *
 * @param[in]  aInstance   A pointer to an OpenThread instance.
 * @param[in]  aPskc       A pointer to the new Thread PSKc.
 *
 * @retval OT_ERROR_NONE           Successfully set the Thread PSKc.
 * @retval OT_ERROR_INVALID_STATE  Thread protocols are enabled.
 *
 * @sa otThreadGetPskc
 *
 */
otError otThreadSetPskc(otInstance *aInstance, const otPskc *aPskc);

/**
 * Set the Thread PSKc
 *
 * This function requires the build-time feature `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` to be enabled.
 *
 * This function will only succeed when Thread protocols are disabled.  A successful
 * call to this function will also invalidate the Active and Pending Operational Datasets in
 * non-volatile memory.
 *
 * @param[in]  aInstance   A pointer to an OpenThread instance.
 * @param[in]  aKeyRef     Key Reference to the new Thread PSKc.
 *
 * @retval OT_ERROR_NONE           Successfully set the Thread PSKc.
 * @retval OT_ERROR_INVALID_STATE  Thread protocols are enabled.
 *
 * @sa otThreadGetPskcRef
 *
 */
otError otThreadSetPskcRef(otInstance *aInstance, otPskcRef aKeyRef);

/**
 * Get the assigned parent priority.
 *
 * @param[in]   aInstance   A pointer to an OpenThread instance.
 *
 * @returns The assigned parent priority value, -2 means not assigned.
 *
 * @sa otThreadSetParentPriority
 *
 */
int8_t otThreadGetParentPriority(otInstance *aInstance);

/**
 * Set the parent priority.
 *
 * @note This API is reserved for testing and demo purposes only. Changing settings with
 * this API will render a production application non-compliant with the Thread Specification.
 *
 * @param[in]  aInstance        A pointer to an OpenThread instance.
 * @param[in]  aParentPriority  The parent priority value.
 *
 * @retval OT_ERROR_NONE           Successfully set the parent priority.
 * @retval OT_ERROR_INVALID_ARGS   If the parent priority value is not among 1, 0, -1 and -2.
 *
 * @sa otThreadGetParentPriority
 *
 */
otError otThreadSetParentPriority(otInstance *aInstance, int8_t aParentPriority);

/**
 * This function gets the maximum number of IP addresses that each MTD child may register with this device as parent.
 *
 * @param[in]  aInstance    A pointer to an OpenThread instance.
 *
 * @returns The maximum number of IP addresses that each MTD child may register with this device as parent.
 *
 * @sa otThreadSetMaxChildIpAddresses
 *
 */
uint8_t otThreadGetMaxChildIpAddresses(otInstance *aInstance);

/**
 * This function sets/restores the maximum number of IP addresses that each MTD child may register with this
 * device as parent.
 *
 * @note This API requires `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE`, and is only used by Thread Test Harness
 *       to limit the address registrations of the reference parent in order to test the MTD DUT reaction.
 *
 * @param[in]  aInstance        A pointer to an OpenThread instance.
 * @param[in]  aMaxIpAddresses  The maximum number of IP addresses that each MTD child may register with this
 *                              device as parent. 0 to clear the setting and restore the default.
 *
 * @retval OT_ERROR_NONE           Successfully set/cleared the number.
 * @retval OT_ERROR_INVALID_ARGS   If exceeds the allowed maximum number.
 *
 * @sa otThreadGetMaxChildIpAddresses
 *
 */
otError otThreadSetMaxChildIpAddresses(otInstance *aInstance, uint8_t aMaxIpAddresses);

/**
 * This enumeration defines the constants used in `otNeighborTableCallback` to indicate changes in neighbor table.
 *
 */
typedef enum
{
    OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED,        ///< A child is being added.
    OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED,      ///< A child is being removed.
    OT_NEIGHBOR_TABLE_EVENT_CHILD_MODE_CHANGED, ///< An existing child's mode is changed.
    OT_NEIGHBOR_TABLE_EVENT_ROUTER_ADDED,       ///< A router is being added.
    OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED,     ///< A router is being removed.
} otNeighborTableEvent;

/**
 * This type represent a neighbor table entry info (child or router) and is used as a parameter in the neighbor table
 * callback `otNeighborTableCallback`.
 *
 */
typedef struct
{
    otInstance *mInstance; ///< The OpenThread instance.
    union
    {
        otChildInfo    mChild;  ///< The child neighbor info.
        otNeighborInfo mRouter; ///< The router neighbor info.
    } mInfo;
} otNeighborTableEntryInfo;

/**
 * This function pointer is called to notify that there is a change in the neighbor table.
 *
 * @param[in]  aEvent      A event flag.
 * @param[in]  aEntryInfo  A pointer to table entry info.
 *
 */
typedef void (*otNeighborTableCallback)(otNeighborTableEvent aEvent, const otNeighborTableEntryInfo *aEntryInfo);

/**
 * This function registers a neighbor table callback function.
 *
 * The provided callback (if non-NULL) will be invoked when there is a change in the neighbor table (e.g., a child or a
 * router neighbor entry is being added/removed or an existing child's mode is changed).
 *
 * Subsequent calls to this method will overwrite the previous callback.  Note that this callback in invoked while the
 * neighbor/child table is being updated and always before the `otStateChangedCallback`.
 *
 * @param[in] aInstance  A pointer to an OpenThread instance.
 * @param[in] aCallback  A pointer to callback handler function.
 *
 */
void otThreadRegisterNeighborTableCallback(otInstance *aInstance, otNeighborTableCallback aCallback);

/**
 * This function sets whether the device was commissioned using CCM.
 *
 * @note This API requires `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE`, and is only used by Thread Test Harness
 *       to indicate whether this device was commissioned using CCM.
 *
 * @param[in]  aInstance  A pointer to an OpenThread instance.
 * @param[in]  aEnabled   TRUE if the device was commissioned using CCM, FALSE otherwise.
 *
 */
void otThreadSetCcmEnabled(otInstance *aInstance, bool aEnabled);

/**
 * This function sets whether the Security Policy TLV version-threshold for routing (VR field) is enabled.
 *
 * @note This API requires `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE`, and is only used by Thread Test Harness
 *       to indicate that thread protocol version check VR should be skipped.
 *
 * @param[in]  aInstance  A pointer to an OpenThread instance.
 * @param[in]  aEnabled   TRUE to enable Security Policy TLV version-threshold for routing, FALSE otherwise.
 *
 */
void otThreadSetThreadVersionCheckEnabled(otInstance *aInstance, bool aEnabled);

/**
 * This function gets the range of router IDs that are allowed to assign to nodes within the thread network.
 *
 * @note This API requires `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE`, and is only used for test purpose. All the
 * router IDs in the range [aMinRouterId, aMaxRouterId] are allowed.
 *
 * @param[in]   aInstance     A pointer to an OpenThread instance.
 * @param[out]  aMinRouterId  The minimum router ID.
 * @param[out]  aMaxRouterId  The maximum router ID.
 *
 * @sa otThreadSetRouterIdRange
 *
 */
void otThreadGetRouterIdRange(otInstance *aInstance, uint8_t *aMinRouterId, uint8_t *aMaxRouterId);

/**
 * This function sets the range of router IDs that are allowed to assign to nodes within the thread network.
 *
 * @note This API requires `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE`, and is only used for test purpose. All the
 * router IDs in the range [aMinRouterId, aMaxRouterId] are allowed.
 *
 * @param[in]  aInstance     A pointer to an OpenThread instance.
 * @param[in]  aMinRouterId  The minimum router ID.
 * @param[in]  aMaxRouterId  The maximum router ID.
 *
 * @retval  OT_ERROR_NONE           Successfully set the range.
 * @retval  OT_ERROR_INVALID_ARGS   aMinRouterId > aMaxRouterId, or the range is not covered by [0, 62].
 *
 * @sa otThreadGetRouterIdRange
 *
 */
otError otThreadSetRouterIdRange(otInstance *aInstance, uint8_t aMinRouterId, uint8_t aMaxRouterId);
/**
 * @}
 *
 */

#ifdef __cplusplus
} // extern "C"
#endif

#endif // OPENTHREAD_THREAD_FTD_H_
