| /* |
| * |
| * Copyright (c) 2015-2017 Nest Labs, Inc. |
| * All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /** |
| * @file |
| * |
| * @brief |
| * Management of the Weave Event Logging. |
| * |
| */ |
| #ifndef _WEAVE_DATA_MANAGEMENT_EVENT_LOGGING_MANAGEMENT_CURRENT_H |
| #define _WEAVE_DATA_MANAGEMENT_EVENT_LOGGING_MANAGEMENT_CURRENT_H |
| |
| #include <Weave/Profiles/data-management/Current/WdmManagedNamespace.h> |
| #include <Weave/Core/WeaveCircularTLVBuffer.h> |
| |
| #if WEAVE_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS |
| #include <Weave/Profiles/time/WeaveTime.h> |
| #endif |
| |
| #include <Weave/Support/PersistedCounter.h> |
| |
| namespace nl { |
| namespace Weave { |
| namespace Profiles { |
| namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) { |
| |
| /** |
| * @brief |
| * Internal event buffer, built around the #WeaveCircularTLVBuffer |
| */ |
| struct CircularEventBuffer |
| { |
| // for doxygen, see the CPP file |
| CircularEventBuffer(uint8_t *inBuffer, size_t inBufferLength, CircularEventBuffer *inPrev, CircularEventBuffer *inNext); |
| |
| // for doxygen, see the CPP file |
| bool IsFinalDestinationForImportance(ImportanceType inImportance) const; |
| |
| event_id_t VendEventID(void); |
| void RemoveEvent(void); |
| |
| // for doxygen, see the CPP file |
| void AddEvent(timestamp_t inEventTimestamp); |
| |
| #if WEAVE_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS |
| // for doxygen, see the CPP file |
| void AddEventUTC(utc_timestamp_t inEventTimestamp); |
| #endif |
| |
| // for doxygen, see the CPP file |
| WEAVE_ERROR RegisterExternalEventsCallback(FetchExternalEventsFunct aFetchCallback, NotifyExternalEventsDeliveredFunct aNotifyCallback, size_t aNumEvents, ExternalEvents **aExternalEventsPtr); |
| |
| // for doxygen, see the CPP file |
| void UnregisterExternalEventsCallback(ExternalEvents *ioPtr); |
| |
| nl::Weave::TLV::WeaveCircularTLVBuffer mBuffer; //< The underlying TLV buffer storing the events in a TLV representation |
| |
| CircularEventBuffer *mPrev; //< A pointer #CircularEventBuffer storing events less important events |
| CircularEventBuffer *mNext; //< A pointer #CircularEventBuffer storing events more important events |
| |
| ImportanceType mImportance; //< The buffer is the final bucket for events of this importance. Events of lesser importance are dropped when they get bumped out of this buffer |
| |
| event_id_t mFirstEventID; //< First event ID stored in the logging subsystem for this importance |
| event_id_t mLastEventID; //< Last event ID vended for this importance |
| |
| timestamp_t mFirstEventTimestamp; //< The timestamp of the first event in this buffer |
| timestamp_t mLastEventTimestamp; //< The timestamp of the last event in this buffer |
| |
| #if WEAVE_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS |
| utc_timestamp_t mFirstEventUTCTimestamp; //< The UTC timestamp of the first event in this buffer |
| utc_timestamp_t mLastEventUTCTimestamp; //< The UTC timestamp of the last event in this buffer |
| |
| bool mUTCInitialized; //< Indicates whether UTC timestamps are initialized in this buffer |
| #endif |
| |
| // The counter we're going to actually use. |
| nl::Weave::MonotonicallyIncreasingCounter *mEventIdCounter; |
| |
| // The backup counter to use if no counter is provided for us. |
| nl::Weave::MonotonicallyIncreasingCounter mNonPersistedCounter; |
| |
| #if WEAVE_CONFIG_EVENT_LOGGING_NUM_EXTERNAL_CALLBACKS |
| ExternalEvents mExternalEventsList[WEAVE_CONFIG_EVENT_LOGGING_NUM_EXTERNAL_CALLBACKS]; |
| |
| ExternalEvents *GetExternalEventsFromEventID(event_id_t aEventID); |
| |
| ExternalEvents *GetNextAvailableExternalEvents(void); |
| #endif // WEAVE_CONFIG_EVENT_LOGGING_NUM_EXTERNAL_CALLBACKS |
| |
| static WEAVE_ERROR GetNextBufferFunct(nl::Weave::TLV::TLVReader& ioReader, uintptr_t &inBufHandle, const uint8_t *&outBufStart, uint32_t &outBufLen); |
| }; |
| |
| |
| /** |
| * @brief |
| * A TLVReader backed by CircularEventBuffer |
| */ |
| class CircularEventReader : public nl::Weave::TLV::TLVReader |
| { |
| friend struct CircularEventBuffer; |
| public: |
| void Init(CircularEventBuffer *inBuf); |
| }; |
| |
| /** |
| * @brief |
| * Internal structure for traversing event list. |
| */ |
| struct CopyAndAdjustDeltaTimeContext |
| { |
| CopyAndAdjustDeltaTimeContext(nl::Weave::TLV::TLVWriter *inWriter, EventLoadOutContext *inContext); |
| |
| nl::Weave::TLV::TLVWriter *mWriter; |
| EventLoadOutContext *mContext; |
| }; |
| |
| /** |
| * @brief |
| * Internal structure for traversing events. |
| */ |
| struct EventEnvelopeContext |
| { |
| EventEnvelopeContext(void); |
| |
| size_t mNumFieldsToRead; |
| int32_t mDeltaTime; |
| #if WEAVE_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS |
| int64_t mDeltaUtc; |
| #endif |
| ImportanceType mImportance; |
| }; |
| |
| enum LoggingManagementStates |
| { |
| kLoggingManagementState_Idle = 1, //< No log offload in progress, log offload can begin without any constraints |
| kLoggingManagementState_InProgress = 2, //< Log offload in progress |
| kLoggingManagementState_Holdoff = 3, //< Log offload has completed; we do not restart the log until the holdoff expires |
| kLoggingManagementState_Shutdown = 4 //< Not capable of performing any logging operation |
| }; |
| |
| // forward class declaration |
| class LogBDXUpload; |
| |
| /** |
| * @brief |
| * A class for managing the in memory event logs. |
| */ |
| |
| class LoggingManagement |
| { |
| friend class LogBDXUpload; |
| public: |
| LoggingManagement(nl::Weave::WeaveExchangeManager* inMgr, |
| size_t inNumBuffers, size_t *inBufferLengths, void **inBuffers, |
| nl::Weave::Platform::PersistedStorage::Key *inCounterKeys, const uint32_t *inCounterEpochs, nl::Weave::PersistedCounter **inCounterStorage); |
| LoggingManagement(nl::Weave::WeaveExchangeManager* inMgr, |
| size_t inNumBuffers, size_t *inBufferLengths, void **inBuffers, |
| nl::Weave::MonotonicallyIncreasingCounter **nWeaveCounter); |
| LoggingManagement(void); |
| |
| static LoggingManagement &GetInstance(void); |
| |
| static void CreateLoggingManagement(nl::Weave::WeaveExchangeManager *inMgr, |
| size_t inNumBuffers, size_t *inBufferLengths, void **inBuffers, |
| nl::Weave::Platform::PersistedStorage::Key *inCounterKeys, const uint32_t *inCounterEpochs, nl::Weave::PersistedCounter **inCounterStorage); |
| static void CreateLoggingManagement(nl::Weave::WeaveExchangeManager *inMgr, |
| size_t inNumBuffers, size_t *inBufferLengths, void **inBuffers, |
| nl::Weave::MonotonicallyIncreasingCounter **nWeaveCounter); |
| static void DestroyLoggingManagement(void); |
| |
| WEAVE_ERROR SetExchangeManager(nl::Weave::WeaveExchangeManager *inMgr); |
| |
| event_id_t LogEvent(const EventSchema &inSchema, EventWriterFunct inEventWriter, void *inAppData, const EventOptions *inOptions); |
| |
| WEAVE_ERROR GetEventReader(nl::Weave::TLV::TLVReader &reader, ImportanceType inImportance); |
| |
| WEAVE_ERROR FetchEventsSince(nl::Weave::TLV::TLVWriter &ioWriter, ImportanceType inImportance, event_id_t &ioEventID); |
| |
| WEAVE_ERROR ScheduleFlushIfNeeded(bool inFlushRequested); |
| |
| WEAVE_ERROR SetLoggingEndpoint(event_id_t *inEventEndpoints, size_t inNumImportanceLevels, size_t &outLoggingPosition); |
| |
| uint32_t GetBytesWritten(void) const; |
| |
| void NotifyEventsDelivered(ImportanceType inImportance, event_id_t inLastDeliveredEventID, uint64_t inRecipientNodeID) const; |
| |
| /** |
| * @brief |
| * IsValid returns whether the LoggingManagement instance is valid |
| * |
| * @retval true if the instance is valid (initialized with the appropriate backing store) |
| * @retval false otherwise |
| */ |
| bool IsValid(void) { return (mEventBuffer != NULL); }; |
| |
| #if WEAVE_CONFIG_EVENT_LOGGING_NUM_EXTERNAL_CALLBACKS |
| bool IsEventExternal(ImportanceType inImportance, event_id_t inEventID) const; |
| event_id_t GetEndOfExternalEventRange(ImportanceType inImportance, event_id_t inEventID) const; |
| #endif // WEAVE_CONFIG_EVENT_LOGGING_NUM_EXTERNAL_CALLBACKS |
| |
| event_id_t GetLastEventID(ImportanceType inImportance); |
| event_id_t GetFirstEventID(ImportanceType inImportance); |
| |
| void ThrottleLogger(void); |
| void UnthrottleLogger(void); |
| |
| void SetBDXUploader(LogBDXUpload *inUploader); |
| |
| WEAVE_ERROR RegisterEventCallbackForImportance(ImportanceType inImportance, FetchExternalEventsFunct inFetchCallback, NotifyExternalEventsDeliveredFunct inNotifyCallback, size_t inNumEvents, ExternalEvents **aExternalEventsPtr); |
| WEAVE_ERROR RegisterEventCallbackForImportance(ImportanceType inImportance, FetchExternalEventsFunct inFetchCallback, size_t inNumEvents, ExternalEvents **aExternalEventsPtr); |
| void UnregisterEventCallbackForImportance(ImportanceType inImportance, ExternalEvents *inPtr); |
| WEAVE_ERROR BlitEvent(EventLoadOutContext *aContext, |
| const EventSchema &inSchema, |
| EventWriterFunct inEventWriter, |
| void *inAppData, |
| const EventOptions *inOptions); |
| |
| #if WEAVE_CONFIG_EVENT_LOGGING_WDM_OFFLOAD |
| bool CheckShouldRunWDM(void); |
| #endif |
| private: |
| event_id_t LogEventPrivate(const EventSchema &inSchema, EventWriterFunct inEventWriter, void *inAppData, const EventOptions *inOptions); |
| |
| void FlushHandler(System::Layer *inSystemLayer, INET_ERROR inErr); |
| void SignalUploadDone(void); |
| WEAVE_ERROR CopyToNextBuffer(CircularEventBuffer *inEventBuffer); |
| WEAVE_ERROR EnsureSpace(size_t inRequiredSpace); |
| |
| static WEAVE_ERROR CopyEventsSince(const nl::Weave::TLV::TLVReader &aReader, size_t aDepth, void *aContext); |
| static WEAVE_ERROR FetchEventParameters(const nl::Weave::TLV::TLVReader &aReader, size_t aDepth, void *aContext); |
| static WEAVE_ERROR CopyAndAdjustDeltaTime(const nl::Weave::TLV::TLVReader &aReader, size_t aDepth, void *aContext); |
| static WEAVE_ERROR EvictEvent(nl::Weave::TLV::WeaveCircularTLVBuffer &inBuffer, void * inAppData, nl::Weave::TLV::TLVReader & inReader); |
| static WEAVE_ERROR AlwaysFail(nl::Weave::TLV::WeaveCircularTLVBuffer &inBuffer, void * inAppData, nl::Weave::TLV::TLVReader & inReader); |
| static WEAVE_ERROR CopyEvent(const nl::Weave::TLV::TLVReader & aReader, nl::Weave::TLV::TLVWriter & aWriter, EventLoadOutContext *aContext); |
| |
| static void LoggingFlushHandler(System::Layer *systemLayer, void *appState, INET_ERROR err); |
| |
| #if WEAVE_CONFIG_EVENT_LOGGING_BDX_OFFLOAD |
| bool CheckShouldRunBDX(void); |
| #endif |
| |
| ImportanceType GetMaxImportance(void); |
| ImportanceType GetCurrentImportance(uint32_t profileId); |
| |
| private: |
| |
| CircularEventBuffer *GetImportanceBuffer(ImportanceType inImportance) const; |
| |
| CircularEventBuffer *mEventBuffer; |
| WeaveExchangeManager *mExchangeMgr; |
| LoggingManagementStates mState; |
| LogBDXUpload *mBDXUploader; |
| uint32_t mBytesWritten; |
| uint32_t mThrottled; |
| ImportanceType mMaxImportanceBuffer; |
| bool mUploadRequested; |
| }; |
| |
| namespace Platform |
| { |
| extern void CriticalSectionEnter(void); |
| extern void CriticalSectionExit(void); |
| } // Platform |
| |
| } // WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) |
| } // Profiles |
| } // Weave |
| } //nl |
| |
| #endif //_WEAVE_DATA_MANAGEMENT_EVENT_LOGGING_MANAGEMENT_CURRENT_H |