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 /** 55 * Implements a trickle timer. 56 * 57 */ 58 class TrickleTimer : public TimerMilli 59 { 60 friend class TrickleTimerTester; 61 62 public: 63 /** 64 * Defines the modes of operation for the `TrickleTimer`. 65 * 66 */ 67 enum Mode : uint8_t 68 { 69 kModeTrickle, ///< Operate as the normal trickle logic (as per RFC 6206). 70 kModePlainTimer, ///< Operate as a plain periodic timer with random interval selected within min/max intervals. 71 }; 72 73 /** 74 * Special value for redundancy constant (aka `k`) to indicate infinity (when used, it disables trickle timer's 75 * suppression behavior, invoking the handler callback independent of number of "consistent" events). 76 * 77 */ 78 static constexpr uint16_t kInfiniteRedundancyConstant = NumericLimits<uint16_t>::kMax; 79 80 /** 81 * Pointer is called when the timer expires (i.e., transmission should happen). 82 * 83 * @param[in] aTimer A reference to the trickle timer. 84 * 85 */ 86 typedef void (&Handler)(TrickleTimer &aTimer); 87 88 /** 89 * Initializes a `TrickleTimer` instance. 90 * 91 * @param[in] aInstance A reference to the OpenThread instance. 92 * @param[in] aHandler A handler which is called when transmission should occur. 93 * 94 */ 95 TrickleTimer(Instance &aInstance, Handler aHandler); 96 97 /** 98 * Indicates whether or not the trickle timer instance is running. 99 * 100 * @retval TRUE If the trickle timer is running. 101 * @retval FALSE If the trickle timer is not running. 102 * 103 */ IsRunning(void) const104 bool IsRunning(void) const { return TimerMilli::IsRunning(); } 105 106 /** 107 * Gets the current operation mode of the trickle timer. 108 * 109 * @returns The current operation mode of the timer. 110 * 111 */ GetMode(void) const112 Mode GetMode(void) const { return mMode; } 113 114 /** 115 * Gets the interval min value of the trickle timer. 116 * 117 * @returns The interval min value in milliseconds. 118 * 119 */ GetIntervalMin(void) const120 uint32_t GetIntervalMin(void) const { return mIntervalMin; } 121 122 /** 123 * Sets the interval min value of the trickle timer while timer is running. 124 * 125 * If @p aIntervalMin is smaller than the current `GetIntervalMax()` the interval max value is also updated to 126 * the new @p aIntervalMin (as if `SetIntervalMax(aIntervalMin)` was called). 127 * 128 * @param[in] aIntervalMin The minimum interval in milliseconds. 129 * 130 */ 131 void SetIntervalMin(uint32_t aIntervalMin); 132 133 /** 134 * Gets the interval max value of the trickle timer. 135 * 136 * @returns The interval max value in milliseconds. 137 * 138 */ GetIntervalMax(void) const139 uint32_t GetIntervalMax(void) const { return mIntervalMax; } 140 141 /** 142 * Sets the interval max value of the trickle timer while timer is running. 143 * 144 * If the given @p aIntervalMax is smaller than the current `GetIntervalMin()`, the interval min value will be 145 * used instead. 146 * 147 * @param[in] aIntervalMax The maximum interval in milliseconds. 148 * 149 */ 150 void SetIntervalMax(uint32_t aIntervalMax); 151 152 /** 153 * This method starts the trickle timer. 154 * 155 * @param[in] aMode The operation mode of timer (trickle or plain periodic mode). 156 * @param[in] aIntervalMin The minimum interval for the timer in milliseconds. 157 * @param[in] aIntervalMax The maximum interval for the timer in milliseconds. 158 * @param[in] aRedundancyConstant The redundancy constant for the timer, also known as `k`. The default value 159 * is set to `kInfiniteRedundancyConstant` which disables the suppression behavior 160 * (i.e., handler is always invoked independent of number of "consistent" events). 161 * 162 */ 163 void Start(Mode aMode, 164 uint32_t aIntervalMin, 165 uint32_t aIntervalMax, 166 uint16_t aRedundancyConstant = kInfiniteRedundancyConstant); 167 168 /** 169 * Stops the trickle timer. 170 * 171 */ Stop(void)172 void Stop(void) { TimerMilli::Stop(); } 173 174 /** 175 * Indicates to the trickle timer a 'consistent' event. 176 * 177 * The 'consistent' events are used to control suppression behavior. The trickle timer keeps track of the number of 178 * 'consistent' events in each interval. The timer handler is invoked only if the number of `consistent` events 179 * received in the interval is less than the redundancy constant. 180 * 181 */ 182 void IndicateConsistent(void); 183 184 /** 185 * Indicates to the trickle timer an 'inconsistent' event. 186 * 187 * Receiving an 'inconsistent' event causes the trickle timer to reset (i.e., start with interval set to the min 188 * value) unless the current interval being used is already equal to the min interval. 189 * 190 */ 191 void IndicateInconsistent(void); 192 193 private: 194 enum Phase : uint8_t 195 { 196 kBeforeRandomTime, // Trickle timer is before random time `t` in the current interval. 197 kAfterRandomTime, // Trickle timer is after random time `t` in the current interval. 198 }; 199 200 void StartNewInterval(void); 201 static void HandleTimer(Timer &aTimer); 202 void HandleTimer(void); 203 void HandleEndOfTimeInInterval(void); 204 void HandleEndOfInterval(void); 205 TimeMilli GetStartTimeOfCurrentInterval(void) const; 206 207 // Shadow base class `TimerMilli` methods to ensure they are hidden. StartAt(void)208 void StartAt(void) {} FireAt(void)209 void FireAt(void) {} FireAtIfEarlier(void)210 void FireAtIfEarlier(void) {} GetFireTime(void)211 void GetFireTime(void) {} 212 213 uint32_t mIntervalMin; // Minimum interval (aka `Imin`). 214 uint32_t mIntervalMax; // Maximum interval (aka `Imax`). 215 uint32_t mInterval; // Current interval (aka `I`). 216 uint32_t mTimeInInterval; // Time in interval (aka `t`). 217 uint16_t mRedundancyConstant; // Redundancy constant (aka 'k'). 218 uint16_t mCounter; // A counter for number of "consistent" transmissions (aka 'c'). 219 Handler mHandler; // Handler callback. 220 Mode mMode; // Trickle timer operation mode. 221 Phase mPhase; // Trickle timer phase (before or after time `t` in the current interval). 222 }; 223 224 /** 225 * @} 226 * 227 */ 228 229 } // namespace ot 230 231 #endif // TRICKLE_TIMER_HPP_ 232