| /* |
| * |
| * Copyright (c) 2016-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 |
| * This file defines subscription client for Weave |
| * Data Management (WDM) profile. |
| * |
| */ |
| |
| #ifndef _WEAVE_DATA_MANAGEMENT_SUBSCRIPTION_CLIENT_CURRENT_H |
| #define _WEAVE_DATA_MANAGEMENT_SUBSCRIPTION_CLIENT_CURRENT_H |
| |
| #include <Weave/Core/WeaveCore.h> |
| |
| #include <Weave/Profiles/data-management/TraitCatalog.h> |
| #include <Weave/Profiles/data-management/TraitPathStore.h> |
| #include <Weave/Profiles/data-management/UpdateClient.h> |
| #include <Weave/Profiles/data-management/UpdateEncoder.h> |
| #include <Weave/Profiles/data-management/EventLogging.h> |
| #include <Weave/Profiles/status-report/StatusReportProfile.h> |
| |
| namespace nl { |
| namespace Weave { |
| namespace Profiles { |
| namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) { |
| |
| typedef uint32_t PropertyPathHandle; |
| typedef uint16_t PropertySchemaHandle; |
| typedef uint16_t PropertyDictionaryKey; |
| typedef uint16_t TraitDataHandle; |
| |
| /** |
| * @class IWeaveWDMMutex |
| * |
| * @brief Interface of a mutex object. Mutexes of this type are implemented by the application |
| * and used in WDM to protect data structures that can be accessed from multiple threads. |
| * Implementations of this interface must behave like a recursive lock. |
| */ |
| |
| class IWeaveWDMMutex |
| { |
| public: |
| virtual void Lock(void) = 0; |
| virtual void Unlock(void) = 0; |
| }; |
| |
| class SubscriptionClient |
| { |
| public: |
| enum |
| { |
| kNoTimeOut = 0, |
| |
| // Note the WDM spec says 0x7FFFFFFF, but Weave implementation can only hold timeout of much shorter |
| // 32-bit in milliseconds, which is about 1200 hours |
| kMaxTimeoutSec = 3600000, |
| }; |
| |
| enum EventID |
| { |
| /** |
| * Marks the end of this subscription. The parameters sent to the |
| * ::nl::Weave::Profiles::DataManagement_Current::SubscriptionClient::EventCallback |
| * will indicate whether a resubscribe will be automatically attempted. |
| * |
| * During the event handler call, the state of the client will be `Terminated`. |
| * If no retry will be attempted, the state of the client will transition to |
| * `Initialized` when the event handler returns. Otherwise, the state will |
| * transition to `ResubscribeHoldoff` and an attempt will be made to re-establish |
| * the subscription after the hold-off time. |
| * |
| * The application may call AbortSubscription() or Free() in this state. |
| * |
| * The parameters sent will also include an error code indicating the |
| * reason for ending the subscription. |
| * |
| * The subscription could have been terminated for a number of reasons |
| * (WRM ACK missing, ExchangeContext allocation failure, response |
| * timeout,...) Some possible error codes generated by the client: |
| * |
| * |Error code | Meaning | |
| * |-----------|---------| |
| * | #WEAVE_ERROR_INVALID_MESSAGE_TYPE | An unrecognized message is received. | |
| * | #WEAVE_ERROR_TIMEOUT | An ack is not received or a liveness check fails.| |
| * | #WEAVE_ERROR_INCORRECT_STATE | Messages are received in an unexpected state. | |
| * | #WEAVE_ERROR_STATUS_REPORT_RECEIVED | A status report is received. | |
| * | #WEAVE_ERROR_INVALID_ARGUMENT | Subscribe request fields are invalid. | |
| */ |
| kEvent_OnSubscriptionTerminated = 1, |
| |
| /** |
| * Generated after the binding has been prepared and ExchangeContext has |
| * been set up but prior to any messages being sent. This is the last |
| * chance for an application to adjust ExchangeContext settings, `mEC` |
| * is valid and can be tuned for timeout settings. The application must |
| * not touch other fields in the client and must not close the |
| * ExchangeContext. |
| */ |
| kEvent_OnExchangeStart = 2, |
| |
| /** |
| * Sent when the engine is ready to send the SubscribeRequest. The |
| * application is expected to fill in the paths that it wants to |
| * subscribe to. |
| */ |
| kEvent_OnSubscribeRequestPrepareNeeded = 3, |
| |
| /** |
| * Generated upon a successful establishment of the subscription. The |
| * application may call EndSubscription(), AbortSubscription(), or |
| * Free() at this point. |
| */ |
| kEvent_OnSubscriptionEstablished = 4, |
| |
| /** |
| * Generated on a receit of a NotificationRequest. The application may |
| * call EndSubscription(), AbortSubscription(), or Free() at this point. |
| */ |
| kEvent_OnNotificationRequest = 5, |
| |
| /** |
| * Generated when the SubscriptionEngine finishes proceesing a |
| * NotificationRequest message. The application may call |
| * EndSubscription(), AbortSubscription(), or Free() at this point. |
| */ |
| kEvent_OnNotificationProcessed = 6, |
| |
| /** |
| * Generated when the SubscriptionEngine encountes an event stream |
| * within the NotificationRequest message. The application may call |
| * EndSubscription(), AbortSubscription(), or Free() at this point. |
| */ |
| kEvent_OnEventStreamReceived = 7, |
| |
| /** |
| * An event indicating subscription activity. It is generated whenever |
| * the client receives an indication on subscription activity; this |
| * includes successful subscription establishment, a reception of a |
| * NotificationRequest or a receipt of a status report in response to |
| * the SubscribeConfirm message. |
| */ |
| kEvent_OnSubscriptionActivity = 8, |
| |
| #if WEAVE_CONFIG_ENABLE_WDM_UPDATE |
| /** |
| * An event denoting the completion of the update. Event parameters |
| * will indicate whether the update of a specific trait path has |
| * succeeded or failed. |
| */ |
| kEvent_OnUpdateComplete = 9, |
| |
| /** |
| * An event denoting that all paths in the update set have been |
| * processed by the peer, and no more paths need to be updated. |
| */ |
| kEvent_OnNoMorePendingUpdates = 10, |
| #endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE |
| }; |
| |
| struct LastObservedEvent |
| { |
| uint64_t mSourceId; |
| uint8_t mImportance; |
| uint64_t mEventId; |
| }; |
| |
| // union of structures for each event some of them might be empty |
| union InEventParam |
| { |
| void Clear(void) { memset(this, 0, sizeof(*this)); } |
| |
| struct |
| { |
| WEAVE_ERROR mReason; |
| |
| bool mIsStatusCodeValid; |
| uint32_t mStatusProfileId; |
| uint16_t mStatusCode; |
| ReferencedTLVData * mAdditionalInfoPtr; |
| bool mWillRetry; |
| |
| SubscriptionClient * mClient; |
| } mSubscriptionTerminated; |
| |
| struct |
| { |
| // Do not close the EC |
| nl::Weave::ExchangeContext * mEC; |
| SubscriptionClient * mClient; |
| } mExchangeStart; |
| |
| struct |
| { |
| SubscriptionClient * mClient; |
| } mSubscribeRequestPrepareNeeded; |
| |
| struct |
| { |
| uint64_t mSubscriptionId; |
| SubscriptionClient * mClient; |
| } mSubscriptionEstablished; |
| |
| struct |
| { |
| // Do not close the EC |
| nl::Weave::ExchangeContext * mEC; |
| |
| // Do not modify the message content |
| PacketBuffer * mMessage; |
| SubscriptionClient * mClient; |
| } mNotificationRequest; |
| |
| struct |
| { |
| SubscriptionClient * mClient; |
| } mNotificationProcessed; |
| |
| struct |
| { |
| nl::Weave::TLV::TLVReader * mReader; |
| SubscriptionClient * mClient; |
| } mEventStreamReceived; |
| |
| struct |
| { |
| SubscriptionClient * mClient; |
| } mSubscriptionActivity; |
| |
| #if WEAVE_CONFIG_ENABLE_WDM_UPDATE |
| struct |
| { |
| WEAVE_ERROR mReason; |
| uint32_t mStatusProfileId; |
| uint16_t mStatusCode; |
| TraitDataHandle mTraitDataHandle; |
| PropertyPathHandle mPropertyPathHandle; |
| SubscriptionClient * mClient; |
| bool mWillRetry; |
| } mUpdateComplete; |
| #endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE |
| }; |
| |
| union OutEventParam |
| { |
| void Clear(void) { memset(this, 0, sizeof(*this)); } |
| |
| struct |
| { |
| TraitPath * mPathList; ///< Pointer to a list of trait paths |
| VersionedTraitPath * mVersionedPathList; ///< Pointer to a list of versioned trait paths. If both this and mPathList are |
| ///< non-NULL, the versioned path list is selected |
| size_t mPathListSize; ///< Number of trait paths in mPathList |
| LastObservedEvent * mLastObservedEventList; ///< A list of the last known events received by the subscriber |
| size_t mLastObservedEventListSize; ///< Number of observed events in mLastObservedEventList |
| uint32_t mTimeoutSecMin; ///< Field specifying lower bound of liveness timeout |
| uint32_t mTimeoutSecMax; ///< Field specifying upper bound of liveness timeout |
| uint64_t mSubscriptionId; ///< The subscription ID to use for a mutual subscription |
| bool mNeedAllEvents; ///< Indicates whether the subscriber is interested in events |
| } mSubscribeRequestPrepareNeeded; |
| }; |
| |
| struct ResubscribeParam |
| { |
| typedef enum |
| { |
| kSubscription, |
| kUpdate |
| } RequestType; |
| WEAVE_ERROR mReason; ///< Error received on most recent failure |
| uint32_t mNumRetries; ///< Number of retries, reset on a successful attempt |
| RequestType mRequestType; ///< Request being backed off |
| }; |
| |
| /** |
| * @brief Callback to pass subscription events to application. |
| * |
| * @param[in] aAppState App state pointer set during initialization of |
| * the SubscriptionClient. |
| * |
| * @param[in] aEvent Indicates which event is happening |
| * |
| * @param[in] aInParam Struct with additional details about the event |
| * |
| * @param[out] aOutParam Information passed back by the application |
| */ |
| typedef void (*EventCallback)(void * const aAppState, EventID aEvent, const InEventParam & aInParam, OutEventParam & aOutParam); |
| |
| static void DefaultEventHandler(EventID aEvent, const InEventParam & aInParam, OutEventParam & aOutParam); |
| |
| /** |
| * @brief Callback to fetch the interval of time to wait before the next |
| * resubscribe. Applications are allowed to abort/free in this function |
| * if they've decided to give up on resubscribing. |
| * |
| * @param[in] aAppState App state pointer set during initialization of |
| * the SubscriptionClient. |
| * |
| * @param[in] aInParam Struct with additional details about the retry |
| * |
| * @param[out] aOutIntervalMsec Time in milliseconds to wait before next retry |
| */ |
| typedef void (*ResubscribePolicyCallback)(void * const aAppState, ResubscribeParam & aInParam, uint32_t & aOutIntervalMsec); |
| |
| static void DefaultResubscribePolicyCallback(void * const aAppState, ResubscribeParam & aInParam, uint32_t & aOutIntervalMsec); |
| |
| void InitiateSubscription(void); |
| void InitiateCounterSubscription(const uint32_t aLivenessTimeoutSec); |
| |
| Binding * GetBinding(void) const; |
| |
| uint64_t GetPeerNodeId(void) const; |
| |
| /** |
| * @brief |
| * End the subscription. |
| * |
| * When #WDM_ENABLE_SUBSCRIPTION_CANCEL compile-time option is enabled, |
| * gracefully end the subscription by sending a CancelRequest to the peer. |
| * The resources associated with the subscription are freed on response |
| * from the peer or on timeout. When the option is disabled, the call is |
| * equivalent to AbortSubscription(). |
| */ |
| WEAVE_ERROR EndSubscription(void); |
| |
| /** |
| * @brief |
| * Abort the subscription. |
| * |
| * Immediately stop accepting all traffic associated with the subscription, |
| * and release all underlying communication resources. The |
| * SubscriptionClient object itself remains valid and may be used again. |
| */ |
| void AbortSubscription(void); |
| |
| /** |
| * @brief |
| * Free this SubscriptionClient object. |
| * |
| * Calls AbortSubscription() if necessary and releases the refcount on this |
| * SubscriptionClient object. Under correct usage, this should enable the |
| * object to be returned to the object pool |
| */ |
| void Free(void); |
| |
| WEAVE_ERROR GetSubscriptionId(uint64_t * const apSubscriptionId); |
| |
| uint32_t GetLivenessTimeoutMsec(void) const { return mLivenessTimeoutMsec; }; |
| void SetLivenessTimeoutMsec(uint32_t val) { mLivenessTimeoutMsec = val; } |
| |
| void EnableResubscribe(ResubscribePolicyCallback aCallback); |
| void DisableResubscribe(void); |
| void ResetResubscribe(void); |
| |
| bool IsInProgressOrEstablished() |
| { |
| return (mCurrentState >= kState_InProgressOrEstablished_Begin && mCurrentState <= kState_InProgressOrEstablished_End); |
| } |
| |
| bool IsRetryEnabled() { return (mResubscribePolicyCallback != NULL); } |
| |
| bool IsEstablished() { return (mCurrentState >= kState_Established_Begin && mCurrentState <= kState_Established_End); } |
| bool IsEstablishedIdle() { return (mCurrentState == kState_SubscriptionEstablished_Idle); } |
| bool IsFree() { return (mCurrentState == kState_Free); } |
| bool IsCanceling() const { return (mCurrentState == kState_Canceling); } |
| bool IsTerminated() { return (mCurrentState == kState_Terminated); } |
| bool IsInResubscribeHoldoff() { return (mCurrentState == kState_Resubscribe_Holdoff); } |
| |
| void IndicateActivity(void); |
| |
| #if WEAVE_CONFIG_ENABLE_WDM_UPDATE |
| void LockUpdateMutex(void); |
| void UnlockUpdateMutex(void); |
| |
| WEAVE_ERROR FlushUpdate(); |
| WEAVE_ERROR FlushUpdate(bool aForce); |
| WEAVE_ERROR SetUpdated(TraitUpdatableDataSink * aDataSink, PropertyPathHandle aPropertyHandle, bool aIsConditional); |
| WEAVE_ERROR ClearUpdated(TraitUpdatableDataSink * aDataSink, PropertyPathHandle aPropertyHandle); |
| void DiscardUpdates(); |
| void SuspendUpdateRetries(); |
| void OnCatalogChanged(); |
| |
| bool IsUpdatePendingOrInProgress() { return (kPendingSetEmpty != mPendingSetState || IsUpdateInProgress()); } |
| #endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE |
| |
| private: |
| friend class SubscriptionEngine; |
| friend class TestTdm; |
| friend class TestWdm; |
| friend class WdmUpdateEncoderTest; |
| friend class MockWdmSubscriptionInitiatorImpl; |
| friend class TraitDataSink; |
| friend class TraitSchemaEngine; |
| friend class UpdateDirtyPathFilter; |
| friend class UpdateDictionaryDirtyPathCut; |
| friend class UpdateEncoder; |
| |
| enum ClientState |
| { |
| kState_Free = 0, |
| kState_Initialized = 1, |
| kState_Subscribing = 2, |
| kState_Subscribing_IdAssigned = 3, |
| kState_SubscriptionEstablished_Idle = 4, |
| kState_SubscriptionEstablished_Confirming = 5, |
| kState_Canceling = 6, |
| kState_Resubscribe_Holdoff = 7, |
| kState_Terminated = 8, |
| |
| kState_NotifyDataSinkOnAbort_Begin = kState_Subscribing, |
| kState_NotifyDataSinkOnAbort_End = kState_Canceling, |
| kState_TimerTick_Begin = kState_Subscribing, |
| kState_TimerTick_End = kState_Resubscribe_Holdoff, |
| |
| // Note that these are the same as the allowed states in NotificationRequestHandler |
| kState_InProgressOrEstablished_Begin = kState_Subscribing, |
| kState_InProgressOrEstablished_End = kState_SubscriptionEstablished_Confirming, |
| |
| kState_Established_Begin = kState_SubscriptionEstablished_Idle, |
| kState_Established_End = kState_SubscriptionEstablished_Confirming, |
| }; |
| |
| ClientState mCurrentState; |
| |
| /** |
| * The runtime configuration; i.e. the desired state of the Client. |
| */ |
| enum ClientConfig |
| { |
| kConfig_Down, /**< The default configuration: no subscription, no binding. |
| The client comes back to this configuration automatically if the responder |
| sends a Cancel request. */ |
| kConfig_Initiator, /**< Subscribe as an initiator */ |
| kConfig_CounterSubscriber /**< Start a "counter subscription" */ |
| }; |
| |
| bool IsInitiator() { return mConfig == kConfig_Initiator; } |
| bool IsCounterSubscriber() { return mConfig == kConfig_CounterSubscriber; } |
| bool ShouldSubscribe() { return mConfig > kConfig_Down; } |
| |
| ClientConfig mConfig; |
| bool mPrevIsPartialChange; |
| #if WDM_ENABLE_PROTOCOL_CHECKS |
| TraitDataHandle mPrevTraitDataHandle; |
| #endif |
| |
| int8_t mRefCount; |
| |
| Binding * mBinding; |
| nl::Weave::ExchangeContext * mEC; |
| |
| void * mAppState; |
| EventCallback mEventCallback; |
| |
| Binding::EventCallback mAppBindingCallback; |
| void * mAppBindingState; |
| |
| ResubscribePolicyCallback mResubscribePolicyCallback; |
| |
| TraitCatalogBase<TraitDataSink> * mDataSinkCatalog; |
| |
| ExchangeContext::Timeout mInactivityTimeoutDuringSubscribingMsec; |
| uint32_t mLivenessTimeoutMsec; |
| uint64_t mSubscriptionId; |
| |
| // retry params |
| uint32_t mRetryCounter; |
| |
| // Do nothing |
| SubscriptionClient(void); |
| |
| void InitAsFree(void); |
| void Reset(void); |
| |
| // AddRef to Binding |
| // store pointers to binding and delegate |
| // null out EC |
| WEAVE_ERROR Init(Binding * const apBinding, void * const apAppState, EventCallback const aEventCallback, |
| const TraitCatalogBase<TraitDataSink> * const apCatalog, |
| const uint32_t aInactivityTimeoutDuringSubscribingMsec, IWeaveWDMMutex * aUpdateMutex); |
| |
| void _InitiateSubscription(void); |
| WEAVE_ERROR SendSubscribeRequest(void); |
| |
| void _Cleanup(); |
| |
| WEAVE_ERROR ProcessDataList(nl::Weave::TLV::TLVReader & aReader); |
| |
| void _AddRef(void); |
| void _Release(void); |
| |
| void TerminateSubscription(WEAVE_ERROR aReason, Profiles::StatusReporting::StatusReport * aStatusReport, bool suppressAppCallback); |
| WEAVE_ERROR _PrepareBinding(void); |
| |
| WEAVE_ERROR ReplaceExchangeContext(void); |
| |
| void FlushExistingExchangeContext(const bool aAbortNow = false); |
| |
| void NotificationRequestHandler(nl::Weave::ExchangeContext * aEC, const nl::Inet::IPPacketInfo * aPktInfo, |
| const nl::Weave::WeaveMessageInfo * aMsgInfo, PacketBuffer * aPayload); |
| |
| #if WDM_ENABLE_SUBSCRIPTION_CANCEL |
| void CancelRequestHandler(nl::Weave::ExchangeContext * aEC, const nl::Inet::IPPacketInfo * aPktInfo, |
| const nl::Weave::WeaveMessageInfo * aMsgInfo, PacketBuffer * aPayload); |
| #endif // WDM_ENABLE_SUBSCRIPTION_CANCEL |
| |
| void TimerEventHandler(void); |
| WEAVE_ERROR RefreshTimer(void); |
| |
| void SetRetryTimer(WEAVE_ERROR aReason); // TODO: rename to SetResubscribeTimer() |
| void CancelSubscriptionTimer(void); |
| |
| void MoveToState(const ClientState aTargetState); |
| |
| const char * GetStateStr(void) const; |
| |
| static void BindingEventCallback(void * const apAppState, const Binding::EventType aEvent, |
| const Binding::InEventParam & aInParam, Binding::OutEventParam & aOutParam); |
| static void OnTimerCallback(System::Layer * aSystemLayer, void * aAppState, System::Error aErrorCode); |
| static void DataSinkOperation_NoMoreData(void * const apOpState, TraitDataSink * const apDataSink); |
| static void OnSendError(ExchangeContext * aEC, WEAVE_ERROR aErrorCode, void * aMsgSpecificContext); |
| static void OnResponseTimeout(nl::Weave::ExchangeContext * aEC); |
| static void OnMessageReceivedFromLocallyInitiatedExchange(nl::Weave::ExchangeContext * aEC, |
| const nl::Inet::IPPacketInfo * aPktInfo, |
| const nl::Weave::WeaveMessageInfo * aMsgInfo, uint32_t aProfileId, |
| uint8_t aMsgType, PacketBuffer * aPayload); |
| |
| #if WEAVE_CONFIG_ENABLE_WDM_UPDATE |
| |
| IWeaveWDMMutex * mUpdateMutex; |
| |
| struct UpdateRequestContext |
| { |
| void Reset(); |
| |
| size_t mItemInProgress; |
| PropertyPathHandle mNextDictionaryElementPathHandle; |
| uint32_t mUpdateRequestIndex; |
| bool mIsPartialUpdate; |
| }; |
| uint32_t mUpdateRetryCounter; |
| bool mSuspendUpdateRetries; |
| bool mUpdateRetryScheduled; |
| bool mUpdateFlushScheduled; |
| |
| void StartUpdateRetryTimer(WEAVE_ERROR aReason); |
| static void OnUpdateTimerCallback(System::Layer * aSystemLayer, void * aAppState, System::Error); |
| static void OnUpdateScheduleWorkCallback(System::Layer * aSystemLayer, void * aAppState, System::Error); |
| void UpdateTimerEventHandler(void); |
| |
| uint32_t GetMaxUpdateSize(void) const { return mMaxUpdateSize == 0 ? UINT16_MAX : mMaxUpdateSize; } |
| void SetMaxUpdateSize(const uint32_t aMaxPayload); |
| |
| // Methods to encode and send update requests |
| void FormAndSendUpdate(); |
| WEAVE_ERROR SendSingleUpdateRequest(void); |
| static WEAVE_ERROR AddElementFunc(UpdateEncoder * aEncoder, void * apCallState, TLV::TLVWriter & aOuterWriter); |
| void SetUpdateStartVersions(void); |
| |
| // Methods to handle update response and exchange failures (OnResponseTimeout, OnSendError) |
| void OnUpdateResponse(WEAVE_ERROR aReason, nl::Weave::Profiles::StatusReporting::StatusReport * apStatus); |
| void OnUpdateNoResponse(WEAVE_ERROR aReason); |
| static bool WillRetryUpdate(WEAVE_ERROR aErr, uint32_t aStatusProfileId, uint16_t aStatusCode); |
| |
| // Methods to purge obsolete pending paths |
| WEAVE_ERROR PurgePendingUpdate(void); |
| void MarkFailedPendingPaths(TraitDataHandle aTraitDataHandle, TraitUpdatableDataSink & aSink, |
| const DataVersion & aLatestVersion); |
| WEAVE_ERROR PurgeFailedPendingPaths(WEAVE_ERROR aErr, size_t & aCount); |
| |
| // Methods to handle potential data loss due to notifications received with updates pending or in progress |
| bool FilterNotifiedPath(TraitDataHandle aTraitDataHandle, PropertyPathHandle aPropertyPathHandle, |
| const TraitSchemaEngine * const aSchemaEngine); |
| void ClearPotentialDataLoss(TraitDataHandle aTraitDataHandle, TraitUpdatableDataSink & aUpdatableSink); |
| bool CheckForSinksWithDataLoss(); |
| static void CheckForSinksWithDataLossIteratorCb(void * aDataSink, TraitDataHandle aDataHandle, void * aContext); |
| |
| // Methods to fail everything and notify the application |
| void PurgeAndNotifyFailedPaths(WEAVE_ERROR aErr, TraitPathStore & aPathStore, size_t & aCount); |
| |
| // Methods to manage the pending set and in-progress list |
| enum PendingSetState |
| { |
| kPendingSetEmpty, |
| kPendingSetOpen, |
| kPendingSetReady |
| }; |
| void SetPendingSetState(PendingSetState aState); |
| WEAVE_ERROR MovePendingToInProgress(void); |
| WEAVE_ERROR AddItemPendingUpdateSet(const TraitPath & aItem, const TraitSchemaEngine * const aSchemaEngine); |
| WEAVE_ERROR MoveInProgressToPending(void); |
| |
| // Tracking if a payload is in flight |
| bool IsUpdateInFlight() { return mUpdateInFlight; } |
| void SetUpdateInFlight() { mUpdateInFlight = true; } |
| void ClearUpdateInFlight() { mUpdateInFlight = false; } |
| |
| // Knowing if an update is pending or in progress |
| bool IsUpdateInProgress() { return (false == mInProgressUpdateList.IsEmpty()); } |
| bool IsReadyToSendNewUpdate() { return (mPendingSetState == kPendingSetReady && false == IsUpdateInProgress()); } |
| |
| // Methods to notify the application |
| void UpdateCompleteEventCbHelper(const TraitPath & aTraitPath, uint32_t aStatusProfileId, uint16_t aStatusCode, |
| WEAVE_ERROR aReason, bool aWillRetry); |
| void NoMorePendingEventCbHelper(void); |
| |
| // Other methods related to mUpdateClient |
| static void UpdateEventCallback(void * const aAppState, UpdateClient::EventType aEvent, |
| const UpdateClient::InEventParam & aInParam, UpdateClient::OutEventParam & aOutParam); |
| void AbortUpdates(WEAVE_ERROR); |
| |
| void ConfigureUpdatableSinks(void); |
| |
| static void MovePendingToInProgressUpdatableSinkTrait(void * aDataSink, TraitDataHandle aDataHandle, void * aContext); |
| static void RefreshUpdatableSinkTrait(void * aDataSink, TraitDataHandle aDataHandle, void * aContext); |
| static void PurgePendingUpdatableSinkTrait(void * aDataSink, TraitDataHandle aDataHandle, void * aContext); |
| static void ConfigureUpdatableSinkTrait(void * aDataSink, TraitDataHandle aDataHandle, void * aContext); |
| static void CleanupUpdatableSinkTrait(void * aDataSink, TraitDataHandle aDataHandle, void * aContext); |
| |
| bool mResubscribeNeeded; |
| UpdateRequestContext mUpdateRequestContext; |
| uint16_t mMaxUpdateSize; |
| bool mUpdateInFlight; |
| |
| // Flags used with mInProgressUpdateList |
| enum |
| { |
| kFlag_ForceMerge = 0x4, /**< In UpdateRequest, DataElements are encoded with the "replace" format by |
| default; this flag is used to force the encoding of |
| dictionaries so that the items are merged. |
| */ |
| kFlag_Private = 0x8, /**< The path was created internally by the engine |
| to encode a dictionary in its own separate |
| DataElement; the application is notified about it |
| only if the update fails. |
| */ |
| |
| }; |
| |
| PendingSetState mPendingSetState; |
| TraitPathStore mPendingUpdateSet; |
| TraitPathStore::Record mPendingStore[WDM_UPDATE_MAX_ITEMS_IN_TRAIT_DIRTY_PATH_STORE]; |
| |
| TraitPathStore mInProgressUpdateList; |
| TraitPathStore::Record mInProgressStore[WDM_UPDATE_MAX_ITEMS_IN_TRAIT_DIRTY_PATH_STORE]; |
| |
| UpdateClient mUpdateClient; |
| UpdateEncoder mUpdateEncoder; |
| #endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE |
| }; |
| |
| }; // namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) |
| }; // namespace Profiles |
| }; // namespace Weave |
| }; // namespace nl |
| |
| #endif // _WEAVE_DATA_MANAGEMENT_SUBSCRIPTION_CLIENT_CURRENT_H |