1 /*
2  *  Copyright (c) 2019, 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 time instance.
32  */
33 
34 #ifndef TIME_HPP_
35 #define TIME_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <stddef.h>
40 #include <stdint.h>
41 
42 #include "common/equatable.hpp"
43 #include "common/serial_number.hpp"
44 
45 namespace ot {
46 
47 /**
48  * @addtogroup core-timer
49  *
50  * @brief
51  *   This module includes definitions for the time instance.
52  *
53  * @{
54  *
55  */
56 
57 /**
58  * Represents a time instance.
59  *
60  */
61 class Time : public Unequatable<Time>
62 {
63 public:
64     static constexpr uint32_t kOneSecondInMsec = 1000u;                 ///< One second interval in msec.
65     static constexpr uint32_t kOneMinuteInMsec = kOneSecondInMsec * 60; ///< One minute interval in msec.
66     static constexpr uint32_t kOneHourInMsec   = kOneMinuteInMsec * 60; ///< One hour interval in msec.
67     static constexpr uint32_t kOneDayInMsec    = kOneHourInMsec * 24;   ///< One day interval in msec.
68     static constexpr uint32_t kOneMsecInUsec   = 1000u;                 ///< One millisecond in microseconds.
69 
70     /**
71      * This constant defines a maximum time duration ensured to be longer than any other duration.
72      *
73      */
74     static const uint32_t kMaxDuration = ~static_cast<uint32_t>(0UL);
75 
76     /**
77      * This is the default constructor for a `Time` object.
78      *
79      */
80     Time(void) = default;
81 
82     /**
83      * Initializes a `Time` object with a given value.
84      *
85      * @param[in] aValue   The numeric time value to initialize the `Time` object.
86      *
87      */
Time(uint32_t aValue)88     explicit Time(uint32_t aValue) { SetValue(aValue); }
89 
90     /**
91      * Gets the numeric time value associated with the `Time` object.
92      *
93      * @returns The numeric `Time` value.
94      *
95      */
GetValue(void) const96     uint32_t GetValue(void) const { return mValue; }
97 
98     /**
99      * Sets the numeric time value.
100      *
101      * @param[in] aValue   The numeric time value.
102      *
103      */
SetValue(uint32_t aValue)104     void SetValue(uint32_t aValue) { mValue = aValue; }
105 
106     /**
107      * Calculates the time duration between two `Time` instances.
108      *
109      * @note Expression `(t1 - t2)` returns the duration of the interval starting from `t2` and ending at `t1`. When
110      * calculating the duration, `t2 is assumed to be in the past relative to `t1`. The duration calculation correctly
111      * takes into account the wrapping of numeric value of `Time` instances. The returned value can span the entire
112      * range of the `uint32_t` type.
113      *
114      * @param[in]   aOther  A `Time` instance to subtract from.
115      *
116      * @returns The duration of interval from @p aOther to this `Time` object.
117      *
118      */
operator -(const Time & aOther) const119     uint32_t operator-(const Time &aOther) const { return mValue - aOther.mValue; }
120 
121     /**
122      * Returns a new `Time` which is ahead of this `Time` object by a given duration.
123      *
124      * @param[in]   aDuration  A duration.
125      *
126      * @returns A new `Time` which is ahead of this object by @aDuration.
127      *
128      */
operator +(uint32_t aDuration) const129     Time operator+(uint32_t aDuration) const { return Time(mValue + aDuration); }
130 
131     /**
132      * Returns a new `Time` which is behind this `Time` object by a given duration.
133      *
134      * @param[in]   aDuration  A duration.
135      *
136      * @returns A new `Time` which is behind this object by @aDuration.
137      *
138      */
operator -(uint32_t aDuration) const139     Time operator-(uint32_t aDuration) const { return Time(mValue - aDuration); }
140 
141     /**
142      * Moves this `Time` object forward by a given duration.
143      *
144      * @param[in]   aDuration  A duration.
145      *
146      */
operator +=(uint32_t aDuration)147     void operator+=(uint32_t aDuration) { mValue += aDuration; }
148 
149     /**
150      * Moves this `Time` object backward by a given duration.
151      *
152      * @param[in]   aDuration  A duration.
153      *
154      */
operator -=(uint32_t aDuration)155     void operator-=(uint32_t aDuration) { mValue -= aDuration; }
156 
157     /**
158      * Indicates whether two `Time` instances are equal.
159      *
160      * @param[in]   aOther   A `Time` instance to compare with.
161      *
162      * @retval TRUE    The two `Time` instances are equal.
163      * @retval FALSE   The two `Time` instances are not equal.
164      *
165      */
operator ==(const Time & aOther) const166     bool operator==(const Time &aOther) const { return mValue == aOther.mValue; }
167 
168     /**
169      * Indicates whether this `Time` instance is strictly before another one.
170      *
171      * @note The comparison operators correctly take into account the wrapping of `Time` numeric value. For a given
172      * `Time` instance `t0`, any `Time` instance `t` where `(t - t0)` is less than half the range of `uint32_t` type
173      * is considered to be after `t0`, otherwise it is considered to be before 't0' (or equal to it). As an example
174      * to illustrate this model we can use clock hours: If we are at hour 12, hours 1 to 5 are considered to be
175      * after 12, and hours 6 to 11 are considered to be before 12.
176      *
177      * @param[in]   aOther   A `Time` instance to compare with.
178      *
179      * @retval TRUE    This `Time` instance is strictly before @p aOther.
180      * @retval FALSE   This `Time` instance is not strictly before @p aOther.
181      *
182      */
operator <(const Time & aOther) const183     bool operator<(const Time &aOther) const { return SerialNumber::IsLess(mValue, aOther.mValue); }
184 
185     /**
186      * Indicates whether this `Time` instance is after or equal to another one.
187      *
188      * @param[in]   aOther   A `Time` instance to compare with.
189      *
190      * @retval TRUE    This `Time` instance is after or equal to @p aOther.
191      * @retval FALSE   This `Time` instance is not after or equal to @p aOther.
192      *
193      */
operator >=(const Time & aOther) const194     bool operator>=(const Time &aOther) const { return !(*this < aOther); }
195 
196     /**
197      * Indicates whether this `Time` instance is before or equal to another one.
198      *
199      * @param[in]   aOther   A `Time` instance to compare with.
200      *
201      * @retval TRUE    This `Time` instance is before or equal to @p aOther.
202      * @retval FALSE   This `Time` instance is not before or equal to @p aOther.
203      *
204      */
operator <=(const Time & aOther) const205     bool operator<=(const Time &aOther) const { return (aOther >= *this); }
206 
207     /**
208      * Indicates whether this `Time` instance is strictly after another one.
209      *
210      * @param[in]   aOther   A `Time` instance to compare with.
211      *
212      * @retval TRUE    This `Time` instance is strictly after @p aOther.
213      * @retval FALSE   This `Time` instance is not strictly after @p aOther.
214      *
215      */
operator >(const Time & aOther) const216     bool operator>(const Time &aOther) const { return (aOther < *this); }
217 
218     /**
219      * Returns a new `Time` instance which is in distant future relative to current `Time` object.
220      *
221      * The distant future is the largest time that is ahead of `Time`. For any time `t`, if `(*this <= t)`, then
222      * `t <= this->GetGetDistantFuture()`, except for the ambiguous `t` value which is half range `(1 << 31)` apart.
223      *
224      * When comparing `GetDistantFuture()` with a time `t` the caller must ensure that `t` is already ahead of `*this`.
225      *
226      * @returns A new `Time` in distance future relative to current `Time` object.
227      *
228      */
GetDistantFuture(void) const229     Time GetDistantFuture(void) const { return Time(mValue + kDistantInterval); }
230 
231     /**
232      * Returns a new `Time` instance which is in distant past relative to current `Time` object.
233      *
234      * The distant past is the smallest time that is before `Time`. For any time `t`, if `(t <= *this )`, then
235      * `this->GetGetDistantPast() <= t`, except for the ambiguous `t` value which is half range `(1 << 31)` apart.
236      *
237      * When comparing `GetDistantPast()` with a time `t` the caller must ensure that the `t` is already before `*this`.
238      *
239      * @returns A new `Time` in distance past relative to current `Time` object.
240      *
241      */
GetDistantPast(void) const242     Time GetDistantPast(void) const { return Time(mValue - kDistantInterval); }
243 
244     /**
245      * Converts a given number of seconds to milliseconds.
246      *
247      * @param[in] aSeconds   The seconds value to convert to milliseconds.
248      *
249      * @returns The number of milliseconds.
250      *
251      */
SecToMsec(uint32_t aSeconds)252     static uint32_t constexpr SecToMsec(uint32_t aSeconds) { return aSeconds * 1000u; }
253 
254     /**
255      * Converts a given number of milliseconds to seconds.
256      *
257      * @param[in] aMilliseconds  The milliseconds value to convert to seconds.
258      *
259      * @returns The number of seconds.
260      *
261      */
MsecToSec(uint32_t aMilliseconds)262     static uint32_t constexpr MsecToSec(uint32_t aMilliseconds) { return aMilliseconds / 1000u; }
263 
264 private:
265     static constexpr uint32_t kDistantInterval = (1UL << 31) - 1;
266 
267     uint32_t mValue;
268 };
269 
270 /**
271  * Represents a time instance (millisecond time).
272  *
273  */
274 typedef Time TimeMilli;
275 
276 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
277 
278 /**
279  * Represents a time instance (microsecond time).
280  *
281  */
282 typedef Time TimeMicro;
283 
284 #endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
285 
286 /**
287  * @}
288  *
289  */
290 
291 } // namespace ot
292 
293 #endif // TIME_HPP_
294