Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / lib / support / PersistedCounter.cpp
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    Copyright (c) 2016-2017 Nest Labs, Inc.
5  *    All rights reserved.
6  *
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
10  *
11  *        http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19 #include "PersistedCounter.h"
20
21 #include <platform/PersistedStorage.h>
22 #include <support/CodeUtils.h>
23 #include <support/logging/CHIPLogging.h>
24
25 #include <stdlib.h>
26 #include <string.h>
27
28 namespace chip {
29
30 PersistedCounter::PersistedCounter() : mId(chip::Platform::PersistedStorage::kEmptyKey), mEpoch(0), mNextEpoch(0) {}
31
32 PersistedCounter::~PersistedCounter() {}
33
34 CHIP_ERROR
35 PersistedCounter::Init(const chip::Platform::PersistedStorage::Key aId, uint32_t aEpoch)
36 {
37     CHIP_ERROR err = CHIP_NO_ERROR;
38     VerifyOrExit(aEpoch > 0, err = CHIP_ERROR_INVALID_INTEGER_VALUE);
39
40     // Store the ID.
41     mId    = aId;
42     mEpoch = aEpoch;
43
44     uint32_t startValue;
45
46     // Read our previously-stored starting value.
47     err = ReadStartValue(startValue);
48     SuccessOrExit(err);
49
50 #if CHIP_CONFIG_PERSISTED_COUNTER_DEBUG_LOGGING
51     ChipLogDetail(EventLogging, "PersistedCounter::Init() aEpoch 0x%x startValue 0x%x", aEpoch, startValue);
52 #endif
53
54     err = PersistNextEpochStart(startValue + aEpoch);
55     SuccessOrExit(err);
56
57     // This will set the starting value, after which we're ready.
58     err = MonotonicallyIncreasingCounter::Init(startValue);
59     SuccessOrExit(err);
60
61 exit:
62     return err;
63 }
64
65 CHIP_ERROR
66 PersistedCounter::Advance()
67 {
68     CHIP_ERROR err = CHIP_NO_ERROR;
69
70     VerifyOrExit(mId != chip::Platform::PersistedStorage::kEmptyKey, err = CHIP_ERROR_INCORRECT_STATE);
71
72     err = MonotonicallyIncreasingCounter::Advance();
73     SuccessOrExit(err);
74
75     if (GetValue() >= mNextEpoch)
76     {
77         // Value advanced past the previously persisted "start point".
78         // Ensure that a new starting point is persisted.
79         err = PersistNextEpochStart(mNextEpoch + mEpoch);
80         SuccessOrExit(err);
81
82         // Advancing the epoch should have ensured that the current value
83         // is valid
84         VerifyOrExit(GetValue() < mNextEpoch, err = CHIP_ERROR_INTERNAL);
85     }
86 exit:
87     return err;
88 }
89
90 CHIP_ERROR
91 PersistedCounter::PersistNextEpochStart(uint32_t aStartValue)
92 {
93     mNextEpoch = aStartValue;
94 #if CHIP_CONFIG_PERSISTED_COUNTER_DEBUG_LOGGING
95     ChipLogDetail(EventLogging, "PersistedCounter::WriteStartValue() aStartValue 0x%x", aStartValue);
96 #endif
97
98     return chip::Platform::PersistedStorage::Write(mId, aStartValue);
99 }
100
101 CHIP_ERROR
102 PersistedCounter::ReadStartValue(uint32_t & aStartValue)
103 {
104     CHIP_ERROR err = CHIP_NO_ERROR;
105
106     aStartValue = 0;
107
108     err = chip::Platform::PersistedStorage::Read(mId, aStartValue);
109     if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
110     {
111         // No previously-stored value, no worries, the counter is initialized to zero.
112         // Suppress the error.
113         err = CHIP_NO_ERROR;
114     }
115     else
116     {
117         SuccessOrExit(err);
118     }
119
120 #if CHIP_CONFIG_PERSISTED_COUNTER_DEBUG_LOGGING
121     ChipLogDetail(EventLogging, "PersistedCounter::ReadStartValue() aStartValue 0x%x", aStartValue);
122 #endif
123
124 exit:
125     return err;
126 }
127
128 } // namespace chip