From 1031280d5bdfc7eea7f87d771e79f36893216e55 Mon Sep 17 00:00:00 2001 From: yunhanw-google Date: Wed, 1 Dec 2021 11:08:09 -0800 Subject: [PATCH] add epoch timestamp in IM Event (#12185) * add epoch timestamp in IM Event * update epoch with type safe --- config/python/CHIPProjectConfig.h | 2 - config/standalone/CHIPProjectConfig.h | 2 - .../p6/include/CHIPProjectConfig.h | 7 - .../chip-tool/include/CHIPProjectAppConfig.h | 2 - .../k32w/k32w0/include/CHIPProjectConfig.h | 7 - .../main/include/CHIPProjectConfig.h | 7 - .../k32w/k32w0/include/CHIPProjectConfig.h | 7 - .../lock-app/p6/include/CHIPProjectConfig.h | 7 - .../include/CHIPProjectConfig.h | 7 - .../qpg/project_include/CHIPProjectConfig.h | 7 - .../main/include/CHIPProjectConfig.h | 7 - .../main/include/CHIPProjectConfig.h | 7 - .../k32w/k32w0/include/CHIPProjectConfig.h | 7 - src/app/EventLoggingTypes.h | 24 ++- src/app/EventManagement.cpp | 154 +++++++++++------- src/app/EventManagement.h | 22 +-- .../tests/TestActiveResolveAttempts.cpp | 2 +- src/lib/dnssd/tests/TestDnssdCache.cpp | 2 +- src/platform/ESP32/SystemTimeSupport.cpp | 64 ++++++++ src/platform/FreeRTOS/SystemTimeSupport.cpp | 51 ++++++ src/platform/Linux/SystemTimeSupport.cpp | 15 ++ src/platform/Zephyr/SystemTimeSupport.cpp | 15 ++ src/platform/mbed/SystemTimeSupport.cpp | 15 ++ src/system/SystemClock.cpp | 49 +++++- src/system/SystemClock.h | 98 +++++++++++ src/system/tests/TestSystemClock.cpp | 2 +- 26 files changed, 423 insertions(+), 166 deletions(-) diff --git a/config/python/CHIPProjectConfig.h b/config/python/CHIPProjectConfig.h index bdb2b613f7ceb7..7282f35db3a033 100644 --- a/config/python/CHIPProjectConfig.h +++ b/config/python/CHIPProjectConfig.h @@ -25,8 +25,6 @@ #define CHIP_CONFIG_ENABLE_EPHEMERAL_UDP_PORT 1 -#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 - #define CHIP_CONFIG_EVENT_LOGGING_NUM_EXTERNAL_CALLBACKS 2 #define CHIP_CONFIG_EVENT_LOGGING_EXTERNAL_EVENT_SUPPORT 1 diff --git a/config/standalone/CHIPProjectConfig.h b/config/standalone/CHIPProjectConfig.h index 5cb03319c166ae..f9a8a80026d852 100644 --- a/config/standalone/CHIPProjectConfig.h +++ b/config/standalone/CHIPProjectConfig.h @@ -26,8 +26,6 @@ #define CHIP_CONFIG_ENABLE_EPHEMERAL_UDP_PORT 1 -#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 - #define CHIP_CONFIG_EVENT_LOGGING_NUM_EXTERNAL_CALLBACKS 2 #define CHIP_CONFIG_EVENT_LOGGING_EXTERNAL_EVENT_SUPPORT 1 diff --git a/examples/all-clusters-app/p6/include/CHIPProjectConfig.h b/examples/all-clusters-app/p6/include/CHIPProjectConfig.h index 94c068c5d18f44..7a6ada1013b678 100644 --- a/examples/all-clusters-app/p6/include/CHIPProjectConfig.h +++ b/examples/all-clusters-app/p6/include/CHIPProjectConfig.h @@ -90,13 +90,6 @@ */ #define CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER "TEST_SN" -/** - * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS - * - * Enable recording UTC timestamps. - */ -#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 - /** * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE * diff --git a/examples/chip-tool/include/CHIPProjectAppConfig.h b/examples/chip-tool/include/CHIPProjectAppConfig.h index 0d5aee9f4135cf..72a5e43927a75d 100644 --- a/examples/chip-tool/include/CHIPProjectAppConfig.h +++ b/examples/chip-tool/include/CHIPProjectAppConfig.h @@ -25,8 +25,6 @@ #define CHIP_CONFIG_ENABLE_EPHEMERAL_UDP_PORT 1 -#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 - #define CHIP_CONFIG_EVENT_LOGGING_NUM_EXTERNAL_CALLBACKS 2 #define CHIP_CONFIG_EVENT_LOGGING_EXTERNAL_EVENT_SUPPORT 1 diff --git a/examples/lighting-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h b/examples/lighting-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h index 93d0990a3fea55..b1087741ca6958 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h +++ b/examples/lighting-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h @@ -132,13 +132,6 @@ */ #define CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD 1 -/** - * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS - * - * Enable recording UTC timestamps. - */ -#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 - /** * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE * diff --git a/examples/lock-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h b/examples/lock-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h index 5b5c95c5721145..d422b6cd6219d8 100644 --- a/examples/lock-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h +++ b/examples/lock-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h @@ -105,13 +105,6 @@ */ //#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 -/** - * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS - * - * Enable recording UTC timestamps. - */ -#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 - /** * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE * diff --git a/examples/lock-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h b/examples/lock-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h index a9446d8c70a984..620662f80ca98a 100644 --- a/examples/lock-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h +++ b/examples/lock-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h @@ -132,13 +132,6 @@ */ #define CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD 1 -/** - * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS - * - * Enable recording UTC timestamps. - */ -#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 - /** * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE * diff --git a/examples/lock-app/p6/include/CHIPProjectConfig.h b/examples/lock-app/p6/include/CHIPProjectConfig.h index cade0849059233..94246045e8aa41 100644 --- a/examples/lock-app/p6/include/CHIPProjectConfig.h +++ b/examples/lock-app/p6/include/CHIPProjectConfig.h @@ -86,13 +86,6 @@ */ #define CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER "TEST_SN" -/** - * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS - * - * Enable recording UTC timestamps. - */ -#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 - /** * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE * diff --git a/examples/persistent-storage/cc13x2x7_26x2x7/include/CHIPProjectConfig.h b/examples/persistent-storage/cc13x2x7_26x2x7/include/CHIPProjectConfig.h index 67a63519b80984..27f3ee9a0268ec 100644 --- a/examples/persistent-storage/cc13x2x7_26x2x7/include/CHIPProjectConfig.h +++ b/examples/persistent-storage/cc13x2x7_26x2x7/include/CHIPProjectConfig.h @@ -117,13 +117,6 @@ */ //#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 -/** - * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS - * - * Enable recording UTC timestamps. - */ -#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 - /** * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE * diff --git a/examples/platform/qpg/project_include/CHIPProjectConfig.h b/examples/platform/qpg/project_include/CHIPProjectConfig.h index 78999997bde3f6..86fda64698b92c 100644 --- a/examples/platform/qpg/project_include/CHIPProjectConfig.h +++ b/examples/platform/qpg/project_include/CHIPProjectConfig.h @@ -101,13 +101,6 @@ */ #define CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER "TEST_SN" -/** - * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS - * - * Enable recording UTC timestamps. - */ -#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 - /** * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE * diff --git a/examples/pump-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h b/examples/pump-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h index 54f16498cf782a..074e0401ab222f 100644 --- a/examples/pump-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h +++ b/examples/pump-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h @@ -109,13 +109,6 @@ */ //#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 -/** - * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS - * - * Enable recording UTC timestamps. - */ -#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 - /** * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE * diff --git a/examples/pump-controller-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h b/examples/pump-controller-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h index 54f16498cf782a..074e0401ab222f 100644 --- a/examples/pump-controller-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h +++ b/examples/pump-controller-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h @@ -109,13 +109,6 @@ */ //#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 -/** - * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS - * - * Enable recording UTC timestamps. - */ -#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 - /** * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE * diff --git a/examples/shell/nxp/k32w/k32w0/include/CHIPProjectConfig.h b/examples/shell/nxp/k32w/k32w0/include/CHIPProjectConfig.h index 0980a0e6b31b80..3308b4598a01d8 100644 --- a/examples/shell/nxp/k32w/k32w0/include/CHIPProjectConfig.h +++ b/examples/shell/nxp/k32w/k32w0/include/CHIPProjectConfig.h @@ -132,13 +132,6 @@ */ #define CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD 1 -/** - * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS - * - * Enable recording UTC timestamps. - */ -#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 - /** * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE * diff --git a/src/app/EventLoggingTypes.h b/src/app/EventLoggingTypes.h index d852e015d5f760..de143ec50c3ba8 100644 --- a/src/app/EventLoggingTypes.h +++ b/src/app/EventLoggingTypes.h @@ -117,9 +117,9 @@ struct Timestamp Timestamp(Type aType) : mType(aType) { mValue = 0; } Timestamp(Type aType, uint64_t aValue) : mType(aType), mValue(aValue) {} Timestamp(System::Clock::Timestamp aValue) : mType(Type::kSystem), mValue(aValue.count()) {} - static Timestamp UTC(uint64_t aValue) + static Timestamp Epoch(System::Clock::Timestamp aValue) { - Timestamp timestamp(Type::kEpoch, aValue); + Timestamp timestamp(Type::kEpoch, aValue.count()); return timestamp; } static Timestamp System(System::Clock::Timestamp aValue) @@ -128,8 +128,8 @@ struct Timestamp return timestamp; } - bool IsSystem() { return mType == Type::kSystem; } - bool IsEpoch() { return mType == Type::kEpoch; } + bool IsSystem() const { return mType == Type::kSystem; } + bool IsEpoch() const { return mType == Type::kEpoch; } Type mType = Type::kSystem; uint64_t mValue = 0; @@ -146,9 +146,9 @@ class EventOptions kUrgent = 0, kNotUrgent, }; - EventOptions(void) : mTimestamp(Timestamp::Type::kSystem), mpEventSchema(nullptr), mUrgent(Type::kNotUrgent) {} + EventOptions(void) : mpEventSchema(nullptr), mUrgent(Type::kNotUrgent) {} - EventOptions(Type aType) : mTimestamp(Timestamp::Type::kSystem), mpEventSchema(nullptr), mUrgent(aType) {} + EventOptions(Type aType) : mpEventSchema(nullptr), mUrgent(aType) {} EventOptions(Timestamp aTimestamp) : mTimestamp(aTimestamp), mpEventSchema(nullptr), mUrgent(Type::kNotUrgent) {} @@ -168,18 +168,16 @@ class EventOptions struct EventLoadOutContext { EventLoadOutContext(TLV::TLVWriter & aWriter, PriorityLevel aPriority, EventNumber aStartingEventNumber) : - mWriter(aWriter), mPriority(aPriority), mStartingEventNumber(aStartingEventNumber), - mCurrentSystemTime(Timestamp::Type::kSystem), mCurrentEventNumber(0), mCurrentUTCTime(Timestamp::Type::kEpoch), mFirst(true) + mWriter(aWriter), mPriority(aPriority), mStartingEventNumber(aStartingEventNumber), mCurrentEventNumber(0), mFirst(true) {} TLV::TLVWriter & mWriter; PriorityLevel mPriority = PriorityLevel::Invalid; EventNumber mStartingEventNumber = 0; - Timestamp mPreviousSystemTime; - Timestamp mCurrentSystemTime; - EventNumber mCurrentEventNumber = 0; - size_t mEventCount = 0; - Timestamp mCurrentUTCTime; + Timestamp mPreviousTime; + Timestamp mCurrentTime; + EventNumber mCurrentEventNumber = 0; + size_t mEventCount = 0; ClusterInfo * mpInterestedEventPaths = nullptr; bool mFirst = true; }; diff --git a/src/app/EventManagement.cpp b/src/app/EventManagement.cpp index e1424dc58606b5..d14e5a3b247b90 100644 --- a/src/app/EventManagement.cpp +++ b/src/app/EventManagement.cpp @@ -86,14 +86,17 @@ struct EventEnvelopeContext EventEnvelopeContext() {} int mFieldsToRead = 0; - /* PriorityLevel and DeltaSystemTimestamp are there if that is not first event when putting events in report*/ - Timestamp mDeltaSystemTime = Timestamp::System(System::Clock::kZero); - Timestamp mDeltaUtc = Timestamp::UTC(0); - PriorityLevel mPriority = PriorityLevel::First; - NodeId mNodeId = 0; - ClusterId mClusterId = 0; - EndpointId mEndpointId = 0; - EventId mEventId = 0; + /* PriorityLevel and DeltaTime are there if that is not first event when putting events in report*/ +#if CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS & CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME + Timestamp mDeltaTime = Timestamp::System(System::Clock::kZero); +#else + Timestamp mDeltaTime = Timestamp::Epoch(System::Clock::kZero); +#endif + PriorityLevel mPriority = PriorityLevel::First; + NodeId mNodeId = 0; + ClusterId mClusterId = 0; + EndpointId mEndpointId = 0; + EventId mEventId = 0; }; void EventManagement::Init(Messaging::ExchangeManager * apExchangeManager, uint32_t aNumBuffers, @@ -284,9 +287,9 @@ CHIP_ERROR EventManagement::CalculateEventSize(EventLoggingDelegate * apDelegate } writer.Init(std::move(buf)); - ctxt.mCurrentEventNumber = GetPriorityBuffer(apOptions->mpEventSchema->mPriority)->GetLastEventNumber(); - ctxt.mCurrentSystemTime.mValue = GetPriorityBuffer(apOptions->mpEventSchema->mPriority)->GetLastEventSystemTimestamp(); - err = ConstructEvent(&ctxt, apDelegate, apOptions); + ctxt.mCurrentEventNumber = GetPriorityBuffer(apOptions->mpEventSchema->mPriority)->GetLastEventNumber(); + ctxt.mCurrentTime.mValue = GetPriorityBuffer(apOptions->mpEventSchema->mPriority)->GetLastEventTimestamp(); + err = ConstructEvent(&ctxt, apDelegate, apOptions); if (CHIP_NO_ERROR == err) { requiredSize = writer.GetLengthWritten(); @@ -331,9 +334,16 @@ CHIP_ERROR EventManagement::ConstructEvent(EventLoadOutContext * apContext, Even eventDataIBBuilder.Priority(chip::to_underlying(apContext->mPriority)); - // TODO: need to add utc and systen system check here - deltatime = apOptions->mTimestamp.mValue - apContext->mCurrentSystemTime.mValue; - eventDataIBBuilder.DeltaSystemTimestamp(deltatime); + deltatime = apOptions->mTimestamp.mValue - apContext->mCurrentTime.mValue; + if (apOptions->mTimestamp.IsSystem()) + { + eventDataIBBuilder.DeltaSystemTimestamp(deltatime); + } + else + { + eventDataIBBuilder.DeltaEpochTimestamp(deltatime); + } + err = eventDataIBBuilder.GetError(); SuccessOrExit(err); @@ -367,10 +377,7 @@ CHIP_ERROR EventManagement::ConstructEvent(EventLoadOutContext * apContext, Even // update these variables since ConstructEvent can be used to track the // state of a set of events over multiple calls. apContext->mCurrentEventNumber++; - if (apContext->mCurrentSystemTime.mType == Timestamp::Type::kSystem) - { - apContext->mCurrentSystemTime = apOptions->mTimestamp; - } + apContext->mCurrentTime = apOptions->mTimestamp; } return err; } @@ -448,18 +455,34 @@ CHIP_ERROR EventManagement::CopyAndAdjustDeltaTime(const TLVReader & aReader, si ctx->mpWriter->Put(TLV::ContextTag(to_underlying(EventDataIB::Tag::kEventNumber)), ctx->mpContext->mCurrentEventNumber); } - // TODO: Add UTC timestamp support - if (aReader.GetTag() == TLV::ContextTag(to_underlying(EventDataIB::Tag::kDeltaSystemTimestamp))) + if (aReader.GetTag() == TLV::ContextTag(to_underlying(EventDataIB::Tag::kDeltaSystemTimestamp)) || + aReader.GetTag() == TLV::ContextTag(to_underlying(EventDataIB::Tag::kDeltaEpochTimestamp))) { if (ctx->mpContext->mFirst) // First event gets a timestamp, subsequent ones get a delta T { - err = ctx->mpWriter->Put(TLV::ContextTag(to_underlying(EventDataIB::Tag::kSystemTimestamp)), - ctx->mpContext->mCurrentSystemTime.mValue); + if (ctx->mpContext->mCurrentTime.IsSystem()) + { + err = ctx->mpWriter->Put(TLV::ContextTag(to_underlying(EventDataIB::Tag::kSystemTimestamp)), + ctx->mpContext->mCurrentTime.mValue); + } + else + { + err = ctx->mpWriter->Put(TLV::ContextTag(to_underlying(EventDataIB::Tag::kEpochTimestamp)), + ctx->mpContext->mCurrentTime.mValue); + } } else { - err = ctx->mpWriter->Put(TLV::ContextTag(to_underlying(EventDataIB::Tag::kDeltaSystemTimestamp)), - ctx->mpContext->mCurrentSystemTime.mValue - ctx->mpContext->mPreviousSystemTime.mValue); + if (ctx->mpContext->mCurrentTime.IsSystem()) + { + err = ctx->mpWriter->Put(TLV::ContextTag(to_underlying(EventDataIB::Tag::kDeltaSystemTimestamp)), + ctx->mpContext->mCurrentTime.mValue - ctx->mpContext->mPreviousTime.mValue); + } + else + { + err = ctx->mpWriter->Put(TLV::ContextTag(to_underlying(EventDataIB::Tag::kDeltaEpochTimestamp)), + ctx->mpContext->mCurrentTime.mValue - ctx->mpContext->mPreviousTime.mValue); + } } } else @@ -498,8 +521,19 @@ CHIP_ERROR EventManagement::LogEventPrivate(EventLoggingDelegate * apDelegate, E CircularEventBuffer * buffer = nullptr; EventLoadOutContext ctxt = EventLoadOutContext(writer, aEventOptions.mpEventSchema->mPriority, GetPriorityBuffer(aEventOptions.mpEventSchema->mPriority)->GetLastEventNumber()); + EventOptions opts; +#if CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS & CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME + Timestamp timestamp; + System::Clock::Timestamp utc_time; + + err = System::SystemClock().GetClock_RealTimeMS(utc_time); + SuccessOrExit(err); + timestamp = Timestamp::Epoch(utc_time); +#else Timestamp timestamp(System::SystemClock().GetMonotonicTimestamp()); - EventOptions opts = EventOptions(timestamp); +#endif + + opts = EventOptions(timestamp); // Start the event container (anonymous structure) in the circular buffer writer.Init(*mpEventBuffer); @@ -508,12 +542,10 @@ CHIP_ERROR EventManagement::LogEventPrivate(EventLoggingDelegate * apDelegate, E // Create all event specific data // Timestamp; encoded as a delta time - if (aEventOptions.mTimestamp.mType == Timestamp::Type::kSystem) - { - opts.mTimestamp = aEventOptions.mTimestamp; - } - if (GetPriorityBuffer(aEventOptions.mpEventSchema->mPriority)->GetFirstEventSystemTimestamp() == 0) + opts.mTimestamp = aEventOptions.mTimestamp; + + if (GetPriorityBuffer(aEventOptions.mpEventSchema->mPriority)->GetFirstEventTimestamp() == 0) { GetPriorityBuffer(aEventOptions.mpEventSchema->mPriority)->UpdateFirstLastEventTime(opts.mTimestamp); } @@ -521,8 +553,8 @@ CHIP_ERROR EventManagement::LogEventPrivate(EventLoggingDelegate * apDelegate, E opts.mUrgent = aEventOptions.mUrgent; opts.mpEventSchema = aEventOptions.mpEventSchema; - ctxt.mCurrentEventNumber = GetPriorityBuffer(opts.mpEventSchema->mPriority)->GetLastEventNumber(); - ctxt.mCurrentSystemTime.mValue = GetPriorityBuffer(opts.mpEventSchema->mPriority)->GetLastEventSystemTimestamp(); + ctxt.mCurrentEventNumber = GetPriorityBuffer(opts.mpEventSchema->mPriority)->GetLastEventNumber(); + ctxt.mCurrentTime.mValue = GetPriorityBuffer(opts.mpEventSchema->mPriority)->GetLastEventTimestamp(); err = CalculateEventSize(apDelegate, &opts, requestSize); SuccessOrExit(err); @@ -568,10 +600,10 @@ CHIP_ERROR EventManagement::LogEventPrivate(EventLoggingDelegate * apDelegate, E #if CHIP_CONFIG_EVENT_LOGGING_VERBOSE_DEBUG_LOGS ChipLogDetail(EventLogging, "LogEvent event number: 0x" ChipLogFormatX64 " schema priority: %u cluster id: " ChipLogFormatMEI - " event id: 0x%" PRIx32 " sys timestamp: 0x" ChipLogFormatX64, + " event id: 0x%" PRIx32 " %s timestamp: 0x" ChipLogFormatX64, ChipLogValueX64(aEventNumber), static_cast(opts.mpEventSchema->mPriority), ChipLogValueMEI(opts.mpEventSchema->mClusterId), opts.mpEventSchema->mEventId, - ChipLogValueX64(opts.mTimestamp.mValue)); + opts.mTimestamp.mType == Timestamp::Type::kSystem ? "Sys" : "Epoch", ChipLogValueX64(opts.mTimestamp.mValue)); #endif // CHIP_CONFIG_EVENT_LOGGING_VERBOSE_DEBUG_LOGS ScheduleFlushIfNeeded(opts.mUrgent); @@ -640,6 +672,7 @@ CHIP_ERROR EventManagement::EventIterator(const TLVReader & aReader, size_t aDep ReturnErrorOnFailure(innerReader.EnterContainer(tlvType1)); err = TLV::Utilities::Iterate(innerReader, FetchEventParameters, &event, false /*recurse*/); + if (event.mFieldsToRead != kRequiredEventField) { return CHIP_ERROR_INVALID_ARGUMENT; @@ -653,7 +686,7 @@ CHIP_ERROR EventManagement::EventIterator(const TLVReader & aReader, size_t aDep if (event.mPriority == apEventLoadOutContext->mPriority) { - apEventLoadOutContext->mCurrentSystemTime.mValue += event.mDeltaSystemTime.mValue; + apEventLoadOutContext->mCurrentTime.mValue += event.mDeltaTime.mValue; if (IsInterestedEventPaths(apEventLoadOutContext, event)) { return CHIP_EVENT_ID_FOUND; @@ -684,8 +717,8 @@ CHIP_ERROR EventManagement::CopyEventsSince(const TLVReader & aReader, size_t aD return err; } - loadOutContext->mPreviousSystemTime.mValue = loadOutContext->mCurrentSystemTime.mValue; - loadOutContext->mFirst = false; + loadOutContext->mPreviousTime.mValue = loadOutContext->mCurrentTime.mValue; + loadOutContext->mFirst = false; loadOutContext->mEventCount++; } @@ -712,10 +745,10 @@ CHIP_ERROR EventManagement::FetchEventsSince(TLVWriter & aWriter, ClusterInfo * buf = buf->GetNextCircularEventBuffer(); } - context.mpInterestedEventPaths = apClusterInfolist; - context.mCurrentSystemTime.mValue = buf->GetFirstEventSystemTimestamp(); - context.mCurrentEventNumber = buf->GetFirstEventNumber(); - err = GetEventReader(reader, aPriority, &bufWrapper); + context.mpInterestedEventPaths = apClusterInfolist; + context.mCurrentTime.mValue = buf->GetFirstEventTimestamp(); + context.mCurrentEventNumber = buf->GetFirstEventNumber(); + err = GetEventReader(reader, aPriority, &bufWrapper); SuccessOrExit(err); err = TLV::Utilities::Iterate(reader, CopyEventsSince, &context, recurse); @@ -725,6 +758,7 @@ CHIP_ERROR EventManagement::FetchEventsSince(TLVWriter & aWriter, ClusterInfo * } exit: + ChipLogProgress(EventLogging, "Debug log, err: %s\n", chip::ErrorStr(err)); aEventNumber = context.mCurrentEventNumber; aEventCount += context.mEventCount; return err; @@ -768,13 +802,6 @@ CHIP_ERROR EventManagement::FetchEventParameters(const TLVReader & aReader, size envelope->mFieldsToRead |= 1 << to_underlying(EventDataIB::Tag::kPriority); } - if (reader.GetTag() == TLV::ContextTag(to_underlying(EventDataIB::Tag::kDeltaSystemTimestamp))) - { - ReturnErrorOnFailure(reader.Get(envelope->mDeltaSystemTime.mValue)); - - envelope->mFieldsToRead |= 1 << to_underlying(EventDataIB::Tag::kDeltaSystemTimestamp); - } - return CHIP_NO_ERROR; } @@ -809,7 +836,7 @@ CHIP_ERROR EventManagement::EvictEvent(CHIPCircularTLVBuffer & apBuffer, void * // event is getting dropped. Increase the event number and first timestamp. EventNumber numEventsToDrop = 1; eventBuffer->RemoveEvent(numEventsToDrop); - eventBuffer->SetFirstEventSystemTimestamp(eventBuffer->GetFirstEventSystemTimestamp() + context.mDeltaSystemTime.mValue); + eventBuffer->SetFirstEventTimestamp(eventBuffer->GetFirstEventTimestamp() + context.mDeltaTime.mValue); ChipLogProgress( EventLogging, "Dropped events from buffer with priority %u due to overflow: { event priority_level: %u, count: 0x" ChipLogFormatX64 @@ -852,14 +879,19 @@ void CircularEventBuffer::Init(uint8_t * apBuffer, uint32_t aBufferLength, Circu CircularEventBuffer * apNext, PriorityLevel aPriorityLevel) { CHIPCircularTLVBuffer::Init(apBuffer, aBufferLength); - mpPrev = apPrev; - mpNext = apNext; - mPriority = aPriorityLevel; - mFirstEventNumber = 1; - mLastEventNumber = 0; - mFirstEventSystemTimestamp = Timestamp::System(System::Clock::kZero); - mLastEventSystemTimestamp = Timestamp::System(System::Clock::kZero); - mpEventNumberCounter = nullptr; + mpPrev = apPrev; + mpNext = apNext; + mPriority = aPriorityLevel; + mFirstEventNumber = 1; + mLastEventNumber = 0; +#if CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS & CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME + mFirstEventTimestamp = Timestamp::Epoch(System::Clock::kZero); + mLastEventTimestamp = Timestamp::Epoch(System::Clock::kZero); +#else + mFirstEventTimestamp = Timestamp::System(System::Clock::kZero); + mLastEventTimestamp = Timestamp::System(System::Clock::kZero); +#endif + mpEventNumberCounter = nullptr; } bool CircularEventBuffer::IsFinalDestinationForPriority(PriorityLevel aPriority) const @@ -869,12 +901,12 @@ bool CircularEventBuffer::IsFinalDestinationForPriority(PriorityLevel aPriority) void CircularEventBuffer::UpdateFirstLastEventTime(Timestamp aEventTimestamp) { - if (mFirstEventSystemTimestamp.mValue == 0) + if (mFirstEventTimestamp.mValue == 0) { - mFirstEventSystemTimestamp = aEventTimestamp; - mLastEventSystemTimestamp = aEventTimestamp; + mFirstEventTimestamp = aEventTimestamp; + mLastEventTimestamp = aEventTimestamp; } - mLastEventSystemTimestamp = aEventTimestamp; + mLastEventTimestamp = aEventTimestamp; } void CircularEventBuffer::RemoveEvent(EventNumber aNumEvents) diff --git a/src/app/EventManagement.h b/src/app/EventManagement.h index cc695130c3c9d8..604084f8e7c665 100644 --- a/src/app/EventManagement.h +++ b/src/app/EventManagement.h @@ -40,9 +40,9 @@ namespace chip { namespace app { -constexpr size_t kMaxEventSizeReserve = 512; -constexpr uint16_t kRequiredEventField = (1 << to_underlying(EventDataIB::Tag::kPriority)) | - (1 << to_underlying(EventDataIB::Tag::kDeltaSystemTimestamp)) | (1 << to_underlying(EventDataIB::Tag::kPath)); +constexpr size_t kMaxEventSizeReserve = 512; +constexpr uint16_t kRequiredEventField = + (1 << to_underlying(EventDataIB::Tag::kPriority)) | (1 << to_underlying(EventDataIB::Tag::kPath)); /** * @brief @@ -137,10 +137,10 @@ class CircularEventBuffer : public TLV::CHIPCircularTLVBuffer EventNumber GetFirstEventNumber() { return mFirstEventNumber; } EventNumber GetLastEventNumber() { return mLastEventNumber; } - uint64_t GetFirstEventSystemTimestamp() { return mFirstEventSystemTimestamp.mValue; } - void SetFirstEventSystemTimestamp(uint64_t aValue) { mLastEventSystemTimestamp.mValue = aValue; } + uint64_t GetFirstEventTimestamp() { return mFirstEventTimestamp.mValue; } + void SetFirstEventTimestamp(uint64_t aValue) { mLastEventTimestamp.mValue = aValue; } - uint64_t GetLastEventSystemTimestamp() { return mLastEventSystemTimestamp.mValue; } + uint64_t GetLastEventTimestamp() { return mLastEventTimestamp.mValue; } virtual ~CircularEventBuffer() = default; @@ -157,11 +157,11 @@ class CircularEventBuffer : public TLV::CHIPCircularTLVBuffer // The backup counter to use if no counter is provided for us. MonotonicallyIncreasingCounter mNonPersistedCounter; - size_t mRequiredSpaceForEvicted = 0; ///< Required space for previous buffer to evict event to new buffer - EventNumber mFirstEventNumber = 0; ///< First event Number stored in the logging subsystem for this priority - EventNumber mLastEventNumber = 0; ///< Last event Number vended for this priority - Timestamp mFirstEventSystemTimestamp; ///< The timestamp of the first event in this buffer - Timestamp mLastEventSystemTimestamp; ///< The timestamp of the last event in this buffer + size_t mRequiredSpaceForEvicted = 0; ///< Required space for previous buffer to evict event to new buffer + EventNumber mFirstEventNumber = 0; ///< First event Number stored in the logging subsystem for this priority + EventNumber mLastEventNumber = 0; ///< Last event Number vended for this priority + Timestamp mFirstEventTimestamp; ///< The timestamp of the first event in this buffer + Timestamp mLastEventTimestamp; ///< The timestamp of the last event in this buffer }; class CircularEventReader; diff --git a/src/lib/dnssd/minimal_mdns/tests/TestActiveResolveAttempts.cpp b/src/lib/dnssd/minimal_mdns/tests/TestActiveResolveAttempts.cpp index ea202c89d0bac0..970a9a896a2b17 100644 --- a/src/lib/dnssd/minimal_mdns/tests/TestActiveResolveAttempts.cpp +++ b/src/lib/dnssd/minimal_mdns/tests/TestActiveResolveAttempts.cpp @@ -26,7 +26,7 @@ using namespace chip; using namespace chip::System::Clock::Literals; using chip::System::Clock::Timeout; -class MockClock : public System::Clock::ClockBase +class MockClock : public System::Clock::ClockImpl { public: System::Clock::Microseconds64 GetMonotonicMicroseconds64() override { return mMsec; } diff --git a/src/lib/dnssd/tests/TestDnssdCache.cpp b/src/lib/dnssd/tests/TestDnssdCache.cpp index a254a14d7b4b59..231dcf695021e4 100644 --- a/src/lib/dnssd/tests/TestDnssdCache.cpp +++ b/src/lib/dnssd/tests/TestDnssdCache.cpp @@ -39,7 +39,7 @@ using namespace chip; using namespace chip::Dnssd; namespace { -class FakeClock : public System::Clock::ClockBase +class FakeClock : public System::Clock::ClockImpl { public: System::Clock::Microseconds64 GetMonotonicMicroseconds64() override { return mTime; } diff --git a/src/platform/ESP32/SystemTimeSupport.cpp b/src/platform/ESP32/SystemTimeSupport.cpp index a0b1d734d1bc1e..d802ea8ed4d389 100644 --- a/src/platform/ESP32/SystemTimeSupport.cpp +++ b/src/platform/ESP32/SystemTimeSupport.cpp @@ -48,6 +48,70 @@ Milliseconds64 ClockImpl::GetMonotonicMilliseconds64(void) return std::chrono::duration_cast(GetMonotonicMicroseconds64()); } +CHIP_ERROR ClockImpl::GetClock_RealTime(Clock::Microseconds64 & aCurTime) +{ + struct timeval tv; + if (gettimeofday(&tv, nullptr) != 0) + { + return CHIP_ERROR_POSIX(errno); + } + if (tv.tv_sec < CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD) + { + return CHIP_ERROR_REAL_TIME_NOT_SYNCED; + } + if (tv.tv_usec < 0) + { + return CHIP_ERROR_REAL_TIME_NOT_SYNCED; + } + static_assert(CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD >= 0, "We might be letting through negative tv_sec values!"); + aCurTime = Clock::Microseconds64((static_cast(tv.tv_sec) * UINT64_C(1000000)) + static_cast(tv.tv_usec)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ClockImpl::GetClock_RealTimeMS(Clock::Milliseconds64 & aCurTime) +{ + struct timeval tv; + if (gettimeofday(&tv, nullptr) != 0) + { + return CHIP_ERROR_POSIX(errno); + } + if (tv.tv_sec < CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD) + { + return CHIP_ERROR_REAL_TIME_NOT_SYNCED; + } + if (tv.tv_usec < 0) + { + return CHIP_ERROR_REAL_TIME_NOT_SYNCED; + } + static_assert(CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD >= 0, "We might be letting through negative tv_sec values!"); + aCurTime = + Clock::Milliseconds64((static_cast(tv.tv_sec) * UINT64_C(1000)) + (static_cast(tv.tv_usec) / 1000)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ClockImpl::SetClock_RealTime(Clock::Microseconds64 aNewCurTime) +{ + struct timeval tv; + tv.tv_sec = static_cast(aNewCurTime.count() / UINT64_C(1000000)); + tv.tv_usec = static_cast(aNewCurTime.count() % UINT64_C(1000000)); + if (settimeofday(&tv, nullptr) != 0) + { + return (errno == EPERM) ? CHIP_ERROR_ACCESS_DENIED : CHIP_ERROR_POSIX(errno); + } +#if CHIP_PROGRESS_LOGGING + { + const time_t timep = tv.tv_sec; + struct tm calendar; + localtime_r(&timep, &calendar); + ChipLogProgress( + DeviceLayer, + "Real time clock set to %ld (%04" PRId16 "/%02" PRId8 "/%02" PRId8 " %02" PRId8 ":%02" PRId8 ":%02" PRId8 " UTC)", + tv.tv_sec, calendar.tm_year, calendar.tm_mon, calendar.tm_mday, calendar.tm_hour, calendar.tm_min, calendar.tm_sec); + } +#endif // CHIP_PROGRESS_LOGGING + return CHIP_NO_ERROR; +} + } // namespace Clock } // namespace System } // namespace chip diff --git a/src/platform/FreeRTOS/SystemTimeSupport.cpp b/src/platform/FreeRTOS/SystemTimeSupport.cpp index 712879ee4ef854..bd6e9acca497f6 100644 --- a/src/platform/FreeRTOS/SystemTimeSupport.cpp +++ b/src/platform/FreeRTOS/SystemTimeSupport.cpp @@ -41,6 +41,8 @@ namespace { constexpr uint32_t kTicksOverflowShift = (configUSE_16_BIT_TICKS) ? 16 : 32; +uint64_t sBootTimeUS = 0; + #ifdef __CORTEX_M BaseType_t sNumOfOverflows; #endif @@ -100,6 +102,55 @@ Clock::Milliseconds64 ClockImpl::GetMonotonicMilliseconds64(void) return Clock::Milliseconds64((FreeRTOSTicksSinceBoot() * kMillisecondsPerSecond) / configTICK_RATE_HZ); } +uint64_t GetClock_Monotonic(void) +{ + return (FreeRTOSTicksSinceBoot() * kMicrosecondsPerSecond) / configTICK_RATE_HZ; +} + +uint64_t GetClock_MonotonicMS(void) +{ + return (FreeRTOSTicksSinceBoot() * kMillisecondsPerSecond) / configTICK_RATE_HZ; +} + +uint64_t GetClock_MonotonicHiRes(void) +{ + return GetClock_Monotonic(); +} + +CHIP_ERROR ClockImpl::GetClock_RealTime(Clock::Microseconds64 & aCurTime) +{ + if (sBootTimeUS == 0) + { + return CHIP_ERROR_REAL_TIME_NOT_SYNCED; + } + aCurTime = Clock::Microseconds64(sBootTimeUS + GetClock_Monotonic()); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ClockImpl::GetClock_RealTimeMS(Clock::Milliseconds64 & aCurTime) +{ + if (sBootTimeUS == 0) + { + return CHIP_ERROR_REAL_TIME_NOT_SYNCED; + } + aCurTime = Clock::Milliseconds64((sBootTimeUS + GetClock_Monotonic()) / 1000); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ClockImpl::SetClock_RealTime(Clock::Microseconds64 aNewCurTime) +{ + uint64_t timeSinceBootUS = GetClock_Monotonic(); + if (aNewCurTime.count() > timeSinceBootUS) + { + sBootTimeUS = aNewCurTime.count() - timeSinceBootUS; + } + else + { + sBootTimeUS = 0; + } + return CHIP_NO_ERROR; +} + } // namespace Clock } // namespace System } // namespace chip diff --git a/src/platform/Linux/SystemTimeSupport.cpp b/src/platform/Linux/SystemTimeSupport.cpp index 3397bd185a0dd4..a4b5ec0b75229a 100644 --- a/src/platform/Linux/SystemTimeSupport.cpp +++ b/src/platform/Linux/SystemTimeSupport.cpp @@ -50,6 +50,21 @@ Milliseconds64 ClockImpl::GetMonotonicMilliseconds64() return std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()); } +CHIP_ERROR ClockImpl::GetClock_RealTime(Clock::Microseconds64 & aCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR ClockImpl::GetClock_RealTimeMS(Clock::Milliseconds64 & aCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR ClockImpl::SetClock_RealTime(Clock::Microseconds64 aNewCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + } // namespace Clock } // namespace System } // namespace chip diff --git a/src/platform/Zephyr/SystemTimeSupport.cpp b/src/platform/Zephyr/SystemTimeSupport.cpp index 0eacdb7b2ce364..eb57d9476e753f 100644 --- a/src/platform/Zephyr/SystemTimeSupport.cpp +++ b/src/platform/Zephyr/SystemTimeSupport.cpp @@ -48,6 +48,21 @@ Milliseconds64 ClockImpl::GetMonotonicMilliseconds64(void) return Milliseconds64(k_uptime_get()); } +CHIP_ERROR ClockImpl::GetClock_RealTime(Clock::Microseconds64 & aCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR ClockImpl::GetClock_RealTimeMS(Clock::Milliseconds64 & aCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR ClockImpl::SetClock_RealTime(Clock::Microseconds64 aNewCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + } // namespace Clock } // namespace System } // namespace chip diff --git a/src/platform/mbed/SystemTimeSupport.cpp b/src/platform/mbed/SystemTimeSupport.cpp index 1f4311eaebf74e..dbf84c4a437c96 100644 --- a/src/platform/mbed/SystemTimeSupport.cpp +++ b/src/platform/mbed/SystemTimeSupport.cpp @@ -71,6 +71,21 @@ Milliseconds64 ClockImpl::GetMonotonicMilliseconds64() return std::chrono::duration_cast(GetMonotonicMicroseconds64()); } +CHIP_ERROR ClockImpl::GetClock_RealTime(Clock::Microseconds64 & aCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR ClockImpl::GetClock_RealTimeMS(Clock::Milliseconds64 & aCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR ClockImpl::SetClock_RealTime(Clock::Microseconds64 aNewCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + } // namespace Clock } // namespace System } // namespace chip diff --git a/src/system/SystemClock.cpp b/src/system/SystemClock.cpp index 1ec09aa65ef73a..c52a1ecec0ed03 100644 --- a/src/system/SystemClock.cpp +++ b/src/system/SystemClock.cpp @@ -82,6 +82,21 @@ ClockBase * gClockBase = &gClockImpl; #define MONOTONIC_CLOCK_ID CLOCK_MONOTONIC #endif +CHIP_ERROR ClockImpl::GetClock_RealTime(Microseconds64 & aCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR ClockImpl::GetClock_RealTimeMS(Milliseconds64 & aCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR ClockImpl::SetClock_RealTime(Microseconds64 aNewCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + Microseconds64 ClockImpl::GetMonotonicMicroseconds64() { struct timespec ts; @@ -100,6 +115,21 @@ Milliseconds64 ClockImpl::GetMonotonicMilliseconds64() #if HAVE_GETTIMEOFDAY +CHIP_ERROR ClockImpl::GetClock_RealTime(Microseconds64 & aCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR ClockImpl::GetClock_RealTimeMS(Milliseconds64 & aCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR ClockImpl::SetClock_RealTime(Microseconds64 aNewCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + Microseconds64 ClockImpl::GetMonotonicMicroseconds64() { struct timeval tv; @@ -121,12 +151,27 @@ Milliseconds64 ClockImpl::GetMonotonicMilliseconds64() // -------------------- Default Get/SetClock Functions for LwIP Systems -------------------- -Microseconds64 ClockImpl::GetMonotonicMicroseconds64(void) +CHIP_ERROR ClockImpl::GetClock_RealTime(Microseconds64 & aCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR ClockImpl::GetClock_RealTimeMS(Milliseconds64 & aCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR ClockImpl::SetClock_RealTime(Microseconds64 aNewCurTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +Microseconds64 ClockImpl::GetMonotonicMicroseconds64() { return GetMonotonicMilliseconds64(); } -Milliseconds64 ClockImpl::GetMonotonicMilliseconds64(void) +Milliseconds64 ClockImpl::GetMonotonicMilliseconds64() { static volatile uint64_t overflow = 0; static volatile u32_t lastSample = 0; diff --git a/src/system/SystemClock.h b/src/system/SystemClock.h index fc74a9601cca02..a65941ef2dbe69 100644 --- a/src/system/SystemClock.h +++ b/src/system/SystemClock.h @@ -184,6 +184,101 @@ class ClockBase * @returns Elapsed time in milliseconds since an arbitrary, platform-defined epoch. */ virtual Milliseconds64 GetMonotonicMilliseconds64() = 0; + + /** + * @brief + * Platform-specific function for getting the current real (civil) time in microsecond Unix time + * format. + * + * This function is expected to return the local platform's notion of current real time, expressed + * as a Unix time value scaled to microseconds. The underlying clock is required to tick at a + * rate of least at whole seconds (values of 1,000,000), but may tick faster. + * + * On those platforms that are capable of tracking real time, GetClock_RealTime() must return the + * error CHIP_ERROR_REAL_TIME_NOT_SYNCED whenever the system is unsynchronized with real time. + * + * Platforms that are incapable of tracking real time should not implement the GetClock_RealTime() + * function, thereby forcing link-time failures of features that depend on access to real time. + * Alternatively, such platforms may supply an implementation of GetClock_RealTime() that returns + * the error CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE. + * + * This function is expected to be thread-safe on any platform that employs threading. + * + * @note + * This function is reserved for internal use by the System Clock. Users of the System + * Clock should call System::Clock::GetClock_RealTime(). + * + * @param[out] aCurTime The current time, expressed as Unix time scaled to microseconds. + * + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_REAL_TIME_NOT_SYNCED + * If the platform is capable of tracking real time, but is + * is currently unsynchronized. + * @retval #CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE + * If the platform is incapable of tracking real time. + */ + virtual CHIP_ERROR GetClock_RealTime(Microseconds64 & aCurTime) = 0; + + /** + * @brief + * Platform-specific function for getting the current real (civil) time in millisecond Unix time + * format. + * + * This function is expected to return the local platform's notion of current real time, expressed + * as a Unix time value scaled to milliseconds. + * + * See the documentation for GetClock_RealTime() for details on the expected behavior. + * + * @note + * This function is reserved for internal use by the System Clock. Users of the System + * Clock should call System::Clock::GetClock_RealTimeMS(). + * + * @param[out] aCurTime The current time, expressed as Unix time scaled to milliseconds. + * + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_REAL_TIME_NOT_SYNCED + * If the platform is capable of tracking real time, but is + * is currently unsynchronized. + * @retval #CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE + * If the platform is incapable of tracking real time. + */ + virtual CHIP_ERROR GetClock_RealTimeMS(Milliseconds64 & aCurTime) = 0; + + /** + * @brief + * Platform-specific function for setting the current real (civil) time. + * + * This function set the local platform's notion of current real time. The new current + * time is expressed as a Unix time value scaled to microseconds. + * + * Once set, underlying platform clock is expected to track real time with a granularity of at least whole + * seconds. + * + * On platforms that support tracking real time, the SetClock_RealTime() function must return the error + * CHIP_ERROR_ACCESS_DENIED if the calling application does not have the privilege to set the + * current time. + * + * Platforms that are incapable of tracking real time, or do not offer the ability to set real time, + * should not implement the SetClock_RealTime() function, thereby forcing link-time failures of features + * that depend on setting real time. Alternatively, such platforms may supply an implementation of + * SetClock_RealTime() that returns the error CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE. + * + * This function is expected to be thread-safe on any platform that employs threading. + * + * @note + * This function is reserved for internal use by the System Clock. Users of the System + * Clock should call System::Clock::GetClock_RealTimeMS(). + * + * @param[in] aNewCurTime The new current time, expressed as Unix time scaled to microseconds. + * + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE + * If the platform is incapable of tracking real time. + * @retval #CHIP_ERROR_ACCESS_DENIED + * If the calling application does not have the privilege to set the + * current time. + */ + virtual CHIP_ERROR SetClock_RealTime(Microseconds64 aNewCurTime) = 0; }; // Currently we have a single implementation class, ClockImpl, whose members are implemented in build-specific files. @@ -193,6 +288,9 @@ class ClockImpl : public ClockBase ~ClockImpl() = default; Microseconds64 GetMonotonicMicroseconds64() override; Milliseconds64 GetMonotonicMilliseconds64() override; + CHIP_ERROR GetClock_RealTime(Microseconds64 & aCurTime) override; + CHIP_ERROR GetClock_RealTimeMS(Milliseconds64 & aCurTime) override; + CHIP_ERROR SetClock_RealTime(Microseconds64 aNewCurTime) override; }; namespace Internal { diff --git a/src/system/tests/TestSystemClock.cpp b/src/system/tests/TestSystemClock.cpp index 3b0fc0977cbb18..62ff182841dfc2 100644 --- a/src/system/tests/TestSystemClock.cpp +++ b/src/system/tests/TestSystemClock.cpp @@ -85,7 +85,7 @@ void TestRealClock(nlTestSuite * inSuite, void * inContext) void TestMockClock(nlTestSuite * inSuite, void * inContext) { - class MockClock : public Clock::ClockBase + class MockClock : public Clock::ClockImpl { public: Clock::Microseconds64 GetMonotonicMicroseconds64() override { return mTime; }