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  * Represents a time instance.
58  */
59 class Time : public Unequatable<Time>
60 {
61 public:
62     static constexpr uint32_t kOneSecondInMsec = 1000u;                 ///< One second interval in msec.
63     static constexpr uint32_t kOneMinuteInMsec = kOneSecondInMsec * 60; ///< One minute interval in msec.
64     static constexpr uint32_t kOneHourInMsec   = kOneMinuteInMsec * 60; ///< One hour interval in msec.
65     static constexpr uint32_t kOneDayInMsec    = kOneHourInMsec * 24;   ///< One day interval in msec.
66     static constexpr uint32_t kOneMsecInUsec   = 1000u;                 ///< One millisecond in microseconds.
67     static constexpr uint32_t kOneSecondInUsec = 1000000u;              ///< One second interval in microseconds.
68 
69     /**
70      * This constant defines a maximum time duration ensured to be longer than any other duration.
71      */
72     static const uint32_t kMaxDuration = ~static_cast<uint32_t>(0UL);
73 
74     /**
75      * This is the default constructor for a `Time` object.
76      */
77     Time(void) = default;
78 
79     /**
80      * Initializes a `Time` object with a given value.
81      *
82      * @param[in] aValue   The numeric time value to initialize the `Time` object.
83      */
Time(uint32_t aValue)84     explicit Time(uint32_t aValue) { SetValue(aValue); }
85 
86     /**
87      * Gets the numeric time value associated with the `Time` object.
88      *
89      * @returns The numeric `Time` value.
90      */
GetValue(void) const91     uint32_t GetValue(void) const { return mValue; }
92 
93     /**
94      * Sets the numeric time value.
95      *
96      * @param[in] aValue   The numeric time value.
97      */
SetValue(uint32_t aValue)98     void SetValue(uint32_t aValue) { mValue = aValue; }
99 
100     /**
101      * Calculates the time duration between two `Time` instances.
102      *
103      * @note Expression `(t1 - t2)` returns the duration of the interval starting from `t2` and ending at `t1`. When
104      * calculating the duration, `t2 is assumed to be in the past relative to `t1`. The duration calculation correctly
105      * takes into account the wrapping of numeric value of `Time` instances. The returned value can span the entire
106      * range of the `uint32_t` type.
107      *
108      * @param[in]   aOther  A `Time` instance to subtract from.
109      *
110      * @returns The duration of interval from @p aOther to this `Time` object.
111      */
operator -(const Time & aOther) const112     uint32_t operator-(const Time &aOther) const { return mValue - aOther.mValue; }
113 
114     /**
115      * Returns a new `Time` which is ahead of this `Time` object by a given duration.
116      *
117      * @param[in]   aDuration  A duration.
118      *
119      * @returns A new `Time` which is ahead of this object by @aDuration.
120      */
operator +(uint32_t aDuration) const121     Time operator+(uint32_t aDuration) const { return Time(mValue + aDuration); }
122 
123     /**
124      * Returns a new `Time` which is behind this `Time` object by a given duration.
125      *
126      * @param[in]   aDuration  A duration.
127      *
128      * @returns A new `Time` which is behind this object by @aDuration.
129      */
operator -(uint32_t aDuration) const130     Time operator-(uint32_t aDuration) const { return Time(mValue - aDuration); }
131 
132     /**
133      * Moves this `Time` object forward by a given duration.
134      *
135      * @param[in]   aDuration  A duration.
136      */
operator +=(uint32_t aDuration)137     void operator+=(uint32_t aDuration) { mValue += aDuration; }
138 
139     /**
140      * Moves this `Time` object backward by a given duration.
141      *
142      * @param[in]   aDuration  A duration.
143      */
operator -=(uint32_t aDuration)144     void operator-=(uint32_t aDuration) { mValue -= aDuration; }
145 
146     /**
147      * Indicates whether two `Time` instances are equal.
148      *
149      * @param[in]   aOther   A `Time` instance to compare with.
150      *
151      * @retval TRUE    The two `Time` instances are equal.
152      * @retval FALSE   The two `Time` instances are not equal.
153      */
operator ==(const Time & aOther) const154     bool operator==(const Time &aOther) const { return mValue == aOther.mValue; }
155 
156     /**
157      * Indicates whether this `Time` instance is strictly before another one.
158      *
159      * @note The comparison operators correctly take into account the wrapping of `Time` numeric value. For a given
160      * `Time` instance `t0`, any `Time` instance `t` where `(t - t0)` is less than half the range of `uint32_t` type
161      * is considered to be after `t0`, otherwise it is considered to be before 't0' (or equal to it). As an example
162      * to illustrate this model we can use clock hours: If we are at hour 12, hours 1 to 5 are considered to be
163      * after 12, and hours 6 to 11 are considered to be before 12.
164      *
165      * @param[in]   aOther   A `Time` instance to compare with.
166      *
167      * @retval TRUE    This `Time` instance is strictly before @p aOther.
168      * @retval FALSE   This `Time` instance is not strictly before @p aOther.
169      */
operator <(const Time & aOther) const170     bool operator<(const Time &aOther) const { return SerialNumber::IsLess(mValue, aOther.mValue); }
171 
172     /**
173      * Indicates whether this `Time` instance is after or equal to another one.
174      *
175      * @param[in]   aOther   A `Time` instance to compare with.
176      *
177      * @retval TRUE    This `Time` instance is after or equal to @p aOther.
178      * @retval FALSE   This `Time` instance is not after or equal to @p aOther.
179      */
operator >=(const Time & aOther) const180     bool operator>=(const Time &aOther) const { return !(*this < aOther); }
181 
182     /**
183      * Indicates whether this `Time` instance is before or equal to another one.
184      *
185      * @param[in]   aOther   A `Time` instance to compare with.
186      *
187      * @retval TRUE    This `Time` instance is before or equal to @p aOther.
188      * @retval FALSE   This `Time` instance is not before or equal to @p aOther.
189      */
operator <=(const Time & aOther) const190     bool operator<=(const Time &aOther) const { return (aOther >= *this); }
191 
192     /**
193      * Indicates whether this `Time` instance is strictly after another one.
194      *
195      * @param[in]   aOther   A `Time` instance to compare with.
196      *
197      * @retval TRUE    This `Time` instance is strictly after @p aOther.
198      * @retval FALSE   This `Time` instance is not strictly after @p aOther.
199      */
operator >(const Time & aOther) const200     bool operator>(const Time &aOther) const { return (aOther < *this); }
201 
202     /**
203      * Returns a new `Time` instance which is in distant future relative to current `Time` object.
204      *
205      * The distant future is the largest time that is ahead of `Time`. For any time `t`, if `(*this <= t)`, then
206      * `t <= this->GetGetDistantFuture()`, except for the ambiguous `t` value which is half range `(1 << 31)` apart.
207      *
208      * When comparing `GetDistantFuture()` with a time `t` the caller must ensure that `t` is already ahead of `*this`.
209      *
210      * @returns A new `Time` in distance future relative to current `Time` object.
211      */
GetDistantFuture(void) const212     Time GetDistantFuture(void) const { return Time(mValue + kDistantInterval); }
213 
214     /**
215      * Returns a new `Time` instance which is in distant past relative to current `Time` object.
216      *
217      * The distant past is the smallest time that is before `Time`. For any time `t`, if `(t <= *this )`, then
218      * `this->GetGetDistantPast() <= t`, except for the ambiguous `t` value which is half range `(1 << 31)` apart.
219      *
220      * When comparing `GetDistantPast()` with a time `t` the caller must ensure that the `t` is already before `*this`.
221      *
222      * @returns A new `Time` in distance past relative to current `Time` object.
223      */
GetDistantPast(void) const224     Time GetDistantPast(void) const { return Time(mValue - kDistantInterval); }
225 
226     /**
227      * Converts a given number of seconds to milliseconds.
228      *
229      * @param[in] aSeconds   The seconds value to convert to milliseconds.
230      *
231      * @returns The number of milliseconds.
232      */
SecToMsec(uint32_t aSeconds)233     static uint32_t constexpr SecToMsec(uint32_t aSeconds) { return aSeconds * 1000u; }
234 
235     /**
236      * Converts a given number of milliseconds to seconds.
237      *
238      * @param[in] aMilliseconds  The milliseconds value to convert to seconds.
239      *
240      * @returns The number of seconds.
241      */
MsecToSec(uint32_t aMilliseconds)242     static uint32_t constexpr MsecToSec(uint32_t aMilliseconds) { return aMilliseconds / 1000u; }
243 
244 private:
245     static constexpr uint32_t kDistantInterval = (1UL << 31) - 1;
246 
247     uint32_t mValue;
248 };
249 
250 /**
251  * Represents a time instance (millisecond time).
252  */
253 typedef Time TimeMilli;
254 
255 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
256 
257 /**
258  * Represents a time instance (microsecond time).
259  */
260 typedef Time TimeMicro;
261 
262 #endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
263 
264 /**
265  * @}
266  */
267 
268 } // namespace ot
269 
270 #endif // TIME_HPP_
271