6 #ifndef ACE_TIME_SYSTEM_CLOCK_COROUTINE_H
7 #define ACE_TIME_SYSTEM_CLOCK_COROUTINE_H
10 #ifdef ACE_ROUTINE_VERSION
13 #include <AceCommon.h>
14 #include <AceRoutine.h>
15 #include "SystemClock.h"
17 class SystemClockCoroutineTest_runCoroutine;
45 class SystemClockCoroutine :
47 public ace_routine::Coroutine {
66 explicit SystemClockCoroutine(
67 Clock* referenceClock ,
69 uint16_t syncPeriodSeconds = 3600,
70 uint16_t initialSyncPeriodSeconds = 5,
71 uint16_t requestTimeoutMillis = 1000,
72 ace_common::TimingStats* timingStats =
nullptr):
73 SystemClock(referenceClock, backupClock),
74 mSyncPeriodSeconds(syncPeriodSeconds),
75 mRequestTimeoutMillis(requestTimeoutMillis),
76 mTimingStats(timingStats),
77 mCurrentSyncPeriodSeconds(initialSyncPeriodSeconds) {}
95 int runCoroutine()
override {
97 if (getReferenceClock() ==
nullptr)
return 0;
99 uint32_t nowMillis = clockMillis();
103 getReferenceClock()->sendRequest();
104 mRequestStartMillis = coroutineMillis();
105 mRequestStatus = kStatusSent;
106 setPrevSyncAttemptMillis(nowMillis);
107 setNextSyncAttemptMillis(
108 nowMillis + mCurrentSyncPeriodSeconds * (uint32_t) 1000);
112 if (getReferenceClock()->isResponseReady()) {
113 mRequestStatus = kStatusOk;
121 uint16_t waitMillis =
122 (uint16_t) coroutineMillis() - mRequestStartMillis;
123 if (waitMillis >= mRequestTimeoutMillis) {
124 mRequestStatus = kStatusTimedOut;
125 setSyncStatusCode(kSyncStatusTimedOut);
134 if (mRequestStatus == kStatusOk) {
135 acetime_t nowSeconds = getReferenceClock()->readResponse();
136 if (mTimingStats !=
nullptr) {
137 uint16_t elapsedMillis =
138 (uint16_t) coroutineMillis() - mRequestStartMillis;
139 mTimingStats->update(elapsedMillis);
142 if (nowSeconds == kInvalidSeconds) {
143 setSyncStatusCode(kSyncStatusError);
145 mRequestStatus = kStatusUnknown;
148 mCurrentSyncPeriodSeconds = mSyncPeriodSeconds;
149 setSyncStatusCode(kSyncStatusOk);
154 setNextSyncAttemptMillis(
155 nowMillis + mCurrentSyncPeriodSeconds * (uint32_t) 1000);
156 COROUTINE_DELAY_SECONDS(mCurrentSyncPeriodSeconds);
161 if (mRequestStatus != kStatusOk) {
162 if (mCurrentSyncPeriodSeconds >= mSyncPeriodSeconds / 2) {
163 mCurrentSyncPeriodSeconds = mSyncPeriodSeconds;
165 mCurrentSyncPeriodSeconds *= 2;
172 uint8_t getRequestStatus()
const {
return mRequestStatus; }
176 SystemClockCoroutine() {}
179 friend class ::SystemClockCoroutineTest_runCoroutine;
182 static const uint8_t kStatusUnknown = 0;
185 static const uint8_t kStatusSent = 1;
188 static const uint8_t kStatusOk = 2;
191 static const uint8_t kStatusTimedOut = 3;
194 SystemClockCoroutine(
const SystemClockCoroutine&) =
delete;
195 SystemClockCoroutine& operator=(
const SystemClockCoroutine&) =
delete;
197 uint16_t
const mSyncPeriodSeconds = 3600;
198 uint16_t
const mRequestTimeoutMillis = 1000;
199 ace_common::TimingStats*
const mTimingStats =
nullptr;
201 uint16_t mRequestStartMillis;
202 uint16_t mCurrentSyncPeriodSeconds = 5;
204 uint8_t mRequestStatus = kStatusUnknown;