/*
 *  Copyright (c) 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
 *   This file includes definitions for data poll (mac data request command) sender.
 */

#ifndef DATA_POLL_MANAGER_HPP_
#define DATA_POLL_MANAGER_HPP_

#include "openthread-core-config.h"

#include "common/code_utils.hpp"
#include "common/locator.hpp"
#include "common/non_copyable.hpp"
#include "common/timer.hpp"
#include "mac/mac.hpp"
#include "mac/mac_frame.hpp"
#include "thread/topology.hpp"

namespace ot {

/**
 * @addtogroup core-data-poll-sender
 *
 * @brief
 *   This module includes definitions for data poll sender.
 *
 * @{
 */

/**
 * This class implements the data poll (mac data request command) sender.
 *
 */

class DataPollSender : public InstanceLocator, private NonCopyable
{
public:
    static constexpr uint8_t kDefaultFastPolls  = 8;  ///< Default number of fast poll tx (@sa StartFastPolls).
    static constexpr uint8_t kMaxFastPolls      = 15; ///< Maximum number of fast poll tx allowed.
    static constexpr uint8_t kMaxFastPollsUsers = 63; ///< Maximum number of the users of fast poll tx allowed.

    /**
     * This constructor initializes the data poll sender object.
     *
     * @param[in]  aInstance   A reference to the OpenThread instance.
     *
     */
    explicit DataPollSender(Instance &aInstance);

    /**
     * This method instructs the data poll sender to start sending periodic data polls.
     *
     */
    void StartPolling(void);

    /**
     * This method instructs the data poll sender to stop sending periodic data polls.
     *
     */
    void StopPolling(void);

    /**
     * This method enqueues a data poll (an IEEE 802.15.4 Data Request) message.
     *
     * @retval kErrorNone          Successfully enqueued a data poll message
     * @retval kErrorAlready       A data poll message is already enqueued.
     * @retval kErrorInvalidState  Device is not in rx-off-when-idle mode.
     * @retval kErrorNoBufs        Insufficient message buffers available.
     *
     */
    Error SendDataPoll(void);

    /**
     * This method sets/clears a user-specified/external data poll period.
     *
     * Value of zero for `aPeriod` clears the user-specified poll period.
     *
     * If the user provides a non-zero poll period, the user value specifies the maximum period between data
     * request transmissions. Note that OpenThread may send data request transmissions more frequently when expecting
     * a control-message from a parent or in case of data poll transmission failures or timeouts, or when the specified
     * value is larger than the child timeout.
     *
     * A non-zero `aPeriod` should be larger than or equal to `OPENTHREAD_CONFIG_MAC_MINIMUM_POLL_PERIOD` (10ms) or
     * this method returns `kErrorInvalidArgs`. If a non-zero `aPeriod` is larger than maximum value of
     * `0x3FFFFFF ((1 << 26) - 1)`, it would be clipped to this value.
     *
     * @param[in]  aPeriod  The data poll period in milliseconds.
     *
     * @retval kErrorNone           Successfully set/cleared user-specified poll period.
     * @retval kErrorInvalidArgs    If aPeriod is invalid.
     *
     */
    Error SetExternalPollPeriod(uint32_t aPeriod);

    /**
     * This method gets the current user-specified/external data poll period.
     *
     * @returns  The data poll period in milliseconds.
     *
     */
    uint32_t GetExternalPollPeriod(void) const { return mExternalPollPeriod; }

    /**
     * This method informs the data poll sender of success/error status of a previously requested poll frame
     * transmission.
     *
     * In case of transmit failure, the data poll sender may choose to send the next data poll more quickly (up to
     * some fixed number of attempts).
     *
     * @param[in] aFrame     The data poll frame.
     * @param[in] aError     Error status of a data poll message transmission.
     *
     */
    void HandlePollSent(Mac::TxFrame &aFrame, Error aError);

    /**
     * This method informs the data poll sender that a data poll timeout happened, i.e., when the ack in response to
     * a data request command indicated that a frame was pending, but no frame was received after timeout interval.
     *
     * Data poll sender may choose to transmit another data poll immediately (up to some fixed number of attempts).
     *
     */
    void HandlePollTimeout(void);

    /**
     * This method informs the data poll sender to process a received MAC frame.
     *
     * @param[in] aFrame     A reference to the received frame to process.
     *
     */
    void ProcessRxFrame(const Mac::RxFrame &aFrame);

#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
    /**
     * This method informs the data poll sender to process a transmitted MAC frame.
     *
     * @param[in]  aFrame      A reference to the frame that was transmitted.
     * @param[in]  aAckFrame   A pointer to the ACK frame, `nullptr` if no ACK was received.
     * @param[in]  aError      kErrorNone when the frame was transmitted successfully,
     *                         kErrorNoAck when the frame was transmitted but no ACK was received,
     *                         kErrorChannelAccessFailure when the tx failed due to activity on the channel,
     *                         kErrorAbort when transmission was aborted for other reasons.
     *
     */
    void ProcessTxDone(const Mac::TxFrame &aFrame, const Mac::RxFrame *aAckFrame, Error aError);
#endif

    /**
     * This method asks the data poll sender to recalculate the poll period.
     *
     * This is mainly used to inform the poll sender that a parameter impacting the poll period (e.g., the child's
     * timeout value which is used to determine the default data poll period) is modified.
     *
     */
    void RecalculatePollPeriod(void);

