• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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