3 * Copyright (c) 2020 Project CHIP Authors
4 * Copyright (c) 2016-2017 Nest Labs, Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 #include "PersistedCounter.h"
21 #include <platform/PersistedStorage.h>
22 #include <support/CodeUtils.h>
23 #include <support/logging/CHIPLogging.h>
30 PersistedCounter::PersistedCounter() : mId(chip::Platform::PersistedStorage::kEmptyKey), mEpoch(0), mNextEpoch(0) {}
32 PersistedCounter::~PersistedCounter() {}
35 PersistedCounter::Init(const chip::Platform::PersistedStorage::Key aId, uint32_t aEpoch)
37 CHIP_ERROR err = CHIP_NO_ERROR;
38 VerifyOrExit(aEpoch > 0, err = CHIP_ERROR_INVALID_INTEGER_VALUE);
46 // Read our previously-stored starting value.
47 err = ReadStartValue(startValue);
50 #if CHIP_CONFIG_PERSISTED_COUNTER_DEBUG_LOGGING
51 ChipLogDetail(EventLogging, "PersistedCounter::Init() aEpoch 0x%x startValue 0x%x", aEpoch, startValue);
54 err = PersistNextEpochStart(startValue + aEpoch);
57 // This will set the starting value, after which we're ready.
58 err = MonotonicallyIncreasingCounter::Init(startValue);
66 PersistedCounter::Advance()
68 CHIP_ERROR err = CHIP_NO_ERROR;
70 VerifyOrExit(mId != chip::Platform::PersistedStorage::kEmptyKey, err = CHIP_ERROR_INCORRECT_STATE);
72 err = MonotonicallyIncreasingCounter::Advance();
75 if (GetValue() >= mNextEpoch)
77 // Value advanced past the previously persisted "start point".
78 // Ensure that a new starting point is persisted.
79 err = PersistNextEpochStart(mNextEpoch + mEpoch);
82 // Advancing the epoch should have ensured that the current value
84 VerifyOrExit(GetValue() < mNextEpoch, err = CHIP_ERROR_INTERNAL);
91 PersistedCounter::PersistNextEpochStart(uint32_t aStartValue)
93 mNextEpoch = aStartValue;
94 #if CHIP_CONFIG_PERSISTED_COUNTER_DEBUG_LOGGING
95 ChipLogDetail(EventLogging, "PersistedCounter::WriteStartValue() aStartValue 0x%x", aStartValue);
98 return chip::Platform::PersistedStorage::Write(mId, aStartValue);
102 PersistedCounter::ReadStartValue(uint32_t & aStartValue)
104 CHIP_ERROR err = CHIP_NO_ERROR;
108 err = chip::Platform::PersistedStorage::Read(mId, aStartValue);
109 if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
111 // No previously-stored value, no worries, the counter is initialized to zero.
112 // Suppress the error.
120 #if CHIP_CONFIG_PERSISTED_COUNTER_DEBUG_LOGGING
121 ChipLogDetail(EventLogging, "PersistedCounter::ReadStartValue() aStartValue 0x%x", aStartValue);