    /**
     * This method sets/clears the attach mode on data poll sender.
     *
     * When attach mode is enabled, the data poll sender will send data polls at a faster rate determined by
     * poll period configuration option `OPENTHREAD_CONFIG_MAC_ATTACH_DATA_POLL_PERIOD`.
     *
     * @param[in]  aMode  The mode value.
     *
     */
    void SetAttachMode(bool aMode);

    /**
     * This method asks data poll sender to send the next given number of polls at a faster rate (poll period defined
     * by `kFastPollPeriod`). This is used by OpenThread stack when it expects a response from the parent/sender.
     *
     * If @p aNumFastPolls is zero the default value specified by `kDefaultFastPolls` is used instead. The number of
     * fast polls is clipped by maximum value specified by `kMaxFastPolls`.
     *
     * Note that per `SendFastPolls()` would increase the internal reference count until up to the allowed maximum
     * value. If there are retransmission mechanism in the caller component, it should be responsible to call
     * `StopFastPolls()` the same times as `SendFastPolls()` it triggered to decrease the reference count properly,
     * guaranteeing to exit fast poll mode gracefully. Otherwise, fast poll would continue until all data polls are sent
     * out.
     *
     * @param[in] aNumFastPolls  If non-zero, number of fast polls to send, if zero, default value is used instead.
     *
     */
    void SendFastPolls(uint8_t aNumFastPolls = 0);

    /**
     * This method asks data poll sender to stop fast polls when the expecting response is received.
     *
     */
    void StopFastPolls(void);

    /**
     * This method gets the maximum data polling period in use.
     *
     * The maximum data poll period is determined based as the minimum of the user-specified poll interval and the
     * default poll interval.
     *
     * @returns The maximum data polling period in use.
     *
     */
    uint32_t GetKeepAlivePollPeriod(void) const;

    /**
     * This method resets the timer for sending keep-alive messages.
     *
     */
    void ResetKeepAliveTimer(void);

    /**
     * This method returns the default maximum poll period.
     *
     * The default poll period is determined based on the child timeout interval, ensuing the child would send data poll
     * within the child's timeout.
     *
     * @returns The maximum default data polling interval (in msec).
     *
     */
    uint32_t GetDefaultPollPeriod(void) const;

    /**
     * This method prepares and returns a data request command frame.
     *
     * @param[in] aTxFrames  The set of TxFrames for all radio links.
     *
     * @returns The data poll frame.
     *
     */
    Mac::TxFrame *PrepareDataRequest(Mac::TxFrames &aTxFrames);

private:
    static constexpr uint8_t kQuickPollsAfterTimeout = 5; // Quick data poll tx in case of back-to-back poll timeouts.
    static constexpr uint8_t kMaxPollRetxAttempts    = OPENTHREAD_CONFIG_FAILED_CHILD_TRANSMISSIONS;
    static constexpr uint8_t kMaxCslPollRetxAttempts = OPENTHREAD_CONFIG_MAC_DEFAULT_MAX_FRAME_RETRIES_DIRECT;

    enum PollPeriodSelector : uint8_t
    {
        kUsePreviousPollPeriod,
        kRecalculatePollPeriod,
    };

    // Poll period under different conditions (in milliseconds).
    static constexpr uint32_t kAttachDataPollPeriod = OPENTHREAD_CONFIG_MAC_ATTACH_DATA_POLL_PERIOD;
    static constexpr uint32_t kRetxPollPeriod       = OPENTHREAD_CONFIG_MAC_RETX_POLL_PERIOD;
    static constexpr uint32_t kFastPollPeriod       = 188;
    static constexpr uint32_t kMinPollPeriod        = OPENTHREAD_CONFIG_MAC_MINIMUM_POLL_PERIOD;
    static constexpr uint32_t kMaxExternalPeriod    = ((1 << 26) - 1); // ~18.6 hours.

    void            ScheduleNextPoll(PollPeriodSelector aPollPeriodSelector);
    uint32_t        CalculatePollPeriod(void) const;
    const Neighbor &GetParent(void) const;
    static void     HandlePollTimer(Timer &aTimer);
#if OPENTHREAD_CONFIG_MULTI_RADIO
    Error GetPollDestinationAddress(Mac::Address &aDest, Mac::RadioType &aRadioType) const;
#else
    Error GetPollDestinationAddress(Mac::Address &aDest) const;
#endif

    TimeMilli mTimerStartTime;
    uint32_t  mPollPeriod;
    uint32_t  mExternalPollPeriod : 26; // In milliseconds.
    uint8_t   mFastPollsUsers : 6;      // Number of callers which request fast polls.

    TimerMilli mTimer;

    bool    mEnabled : 1;              // Indicates whether data polling is enabled/started.
    bool    mAttachMode : 1;           // Indicates whether in attach mode (to use attach poll period).
    bool    mRetxMode : 1;             // Indicates whether last poll tx failed at mac/radio layer (poll retx mode).
    uint8_t mPollTimeoutCounter : 4;   // Poll timeouts counter (0 to `kQuickPollsAfterTimout`).
    uint8_t mPollTxFailureCounter : 4; // Poll tx failure counter (0 to `kMaxPollRetxAttempts`).
    uint8_t mRemainingFastPolls : 4;   // Number of remaining fast polls when in transient fast polling mode.
};

/**
 * @}
 *
 */

} // namespace ot

#endif // DATA_POLL_MANAGER_HPP_
