• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * This class 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 
69     /**
70      * This constant defines a maximum time duration ensured to be longer than any other duration.
71      *
72      */
73     static const uint32_t kMaxDuration = ~static_cast<uint32_t>(0UL);
74 
75     /**
76      * This is the default constructor for a `Time` object.
77      *
78      */
79     Time(void) = default;
80 
81     /**
82      * This constructor initializes a `Time` object with a given value.
83      *
84      * @param[in] aValue   The numeric time value to initialize the `Time` object.
85      *
86      */
Time(uint32_t aValue)87     explicit Time(uint32_t aValue) { SetValue(aValue); }
88 
89     /**
90      * This method gets the numeric time value associated with the `Time` object.
91      *
92      * @returns The numeric `Time` value.
93      *
94      */
GetValue(void) const95     uint32_t GetValue(void) const { return mValue; }
96 
97     /**
98      * This method sets the numeric time value.
99      *
100      * @param[in] aValue   The numeric time value.
101      *
102      */
SetValue(uint32_t aValue)103     void SetValue(uint32_t aValue) { mValue = aValue; }
104 
105     /**
106      * This method calculates the time duration between two `Time` instances.
107      *
108      * @note Expression `(t1 - t2)` returns the duration of the interval starting from `t2` and ending at `t1`. When
109      * calculating the duration, `t2 is assumed to be in the past relative to `t1`. The duration calculation correctly
110      * takes into account the wrapping of numeric value of `Time` instances. The returned value can span the entire
111      * range of the `uint32_t` type.
112      *
113      * @param[in]   aOther  A `Time` instance to subtract from.
114      *
115      * @returns The duration of interval from @p aOther to this `Time` object.
116      *
117      */
operator -(const Time & aOther) const118     uint32_t operator-(const Time &aOther) const { return mValue - aOther.mValue; }
119 
120     /**
121      * This method returns a new `Time` which is ahead of this `Time` object by a given duration.
122      *
123      * @param[in]   aDuration  A duration.
124      *
125      * @returns A new `Time` which is ahead of this object by @aDuration.
126      *
127      */
operator +(uint32_t aDuration) const128     Time operator+(uint32_t aDuration) const { return Time(mValue + aDuration); }
129 
130     /**
131      * This method returns a new `Time` which is behind this `Time` object by a given duration.
132      *
133      * @param[in]   aDuration  A duration.
134      *
135      * @returns A new `Time` which is behind this object by @aDuration.
136      *
137      */
operator -(uint32_t aDuration) const138     Time operator-(uint32_t aDuration) const { return Time(mValue - aDuration); }
139 
140     /**
141      * This method moves this `Time` object forward by a given duration.
142      *
143      * @param[in]   aDuration  A duration.
144      *
145      */
operator +=(uint32_t aDuration)146     void operator+=(uint32_t aDuration) { mValue += aDuration; }
147 
148     /**
149      * This method moves this `Time` object backward by a given duration.
150      *
151      * @param[in]   aDuration  A duration.
152      *
153      */
operator -=(uint32_t aDuration)154     void operator-=(uint32_t aDuration) { mValue -= aDuration; }
155 
156     /**
157      * This method indicates whether two `Time` instances are equal.
158      *
159      * @param[in]   aOther   A `Time` instance to compare with.
160      *
161      * @retval TRUE    The two `Time` instances are equal.
162      * @retval FALSE   The two `Time` instances are not equal.
163      *
164      */
operator ==(const Time & aOther) const165     bool operator==(const Time &aOther) const { return mValue == aOther.mValue; }
166 
167     /**
168      * This method indicates whether this `Time` instance is strictly before another one.
169      *
170      * @note The comparison operators correctly take into account the wrapping of `Time` numeric value. For a given
171      * `Time` instance `t0`, any `Time` instance `t` where `(t - t0)` is less than half the range of `uint32_t` type
172      * is considered to be after `t0`, otherwise it is considered to be before 't0' (or equal to it). As an example
173      * to illustrate this model we can use clock hours: If we are at hour 12, hours 1 to 5 are considered to be
174      * after 12, and hours 6 to 11 are considered to be before 12.
175      *
176      * @param[in]   aOther   A `Time` instance to compare with.
177      *
178      * @retval TRUE    This `Time` instance is strictly before @p aOther.
179      * @retval FALSE   This `Time` instance is not strictly before @p aOther.
180      *
181      */
operator <(const Time & aOther) const182     bool operator<(const Time &aOther) const { return SerialNumber::IsLess(mValue, aOther.mValue); }
183 
184     /**
185      * This method indicates whether this `Time` instance is after or equal to another one.
186      *
187      * @param[in]   aOther   A `Time` instance to compare with.
188      *
189      * @retval TRUE    This `Time` instance is after or equal to @p aOther.
190      * @retval FALSE   This `Time` instance is not after or equal to @p aOther.
191      *
192      */
operator >=(const Time & aOther) const193     bool operator>=(const Time &aOther) const { return !(*this < aOther); }
194 
195     /**
196      * This method indicates whether this `Time` instance is before or equal to another one.
197      *
198      * @param[in]   aOther   A `Time` instance to compare with.
199      *
200      * @retval TRUE    This `Time` instance is before or equal to @p aOther.
201      * @retval FALSE   This `Time` instance is not before or equal to @p aOther.
202      *
203      */
operator <=(const Time & aOther) const204     bool operator<=(const Time &aOther) const { return (aOther >= *this); }
205 
206     /**
207      * This method indicates whether this `Time` instance is strictly after another one.
208      *
209      * @param[in]   aOther   A `Time` instance to compare with.
210      *
211      * @retval TRUE    This `Time` instance is strictly after @p aOther.
212      * @retval FALSE   This `Time` instance is not strictly after @p aOther.
213      *
214      */
operator >(const Time & aOther) const215     bool operator>(const Time &aOther) const { return (aOther < *this); }
216 
217     /**
218      * This method returns a new `Time` instance which is in distant future relative to current `Time` object.
219      *
220      * The returned distance future `Time` is guaranteed to be equal or after (as defined by comparison operator `<=`)
221      * any other `Time` which is after this `Time` object, i.e., for any `t` for which we have `*this <= t`, it is
222      * ensured that `t <= this->GetGetDistantFuture()`.
223      *
224      * @returns A new `Time` in distance future relative to current `Time` object.
225      *
226      */
GetDistantFuture(void) const227     Time GetDistantFuture(void) const { return Time(mValue + kDistantFuture); }
228 
229     /**
230      * This method returns a new `Time` instance which is in distant past relative to current `Time` object.
231      *
232      * The returned distance past `Time` is guaranteed to be equal or before (as defined by comparison operator `>=`)
233      * any other `Time` which is before this `Time` object, i.e., for any `t` for which we have `*this >= t`, it is
234      * ensured that `t >= this->GetDistantPast()`.
235      *
236      * @returns A new `Time` in distance past relative to current `Time` object.
237      *
238      */
GetDistantPast(void) const239     Time GetDistantPast(void) const { return Time(mValue - kDistantFuture); }
240 
241     /**
242      * This static method converts a given number of seconds to milliseconds.
243      *
244      * @param[in] aSeconds   The seconds value to convert to milliseconds.
245      *
246      * @returns The number of milliseconds.
247      *
248      */
SecToMsec(uint32_t aSeconds)249     static uint32_t constexpr SecToMsec(uint32_t aSeconds) { return aSeconds * 1000u; }
250 
251     /**
252      * This static method converts a given number of milliseconds to seconds.
253      *
254      * @param[in] aMilliseconds  The milliseconds value to convert to seconds.
255      *
256      * @returns The number of seconds.
257      *
258      */
MsecToSec(uint32_t aMilliseconds)259     static uint32_t constexpr MsecToSec(uint32_t aMilliseconds) { return aMilliseconds / 1000u; }
260 
261 private:
262     static constexpr uint32_t kDistantFuture = (1UL << 31);
263 
264     uint32_t mValue;
265 };
266 
267 /**
268  * This type represents a time instance (millisecond time).
269  *
270  */
271 typedef Time TimeMilli;
272 
273 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
274 
275 /**
276  * This type represents a time instance (microsecond time).
277  *
278  */
279 typedef Time TimeMicro;
280 
281 #endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
282 
283 /**
284  * @}
285  *
286  */
287 
288 } // namespace ot
289 
290 #endif // TIME_HPP_
291