1 /* 2 * Copyright (c) 2016, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * This file includes definitions for the trickle timer logic. 32 */ 33 34 #ifndef TRICKLE_TIMER_HPP_ 35 #define TRICKLE_TIMER_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include "common/numeric_limits.hpp" 40 #include "common/timer.hpp" 41 42 namespace ot { 43 44 /** 45 * @addtogroup core-timer-trickle 46 * 47 * @brief 48 * This module includes definitions for the trickle timer logic. 49 * 50 * @{ 51 */ 52 53 /** 54 * Implements a trickle timer. 55 */ 56 class TrickleTimer : public TimerMilli 57 { 58 friend class TrickleTimerTester; 59 60 public: 61 /** 62 * Defines the modes of operation for the `TrickleTimer`. 63 */ 64 enum Mode : uint8_t 65 { 66 kModeTrickle, ///< Operate as the normal trickle logic (as per RFC 6206). 67 kModePlainTimer, ///< Operate as a plain periodic timer with random interval selected within min/max intervals. 68 }; 69 70 /** 71 * Special value for redundancy constant (aka `k`) to indicate infinity (when used, it disables trickle timer's 72 * suppression behavior, invoking the handler callback independent of number of "consistent" events). 73 */ 74 static constexpr uint16_t kInfiniteRedundancyConstant = NumericLimits<uint16_t>::kMax; 75 76 /** 77 * Pointer is called when the timer expires (i.e., transmission should happen). 78 * 79 * @param[in] aTimer A reference to the trickle timer. 80 */ 81 typedef void (&Handler)(TrickleTimer &aTimer); 82 83 /** 84 * Initializes a `TrickleTimer` instance. 85 * 86 * @param[in] aInstance A reference to the OpenThread instance. 87 * @param[in] aHandler A handler which is called when transmission should occur. 88 */ 89 TrickleTimer(Instance &aInstance, Handler aHandler); 90 91 /** 92 * Indicates whether or not the trickle timer instance is running. 93 * 94 * @retval TRUE If the trickle timer is running. 95 * @retval FALSE If the trickle timer is not running. 96 */ IsRunning(void) const97 bool IsRunning(void) const { return TimerMilli::IsRunning(); } 98 99 /** 100 * Gets the current operation mode of the trickle timer. 101 * 102 * @returns The current operation mode of the timer. 103 */ GetMode(void) const104 Mode GetMode(void) const { return mMode; } 105 106 /** 107 * Gets the interval min value of the trickle timer. 108 * 109 * @returns The interval min value in milliseconds. 110 */ GetIntervalMin(void) const111 uint32_t GetIntervalMin(void) const { return mIntervalMin; } 112 113 /** 114 * Sets the interval min value of the trickle timer while timer is running. 115 * 116 * If @p aIntervalMin is smaller than the current `GetIntervalMax()` the interval max value is also updated to 117 * the new @p aIntervalMin (as if `SetIntervalMax(aIntervalMin)` was called). 118 * 119 * @param[in] aIntervalMin The minimum interval in milliseconds. 120 */ 121 void SetIntervalMin(uint32_t aIntervalMin); 122 123 /** 124 * Gets the interval max value of the trickle timer. 125 * 126 * @returns The interval max value in milliseconds. 127 */ GetIntervalMax(void) const128 uint32_t GetIntervalMax(void) const { return mIntervalMax; } 129 130 /** 131 * Sets the interval max value of the trickle timer while timer is running. 132 * 133 * If the given @p aIntervalMax is smaller than the current `GetIntervalMin()`, the interval min value will be 134 * used instead. 135 * 136 * @param[in] aIntervalMax The maximum interval in milliseconds. 137 */ 138 void SetIntervalMax(uint32_t aIntervalMax); 139 140 /** 141 * This method starts the trickle timer. 142 * 143 * @param[in] aMode The operation mode of timer (trickle or plain periodic mode). 144 * @param[in] aIntervalMin The minimum interval for the timer in milliseconds. 145 * @param[in] aIntervalMax The maximum interval for the timer in milliseconds. 146 * @param[in] aRedundancyConstant The redundancy constant for the timer, also known as `k`. The default value 147 * is set to `kInfiniteRedundancyConstant` which disables the suppression behavior 148 * (i.e., handler is always invoked independent of number of "consistent" events). 149 */ 150 void Start(Mode aMode, 151 uint32_t aIntervalMin, 152 uint32_t aIntervalMax, 153 uint16_t aRedundancyConstant = kInfiniteRedundancyConstant); 154 155 /** 156 * Stops the trickle timer. 157 */ Stop(void)158 void Stop(void) { TimerMilli::Stop(); } 159 160 /** 161 * Indicates to the trickle timer a 'consistent' event. 162 * 163 * The 'consistent' events are used to control suppression behavior. The trickle timer keeps track of the number of 164 * 'consistent' events in each interval. The timer handler is invoked only if the number of `consistent` events 165 * received in the interval is less than the redundancy constant. 166 */ 167 void IndicateConsistent(void); 168 169 /** 170 * Indicates to the trickle timer an 'inconsistent' event. 171 * 172 * Receiving an 'inconsistent' event causes the trickle timer to reset (i.e., start with interval set to the min 173 * value) unless the current interval being used is already equal to the min interval. 174 */ 175 void IndicateInconsistent(void); 176 177 private: 178 enum Phase : uint8_t 179 { 180 kBeforeRandomTime, // Trickle timer is before random time `t` in the current interval. 181 kAfterRandomTime, // Trickle timer is after random time `t` in the current interval. 182 }; 183 184 void StartNewInterval(void); 185 static void HandleTimer(Timer &aTimer); 186 void HandleTimer(void); 187 void HandleEndOfTimeInInterval(void); 188 void HandleEndOfInterval(void); 189 TimeMilli GetStartTimeOfCurrentInterval(void) const; 190 191 // Shadow base class `TimerMilli` methods to ensure they are hidden. StartAt(void)192 void StartAt(void) {} FireAt(void)193 void FireAt(void) {} FireAtIfEarlier(void)194 void FireAtIfEarlier(void) {} GetFireTime(void)195 void GetFireTime(void) {} 196 197 uint32_t mIntervalMin; // Minimum interval (aka `Imin`). 198 uint32_t mIntervalMax; // Maximum interval (aka `Imax`). 199 uint32_t mInterval; // Current interval (aka `I`). 200 uint32_t mTimeInInterval; // Time in interval (aka `t`). 201 uint16_t mRedundancyConstant; // Redundancy constant (aka 'k'). 202 uint16_t mCounter; // A counter for number of "consistent" transmissions (aka 'c'). 203 Handler mHandler; // Handler callback. 204 Mode mMode; // Trickle timer operation mode. 205 Phase mPhase; // Trickle timer phase (before or after time `t` in the current interval). 206 }; 207 208 /** 209 * @} 210 */ 211 212 } // namespace ot 213 214 #endif // TRICKLE_TIMER_HPP_ 215