diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 8358a3ba8..a8643b0cf 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -1966,7 +1966,7 @@ void Interpreter::HandleIcmpReceive(Message & aMessage, if (aMessage.Read(aMessage.GetOffset(), sizeof(uint32_t), ×tamp) >= static_cast(sizeof(uint32_t))) { - mServer->OutputFormat(" time=%dms", TimerMilli::Elapsed(HostSwap32(timestamp))); + mServer->OutputFormat(" time=%dms", TimerMilli::GetNow().GetValue() - HostSwap32(timestamp)); } mServer->OutputFormat("\r\n"); @@ -2022,7 +2022,7 @@ void Interpreter::ProcessPing(int argc, char *argv[]) case 3: SuccessOrExit(error = ParsePingInterval(argv[index], interval)); - VerifyOrExit(0 < interval && interval <= Timer::kMaxDt, error = OT_ERROR_INVALID_ARGS); + VerifyOrExit(0 < interval && interval <= Timer::kMaxDelay, error = OT_ERROR_INVALID_ARGS); mInterval = interval; break; @@ -2049,7 +2049,7 @@ void Interpreter::HandlePingTimer(Timer &aTimer) void Interpreter::HandlePingTimer() { otError error = OT_ERROR_NONE; - uint32_t timestamp = HostSwap32(TimerMilli::GetNow()); + uint32_t timestamp = HostSwap32(TimerMilli::GetNow().GetValue()); otMessage * message; const otMessageInfo *messageInfo = static_cast(&mMessageInfo); diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 85f1b9f36..0345073d3 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -318,6 +318,7 @@ HEADERS_COMMON = \ common/settings.hpp \ common/string.hpp \ common/tasklet.hpp \ + common/time.hpp \ common/timer.hpp \ common/tlvs.hpp \ common/trickle_timer.hpp \ diff --git a/src/core/api/thread_api.cpp b/src/core/api/thread_api.cpp index 96a8832ea..65c3246d7 100644 --- a/src/core/api/thread_api.cpp +++ b/src/core/api/thread_api.cpp @@ -320,8 +320,8 @@ otError otThreadGetParentInfo(otInstance *aInstance, otRouterInfo *aParentInfo) aParentInfo->mPathCost = parent->GetCost(); aParentInfo->mLinkQualityIn = parent->GetLinkInfo().GetLinkQuality(); aParentInfo->mLinkQualityOut = parent->GetLinkQualityOut(); - aParentInfo->mAge = static_cast(TimerMilli::MsecToSec(TimerMilli::Elapsed(parent->GetLastHeard()))); - aParentInfo->mAllocated = true; + aParentInfo->mAge = static_cast(Time::MsecToSec(TimerMilli::GetNow() - parent->GetLastHeard())); + aParentInfo->mAllocated = true; aParentInfo->mLinkEstablished = parent->GetState() == Neighbor::kStateValid; #if !OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE diff --git a/src/core/coap/coap.cpp b/src/core/coap/coap.cpp index 341167c4f..3e0b09165 100644 --- a/src/core/coap/coap.cpp +++ b/src/core/coap/coap.cpp @@ -260,8 +260,8 @@ void CoapBase::HandleRetransmissionTimer(Timer &aTimer) void CoapBase::HandleRetransmissionTimer(void) { - uint32_t now = TimerMilli::GetNow(); - uint32_t nextDelta = TimerMilli::kForeverDt; + TimeMilli now = TimerMilli::GetNow(); + uint32_t nextDelta = TimeMilli::kMaxDuration; CoapMetadata coapMetadata; Message * message = static_cast(mPendingRequests.GetHead()); Message * nextMessage = NULL; @@ -274,7 +274,8 @@ void CoapBase::HandleRetransmissionTimer(void) if (coapMetadata.IsLater(now)) { - uint32_t diff = TimerMilli::Elapsed(now, coapMetadata.mNextTimerShot); + uint32_t diff = coapMetadata.mNextTimerShot - now; + // Calculate the next delay and choose the lowest. if (diff < nextDelta) { @@ -314,7 +315,7 @@ void CoapBase::HandleRetransmissionTimer(void) message = nextMessage; } - if (nextDelta != TimerMilli::kForeverDt) + if (nextDelta != TimeMilli::kMaxDuration) { mRetransmissionTimer.Start(nextDelta); } @@ -372,7 +373,7 @@ Message *CoapBase::CopyAndEnqueueMessage(const Message & aMessage, // Setup the timer. if (mRetransmissionTimer.IsRunning()) { - uint32_t alarmFireTime; + TimeMilli alarmFireTime; // If timer is already running, check if it should be restarted with earlier fire time. alarmFireTime = mRetransmissionTimer.GetFireTime(); @@ -682,10 +683,10 @@ CoapMetadata::CoapMetadata(bool aConfirmable, mResponseHandler = aHandler; mResponseContext = aContext; mRetransmissionCount = 0; - mRetransmissionTimeout = TimerMilli::SecToMsec(kAckTimeout); + mRetransmissionTimeout = Time::SecToMsec(kAckTimeout); mRetransmissionTimeout += Random::NonCrypto::GetUint32InRange( - 0, TimerMilli::SecToMsec(kAckTimeout) * kAckRandomFactorNumerator / kAckRandomFactorDenominator - - TimerMilli::SecToMsec(kAckTimeout) + 1); + 0, Time::SecToMsec(kAckTimeout) * kAckRandomFactorNumerator / kAckRandomFactorDenominator - + Time::SecToMsec(kAckTimeout) + 1); if (aConfirmable) { @@ -790,7 +791,7 @@ void ResponsesQueue::EnqueueResponse(Message &aMessage, const Ip6::MessageInfo & if (!mTimer.IsRunning()) { - mTimer.Start(TimerMilli::SecToMsec(kExchangeLifetime)); + mTimer.Start(Time::SecToMsec(kExchangeLifetime)); } exit: @@ -852,9 +853,15 @@ void ResponsesQueue::HandleTimer(void) uint32_t EnqueuedResponseHeader::GetRemainingTime(void) const { - int32_t remainingTime = static_cast(mDequeueTime - TimerMilli::GetNow()); + TimeMilli now = TimerMilli::GetNow(); + uint32_t remainingTime = 0; - return remainingTime >= 0 ? static_cast(remainingTime) : 0; + if (mDequeueTime > now) + { + remainingTime = mDequeueTime - now; + } + + return remainingTime; } Coap::Coap(Instance &aInstance) diff --git a/src/core/coap/coap.hpp b/src/core/coap/coap.hpp index 9486f8733..46fc4db16 100644 --- a/src/core/coap/coap.hpp +++ b/src/core/coap/coap.hpp @@ -166,8 +166,9 @@ public: * * @retval TRUE If the message shall be sent before the given time. * @retval FALSE Otherwise. + * */ - bool IsEarlier(uint32_t aTime) const { return (static_cast(aTime - mNextTimerShot) >= 0); } + bool IsEarlier(TimeMilli aTime) const { return aTime >= mNextTimerShot; } /** * This method checks if the message shall be sent after the given time. @@ -176,8 +177,9 @@ public: * * @retval TRUE If the message shall be sent after the given time. * @retval FALSE Otherwise. + * */ - bool IsLater(uint32_t aTime) const { return (static_cast(aTime - mNextTimerShot) < 0); } + bool IsLater(TimeMilli aTime) const { return aTime < mNextTimerShot; } private: Ip6::Address mSourceAddress; ///< IPv6 address of the message source. @@ -185,7 +187,7 @@ private: uint16_t mDestinationPort; ///< UDP port of the message destination. otCoapResponseHandler mResponseHandler; ///< A function pointer that is called on response reception. void * mResponseContext; ///< A pointer to arbitrary context information. - uint32_t mNextTimerShot; ///< Time when the timer should shoot for this message. + TimeMilli mNextTimerShot; ///< Time when the timer should shoot for this message. uint32_t mRetransmissionTimeout; ///< Delay that is applied to next retransmission. uint8_t mRetransmissionCount; ///< Number of retransmissions. bool mAcknowledged : 1; ///< Information that request was acknowledged. @@ -268,7 +270,7 @@ public: * */ explicit EnqueuedResponseHeader(const Ip6::MessageInfo &aMessageInfo) - : mDequeueTime(TimerMilli::GetNow() + TimerMilli::SecToMsec(kExchangeLifetime)) + : mDequeueTime(TimerMilli::GetNow() + Time::SecToMsec(kExchangeLifetime)) , mMessageInfo(aMessageInfo) { } @@ -305,7 +307,7 @@ public: * @retval FALSE Otherwise. * */ - bool IsEarlier(uint32_t aTime) const { return (static_cast(aTime - mDequeueTime) >= 0); } + bool IsEarlier(TimeMilli aTime) const { return aTime >= mDequeueTime; } /** * This method returns number of milliseconds in which the message should be sent. @@ -324,7 +326,7 @@ public: const Ip6::MessageInfo &GetMessageInfo(void) const { return mMessageInfo; } private: - uint32_t mDequeueTime; + TimeMilli mDequeueTime; const Ip6::MessageInfo mMessageInfo; }; diff --git a/src/core/common/time.hpp b/src/core/common/time.hpp new file mode 100644 index 000000000..350687fa5 --- /dev/null +++ b/src/core/common/time.hpp @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2019, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file includes definitions for time instance. + */ + +#ifndef TIME_HPP_ +#define TIME_HPP_ + +#include "openthread-core-config.h" + +#include +#include + +namespace ot { + +/** + * @addtogroup core-timer + * + * @brief + * This module includes definitions for the time instance. + * + * @{ + * + */ + +/** + * This class represents a time instance. + * + */ +class Time +{ +public: + /** + * This constant defines a maximum time duration ensured to be longer than any other duration. + * + */ + static const uint32_t kMaxDuration = ~static_cast(0UL); + + /** + * This is the default constructor for a `Time` object. + * + */ + Time(void) {} + + /** + * This constructor initializes a `Time` object with a given value. + * + * @param[in] aValue The numeric time value to initialize the `Time` object. + * + */ + explicit Time(uint32_t aValue) { SetValue(aValue); } + + /** + * This method gets the numeric time value associated with the `Time` object. + * + * @returns The numeric `Time` value. + * + */ + uint32_t GetValue(void) const { return mValue; } + + /** + * This method sets the numeric time value. + * + * @param[in] aValue The numeric time value. + * + */ + void SetValue(uint32_t aValue) { mValue = aValue; } + + /** + * This method calculates the time duration between two `Time` instances. + * + * @note Expression `(t1 - t2)` returns the duration of the interval starting from `t2` and ending at `t1`. When + * calculating the duration, `t2 is assumed to be in the past relative to `t1`. The duration calculation correctly + * takes into account the wrapping of numeric value of `Time` instances. The returned value can span the entire + * range of the `uint32_t` type. + * + * @param[in] aOther A `Time` instance to subtract from. + * + * @returns The duration of interval from @p aOther to this `Time` object. + * + */ + uint32_t operator-(const Time &aOther) const { return mValue - aOther.mValue; } + + /** + * This method returns a new `Time` which is ahead of this `Time` object by a given duration. + * + * @param[in] aDuration A duration. + * + * @returns A new `Time` which is ahead of this object by @aDuration. + * + */ + Time operator+(uint32_t aDuration) const { return Time(mValue + aDuration); } + + /** + * This method returns a new `Time` which is behind this `Time` object by a given duration. + * + * @param[in] aDuration A duration. + * + * @returns A new `Time` which is behind this object by @aDuration. + * + */ + Time operator-(uint32_t aDuration) const { return Time(mValue - aDuration); } + + /** + * This method moves this `Time` object forward by a given duration. + * + * @param[in] aDuration A duration. + * + */ + void operator+=(uint32_t aDuration) { mValue += aDuration; } + + /** + * This method moves this `Time` object backward by a given duration. + * + * @param[in] aDuration A duration. + * + */ + void operator-=(uint32_t aDuration) { mValue -= aDuration; } + + /** + * This method indicates whether two `Time` instances are equal. + * + * @param[in] aOther A `Time` instance to compare with. + * + * @retval TRUE The two `Time` instances are equal. + * @retval FALSE The two `Time` instances are not equal. + * + */ + bool operator==(const Time &aOther) const { return mValue == aOther.mValue; } + + /** + * This method indicates whether two `Time` instance are not equal. + * + * @param[in] aOther A `Time` instance to compare with. + * + * @retval TRUE The two `Time` instances are not equal. + * @retval FALSE The two `Time` instances are equal. + * + */ + bool operator!=(const Time &aOther) const { return !(*this == aOther); } + + /** + * This method indicates whether this `Time` instance is strictly before another one. + * + * @note The comparison operators correctly take into account the wrapping of `Time` numeric value. For a given + * `Time` instance `t0`, any `Time` instance `t` where `(t - t0)` is less than half the range of `uint32_t` type + * is considered to be after `t0`, otherwise it is considered to be before 't0' (or equal to it). As an example + * to illustrate this model we can use clock hours: If we are at hour 12, hours 1 to 5 are considered to be + * after 12, and hours 6 to 11 are considered to be before 12. + * + * @param[in] aOther A `Time` instance to compare with. + * + * @retval TRUE This `Time` instance is strictly before @p aOther. + * @retval FALSE This `Time` instance is not strictly before @p aOther. + * + */ + bool operator<(const Time &aOther) const { return ((mValue - aOther.mValue) & (1UL << 31)) != 0; } + + /** + * This method indicates whether this `Time` instance is after or equal to another one. + * + * @param[in] aOther A `Time` instance to compare with. + * + * @retval TRUE This `Time` instance is after or equal to @p aOther. + * @retval FALSE This `Time` instance is not after or equal to @p aOther. + * + */ + bool operator>=(const Time &aOther) const { return !(*this < aOther); } + + /** + * This method indicates whether this `Time` instance is before or equal to another one. + * + * @param[in] aOther A `Time` instance to compare with. + * + * @retval TRUE This `Time` instance is before or equal to @p aOther. + * @retval FALSE This `Time` instance is not before or equal to @p aOther. + * + */ + bool operator<=(const Time &aOther) const { return (aOther >= *this); } + + /** + * This method indicates whether this `Time` instance is strictly after another one. + * + * @param[in] aOther A `Time` instance to compare with. + * + * @retval TRUE This `Time` instance is strictly after @p aOther. + * @retval FALSE This `Time` instance is not strictly after @p aOther. + * + */ + bool operator>(const Time &aOther) const { return (aOther < *this); } + + /** + * This static method converts a given number of seconds to milliseconds. + * + * @returns The number of milliseconds. + * + */ + static uint32_t SecToMsec(uint32_t aSeconds) { return aSeconds * 1000u; } + + /** + * This static method converts a given number of milliseconds to seconds. + * + * @returns The number of seconds. + * + */ + static uint32_t MsecToSec(uint32_t aMilliseconds) { return aMilliseconds / 1000u; } + +private: + uint32_t mValue; +}; + +/** + * This type represents a time instance (millisecond time). + * + */ +typedef Time TimeMilli; + +#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE + +/** + * This type represents a time instance (microsecond time). + * + */ +typedef Time TimeMicro; + +#endif // OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE + +/** + * @} + * + */ + +} // namespace ot + +#endif // TIME_HPP_ diff --git a/src/core/common/timer.cpp b/src/core/common/timer.cpp index 4e50be166..63fe8e309 100644 --- a/src/core/common/timer.cpp +++ b/src/core/common/timer.cpp @@ -44,13 +44,13 @@ namespace ot { const TimerScheduler::AlarmApi TimerMilliScheduler::sAlarmMilliApi = {&otPlatAlarmMilliStartAt, &otPlatAlarmMilliStop, &otPlatAlarmMilliGetNow}; -bool Timer::DoesFireBefore(const Timer &aSecondTimer, uint32_t aNow) +bool Timer::DoesFireBefore(const Timer &aSecondTimer, Time aNow) { bool retval; - bool isBeforeNow = TimerScheduler::IsStrictlyBefore(GetFireTime(), aNow); + bool isBeforeNow = (GetFireTime() < aNow); // Check if one timer is before `now` and the other one is not. - if (TimerScheduler::IsStrictlyBefore(aSecondTimer.GetFireTime(), aNow) != isBeforeNow) + if ((aSecondTimer.GetFireTime() < aNow) != isBeforeNow) { // One timer is before `now` and the other one is not, so if this timer's fire time is before `now` then // the second fire time would be after `now` and this timer would fire before the second timer. @@ -62,16 +62,21 @@ bool Timer::DoesFireBefore(const Timer &aSecondTimer, uint32_t aNow) // Both timers are before `now` or both are after `now`. Either way the difference is guaranteed to be less // than `kMaxDt` so we can safely compare the fire times directly. - retval = TimerScheduler::IsStrictlyBefore(GetFireTime(), aSecondTimer.GetFireTime()); + retval = GetFireTime() < aSecondTimer.GetFireTime(); } return retval; } -void TimerMilli::StartAt(uint32_t aT0, uint32_t aDt) +void TimerMilli::Start(uint32_t aDelay) { - assert(aDt <= kMaxDt); - mFireTime = aT0 + aDt; + StartAt(GetNow(), aDelay); +} + +void TimerMilli::StartAt(TimeMilli aStartTime, uint32_t aDelay) +{ + assert(aDelay <= kMaxDelay); + mFireTime = aStartTime + aDelay; Get().Add(*this); } @@ -97,7 +102,9 @@ void TimerScheduler::Add(Timer &aTimer, const AlarmApi &aAlarmApi) for (cur = mHead; cur; cur = cur->mNext) { - if (aTimer.DoesFireBefore(*cur, aAlarmApi.AlarmGetNow())) + Time now(aAlarmApi.AlarmGetNow()); + + if (aTimer.DoesFireBefore(*cur, now)) { if (prev) { @@ -160,10 +167,12 @@ void TimerScheduler::SetAlarm(const AlarmApi &aAlarmApi) } else { - uint32_t now = aAlarmApi.AlarmGetNow(); - uint32_t remaining = IsStrictlyBefore(now, mHead->mFireTime) ? (mHead->mFireTime - now) : 0; + Time now(aAlarmApi.AlarmGetNow()); + uint32_t remaining; - aAlarmApi.AlarmStartAt(&GetInstance(), now, remaining); + remaining = (now < mHead->mFireTime) ? (mHead->mFireTime - now) : 0; + + aAlarmApi.AlarmStartAt(&GetInstance(), now.GetValue(), remaining); } } @@ -173,32 +182,20 @@ void TimerScheduler::ProcessTimers(const AlarmApi &aAlarmApi) if (timer) { - if (!IsStrictlyBefore(aAlarmApi.AlarmGetNow(), timer->mFireTime)) + Time now(aAlarmApi.AlarmGetNow()); + + if (now >= timer->mFireTime) { - Remove(*timer, aAlarmApi); + Remove(*timer, aAlarmApi); // `Remove()` will `SetAlarm` for next timer if there is any. timer->Fired(); - } - else - { - SetAlarm(aAlarmApi); + ExitNow(); } } - else - { - SetAlarm(aAlarmApi); - } -} -bool TimerScheduler::IsStrictlyBefore(uint32_t aTimeA, uint32_t aTimeB) -{ - uint32_t diff = aTimeA - aTimeB; + SetAlarm(aAlarmApi); - // Three cases: - // 1) aTimeA is before aTimeB => Difference is negative (last bit of difference is set) => Returning true. - // 2) aTimeA is same as aTimeB => Difference is zero (last bit of difference is clear) => Returning false. - // 3) aTimeA is after aTimeB => Difference is positive (last bit of difference is clear) => Returning false. - - return ((diff & (1UL << 31)) != 0); +exit: + return; } extern "C" void otPlatAlarmMilliFired(otInstance *aInstance) @@ -215,11 +212,15 @@ exit: #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE const TimerScheduler::AlarmApi TimerMicroScheduler::sAlarmMicroApi = {&otPlatAlarmMicroStartAt, &otPlatAlarmMicroStop, &otPlatAlarmMicroGetNow}; - -void TimerMicro::StartAt(uint32_t aT0, uint32_t aDt) +void TimerMicro::Start(uint32_t aDelay) { - assert(aDt <= kMaxDt); - mFireTime = aT0 + aDt; + StartAt(GetNow(), aDelay); +} + +void TimerMicro::StartAt(TimeMicro aStartTime, uint32_t aDelay) +{ + assert(aDelay <= kMaxDelay); + mFireTime = aStartTime + aDelay; Get().Add(*this); } diff --git a/src/core/common/timer.hpp b/src/core/common/timer.hpp index 3e000a388..9b6293143 100644 --- a/src/core/common/timer.hpp +++ b/src/core/common/timer.hpp @@ -45,6 +45,7 @@ #include "common/debug.hpp" #include "common/locator.hpp" #include "common/tasklet.hpp" +#include "common/time.hpp" namespace ot { @@ -69,9 +70,11 @@ class Timer : public InstanceLocator, public OwnerLocator friend class TimerScheduler; public: - static const uint32_t kMaxDt = - (1UL << 31) - 1; ///< Maximum permitted value for parameter `aDt` in `Start` and `StartAt` method. - static const uint32_t kForeverDt = 0xffffffff; ///< The special forever `aDt` value. + /** + * This constant defines maximum delay allowed when starting a timer. + * + */ + static const uint32_t kMaxDelay = (Time::kMaxDuration >> 1); /** * This function pointer is called when the timer expires. @@ -93,7 +96,7 @@ public: : InstanceLocator(aInstance) , OwnerLocator(aOwner) , mHandler(aHandler) - , mFireTime(0) + , mFireTime() , mNext(this) { } @@ -101,10 +104,10 @@ public: /** * This method returns the fire time of the timer. * - * @returns The fire time in milliseconds. + * @returns The fire time. * */ - uint32_t GetFireTime(void) const { return mFireTime; } + Time GetFireTime(void) const { return mFireTime; } /** * This method indicates whether or not the timer instance is running. @@ -126,13 +129,13 @@ protected: * @retval FALSE If the fire time of this timer object is the same or after aTimer's fire time. * */ - bool DoesFireBefore(const Timer &aSecondTimer, uint32_t aNow); + bool DoesFireBefore(const Timer &aSecondTimer, Time aNow); void Fired(void) { mHandler(*this); } - Handler mHandler; - uint32_t mFireTime; - Timer * mNext; + Handler mHandler; + Time mFireTime; + Timer * mNext; }; /** @@ -156,23 +159,21 @@ public: } /** - * This method schedules the timer to fire a @p dt milliseconds from now. + * This method schedules the timer to fire after a given delay (in milliseconds) from now. * - * @param[in] aDt The expire time in milliseconds from now. - * (aDt must be smaller than or equal to kMaxDt). + * @param[in] aDelay The delay in milliseconds. It must not be longer than `kMaxDelay`. * */ - void Start(uint32_t aDt) { StartAt(GetNow(), aDt); } + void Start(uint32_t aDelay); /** - * This method schedules the timer to fire at @p aDt milliseconds from @p aT0. + * This method schedules the timer to fire after a given delay (in milliseconds) from a given start time. * - * @param[in] aT0 The start time in milliseconds. - * @param[in] aDt The expire time in milliseconds from @p aT0. - * (aDt must be smaller than or equal to kMaxDt). + * @param[in] aStartTime The start time. + * @param[in] aDelay The delay in milliseconds. It must not be longer than `kMaxDelay`. * */ - void StartAt(uint32_t aT0, uint32_t aDt); + void StartAt(TimeMilli sStartTime, uint32_t aDelay); /** * This method stops the timer. @@ -180,69 +181,13 @@ public: */ void Stop(void); - /** - * This static method returns the time diff in milliseconds between @p aStart and @p aEnd. - * - * @param[in] aStart The start time. - * @param[in] aEnd The end time. - * - * @returns The time diff in milliseconds. - * - */ - static int32_t Diff(uint32_t aStart, uint32_t aEnd) - { - uint32_t diff = aEnd - aStart; - return reinterpret_cast(diff); - } - - /** - * This static method returns the time elapsed in milliseconds from @p aStart to @p aEnd. - * - * @note This method assumes @p aEnd is after @p aStart. - * - * @param[in] aStart The start time. - * @param[in] aEnd The end time. - * - * @returns The elapsed time in milliseconds. - * - */ - static uint32_t Elapsed(uint32_t aStart, uint32_t aEnd) { return aEnd - aStart; } - - /** - * This static method returns the time passed in milliseconds since @p aStart. - * - * @note This method assumes now is after @p aStart. - * - * @param[in] aStart The start time. - * - * @returns The elapsed time in milliseconds. - * - */ - static uint32_t Elapsed(uint32_t aStart) { return Elapsed(aStart, GetNow()); } - /** * This static method returns the current time in milliseconds. * * @returns The current time in milliseconds. * */ - static uint32_t GetNow(void) { return otPlatAlarmMilliGetNow(); } - - /** - * This static method returns the number of milliseconds given seconds. - * - * @returns The number of milliseconds. - * - */ - static uint32_t SecToMsec(uint32_t aSeconds) { return aSeconds * 1000u; } - - /** - * This static method returns the number of seconds given milliseconds. - * - * @returns The number of seconds. - * - */ - static uint32_t MsecToSec(uint32_t aMilliseconds) { return aMilliseconds / 1000u; } + static TimeMilli GetNow(void) { return TimeMilli(otPlatAlarmMilliGetNow()); } }; /** @@ -291,22 +236,6 @@ class TimerScheduler : public InstanceLocator { friend class Timer; -public: - /** - * This static method compares two times and indicates if the first time is strictly before (earlier) than the - * second time. - * - * This method requires that the difference between the two given times to be smaller than kMaxDt. - * - * @param[in] aTimerA The first time for comparison. - * @param[in] aTimerB The second time for comparison. - * - * @returns TRUE if aTimeA is before aTimeB. - * @returns FALSE if aTimeA is same time or after aTimeB. - * - */ - static bool IsStrictlyBefore(uint32_t aTimeA, uint32_t aTimeB); - protected: /** * The Alarm APIs definition @@ -436,23 +365,21 @@ public: } /** - * This method schedules the timer to fire a @p aDt microseconds from now. + * This method schedules the timer to fire after a given delay (in microseconds) from now. * - * @param[in] aDt The expire time in microseconds from now. - * (aDt must be smaller than or equal to kMaxDt). + * @param[in] aDelay The delay in microseconds. It must not be be longer than `kMaxDelay`. * */ - void Start(uint32_t aDt) { StartAt(GetNow(), aDt); } + void Start(uint32_t aDelay); /** - * This method schedules the timer to fire at @p aDt microseconds from @p aT0. + * This method schedules the timer to fire after a given delay (in microseconds) from a given start time. * - * @param[in] aT0 The start time in microseconds. - * @param[in] aDt The expire time in microseconds from @p aT0. - * (aDt must be smaller than or equal to kMaxDt). + * @param[in] aStartTime The start time. + * @param[in] aDelay The delay in microseconds. It must not be longer than `kMaxDelay`. * */ - void StartAt(uint32_t aT0, uint32_t aDt); + void StartAt(TimeMicro aStartTime, uint32_t aDelay); /** * This method stops the timer. @@ -466,7 +393,7 @@ public: * @returns The current time in microseconds. * */ - static uint32_t GetNow(void) { return otPlatAlarmMicroGetNow(); } + static TimeMicro GetNow(void) { return Time(otPlatAlarmMicroGetNow()); } }; /** diff --git a/src/core/mac/data_poll_handler.cpp b/src/core/mac/data_poll_handler.cpp index ef889b83f..8309f88cd 100644 --- a/src/core/mac/data_poll_handler.cpp +++ b/src/core/mac/data_poll_handler.cpp @@ -300,8 +300,7 @@ void DataPollHandler::ProcessPendingPolls(void) // Find the child with earliest poll receive time. - if ((mIndirectTxChild == NULL) || - TimerScheduler::IsStrictlyBefore(child->GetLastHeard(), mIndirectTxChild->GetLastHeard())) + if ((mIndirectTxChild == NULL) || (child->GetLastHeard() < mIndirectTxChild->GetLastHeard())) { mIndirectTxChild = child; } diff --git a/src/core/mac/data_poll_sender.cpp b/src/core/mac/data_poll_sender.cpp index a4e834ce1..ad94b622f 100644 --- a/src/core/mac/data_poll_sender.cpp +++ b/src/core/mac/data_poll_sender.cpp @@ -386,8 +386,8 @@ exit: void DataPollSender::ScheduleNextPoll(PollPeriodSelector aPollPeriodSelector) { - uint32_t now; - uint32_t oldPeriod = mPollPeriod; + TimeMilli now; + uint32_t oldPeriod = mPollPeriod; if (aPollPeriodSelector == kRecalculatePollPeriod) { @@ -408,7 +408,8 @@ void DataPollSender::ScheduleNextPoll(PollPeriodSelector aPollPeriodSelector) // a switch to a shorter poll interval, the first data poll // will not be sent too quickly (and possibly before the // response is available/prepared on the parent node). - if (TimerScheduler::IsStrictlyBefore(mTimerStartTime + mPollPeriod, now + kMinPollPeriod)) + + if (mTimerStartTime + mPollPeriod < now + kMinPollPeriod) { mTimer.StartAt(now, kMinPollPeriod); } @@ -473,7 +474,7 @@ void DataPollSender::HandlePollTimer(Timer &aTimer) uint32_t DataPollSender::GetDefaultPollPeriod(void) const { - return TimerMilli::SecToMsec(Get().GetTimeout()) - + return Time::SecToMsec(Get().GetTimeout()) - static_cast(kRetxPollPeriod) * kMaxPollRetxAttempts; } diff --git a/src/core/mac/data_poll_sender.hpp b/src/core/mac/data_poll_sender.hpp index 279e9892f..6c053e4df 100644 --- a/src/core/mac/data_poll_sender.hpp +++ b/src/core/mac/data_poll_sender.hpp @@ -271,10 +271,10 @@ private: static void HandlePollTimer(Timer &aTimer); static void UpdateIfLarger(uint32_t &aPreiod, uint32_t aNewPeriod); - uint32_t mTimerStartTime; - uint32_t mPollPeriod; - uint32_t mExternalPollPeriod : 26; //< In milliseconds. - uint8_t mFastPollsUsers : 6; //< Number of callers which request fast polls. + TimeMilli mTimerStartTime; + uint32_t mPollPeriod; + uint32_t mExternalPollPeriod : 26; //< In milliseconds. + uint8_t mFastPollsUsers : 6; //< Number of callers which request fast polls. TimerMilli mTimer; diff --git a/src/core/mac/sub_mac.cpp b/src/core/mac/sub_mac.cpp index 970703288..547df5ffb 100644 --- a/src/core/mac/sub_mac.cpp +++ b/src/core/mac/sub_mac.cpp @@ -418,7 +418,7 @@ otError SubMac::EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration) SetState(kStateEnergyScan); mEnergyScanMaxRssi = kInvalidRssiValue; - mEnergyScanEndTime = TimerMilli::GetNow() + aScanDuration; + mEnergyScanEndTime = TimerMilli::GetNow() + static_cast(aScanDuration); mTimer.Start(0); } else @@ -442,7 +442,7 @@ void SubMac::SampleRssi(void) } } - if (TimerMilliScheduler::IsStrictlyBefore(TimerMilli::GetNow(), mEnergyScanEndTime)) + if (TimerMilli::GetNow() < mEnergyScanEndTime) { mTimer.StartAt(mTimer.GetFireTime(), kEnergyScanRssiSampleInterval); } diff --git a/src/core/mac/sub_mac.hpp b/src/core/mac/sub_mac.hpp index 53bac3ab2..dd752892a 100644 --- a/src/core/mac/sub_mac.hpp +++ b/src/core/mac/sub_mac.hpp @@ -411,7 +411,7 @@ private: ExtAddress mExtAddress; bool mRxOnWhenBackoff; int8_t mEnergyScanMaxRssi; - uint32_t mEnergyScanEndTime; + TimeMilli mEnergyScanEndTime; TxFrame & mTransmitFrame; Callbacks mCallbacks; otLinkPcapCallback mPcapCallback; diff --git a/src/core/meshcop/commissioner.cpp b/src/core/meshcop/commissioner.cpp index 3d327a714..67d7cb6c9 100644 --- a/src/core/meshcop/commissioner.cpp +++ b/src/core/meshcop/commissioner.cpp @@ -276,7 +276,7 @@ otError Commissioner::AddJoiner(const Mac::ExtAddress *aEui64, const char *aPskd (void)strlcpy(joiner->mPsk, aPskd, sizeof(joiner->mPsk)); joiner->mValid = true; - joiner->mExpirationTime = TimerMilli::GetNow() + TimerMilli::SecToMsec(aTimeout); + joiner->mExpirationTime = TimerMilli::GetNow() + Time::SecToMsec(aTimeout); UpdateJoinerExpirationTimer(); @@ -346,12 +346,11 @@ otError Commissioner::RemoveJoiner(const Mac::ExtAddress *aEui64, uint32_t aDela if (aDelay > 0) { - uint32_t now = TimerMilli::GetNow(); + TimeMilli now = TimerMilli::GetNow(); - if ((static_cast(joiner->mExpirationTime - now) > 0) && - (static_cast(joiner->mExpirationTime - now) > TimerMilli::SecToMsec(aDelay))) + if ((joiner->mExpirationTime > now) && (joiner->mExpirationTime - now > Time::SecToMsec(aDelay))) { - joiner->mExpirationTime = now + TimerMilli::SecToMsec(aDelay); + joiner->mExpirationTime = now + Time::SecToMsec(aDelay); UpdateJoinerExpirationTimer(); } } @@ -427,7 +426,7 @@ void Commissioner::HandleJoinerExpirationTimer(Timer &aTimer) void Commissioner::HandleJoinerExpirationTimer(void) { - uint32_t now = TimerMilli::GetNow(); + TimeMilli now = TimerMilli::GetNow(); // Remove Joiners. for (Joiner *joiner = &mJoiners[0]; joiner < OT_ARRAY_END(mJoiners); joiner++) @@ -437,7 +436,7 @@ void Commissioner::HandleJoinerExpirationTimer(void) continue; } - if (static_cast(now - joiner->mExpirationTime) >= 0) + if (now >= joiner->mExpirationTime) { otLogDebgMeshCoP("removing joiner due to timeout or successfully joined"); RemoveJoiner(&joiner->mEui64, 0); // remove immediately @@ -449,32 +448,34 @@ void Commissioner::HandleJoinerExpirationTimer(void) void Commissioner::UpdateJoinerExpirationTimer(void) { - uint32_t now = TimerMilli::GetNow(); - uint32_t nextTimeout = TimerMilli::kForeverDt; + TimeMilli now = TimerMilli::GetNow(); + uint32_t nextTimeout = TimeMilli::kMaxDuration; // Check if timer should be set for next Joiner. for (Joiner *joiner = &mJoiners[0]; joiner < OT_ARRAY_END(mJoiners); joiner++) { - int32_t diff; + uint32_t diff; if (!joiner->mValid) { continue; } - diff = TimerMilli::Diff(now, joiner->mExpirationTime); - if (diff <= 0) + if (now >= joiner->mExpirationTime) { nextTimeout = 0; break; } - else if (static_cast(diff) < nextTimeout) + + diff = joiner->mExpirationTime - now; + + if (diff < nextTimeout) { - nextTimeout = static_cast(diff); + nextTimeout = diff; } } - if (nextTimeout != TimerMilli::kForeverDt) + if (nextTimeout != TimeMilli::kMaxDuration) { // Update the timer to the timeout of the next Joiner. mJoinerExpirationTimer.Start(nextTimeout); @@ -724,7 +725,7 @@ void Commissioner::HandleLeaderPetitionResponse(Coap::Message * aMessage SetState(OT_COMMISSIONER_STATE_ACTIVE); mTransmitAttempts = 0; - mTimer.Start(TimerMilli::SecToMsec(kKeepAliveTimeout) / 2); + mTimer.Start(Time::SecToMsec(kKeepAliveTimeout) / 2); exit: @@ -736,7 +737,7 @@ exit: } else { - mTimer.Start(TimerMilli::SecToMsec(kPetitionRetryDelay)); + mTimer.Start(Time::SecToMsec(kPetitionRetryDelay)); } } } @@ -808,7 +809,7 @@ void Commissioner::HandleLeaderKeepAliveResponse(Coap::Message * aMessag VerifyOrExit(state.GetState() == StateTlv::kAccept, SetState(OT_COMMISSIONER_STATE_DISABLED)); - mTimer.Start(TimerMilli::SecToMsec(kKeepAliveTimeout) / 2); + mTimer.Start(Time::SecToMsec(kKeepAliveTimeout) / 2); exit: diff --git a/src/core/meshcop/commissioner.hpp b/src/core/meshcop/commissioner.hpp index 0cc18a909..76370c54d 100644 --- a/src/core/meshcop/commissioner.hpp +++ b/src/core/meshcop/commissioner.hpp @@ -328,7 +328,7 @@ private: struct Joiner { Mac::ExtAddress mEui64; - uint32_t mExpirationTime; + TimeMilli mExpirationTime; char mPsk[Dtls::kPskMaxLength + 1]; bool mValid : 1; bool mAny : 1; diff --git a/src/core/meshcop/dataset.cpp b/src/core/meshcop/dataset.cpp index 80ffb9b12..3a1a2bab4 100644 --- a/src/core/meshcop/dataset.cpp +++ b/src/core/meshcop/dataset.cpp @@ -477,7 +477,7 @@ otError Dataset::AppendMleDatasetTlv(Message &aMessage) const } else if (cur->GetType() == Tlv::kDelayTimer) { - uint32_t elapsed = TimerMilli::Elapsed(mUpdateTime); + uint32_t elapsed = TimerMilli::GetNow() - mUpdateTime; DelayTimerTlv delayTimer(static_cast(*cur)); if (delayTimer.GetDelayTimer() > elapsed) diff --git a/src/core/meshcop/dataset.hpp b/src/core/meshcop/dataset.hpp index e4e4adf2a..5b43bfc19 100644 --- a/src/core/meshcop/dataset.hpp +++ b/src/core/meshcop/dataset.hpp @@ -41,6 +41,7 @@ #include "common/locator.hpp" #include "common/message.hpp" +#include "common/timer.hpp" #include "meshcop/meshcop_tlvs.hpp" namespace ot { @@ -139,7 +140,7 @@ public: * @returns The local time the dataset was last updated. * */ - uint32_t GetUpdateTime(void) const { return mUpdateTime; } + TimeMilli GetUpdateTime(void) const { return mUpdateTime; } /** * This method returns a reference to the Timestamp. @@ -242,7 +243,7 @@ private: void Remove(uint8_t *aStart, uint8_t aLength); uint8_t mTlvs[kMaxSize]; ///< The Dataset buffer - uint32_t mUpdateTime; ///< Local time last updated + TimeMilli mUpdateTime; ///< Local time last updated uint16_t mLength; ///< The number of valid bytes in @var mTlvs Tlv::Type mType; ///< Active or Pending }; diff --git a/src/core/meshcop/dataset_local.cpp b/src/core/meshcop/dataset_local.cpp index be12220e8..a50a17e78 100644 --- a/src/core/meshcop/dataset_local.cpp +++ b/src/core/meshcop/dataset_local.cpp @@ -107,7 +107,7 @@ otError DatasetLocal::Read(Dataset &aDataset) const delayTimer = static_cast(aDataset.Get(Tlv::kDelayTimer)); VerifyOrExit(delayTimer); - elapsed = TimerMilli::Elapsed(mUpdateTime); + elapsed = TimerMilli::GetNow() - mUpdateTime; if (delayTimer->GetDelayTimer() > elapsed) { diff --git a/src/core/meshcop/dataset_local.hpp b/src/core/meshcop/dataset_local.hpp index 9e77c63ab..cdffe9703 100644 --- a/src/core/meshcop/dataset_local.hpp +++ b/src/core/meshcop/dataset_local.hpp @@ -121,7 +121,7 @@ public: * @returns The local time this dataset was last updated or restored. * */ - uint32_t GetUpdateTime(void) const { return mUpdateTime; } + TimeMilli GetUpdateTime(void) const { return mUpdateTime; } /** * This method stores the dataset into non-volatile memory. @@ -156,7 +156,7 @@ private: void SetTimestamp(const Dataset &aDataset); Timestamp mTimestamp; ///< Active or Pending Timestamp - uint32_t mUpdateTime; ///< Local time last updated + TimeMilli mUpdateTime; ///< Local time last updated Tlv::Type mType; ///< Active or Pending bool mTimestampPresent : 1; ///< Whether a timestamp is present bool mSaved : 1; ///< Whether a dataset is saved in non-volatile diff --git a/src/core/meshcop/dataset_manager.cpp b/src/core/meshcop/dataset_manager.cpp index 2fd4aa7e3..0ca3923f6 100644 --- a/src/core/meshcop/dataset_manager.cpp +++ b/src/core/meshcop/dataset_manager.cpp @@ -808,9 +808,9 @@ void PendingDataset::StartDelayTimer(void) uint32_t delay = delayTimer->GetDelayTimer(); // the Timer implementation does not support the full 32 bit range - if (delay > Timer::kMaxDt) + if (delay > Timer::kMaxDelay) { - delay = Timer::kMaxDt; + delay = Timer::kMaxDelay; } mDelayTimer.StartAt(dataset.GetUpdateTime(), delay); diff --git a/src/core/meshcop/dtls.cpp b/src/core/meshcop/dtls.cpp index 2364ae793..4afb7de58 100644 --- a/src/core/meshcop/dtls.cpp +++ b/src/core/meshcop/dtls.cpp @@ -668,7 +668,7 @@ int Dtls::HandleMbedtlsGetTimer(void) { rval = 2; } - else if (static_cast(mTimerIntermediate - TimerMilli::GetNow()) <= 0) + else if (mTimerIntermediate <= TimerMilli::GetNow()) { rval = 1; } diff --git a/src/core/meshcop/dtls.hpp b/src/core/meshcop/dtls.hpp index d4d72cadc..7100a8f29 100644 --- a/src/core/meshcop/dtls.hpp +++ b/src/core/meshcop/dtls.hpp @@ -471,8 +471,8 @@ private: TimerMilliContext mTimer; - uint32_t mTimerIntermediate; - bool mTimerSet : 1; + TimeMilli mTimerIntermediate; + bool mTimerSet : 1; bool mLayerTwoSecurity : 1; diff --git a/src/core/meshcop/joiner_router.cpp b/src/core/meshcop/joiner_router.cpp index 09e019f00..1539d959d 100644 --- a/src/core/meshcop/joiner_router.cpp +++ b/src/core/meshcop/joiner_router.cpp @@ -387,7 +387,7 @@ void JoinerRouter::SendDelayedJoinerEntrust(void) { DelayedJoinEntHeader delayedJoinEnt; Coap::Message * message = static_cast(mDelayedJoinEnts.GetHead()); - uint32_t now = TimerMilli::GetNow(); + TimeMilli now = TimerMilli::GetNow(); Ip6::MessageInfo messageInfo; VerifyOrExit(message != NULL); diff --git a/src/core/meshcop/joiner_router.hpp b/src/core/meshcop/joiner_router.hpp index 52aafeb48..c497694b2 100644 --- a/src/core/meshcop/joiner_router.hpp +++ b/src/core/meshcop/joiner_router.hpp @@ -135,7 +135,7 @@ public: * @param[in] aKek A pointer to the KEK. * */ - void Init(uint32_t aSendTime, Ip6::MessageInfo &aMessageInfo, const uint8_t *aKek) + void Init(TimeMilli aSendTime, Ip6::MessageInfo &aMessageInfo, const uint8_t *aKek) { mSendTime = aSendTime; mMessageInfo = aMessageInfo; @@ -185,7 +185,7 @@ public: * @returns A time when the message shall be sent. * */ - uint32_t GetSendTime(void) const { return mSendTime; } + TimeMilli GetSendTime(void) const { return mSendTime; } /** * This method returns a destination of the delayed message. @@ -211,7 +211,7 @@ public: * @retval TRUE If the message shall be sent before the given time. * @retval FALSE Otherwise. */ - bool IsEarlier(uint32_t aTime) const { return (static_cast(aTime - mSendTime) > 0); } + bool IsEarlier(TimeMilli aTime) const { return aTime > mSendTime; } /** * This method checks if the message shall be sent after the given time. @@ -221,11 +221,11 @@ public: * @retval TRUE If the message shall be sent after the given time. * @retval FALSE Otherwise. */ - bool IsLater(uint32_t aTime) const { return (static_cast(aTime - mSendTime) < 0); } + bool IsLater(TimeMilli aTime) const { return aTime < mSendTime; } private: Ip6::MessageInfo mMessageInfo; ///< Message info of the message to send. - uint32_t mSendTime; ///< Time when the message shall be sent. + TimeMilli mSendTime; ///< Time when the message shall be sent. uint8_t mKek[KeyManager::kMaxKeyLength]; ///< KEK used by MAC layer to encode this message. }; diff --git a/src/core/meshcop/leader.cpp b/src/core/meshcop/leader.cpp index 618707f56..9bfe81006 100644 --- a/src/core/meshcop/leader.cpp +++ b/src/core/meshcop/leader.cpp @@ -113,7 +113,7 @@ void Leader::HandlePetition(Coap::Message &aMessage, const Ip6::MessageInfo &aMe } state = StateTlv::kAccept; - mTimer.Start(TimerMilli::SecToMsec(kTimeoutLeaderPetition)); + mTimer.Start(Time::SecToMsec(kTimeoutLeaderPetition)); exit: SendPetitionResponse(aMessage, aMessageInfo, state); @@ -207,7 +207,7 @@ void Leader::HandleKeepAlive(Coap::Message &aMessage, const Ip6::MessageInfo &aM } responseState = StateTlv::kAccept; - mTimer.Start(TimerMilli::SecToMsec(kTimeoutLeaderPetition)); + mTimer.Start(Time::SecToMsec(kTimeoutLeaderPetition)); } SendKeepAliveResponse(aMessage, aMessageInfo, responseState); diff --git a/src/core/net/dhcp6_client.cpp b/src/core/net/dhcp6_client.cpp index a10e4c867..c4bf40885 100644 --- a/src/core/net/dhcp6_client.cpp +++ b/src/core/net/dhcp6_client.cpp @@ -204,7 +204,7 @@ bool Dhcp6Client::ProcessNextIdentityAssociation() mIdentityAssociationCurrent = &mIdentityAssociations[i]; - mTrickleTimer.Start(TimerMilli::SecToMsec(kTrickleTimerImin), TimerMilli::SecToMsec(kTrickleTimerImax), + mTrickleTimer.Start(Time::SecToMsec(kTrickleTimerImin), Time::SecToMsec(kTrickleTimerImax), TrickleTimer::kModeNormal); mTrickleTimer.IndicateInconsistent(); @@ -317,7 +317,7 @@ otError Dhcp6Client::AppendElapsedTime(Message &aMessage) ElapsedTime option; option.Init(); - option.SetElapsedTime(static_cast(TimerMilli::MsecToSec(TimerMilli::Elapsed(mStartTime)))); + option.SetElapsedTime(static_cast(Time::MsecToSec(TimerMilli::GetNow() - mStartTime))); return aMessage.Append(&option, sizeof(option)); } diff --git a/src/core/net/dhcp6_client.hpp b/src/core/net/dhcp6_client.hpp index 7c7dca71f..4b453e236 100644 --- a/src/core/net/dhcp6_client.hpp +++ b/src/core/net/dhcp6_client.hpp @@ -154,8 +154,8 @@ private: TrickleTimer mTrickleTimer; - uint8_t mTransactionId[kTransactionIdSize]; - uint32_t mStartTime; + uint8_t mTransactionId[kTransactionIdSize]; + TimeMilli mStartTime; IdentityAssociation mIdentityAssociations[OPENTHREAD_CONFIG_DHCP6_CLIENT_NUM_PREFIXES]; IdentityAssociation *mIdentityAssociationCurrent; diff --git a/src/core/net/dns_client.cpp b/src/core/net/dns_client.cpp index 7f91ac968..e55c075db 100644 --- a/src/core/net/dns_client.cpp +++ b/src/core/net/dns_client.cpp @@ -159,10 +159,10 @@ exit: Message *Client::CopyAndEnqueueMessage(const Message &aMessage, const QueryMetadata &aQueryMetadata) { - otError error = OT_ERROR_NONE; - uint32_t now = TimerMilli::GetNow(); - Message *messageCopy = NULL; - uint32_t nextTransmissionTime; + otError error = OT_ERROR_NONE; + TimeMilli now = TimerMilli::GetNow(); + Message * messageCopy = NULL; + TimeMilli nextTransmissionTime; // Create a message copy for further retransmissions. VerifyOrExit((messageCopy = aMessage.Clone()) != NULL, error = OT_ERROR_NO_BUFS); @@ -394,8 +394,8 @@ void Client::HandleRetransmissionTimer(Timer &aTimer) void Client::HandleRetransmissionTimer(void) { - uint32_t now = TimerMilli::GetNow(); - uint32_t nextDelta = TimerMilli::kForeverDt; + TimeMilli now = TimerMilli::GetNow(); + uint32_t nextDelta = TimeMilli::kMaxDuration; QueryMetadata queryMetadata; Message * message = mPendingQueries.GetHead(); Message * nextMessage = NULL; @@ -408,7 +408,7 @@ void Client::HandleRetransmissionTimer(void) if (queryMetadata.IsLater(now)) { - uint32_t diff = TimerMilli::Elapsed(now, queryMetadata.mTransmissionTime); + uint32_t diff = queryMetadata.mTransmissionTime - TimerMilli::GetNow(); // Calculate the next delay and choose the lowest. if (diff < nextDelta) @@ -425,12 +425,12 @@ void Client::HandleRetransmissionTimer(void) queryMetadata.mTransmissionTime = now + kResponseTimeout; queryMetadata.UpdateIn(*message); - diff = TimerMilli::Elapsed(now, queryMetadata.mTransmissionTime); + diff = kResponseTimeout; // Check if retransmission time is lower than current lowest. if (diff < nextDelta) { - nextDelta = queryMetadata.mTransmissionTime - now; + nextDelta = kResponseTimeout; } // Retransmit @@ -449,7 +449,7 @@ void Client::HandleRetransmissionTimer(void) message = nextMessage; } - if (nextDelta != TimerMilli::kForeverDt) + if (nextDelta != TimeMilli::kMaxDuration) { mRetransmissionTimer.Start(nextDelta); } diff --git a/src/core/net/dns_client.hpp b/src/core/net/dns_client.hpp index 90bf75fa6..4c46cbb47 100644 --- a/src/core/net/dns_client.hpp +++ b/src/core/net/dns_client.hpp @@ -122,7 +122,7 @@ public: * @retval TRUE If the message shall be sent before the given time. * @retval FALSE Otherwise. */ - bool IsEarlier(uint32_t aTime) const { return (static_cast(aTime - mTransmissionTime) > 0); } + bool IsEarlier(TimeMilli aTime) const { return aTime > mTransmissionTime; } /** * This method checks if the message shall be sent after the given time. @@ -132,13 +132,13 @@ public: * @retval TRUE If the message shall be sent after the given time. * @retval FALSE Otherwise. */ - bool IsLater(uint32_t aTime) const { return (static_cast(aTime - mTransmissionTime) < 0); } + bool IsLater(TimeMilli aTime) const { return aTime < mTransmissionTime; } private: const char * mHostname; ///< A hostname to be find. otDnsResponseHandler mResponseHandler; ///< A function pointer that is called on response reception. void * mResponseContext; ///< A pointer to arbitrary context information. - uint32_t mTransmissionTime; ///< Time when the timer should shoot for this message. + TimeMilli mTransmissionTime; ///< Time when the timer should shoot for this message. Ip6::Address mSourceAddress; ///< IPv6 address of the message source. Ip6::Address mDestinationAddress; ///< IPv6 address of the message destination. uint16_t mDestinationPort; ///< UDP port of the message destination. diff --git a/src/core/net/ip6_mpl.cpp b/src/core/net/ip6_mpl.cpp index c04e1f581..c1875e5e7 100644 --- a/src/core/net/ip6_mpl.cpp +++ b/src/core/net/ip6_mpl.cpp @@ -43,13 +43,13 @@ namespace ot { namespace Ip6 { -void MplBufferedMessageMetadata::GenerateNextTransmissionTime(uint32_t aCurrentTime, uint8_t aInterval) +void MplBufferedMessageMetadata::GenerateNextTransmissionTime(TimeMilli aCurrentTime, uint8_t aInterval) { // Emulate Trickle timer behavior and set up the next retransmission within [0,I) range. - uint8_t t = aInterval == 0 ? aInterval : Random::NonCrypto::GetUint8InRange(0, aInterval); + uint8_t t = (aInterval == 0) ? aInterval : Random::NonCrypto::GetUint8InRange(0, aInterval); // Set transmission time at the beginning of the next interval. - SetTransmissionTime(aCurrentTime + GetIntervalOffset() + t); + SetTransmissionTime(aCurrentTime + static_cast(GetIntervalOffset() + t)); SetIntervalOffset(aInterval - t); } @@ -235,11 +235,11 @@ exit: void Mpl::AddBufferedMessage(Message &aMessage, uint16_t aSeedId, uint8_t aSequence, bool aIsOutbound) { - uint32_t now = TimerMilli::GetNow(); + TimeMilli now = TimerMilli::GetNow(); otError error = OT_ERROR_NONE; Message * messageCopy = NULL; MplBufferedMessageMetadata messageMetadata; - uint32_t nextTransmissionTime; + TimeMilli nextTransmissionTime; uint8_t hopLimit = 0; #if OPENTHREAD_CONFIG_MPL_DYNAMIC_INTERVAL_ENABLE @@ -333,8 +333,8 @@ void Mpl::HandleRetransmissionTimer(Timer &aTimer) void Mpl::HandleRetransmissionTimer(void) { - uint32_t now = TimerMilli::GetNow(); - uint32_t nextDelta = TimerMilli::kForeverDt; + TimeMilli now = TimerMilli::GetNow(); + uint32_t nextDelta = TimeMilli::kMaxDuration; MplBufferedMessageMetadata messageMetadata; Message *message = mBufferedMessageSet.GetHead(); @@ -347,7 +347,7 @@ void Mpl::HandleRetransmissionTimer(void) if (messageMetadata.IsLater(now)) { - uint32_t diff = TimerMilli::Elapsed(now, messageMetadata.GetTransmissionTime()); + uint32_t diff = messageMetadata.GetTransmissionTime() - now; // Calculate the next retransmission time and choose the lowest. if (diff < nextDelta) @@ -379,7 +379,7 @@ void Mpl::HandleRetransmissionTimer(void) messageMetadata.GenerateNextTransmissionTime(now, kDataMessageInterval); messageMetadata.UpdateIn(*message); - diff = TimerMilli::Elapsed(now, messageMetadata.GetTransmissionTime()); + diff = messageMetadata.GetTransmissionTime() - now; // Check if retransmission time is lower than the current lowest one. if (diff < nextDelta) @@ -413,7 +413,7 @@ void Mpl::HandleRetransmissionTimer(void) message = nextMessage; } - if (nextDelta != TimerMilli::kForeverDt) + if (nextDelta != TimeMilli::kMaxDuration) { mRetransmissionTimer.Start(nextDelta); } diff --git a/src/core/net/ip6_mpl.hpp b/src/core/net/ip6_mpl.hpp index 2764df8e1..79e564c1e 100644 --- a/src/core/net/ip6_mpl.hpp +++ b/src/core/net/ip6_mpl.hpp @@ -320,7 +320,7 @@ public: * @retval TRUE If the message shall be sent before the given time. * @retval FALSE Otherwise. */ - bool IsEarlier(uint32_t aTime) const { return (static_cast(aTime - mTransmissionTime) > 0); } + bool IsEarlier(TimeMilli aTime) const { return aTime > mTransmissionTime; } /** * This method checks if the message shall be sent after the given time. @@ -330,7 +330,7 @@ public: * @retval TRUE If the message shall be sent after the given time. * @retval FALSE Otherwise. */ - bool IsLater(uint32_t aTime) const { return (static_cast(aTime - mTransmissionTime) < 0); } + bool IsLater(TimeMilli aTime) const { return aTime < mTransmissionTime; } /** * This method returns the MPL Seed Id value. @@ -386,7 +386,7 @@ public: * @returns The transmission timestamp of the message. * */ - uint32_t GetTransmissionTime(void) const { return mTransmissionTime; } + TimeMilli GetTransmissionTime(void) const { return mTransmissionTime; } /** * This method sets the transmission timestamp of the message. @@ -394,7 +394,7 @@ public: * @param[in] aTransmissionTime The transmission timestamp of the message. * */ - void SetTransmissionTime(uint32_t aTransmissionTime) { mTransmissionTime = aTransmissionTime; } + void SetTransmissionTime(TimeMilli aTransmissionTime) { mTransmissionTime = aTransmissionTime; } /** * This method returns the offset from the transmission time to the end of trickle interval. @@ -418,14 +418,14 @@ public: * @param[in] aCurrentTime Current time (in milliseconds). * @param[in] aInterval The current interval size (in milliseconds). */ - void GenerateNextTransmissionTime(uint32_t aCurrentTime, uint8_t aInterval); + void GenerateNextTransmissionTime(TimeMilli aCurrentTime, uint8_t aInterval); private: - uint16_t mSeedId; - uint8_t mSequence; - uint8_t mTransmissionCount; - uint32_t mTransmissionTime; - uint8_t mIntervalOffset; + uint16_t mSeedId; + uint8_t mSequence; + uint8_t mTransmissionCount; + TimeMilli mTransmissionTime; + uint8_t mIntervalOffset; } OT_TOOL_PACKED_END; /** diff --git a/src/core/net/sntp_client.cpp b/src/core/net/sntp_client.cpp index 4c9a9ba19..4e397f3e4 100644 --- a/src/core/net/sntp_client.cpp +++ b/src/core/net/sntp_client.cpp @@ -98,14 +98,14 @@ otError Client::Query(const otSntpQuery *aQuery, otSntpResponseHandler aHandler, VerifyOrExit(aQuery->mMessageInfo != NULL, error = OT_ERROR_INVALID_ARGS); // Originate timestamp is used only as a unique token. - header.SetTransmitTimestampSeconds(TimerMilli::GetNow() / 1000 + kTimeAt1970); + header.SetTransmitTimestampSeconds(TimerMilli::GetNow().GetValue() / 1000 + kTimeAt1970); VerifyOrExit((message = NewMessage(header)) != NULL, error = OT_ERROR_NO_BUFS); messageInfo = static_cast(aQuery->mMessageInfo); queryMetadata.mTransmitTimestamp = header.GetTransmitTimestampSeconds(); - queryMetadata.mTransmissionTime = TimerMilli::GetNow() + kResponseTimeout; + queryMetadata.mTransmissionTime = TimerMilli::GetNow() + static_cast(kResponseTimeout); queryMetadata.mSourceAddress = messageInfo->GetSockAddr(); queryMetadata.mDestinationPort = messageInfo->GetPeerPort(); queryMetadata.mDestinationAddress = messageInfo->GetPeerAddr(); @@ -146,10 +146,10 @@ exit: Message *Client::CopyAndEnqueueMessage(const Message &aMessage, const QueryMetadata &aQueryMetadata) { - otError error = OT_ERROR_NONE; - uint32_t now = TimerMilli::GetNow(); - Message *messageCopy = NULL; - uint32_t nextTransmissionTime; + otError error = OT_ERROR_NONE; + TimeMilli now = TimerMilli::GetNow(); + Message * messageCopy = NULL; + TimeMilli nextTransmissionTime; // Create a message copy for further retransmissions. VerifyOrExit((messageCopy = aMessage.Clone()) != NULL, error = OT_ERROR_NO_BUFS); @@ -268,8 +268,8 @@ void Client::HandleRetransmissionTimer(Timer &aTimer) void Client::HandleRetransmissionTimer(void) { - uint32_t now = TimerMilli::GetNow(); - uint32_t nextDelta = TimerMilli::kForeverDt; + TimeMilli now = TimerMilli::GetNow(); + uint32_t nextDelta = TimeMilli::kMaxDuration; QueryMetadata queryMetadata; Message * message = mPendingQueries.GetHead(); Message * nextMessage = NULL; @@ -282,7 +282,7 @@ void Client::HandleRetransmissionTimer(void) if (queryMetadata.IsLater(now)) { - uint32_t diff = TimerMilli::Elapsed(now, queryMetadata.mTransmissionTime); + uint32_t diff = queryMetadata.mTransmissionTime - now; // Calculate the next delay and choose the lowest. if (diff < nextDelta) @@ -299,7 +299,7 @@ void Client::HandleRetransmissionTimer(void) queryMetadata.mTransmissionTime = now + kResponseTimeout; queryMetadata.UpdateIn(*message); - diff = TimerMilli::Elapsed(now, queryMetadata.mTransmissionTime); + diff = kResponseTimeout; // Check if retransmission time is lower than current lowest. if (diff < nextDelta) @@ -323,7 +323,7 @@ void Client::HandleRetransmissionTimer(void) message = nextMessage; } - if (nextDelta != TimerMilli::kForeverDt) + if (nextDelta != TimeMilli::kMaxDuration) { mRetransmissionTimer.Start(nextDelta); } diff --git a/src/core/net/sntp_client.hpp b/src/core/net/sntp_client.hpp index 7f05ac8d1..d6feaa005 100644 --- a/src/core/net/sntp_client.hpp +++ b/src/core/net/sntp_client.hpp @@ -492,7 +492,7 @@ public: * @retval TRUE If the message shall be sent before the given time. * @retval FALSE Otherwise. */ - bool IsEarlier(uint32_t aTime) const { return (static_cast(aTime - mTransmissionTime) > 0); } + bool IsEarlier(TimeMilli aTime) const { return aTime > mTransmissionTime; } /** * This method checks if the message shall be sent after the given time. @@ -502,13 +502,13 @@ public: * @retval TRUE If the message shall be sent after the given time. * @retval FALSE Otherwise. */ - bool IsLater(uint32_t aTime) const { return (static_cast(aTime - mTransmissionTime) < 0); } + bool IsLater(TimeMilli aTime) const { return aTime < mTransmissionTime; } private: uint32_t mTransmitTimestamp; ///< Time at the client when the request departed for the server. otSntpResponseHandler mResponseHandler; ///< A function pointer that is called on response reception. void * mResponseContext; ///< A pointer to arbitrary context information. - uint32_t mTransmissionTime; ///< Time when the timer should shoot for this message. + TimeMilli mTransmissionTime; ///< Time when the timer should shoot for this message. Ip6::Address mSourceAddress; ///< IPv6 address of the message source. Ip6::Address mDestinationAddress; ///< IPv6 address of the message destination. uint16_t mDestinationPort; ///< UDP port of the message destination. diff --git a/src/core/thread/address_resolver.cpp b/src/core/thread/address_resolver.cpp index 349845bcd..d76894361 100644 --- a/src/core/thread/address_resolver.cpp +++ b/src/core/thread/address_resolver.cpp @@ -660,7 +660,7 @@ void AddressResolver::HandleAddressQuery(Coap::Message &aMessage, const Ip6::Mes if (child.HasIp6Address(GetInstance(), targetTlv.GetTarget())) { mlIidTlv.SetIid(child.GetExtAddress()); - lastTransactionTimeTlv.SetTime(TimerMilli::Elapsed(child.GetLastHeard())); + lastTransactionTimeTlv.SetTime(TimerMilli::GetNow() - child.GetLastHeard()); SendAddressQueryResponse(targetTlv, mlIidTlv, &lastTransactionTimeTlv, aMessageInfo.GetPeerAddr()); ExitNow(); } diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 4ba915a4e..d037e8f7f 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1886,8 +1886,8 @@ void Mle::HandleDelayedResponseTimer(Timer &aTimer) void Mle::HandleDelayedResponseTimer(void) { DelayedResponseHeader delayedResponse; - uint32_t now = TimerMilli::GetNow(); - uint32_t nextDelay = TimerMilli::kForeverDt; + TimeMilli now = TimerMilli::GetNow(); + uint32_t nextDelay = TimeMilli::kMaxDuration; Message * message = mDelayedResponses.GetHead(); Message * nextMessage = NULL; @@ -1898,10 +1898,12 @@ void Mle::HandleDelayedResponseTimer(void) if (delayedResponse.IsLater(now)) { + uint32_t diff = delayedResponse.GetSendTime() - now; + // Calculate the next delay and choose the lowest. - if (delayedResponse.GetSendTime() - now < nextDelay) + if (diff < nextDelay) { - nextDelay = delayedResponse.GetSendTime() - now; + nextDelay = diff; } } else @@ -1935,7 +1937,7 @@ void Mle::HandleDelayedResponseTimer(void) message = nextMessage; } - if (nextDelay != TimerMilli::kForeverDt) + if (nextDelay != TimeMilli::kMaxDuration) { mDelayedResponseTimer.Start(nextDelay); } @@ -2186,8 +2188,8 @@ void Mle::ScheduleMessageTransmissionTimer(void) if ((mRole == OT_DEVICE_ROLE_CHILD) && IsRxOnWhenIdle()) { - interval = TimerMilli::SecToMsec(mTimeout) - - static_cast(kUnicastRetransmissionDelay) * kMaxChildKeepAliveAttempts; + interval = + Time::SecToMsec(mTimeout) - static_cast(kUnicastRetransmissionDelay) * kMaxChildKeepAliveAttempts; } exit: @@ -2557,9 +2559,9 @@ exit: otError Mle::AddDelayedResponse(Message &aMessage, const Ip6::Address &aDestination, uint16_t aDelay) { - otError error = OT_ERROR_NONE; - uint32_t alarmFireTime; - uint32_t sendTime = TimerMilli::GetNow() + aDelay; + otError error = OT_ERROR_NONE; + TimeMilli alarmFireTime; + TimeMilli sendTime = TimerMilli::GetNow() + aDelay; // Append the message with DelayedRespnoseHeader and add to the list. DelayedResponseHeader delayedResponse(sendTime, aDestination); @@ -4051,7 +4053,7 @@ void Mle::HandleParentSearchTimer(void) // from `UpdateParentSearchState()`. We want to limit this to happen // only once within a backoff interval. - if (TimerMilli::Elapsed(mParentSearchBackoffCancelTime) >= kParentSearchBackoffInterval) + if (TimerMilli::GetNow() - mParentSearchBackoffCancelTime >= kParentSearchBackoffInterval) { mParentSearchBackoffWasCanceled = false; otLogInfoMle("PeriodicParentSearch: Backoff cancellation is allowed on parent switch"); diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 1376b0f31..2b7881515 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -377,7 +377,7 @@ public: * @param[in] aDestination IPv6 address of the message destination. * */ - DelayedResponseHeader(uint32_t aSendTime, const Ip6::Address &aDestination) + DelayedResponseHeader(TimeMilli aSendTime, const Ip6::Address &aDestination) { mSendTime = aSendTime; mDestination = aDestination; @@ -426,7 +426,7 @@ public: * @returns A time when the message shall be sent. * */ - uint32_t GetSendTime(void) const { return mSendTime; } + TimeMilli GetSendTime(void) const { return mSendTime; } /** * This method returns a destination of the delayed message. @@ -443,8 +443,9 @@ public: * * @retval TRUE If the message shall be sent before the given time. * @retval FALSE Otherwise. + * */ - bool IsEarlier(uint32_t aTime) { return (static_cast(aTime - mSendTime) > 0); } + bool IsEarlier(TimeMilli aTime) { return aTime > mSendTime; } /** * This method checks if the message shall be sent after the given time. @@ -453,12 +454,13 @@ public: * * @retval TRUE If the message shall be sent after the given time. * @retval FALSE Otherwise. + * */ - bool IsLater(uint32_t aTime) { return (static_cast(aTime - mSendTime) < 0); } + bool IsLater(TimeMilli aTime) { return aTime < mSendTime; } private: Ip6::Address mDestination; ///< IPv6 address of the message destination. - uint32_t mSendTime; ///< Time when the message shall be sent. + TimeMilli mSendTime; ///< Time when the message shall be sent. } OT_TOOL_PACKED_END; /** @@ -1794,7 +1796,7 @@ private: bool mParentSearchIsInBackoff : 1; bool mParentSearchBackoffWasCanceled : 1; bool mParentSearchRecentlyDetached : 1; - uint32_t mParentSearchBackoffCancelTime; + TimeMilli mParentSearchBackoffCancelTime; TimerMilli mParentSearchTimer; #endif diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index dafe03192..28420e7c9 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -396,8 +396,8 @@ void MleRouter::ResetAdvertiseInterval(void) if (!mAdvertiseTimer.IsRunning()) { - mAdvertiseTimer.Start(TimerMilli::SecToMsec(kAdvertiseIntervalMin), - TimerMilli::SecToMsec(kAdvertiseIntervalMax), TrickleTimer::kModeNormal); + mAdvertiseTimer.Start(Time::SecToMsec(kAdvertiseIntervalMin), Time::SecToMsec(kAdvertiseIntervalMax), + TrickleTimer::kModeNormal); } mAdvertiseTimer.IndicateInconsistent(); @@ -1669,7 +1669,7 @@ otError MleRouter::HandleParentRequest(const Message &aMessage, const Ip6::Messa } #endif } - else if (TimerMilli::Elapsed(child->GetLastHeard()) < kParentRequestRouterTimeout - kParentRequestDuplicateMargin) + else if (TimerMilli::GetNow() - child->GetLastHeard() < kParentRequestRouterTimeout - kParentRequestDuplicateMargin) { ExitNow(error = OT_ERROR_DUPLICATED); } @@ -1677,7 +1677,7 @@ otError MleRouter::HandleParentRequest(const Message &aMessage, const Ip6::Messa if (!child->IsStateValidOrRestoring()) { child->SetLastHeard(TimerMilli::GetNow()); - child->SetTimeout(TimerMilli::MsecToSec(kMaxChildIdRequestTimeout)); + child->SetTimeout(Time::MsecToSec(kMaxChildIdRequestTimeout)); } SendParentResponse(child, challenge, !scanMask.IsEndDeviceFlagSet()); @@ -1752,8 +1752,8 @@ void MleRouter::HandleStateUpdateTimer(void) { SendAdvertisement(); - mAdvertiseTimer.Start(TimerMilli::SecToMsec(kReedAdvertiseInterval), - TimerMilli::SecToMsec(kReedAdvertiseInterval + kReedAdvertiseJitter), + mAdvertiseTimer.Start(Time::SecToMsec(kReedAdvertiseInterval), + Time::SecToMsec(kReedAdvertiseInterval + kReedAdvertiseJitter), TrickleTimer::kModePlainTimer); } @@ -1801,7 +1801,7 @@ void MleRouter::HandleStateUpdateTimer(void) case Neighbor::kStateValid: case Neighbor::kStateRestored: case Neighbor::kStateChildUpdateRequest: - timeout = TimerMilli::SecToMsec(child.GetTimeout()); + timeout = Time::SecToMsec(child.GetTimeout()); break; case Neighbor::kStateParentResponse: @@ -1810,7 +1810,7 @@ void MleRouter::HandleStateUpdateTimer(void) break; } - if (TimerMilli::Elapsed(child.GetLastHeard()) >= timeout) + if (TimerMilli::GetNow() - child.GetLastHeard() >= timeout) { otLogInfoMle("Child timeout expired"); RemoveNeighbor(child); @@ -1834,13 +1834,13 @@ void MleRouter::HandleStateUpdateTimer(void) continue; } - age = TimerMilli::Elapsed(router.GetLastHeard()); + age = TimerMilli::GetNow() - router.GetLastHeard(); if (router.GetState() == Neighbor::kStateValid) { #if OPENTHREAD_CONFIG_MLE_SEND_LINK_REQUEST_ON_ADV_TIMEOUT == 0 - if (age >= TimerMilli::SecToMsec(kMaxNeighborAge)) + if (age >= Time::SecToMsec(kMaxNeighborAge)) { otLogInfoMle("Router timeout expired"); RemoveNeighbor(router); @@ -1849,9 +1849,9 @@ void MleRouter::HandleStateUpdateTimer(void) #else - if (age >= TimerMilli::SecToMsec(kMaxNeighborAge)) + if (age >= Time::SecToMsec(kMaxNeighborAge)) { - if (age < TimerMilli::SecToMsec(kMaxNeighborAge) + kMaxTransmissionCount * kUnicastRetransmissionDelay) + if (age < Time::SecToMsec(kMaxNeighborAge) + kMaxTransmissionCount * kUnicastRetransmissionDelay) { otLogInfoMle("Router timeout expired"); SendLinkRequest(&router); @@ -1878,8 +1878,7 @@ void MleRouter::HandleStateUpdateTimer(void) if (GetRole() == OT_DEVICE_ROLE_LEADER) { if (mRouterTable.GetRouter(router.GetNextHop()) == NULL && - mRouterTable.GetLinkCost(router) >= kMaxRouteCost && - age >= TimerMilli::SecToMsec(kMaxLeaderToRouterTimeout)) + mRouterTable.GetLinkCost(router) >= kMaxRouteCost && age >= Time::SecToMsec(kMaxLeaderToRouterTimeout)) { otLogInfoMle("Router ID timeout expired (no route)"); mRouterTable.Release(router.GetRouterId()); @@ -3618,7 +3617,7 @@ otError MleRouter::GetChildInfo(Child &aChild, otChildInfo &aChildInfo) aChildInfo.mRloc16 = aChild.GetRloc16(); aChildInfo.mChildId = GetChildId(aChild.GetRloc16()); aChildInfo.mNetworkDataVersion = aChild.GetNetworkDataVersion(); - aChildInfo.mAge = TimerMilli::MsecToSec(TimerMilli::Elapsed(aChild.GetLastHeard())); + aChildInfo.mAge = Time::MsecToSec(TimerMilli::GetNow() - aChild.GetLastHeard()); aChildInfo.mLinkQualityIn = aChild.GetLinkInfo().GetLinkQuality(); aChildInfo.mAverageRssi = aChild.GetLinkInfo().GetAverageRss(); aChildInfo.mLastRssi = aChild.GetLinkInfo().GetLastRss(); @@ -3641,7 +3640,7 @@ exit: void MleRouter::GetNeighborInfo(Neighbor &aNeighbor, otNeighborInfo &aNeighInfo) { aNeighInfo.mExtAddress = aNeighbor.GetExtAddress(); - aNeighInfo.mAge = TimerMilli::MsecToSec(TimerMilli::Elapsed(aNeighbor.GetLastHeard())); + aNeighInfo.mAge = Time::MsecToSec(TimerMilli::GetNow() - aNeighbor.GetLastHeard()); aNeighInfo.mRloc16 = aNeighbor.GetRloc16(); aNeighInfo.mLinkFrameCounter = aNeighbor.GetLinkFrameCounter(); aNeighInfo.mMleFrameCounter = aNeighbor.GetMleFrameCounter(); diff --git a/src/core/thread/network_data.cpp b/src/core/thread/network_data.cpp index 6273ca2e1..2c24877f7 100644 --- a/src/core/thread/network_data.cpp +++ b/src/core/thread/network_data.cpp @@ -996,7 +996,8 @@ otError NetworkData::SendServerDataNotification(uint16_t aRloc16) Coap::Message * message = NULL; Ip6::MessageInfo messageInfo; - VerifyOrExit(!mLastAttemptWait || TimerMilli::Elapsed(mLastAttempt) < kDataResubmitDelay, error = OT_ERROR_ALREADY); + VerifyOrExit(!mLastAttemptWait || (TimerMilli::GetNow() - mLastAttempt < kDataResubmitDelay), + error = OT_ERROR_ALREADY); VerifyOrExit((message = Get().NewMessage()) != NULL, error = OT_ERROR_NO_BUFS); diff --git a/src/core/thread/network_data.hpp b/src/core/thread/network_data.hpp index 37ae414e1..5298365c3 100644 --- a/src/core/thread/network_data.hpp +++ b/src/core/thread/network_data.hpp @@ -41,6 +41,7 @@ #include "coap/coap.hpp" #include "common/locator.hpp" +#include "common/timer.hpp" #include "net/udp6.hpp" #include "thread/lowpan.hpp" #include "thread/mle_router.hpp" @@ -517,7 +518,7 @@ private: const Type mType; bool mLastAttemptWait; - uint32_t mLastAttempt; + TimeMilli mLastAttempt; }; } // namespace NetworkData diff --git a/src/core/thread/network_data_leader_ftd.cpp b/src/core/thread/network_data_leader_ftd.cpp index 7f4038274..1f64dbeb8 100644 --- a/src/core/thread/network_data_leader_ftd.cpp +++ b/src/core/thread/network_data_leader_ftd.cpp @@ -1193,9 +1193,9 @@ void Leader::StartContextReuseTimer(uint8_t aContextId) { mContextLastUsed[aContextId - kMinContextId] = TimerMilli::GetNow(); - if (mContextLastUsed[aContextId - kMinContextId] == 0) + if (mContextLastUsed[aContextId - kMinContextId].GetValue() == 0) { - mContextLastUsed[aContextId - kMinContextId] = 1; + mContextLastUsed[aContextId - kMinContextId].SetValue(1); } mTimer.Start(kStateUpdatePeriod); @@ -1203,7 +1203,7 @@ void Leader::StartContextReuseTimer(uint8_t aContextId) void Leader::StopContextReuseTimer(uint8_t aContextId) { - mContextLastUsed[aContextId - kMinContextId] = 0; + mContextLastUsed[aContextId - kMinContextId].SetValue(0); } otError Leader::SendServerDataNotification(uint16_t aRloc16) @@ -1559,12 +1559,12 @@ void Leader::HandleTimer(void) for (uint8_t i = 0; i < kNumContextIds; i++) { - if (mContextLastUsed[i] == 0) + if (mContextLastUsed[i].GetValue() == 0) { continue; } - if (TimerMilli::Elapsed(mContextLastUsed[i]) >= TimerMilli::SecToMsec(mContextIdReuseDelay)) + if (TimerMilli::GetNow() - mContextLastUsed[i] >= Time::SecToMsec(mContextIdReuseDelay)) { FreeContext(kMinContextId + i); } diff --git a/src/core/thread/network_data_leader_ftd.hpp b/src/core/thread/network_data_leader_ftd.hpp index dab990aa5..edf54e997 100644 --- a/src/core/thread/network_data_leader_ftd.hpp +++ b/src/core/thread/network_data_leader_ftd.hpp @@ -244,7 +244,7 @@ private: }; uint16_t mContextUsed; - uint32_t mContextLastUsed[kNumContextIds]; + TimeMilli mContextLastUsed[kNumContextIds]; uint32_t mContextIdReuseDelay; TimerMilli mTimer; diff --git a/src/core/thread/router_table.cpp b/src/core/thread/router_table.cpp index 084cd3e42..b98bcae3c 100644 --- a/src/core/thread/router_table.cpp +++ b/src/core/thread/router_table.cpp @@ -441,7 +441,7 @@ otError RouterTable::GetRouterInfo(uint16_t aRouterId, otRouterInfo &aRouterInfo aRouterInfo.mPathCost = router->GetCost(); aRouterInfo.mLinkQualityIn = router->GetLinkInfo().GetLinkQuality(); aRouterInfo.mLinkQualityOut = router->GetLinkQualityOut(); - aRouterInfo.mAge = static_cast(TimerMilli::MsecToSec(TimerMilli::Elapsed(router->GetLastHeard()))); + aRouterInfo.mAge = static_cast(Time::MsecToSec(TimerMilli::GetNow() - router->GetLastHeard())); exit: return error; @@ -454,8 +454,7 @@ Router *RouterTable::GetLeader(void) uint32_t RouterTable::GetLeaderAge(void) const { - return (mActiveRouterCount > 0) ? TimerMilli::MsecToSec(TimerMilli::Elapsed(mRouterIdSequenceLastUpdated)) - : 0xffffffff; + return (mActiveRouterCount > 0) ? Time::MsecToSec(TimerMilli::GetNow() - mRouterIdSequenceLastUpdated) : 0xffffffff; } uint8_t RouterTable::GetNeighborCount(void) const diff --git a/src/core/thread/router_table.hpp b/src/core/thread/router_table.hpp index bd1fde0ec..c66b8e935 100644 --- a/src/core/thread/router_table.hpp +++ b/src/core/thread/router_table.hpp @@ -290,7 +290,7 @@ public: * @returns The local time when the Router ID Sequence was last updated. * */ - uint32_t GetRouterIdSequenceLastUpdated(void) const { return mRouterIdSequenceLastUpdated; } + TimeMilli GetRouterIdSequenceLastUpdated(void) const { return mRouterIdSequenceLastUpdated; } /** * This method returns the number of neighbor links. @@ -356,7 +356,7 @@ private: Router mRouters[Mle::kMaxRouters]; RouterIdSet mAllocatedRouterIds; uint8_t mRouterIdReuseDelay[Mle::kMaxRouterId + 1]; - uint32_t mRouterIdSequenceLastUpdated; + TimeMilli mRouterIdSequenceLastUpdated; uint8_t mRouterIdSequence; uint8_t mActiveRouterCount; }; diff --git a/src/core/thread/time_sync_service.cpp b/src/core/thread/time_sync_service.cpp index db83e27aa..18b88b684 100644 --- a/src/core/thread/time_sync_service.cpp +++ b/src/core/thread/time_sync_service.cpp @@ -153,7 +153,7 @@ void TimeSync::NotifyTimeSyncCallback(void) void TimeSync::ProcessTimeSync(void) { if (Get().GetRole() == OT_DEVICE_ROLE_LEADER && - TimerMilli::Elapsed(mLastTimeSyncSent) > TimerMilli::SecToMsec(mTimeSyncPeriod)) + (TimerMilli::GetNow() - mLastTimeSyncSent > Time::SecToMsec(mTimeSyncPeriod))) { IncrementTimeSyncSeq(); mTimeSyncRequired = true; @@ -192,7 +192,7 @@ void TimeSync::HandleStateChanged(otChangedFlags aFlags) // Network time status will become OT_NETWORK_TIME_UNSYNCHRONIZED because no network time has yet been received // on the new partition. - mLastTimeSyncReceived = 0; + mLastTimeSyncReceived.SetValue(0); stateChanged = true; @@ -223,8 +223,8 @@ void TimeSync::HandleTimeout(Timer &aTimer) void TimeSync::CheckAndHandleChanges(bool aTimeUpdated) { otNetworkTimeStatus networkTimeStatus = OT_NETWORK_TIME_SYNCHRONIZED; - const uint32_t resyncNeededThresholdMs = 2 * TimerMilli::SecToMsec(mTimeSyncPeriod); - const uint32_t timeSyncLastSyncMs = TimerMilli::Elapsed(mLastTimeSyncReceived); + const uint32_t resyncNeededThresholdMs = 2 * Time::SecToMsec(mTimeSyncPeriod); + const uint32_t timeSyncLastSyncMs = TimerMilli::GetNow() - mLastTimeSyncReceived; mTimer.Stop(); @@ -238,7 +238,7 @@ void TimeSync::CheckAndHandleChanges(bool aTimeUpdated) case OT_DEVICE_ROLE_CHILD: case OT_DEVICE_ROLE_ROUTER: - if (mLastTimeSyncReceived == 0) + if (mLastTimeSyncReceived.GetValue() == 0) { // Haven't yet received any time sync networkTimeStatus = OT_NETWORK_TIME_UNSYNCHRONIZED; diff --git a/src/core/thread/time_sync_service.hpp b/src/core/thread/time_sync_service.hpp index b382b39df..8563b340f 100644 --- a/src/core/thread/time_sync_service.hpp +++ b/src/core/thread/time_sync_service.hpp @@ -209,10 +209,10 @@ private: uint16_t mTimeSyncPeriod; ///< The time synchronization period. uint16_t mXtalThreshold; ///< The XTAL accuracy threshold for a device to become a Router, in PPM. #if OPENTHREAD_FTD - uint32_t mLastTimeSyncSent; ///< The time when the last time synchronization message was sent. + TimeMilli mLastTimeSyncSent; ///< The time when the last time synchronization message was sent. #endif - uint32_t mLastTimeSyncReceived; ///< The time when the last time synchronization message was received. - int64_t mNetworkTimeOffset; ///< The time offset to the Thread Network time + TimeMilli mLastTimeSyncReceived; ///< The time when the last time synchronization message was received. + int64_t mNetworkTimeOffset; ///< The time offset to the Thread Network time otNetworkTimeSyncCallbackFn mTimeSyncCallback; ///< The callback to be called when time sync is handled or status updated. void * mTimeSyncCallbackContext; ///< The context to be passed to callback. diff --git a/src/core/thread/topology.hpp b/src/core/thread/topology.hpp index 984e69545..ba2a0c3cb 100644 --- a/src/core/thread/topology.hpp +++ b/src/core/thread/topology.hpp @@ -40,6 +40,7 @@ #include "common/message.hpp" #include "common/random.hpp" +#include "common/timer.hpp" #include "mac/mac_frame.hpp" #include "net/ip6.hpp" #include "thread/device_mode.hpp" @@ -208,7 +209,7 @@ public: * @returns The last heard time. * */ - uint32_t GetLastHeard(void) const { return mLastHeard; } + TimeMilli GetLastHeard(void) const { return mLastHeard; } /** * This method sets the last heard time. @@ -216,7 +217,7 @@ public: * @param[in] aLastHeard The last heard time. * */ - void SetLastHeard(uint32_t aLastHeard) { mLastHeard = aLastHeard; } + void SetLastHeard(TimeMilli aLastHeard) { mLastHeard = aLastHeard; } /** * This method gets the link frame counter value. @@ -344,7 +345,7 @@ public: private: Mac::ExtAddress mMacAddr; ///< The IEEE 802.15.4 Extended Address - uint32_t mLastHeard; ///< Time when last heard. + TimeMilli mLastHeard; ///< Time when last heard. union { struct diff --git a/src/core/utils/channel_manager.cpp b/src/core/utils/channel_manager.cpp index 392d03a24..e5432210c 100644 --- a/src/core/utils/channel_manager.cpp +++ b/src/core/utils/channel_manager.cpp @@ -98,7 +98,7 @@ void ChannelManager::PreparePendingDataset(void) { uint64_t pendingTimestamp = 0; uint64_t pendingActiveTimestamp = 0; - uint32_t delayInMs = TimerMilli::SecToMsec(static_cast(mDelay)); + uint32_t delayInMs = Time::SecToMsec(static_cast(mDelay)); otOperationalDataset dataset; otError error; @@ -216,7 +216,7 @@ void ChannelManager::PreparePendingDataset(void) else { otLogInfoUtil("ChannelManager: %s error in dataset update (channel change %d), retry in %d sec", - otThreadErrorToString(error), mChannel, TimerMilli::MsecToSec(kPendingDatasetTxRetryInterval)); + otThreadErrorToString(error), mChannel, Time::MsecToSec(kPendingDatasetTxRetryInterval)); mTimer.Start(kPendingDatasetTxRetryInterval); } @@ -393,7 +393,7 @@ void ChannelManager::StartAutoSelectTimer(void) if (mAutoSelectEnabled) { - mTimer.Start(TimerMilli::SecToMsec(mAutoSelectInterval)); + mTimer.Start(Time::SecToMsec(mAutoSelectInterval)); } else { @@ -419,14 +419,13 @@ otError ChannelManager::SetAutoChannelSelectionInterval(uint32_t aInterval) otError error = OT_ERROR_NONE; uint32_t prevInterval = mAutoSelectInterval; - VerifyOrExit((aInterval != 0) && (aInterval <= TimerMilli::MsecToSec(Timer::kMaxDt)), - error = OT_ERROR_INVALID_ARGS); + VerifyOrExit((aInterval != 0) && (aInterval <= Time::MsecToSec(Timer::kMaxDelay)), error = OT_ERROR_INVALID_ARGS); mAutoSelectInterval = aInterval; if (mAutoSelectEnabled && (mState == kStateIdle) && mTimer.IsRunning() && (prevInterval != aInterval)) { - mTimer.StartAt(mTimer.GetFireTime() - TimerMilli::SecToMsec(prevInterval), TimerMilli::SecToMsec(aInterval)); + mTimer.StartAt(mTimer.GetFireTime() - Time::SecToMsec(prevInterval), Time::SecToMsec(aInterval)); } exit: diff --git a/src/core/utils/child_supervision.cpp b/src/core/utils/child_supervision.cpp index e25e7f903..e69efb5bc 100644 --- a/src/core/utils/child_supervision.cpp +++ b/src/core/utils/child_supervision.cpp @@ -222,7 +222,7 @@ void SupervisionListener::RestartTimer(void) if ((mTimeout != 0) && (Get().GetRole() != OT_DEVICE_ROLE_DISABLED) && !Get().GetRxOnWhenIdle()) { - mTimer.Start(TimerMilli::SecToMsec(mTimeout)); + mTimer.Start(Time::SecToMsec(mTimeout)); } else { diff --git a/src/core/utils/jam_detector.cpp b/src/core/utils/jam_detector.cpp index 545f109b5..7b31619a5 100644 --- a/src/core/utils/jam_detector.cpp +++ b/src/core/utils/jam_detector.cpp @@ -208,7 +208,7 @@ exit: void JamDetector::UpdateHistory(bool aDidExceedThreshold) { - int32_t diff = TimerMilli::Diff(mCurSecondStartTime, TimerMilli::GetNow()); + uint32_t interval = TimerMilli::GetNow() - mCurSecondStartTime; // If the RSSI is ever below the threshold, update mAlwaysAboveThreshold // for current second interval. @@ -218,7 +218,8 @@ void JamDetector::UpdateHistory(bool aDidExceedThreshold) } // If we reached end of current one second interval, update the history bitmap - if (diff >= kOneSecondInterval) + + if (interval >= kOneSecondInterval) { mHistoryBitmap <<= 1; @@ -229,7 +230,7 @@ void JamDetector::UpdateHistory(bool aDidExceedThreshold) mAlwaysAboveThreshold = true; - mCurSecondStartTime += (static_cast(diff) / kOneSecondInterval) * kOneSecondInterval; + mCurSecondStartTime += (interval / kOneSecondInterval) * kOneSecondInterval; UpdateJamState(); } diff --git a/src/core/utils/jam_detector.hpp b/src/core/utils/jam_detector.hpp index 987bfc838..a0ce15dcc 100644 --- a/src/core/utils/jam_detector.hpp +++ b/src/core/utils/jam_detector.hpp @@ -198,7 +198,7 @@ private: Notifier::Callback mNotifierCallback; // Notifier callback TimerMilli mTimer; // RSSI sample timer uint64_t mHistoryBitmap; // History bitmap, each bit correspond to 1 sec interval - uint32_t mCurSecondStartTime; // Start time for current 1 sec interval + TimeMilli mCurSecondStartTime; // Start time for current 1 sec interval uint16_t mSampleInterval; // Current sample interval uint8_t mWindow : 6; // Window (in sec) to monitor jamming uint8_t mBusyPeriod : 6; // BusyPeriod (in sec) with mWindow to alert jamming diff --git a/tests/unit/test_timer.cpp b/tests/unit/test_timer.cpp index 2b06018b0..8e4683beb 100644 --- a/tests/unit/test_timer.cpp +++ b/tests/unit/test_timer.cpp @@ -317,7 +317,7 @@ int TestTwoTimers(void) sNow += kTimerInterval; - timer2.StartAt(kTimeT0, kTimerInterval - 2); // Timer 2 is even before timer 1 + timer2.StartAt(ot::TimeMilli(kTimeT0), kTimerInterval - 2); // Timer 2 is even before timer 1 VerifyOrQuit(sCallCount[kCallCountIndexTimerHandler] == 0, "TestTwoTimers: Handler CallCount Failed.\n"); VerifyOrQuit(timer1.IsRunning() == true, "TestTwoTimers: Timer running Failed.\n"); @@ -364,7 +364,7 @@ int TestTwoTimers(void) sNow += kTimerInterval + 5; - timer2.Start(ot::Timer::kMaxDt); + timer2.Start(ot::Timer::kMaxDelay); VerifyOrQuit(sCallCount[kCallCountIndexAlarmStart] == 1, "TestTwoTimers: Start CallCount Failed.\n"); VerifyOrQuit(sCallCount[kCallCountIndexAlarmStop] == 0, "TestTwoTimers: Stop CallCount Failed.\n"); @@ -380,12 +380,12 @@ int TestTwoTimers(void) VerifyOrQuit(sCallCount[kCallCountIndexTimerHandler] == 1, "TestTwoTimers: Handler CallCount Failed.\n"); VerifyOrQuit(timer1.GetFiredCounter() == 1, "TestTwoTimers: Fire Counter failed.\n"); VerifyOrQuit(sPlatT0 == sNow, "TestTwoTimers: Start params Failed.\n"); - VerifyOrQuit(sPlatDt == ot::Timer::kMaxDt, "TestTwoTimers: Start params Failed.\n"); + VerifyOrQuit(sPlatDt == ot::Timer::kMaxDelay, "TestTwoTimers: Start params Failed.\n"); VerifyOrQuit(timer1.IsRunning() == false, "TestTwoTimers: Timer running Failed.\n"); VerifyOrQuit(timer2.IsRunning() == true, "TestTwoTimers: Timer running Failed.\n"); VerifyOrQuit(sTimerOn == true, "TestTwoTimers: Platform Timer State Failed.\n"); - sNow += ot::Timer::kMaxDt; + sNow += ot::Timer::kMaxDelay; otPlatAlarmMilliFired(instance); VerifyOrQuit(sCallCount[kCallCountIndexAlarmStart] == 2, "TestTwoTimers: Start CallCount Failed.\n"); @@ -415,7 +415,7 @@ static void TenTimers(uint32_t aTimeShift) const uint32_t kNumTriggers = 7; const uint32_t kTimeT0[kNumTimers] = {1000, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008}; const uint32_t kTimerInterval[kNumTimers] = { - 20, 100, (ot::Timer::kMaxDt - kTimeT0[2]), 100000, 1000000, 10, ot::Timer::kMaxDt, 200, 200, 200}; + 20, 100, (ot::Timer::kMaxDelay - kTimeT0[2]), 100000, 1000000, 10, ot::Timer::kMaxDelay, 200, 200, 200}; // Expected timer fire order // timer # Trigger time // 5 1014 @@ -426,10 +426,10 @@ static void TenTimers(uint32_t aTimeShift) // 9 1208 // 3 101002 // 4 1001003 - // 2 kMaxDt - // 6 kMaxDt + 1005 + // 2 kMaxDuration + // 6 kMaxDuration + 1005 const uint32_t kTriggerTimes[kNumTriggers] = { - 1014, 1020, 1100, 1207, 101004, ot::Timer::kMaxDt, ot::Timer::kMaxDt + kTimeT0[6]}; + 1014, 1020, 1100, 1207, 101004, ot::Timer::kMaxDelay, ot::Timer::kMaxDelay + kTimeT0[6]}; // Expected timers fired by each kTriggerTimes[] value // Trigger # Timers Fired // 0 5 @@ -546,7 +546,7 @@ int TestTenTimers(void) { // Time shift to change the start/fire time of ten timers. const uint32_t kTimeShift[] = { - 0, 100000U, 0U - 1U, 0U - 1100U, ot::Timer::kMaxDt, ot::Timer::kMaxDt + 1020U, + 0, 100000U, 0U - 1U, 0U - 1100U, ot::Timer::kMaxDelay, ot::Timer::kMaxDelay + 1020U, }; size_t i; @@ -559,6 +559,87 @@ int TestTenTimers(void) return 0; } +/** + * Test the `Timer::Time` class. + */ +int TestTimerTime(void) +{ + const uint32_t kMaxTime = 0xffffffff; + const uint32_t kStartTimes[] = {0, 100, kMaxTime / 2, kMaxTime - 100, kMaxTime}; + const uint32_t kDurations[] = {1, 100, ot::Timer::kMaxDelay - 1, ot::Timer::kMaxDelay}; + + ot::Time t1; + ot::Time t2; + + for (size_t i = 0; i < OT_ARRAY_LENGTH(kStartTimes); i++) + { + uint32_t start = kStartTimes[i]; + + for (size_t j = 0; j < OT_ARRAY_LENGTH(kDurations); j++) + { + uint32_t duration = kDurations[j]; + + printf("TestTimerTime() start=%-10x duration=%-10x ", start, duration); + + t1.SetValue(start); + VerifyOrQuit(t1.GetValue() == start, "Time::SetValue() failed.\n"); + + t2 = t1; + VerifyOrQuit(t1.GetValue() == start, "Time assignment failed.\n"); + + VerifyOrQuit(t1 == t2, "Time == failed.\n"); + VerifyOrQuit(!(t1 != t2), "Time != failed.\n"); + VerifyOrQuit(!(t1 < t2), "Time < failed.\n"); + VerifyOrQuit((t1 <= t2), "Time <= failed.\n"); + VerifyOrQuit(!(t1 > t2), "Time > failed.\n"); + VerifyOrQuit((t1 >= t2), "Time >= failed.\n"); + VerifyOrQuit(t2 - t1 == 0, "Time difference failed\n"); + + t2 = t1 + duration; + VerifyOrQuit(!(t1 == t2), "Time == failed.\n"); + VerifyOrQuit((t1 != t2), "Time != failed.\n"); + VerifyOrQuit((t1 < t2), "Time < failed.\n"); + VerifyOrQuit((t1 <= t2), "Time <= failed.\n"); + VerifyOrQuit(!(t1 > t2), "Time > failed.\n"); + VerifyOrQuit(!(t1 >= t2), "Time >= failed.\n"); + VerifyOrQuit(t2 - t1 == duration, "Time difference failed\n"); + + t2 = t1; + t2 += duration; + VerifyOrQuit(!(t1 == t2), "Time == failed.\n"); + VerifyOrQuit((t1 != t2), "Time != failed.\n"); + VerifyOrQuit((t1 < t2), "Time < failed.\n"); + VerifyOrQuit((t1 <= t2), "Time <= failed.\n"); + VerifyOrQuit(!(t1 > t2), "Time > failed.\n"); + VerifyOrQuit(!(t1 >= t2), "Time >= failed.\n"); + VerifyOrQuit(t2 - t1 == duration, "Time difference failed\n"); + + t2 = t1 - duration; + VerifyOrQuit(!(t1 == t2), "Time == failed.\n"); + VerifyOrQuit((t1 != t2), "Time != failed.\n"); + VerifyOrQuit(!(t1 < t2), "Time < failed.\n"); + VerifyOrQuit(!(t1 <= t2), "Time <= failed.\n"); + VerifyOrQuit((t1 > t2), "Time > failed.\n"); + VerifyOrQuit((t1 >= t2), "Time >= failed.\n"); + VerifyOrQuit(t1 - t2 == duration, "Time difference failed\n"); + + t2 = t1; + t2 -= duration; + VerifyOrQuit(!(t1 == t2), "Time == failed.\n"); + VerifyOrQuit((t1 != t2), "Time != failed.\n"); + VerifyOrQuit(!(t1 < t2), "Time < failed.\n"); + VerifyOrQuit(!(t1 <= t2), "Time <= failed.\n"); + VerifyOrQuit((t1 > t2), "Time > failed.\n"); + VerifyOrQuit((t1 >= t2), "Time >= failed.\n"); + VerifyOrQuit(t1 - t2 == duration, "Time difference failed\n"); + + printf("--> PASSED\n"); + } + } + + return 0; +} + void RunTimerTests(void) { TestOneTimer(); @@ -570,6 +651,7 @@ void RunTimerTests(void) int main(void) { RunTimerTests(); + TestTimerTime(); printf("All tests passed\n"); return 0; }