Line data Source code
1 : /* 2 : * Copyright (c) 2022 Project CHIP Authors 3 : * 4 : * Licensed under the Apache License, Version 2.0 (the "License"); 5 : * you may not use this file except in compliance with the License. 6 : * You may obtain a copy of the License at 7 : * 8 : * http://www.apache.org/licenses/LICENSE-2.0 9 : * 10 : * Unless required by applicable law or agreed to in writing, software 11 : * distributed under the License is distributed on an "AS IS" BASIS, 12 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 : * See the License for the specific language governing permissions and 14 : * limitations under the License. 15 : */ 16 : #pragma once 17 : 18 : #include <app/AttributePersistenceProvider.h> 19 : #include <lib/support/ScopedBuffer.h> 20 : #include <lib/support/Span.h> 21 : #include <system/SystemClock.h> 22 : 23 : namespace chip { 24 : namespace app { 25 : 26 : class DeferredAttribute 27 : { 28 : public: 29 : explicit DeferredAttribute(const ConcreteAttributePath & path) : mPath(path) {} 30 : 31 0 : bool Matches(const ConcreteAttributePath & path) const { return mPath == path; } 32 0 : bool IsArmed() const { return static_cast<bool>(mValue); } 33 0 : System::Clock::Timestamp GetFlushTime() const { return mFlushTime; } 34 : 35 : CHIP_ERROR PrepareWrite(System::Clock::Timestamp flushTime, const ByteSpan & value); 36 : void Flush(AttributePersistenceProvider & persister); 37 : 38 : private: 39 : const ConcreteAttributePath mPath; 40 : System::Clock::Timestamp mFlushTime; 41 : Platform::ScopedMemoryBufferWithSize<uint8_t> mValue; 42 : }; 43 : 44 : /** 45 : * Decorator class for the AttributePersistenceProvider implementation that 46 : * defers writes of selected attributes. 47 : * 48 : * This class is useful to increase the flash lifetime by reducing the number 49 : * of writes of fast-changing attributes, such as CurrentLevel attribute of the 50 : * LevelControl cluster. 51 : */ 52 : class DeferredAttributePersistenceProvider : public AttributePersistenceProvider 53 : { 54 : public: 55 : DeferredAttributePersistenceProvider(AttributePersistenceProvider & persister, 56 : const Span<DeferredAttribute> & deferredAttributes, 57 : System::Clock::Milliseconds32 writeDelay) : 58 : mPersister(persister), 59 : mDeferredAttributes(deferredAttributes), mWriteDelay(writeDelay) 60 : {} 61 : 62 : /* 63 : * If the written attribute is one of the deferred attributes specified in the constructor, 64 : * postpone the write operation by the configured delay. If this attribute changes within the 65 : * delay period, further postpone the operation so that the actual write happens once the 66 : * attribute has remained constant for the write delay period. 67 : * 68 : * For other attributes, immediately pass the write operation to the decorated persister. 69 : */ 70 : CHIP_ERROR WriteValue(const ConcreteAttributePath & aPath, const ByteSpan & aValue) override; 71 : CHIP_ERROR ReadValue(const ConcreteAttributePath & aPath, const EmberAfAttributeMetadata * aMetadata, 72 : MutableByteSpan & aValue) override; 73 : 74 : private: 75 : void FlushAndScheduleNext(); 76 : 77 : AttributePersistenceProvider & mPersister; 78 : const Span<DeferredAttribute> mDeferredAttributes; 79 : const System::Clock::Milliseconds32 mWriteDelay; 80 : }; 81 : 82 : } // namespace app 83 : } // namespace chip