/* * Copyright (c) 2016, 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 trickle timer logic. */ #ifndef TRICKLE_TIMER_HPP_ #define TRICKLE_TIMER_HPP_ #include "openthread-core-config.h" #include "common/numeric_limits.hpp" #include "common/timer.hpp" namespace ot { /** * @addtogroup core-timer-trickle * * @brief * This module includes definitions for the trickle timer logic. * * @{ * */ /** * Implements a trickle timer. * */ class TrickleTimer : public TimerMilli { friend class TrickleTimerTester; public: /** * Defines the modes of operation for the `TrickleTimer`. * */ enum Mode : uint8_t { kModeTrickle, ///< Operate as the normal trickle logic (as per RFC 6206). kModePlainTimer, ///< Operate as a plain periodic timer with random interval selected within min/max intervals. }; /** * Special value for redundancy constant (aka `k`) to indicate infinity (when used, it disables trickle timer's * suppression behavior, invoking the handler callback independent of number of "consistent" events). * */ static constexpr uint16_t kInfiniteRedundancyConstant = NumericLimits::kMax; /** * Pointer is called when the timer expires (i.e., transmission should happen). * * @param[in] aTimer A reference to the trickle timer. * */ typedef void (&Handler)(TrickleTimer &aTimer); /** * Initializes a `TrickleTimer` instance. * * @param[in] aInstance A reference to the OpenThread instance. * @param[in] aHandler A handler which is called when transmission should occur. * */ TrickleTimer(Instance &aInstance, Handler aHandler); /** * Indicates whether or not the trickle timer instance is running. * * @retval TRUE If the trickle timer is running. * @retval FALSE If the trickle timer is not running. * */ bool IsRunning(void) const { return TimerMilli::IsRunning(); } /** * Gets the current operation mode of the trickle timer. * * @returns The current operation mode of the timer. * */ Mode GetMode(void) const { return mMode; } /** * Gets the interval min value of the trickle timer. * * @returns The interval min value in milliseconds. * */ uint32_t GetIntervalMin(void) const { return mIntervalMin; } /** * Sets the interval min value of the trickle timer while timer is running. * * If @p aIntervalMin is smaller than the current `GetIntervalMax()` the interval max value is also updated to * the new @p aIntervalMin (as if `SetIntervalMax(aIntervalMin)` was called). * * @param[in] aIntervalMin The minimum interval in milliseconds. * */ void SetIntervalMin(uint32_t aIntervalMin); /** * Gets the interval max value of the trickle timer. * * @returns The interval max value in milliseconds. * */ uint32_t GetIntervalMax(void) const { return mIntervalMax; } /** * Sets the interval max value of the trickle timer while timer is running. * * If the given @p aIntervalMax is smaller than the current `GetIntervalMin()`, the interval min value will be * used instead. * * @param[in] aIntervalMax The maximum interval in milliseconds. * */ void SetIntervalMax(uint32_t aIntervalMax); /** * This method starts the trickle timer. * * @param[in] aMode The operation mode of timer (trickle or plain periodic mode). * @param[in] aIntervalMin The minimum interval for the timer in milliseconds. * @param[in] aIntervalMax The maximum interval for the timer in milliseconds. * @param[in] aRedundancyConstant The redundancy constant for the timer, also known as `k`. The default value * is set to `kInfiniteRedundancyConstant` which disables the suppression behavior * (i.e., handler is always invoked independent of number of "consistent" events). * */ void Start(Mode aMode, uint32_t aIntervalMin, uint32_t aIntervalMax, uint16_t aRedundancyConstant = kInfiniteRedundancyConstant); /** * Stops the trickle timer. * */ void Stop(void) { TimerMilli::Stop(); } /** * Indicates to the trickle timer a 'consistent' event. * * The 'consistent' events are used to control suppression behavior. The trickle timer keeps track of the number of * 'consistent' events in each interval. The timer handler is invoked only if the number of `consistent` events * received in the interval is less than the redundancy constant. * */ void IndicateConsistent(void); /** * Indicates to the trickle timer an 'inconsistent' event. * * Receiving an 'inconsistent' event causes the trickle timer to reset (i.e., start with interval set to the min * value) unless the current interval being used is already equal to the min interval. * */ void IndicateInconsistent(void); private: enum Phase : uint8_t { kBeforeRandomTime, // Trickle timer is before random time `t` in the current interval. kAfterRandomTime, // Trickle timer is after random time `t` in the current interval. }; void StartNewInterval(void); static void HandleTimer(Timer &aTimer); void HandleTimer(void); void HandleEndOfTimeInInterval(void); void HandleEndOfInterval(void); TimeMilli GetStartTimeOfCurrentInterval(void) const; // Shadow base class `TimerMilli` methods to ensure they are hidden. void StartAt(void) {} void FireAt(void) {} void FireAtIfEarlier(void) {} void GetFireTime(void) {} uint32_t mIntervalMin; // Minimum interval (aka `Imin`). uint32_t mIntervalMax; // Maximum interval (aka `Imax`). uint32_t mInterval; // Current interval (aka `I`). uint32_t mTimeInInterval; // Time in interval (aka `t`). uint16_t mRedundancyConstant; // Redundancy constant (aka 'k'). uint16_t mCounter; // A counter for number of "consistent" transmissions (aka 'c'). Handler mHandler; // Handler callback. Mode mMode; // Trickle timer operation mode. Phase mPhase; // Trickle timer phase (before or after time `t` in the current interval). }; /** * @} * */ } // namespace ot #endif // TRICKLE_TIMER_HPP_