Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2021-2024 Project CHIP Authors
4 : *
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * You may obtain a copy of the License at
8 : *
9 : * http://www.apache.org/licenses/LICENSE-2.0
10 : *
11 : * Unless required by applicable law or agreed to in writing, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 : #pragma once
18 :
19 : #include <lib/core/CHIPPersistentStorageDelegate.h>
20 : #include <lib/core/DataModelTypes.h>
21 : #include <lib/support/CHIPMemString.h>
22 :
23 : #include <stdio.h>
24 :
25 : namespace chip {
26 :
27 : /**
28 : * Represents a key used for addressing a specific storage element.
29 : *
30 : * May contain generic fixed keys (e.g. "g/fidx") or formatted fabric-specific
31 : * keys ("f/%x/..." where %x is the fabric index).
32 : */
33 : class StorageKeyName
34 : {
35 : public:
36 : StorageKeyName(const StorageKeyName & other) = default;
37 : StorageKeyName & operator=(const StorageKeyName & other) = default;
38 :
39 28404 : ~StorageKeyName() { memset(mKeyNameBuffer, 0, sizeof(mKeyNameBuffer)); }
40 :
41 22592 : const char * KeyName() const { return mKeyNameBuffer; }
42 :
43 2 : bool IsInitialized() const { return mKeyNameBuffer[0] != 0; }
44 4945 : bool IsUninitialized() const { return mKeyNameBuffer[0] == 0; }
45 4945 : bool operator!() const { return IsUninitialized(); }
46 :
47 7870 : static StorageKeyName FromConst(const char * value)
48 : {
49 7870 : StorageKeyName result;
50 7870 : Platform::CopyString(result.mKeyNameBuffer, value);
51 7870 : return result;
52 : }
53 :
54 16841 : static StorageKeyName ENFORCE_FORMAT(1, 2) Formatted(const char * format, ...)
55 : {
56 16841 : StorageKeyName result;
57 :
58 : va_list args;
59 16841 : va_start(args, format);
60 16841 : vsnprintf(result.mKeyNameBuffer, sizeof(result.mKeyNameBuffer), format, args);
61 16841 : va_end(args);
62 :
63 16841 : return result;
64 : }
65 :
66 : // Explicit 0-filled key. MUST be initialized later
67 2813 : static StorageKeyName Uninitialized()
68 : {
69 2813 : StorageKeyName result;
70 2813 : return result;
71 : }
72 :
73 : private:
74 : // May only be created by the underlying constructor methods
75 30449 : StorageKeyName() {}
76 :
77 : // Contains the storage for the key name because some strings may be formatted.
78 : char mKeyNameBuffer[PersistentStorageDelegate::kKeyLengthMax + 1] = { 0 };
79 : };
80 :
81 : /**
82 : * This is the common key allocation policy for all classes using
83 : * PersistentStorageDelegate storage.
84 : *
85 : * Keys should have the following formats:
86 : *
87 : * * Keys that are not tied to a specific fabric: "g/....".
88 : * * Keys that are tied to a specific fabric: "f/%x/...." where the %x gets
89 : * replaced by the fabric index.
90 : */
91 : class DefaultStorageKeyAllocator
92 : {
93 : private:
94 : DefaultStorageKeyAllocator() = default;
95 :
96 : public:
97 : // Fabric Table
98 1192 : static StorageKeyName FabricIndexInfo() { return StorageKeyName::FromConst("g/fidx"); }
99 1597 : static StorageKeyName FabricNOC(FabricIndex fabric) { return StorageKeyName::Formatted("f/%x/n", fabric); }
100 1564 : static StorageKeyName FabricICAC(FabricIndex fabric) { return StorageKeyName::Formatted("f/%x/i", fabric); }
101 1602 : static StorageKeyName FabricRCAC(FabricIndex fabric) { return StorageKeyName::Formatted("f/%x/r", fabric); }
102 36 : static StorageKeyName FabricVVSC(FabricIndex fabric) { return StorageKeyName::Formatted("f/%x/vvsc", fabric); }
103 38 : static StorageKeyName FabricVidVerificationStatement(FabricIndex fabric)
104 : {
105 38 : return StorageKeyName::Formatted("f/%x/vvs", fabric);
106 : }
107 779 : static StorageKeyName FabricMetadata(FabricIndex fabric) { return StorageKeyName::Formatted("f/%x/m", fabric); }
108 811 : static StorageKeyName FabricOpKey(FabricIndex fabric) { return StorageKeyName::Formatted("f/%x/o", fabric); }
109 :
110 : // Fail-safe handling
111 1924 : static StorageKeyName FabricTableCommitMarkerKey() { return StorageKeyName::FromConst("g/fs/c"); }
112 : static StorageKeyName FailSafeNetworkConfig() { return StorageKeyName::FromConst("g/fs/n"); }
113 :
114 : // LastKnownGoodTime
115 2058 : static StorageKeyName LastKnownGoodTimeKey() { return StorageKeyName::FromConst("g/lkgt"); }
116 :
117 : // Session resumption
118 879 : static StorageKeyName FabricSession(FabricIndex fabric, NodeId nodeId)
119 : {
120 879 : return StorageKeyName::Formatted("f/%x/s/%08" PRIX32 "%08" PRIX32, fabric, static_cast<uint32_t>(nodeId >> 32),
121 879 : static_cast<uint32_t>(nodeId));
122 : }
123 :
124 496 : static StorageKeyName SessionResumptionIndex() { return StorageKeyName::FromConst("g/sri"); }
125 683 : static StorageKeyName SessionResumption(const char * resumptionIdBase64)
126 : {
127 683 : return StorageKeyName::Formatted("g/s/%s", resumptionIdBase64);
128 : }
129 :
130 : // Access Control
131 0 : static StorageKeyName AccessControlAclEntry(FabricIndex fabric, size_t index)
132 : {
133 0 : return StorageKeyName::Formatted("f/%x/ac/0/%x", fabric, static_cast<unsigned>(index));
134 : }
135 :
136 0 : static StorageKeyName AccessControlExtensionEntry(FabricIndex fabric) { return StorageKeyName::Formatted("f/%x/ac/1", fabric); }
137 :
138 : // Group Message Counters
139 787 : static StorageKeyName GroupDataCounter() { return StorageKeyName::FromConst("g/gdc"); }
140 786 : static StorageKeyName GroupControlCounter() { return StorageKeyName::FromConst("g/gcc"); }
141 :
142 : // ICD Check-In Counter
143 : static StorageKeyName ICDCheckInCounter() { return StorageKeyName::FromConst("g/icd/cic"); }
144 :
145 : // Device Information Provider
146 : static StorageKeyName UserLabelLengthKey(EndpointId endpoint) { return StorageKeyName::Formatted("g/userlbl/%x", endpoint); }
147 : static StorageKeyName UserLabelIndexKey(EndpointId endpoint, uint32_t index)
148 : {
149 : return StorageKeyName::Formatted("g/userlbl/%x/%" PRIx32, endpoint, index);
150 : }
151 :
152 : // Group Data Provider
153 :
154 : // List of fabric indices that have endpoint-to-group associations defined.
155 386 : static StorageKeyName GroupFabricList() { return StorageKeyName::FromConst("g/gfl"); }
156 1364 : static StorageKeyName FabricGroups(chip::FabricIndex fabric) { return StorageKeyName::Formatted("f/%x/g", fabric); }
157 906 : static StorageKeyName FabricGroup(chip::FabricIndex fabric, chip::GroupId group)
158 : {
159 906 : return StorageKeyName::Formatted("f/%x/g/%x", fabric, group);
160 : }
161 526 : static StorageKeyName FabricGroupKey(chip::FabricIndex fabric, uint16_t index)
162 : {
163 526 : return StorageKeyName::Formatted("f/%x/gk/%x", fabric, index);
164 : }
165 415 : static StorageKeyName FabricGroupEndpoint(chip::FabricIndex fabric, chip::GroupId group, chip::EndpointId endpoint)
166 : {
167 415 : return StorageKeyName::Formatted("f/%x/g/%x/e/%x", fabric, group, endpoint);
168 : }
169 387 : static StorageKeyName FabricKeyset(chip::FabricIndex fabric, uint16_t keyset)
170 : {
171 387 : return StorageKeyName::Formatted("f/%x/k/%x", fabric, keyset);
172 : }
173 :
174 0 : static StorageKeyName AttributeValue(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId)
175 : {
176 : // Needs at most 26 chars: 6 for "g/a///", 4 for the endpoint id, 8 each
177 : // for the cluster and attribute ids.
178 0 : return StorageKeyName::Formatted("g/a/%x/%" PRIx32 "/%" PRIx32, endpointId, clusterId, attributeId);
179 : }
180 :
181 : // Returns the key for Safely stored attributes.
182 0 : static StorageKeyName SafeAttributeValue(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId)
183 : {
184 : // Needs at most 26 chars: 6 for "s/a///", 4 for the endpoint id, 8 each
185 : // for the cluster and attribute ids.
186 0 : return StorageKeyName::Formatted("g/sa/%x/%" PRIx32 "/%" PRIx32, endpointId, clusterId, attributeId);
187 : }
188 :
189 : // TODO: Should store fabric-specific parts of the binding list under keys
190 : // starting with "f/%x/".
191 37 : static StorageKeyName BindingTable() { return StorageKeyName::FromConst("g/bt"); }
192 218 : static StorageKeyName BindingTableEntry(uint8_t index) { return StorageKeyName::Formatted("g/bt/%x", index); }
193 :
194 : // ICD Management
195 :
196 44 : static StorageKeyName ICDManagementTableEntry(chip::FabricIndex fabric, uint16_t index)
197 : {
198 44 : return StorageKeyName::Formatted("f/%x/icd/%x", fabric, index);
199 : }
200 :
201 : // Thread Network Directory
202 :
203 : static StorageKeyName ThreadNetworkDirectoryIndex() { return StorageKeyName::FromConst("g/tnd/i"); }
204 : static StorageKeyName ThreadNetworkDirectoryDataset(uint64_t extendedPanId)
205 : {
206 : return StorageKeyName::Formatted("g/tnd/n/%08" PRIx32 "%08" PRIx32, // some platforms can't format uint64
207 : static_cast<uint32_t>(extendedPanId >> 32), static_cast<uint32_t>(extendedPanId));
208 : }
209 :
210 : // OTA
211 :
212 : static StorageKeyName OTADefaultProviders() { return StorageKeyName::FromConst("g/o/dp"); }
213 : static StorageKeyName OTACurrentProvider() { return StorageKeyName::FromConst("g/o/cp"); }
214 : static StorageKeyName OTAUpdateToken() { return StorageKeyName::FromConst("g/o/ut"); }
215 : static StorageKeyName OTACurrentUpdateState() { return StorageKeyName::FromConst("g/o/us"); }
216 : static StorageKeyName OTATargetVersion() { return StorageKeyName::FromConst("g/o/tv"); }
217 :
218 : // Event number counter.
219 1 : static StorageKeyName IMEventNumber() { return StorageKeyName::FromConst("g/im/ec"); }
220 :
221 : // Subscription resumption
222 440 : static StorageKeyName SubscriptionResumption(size_t index)
223 : {
224 440 : return StorageKeyName::Formatted("g/su/%x", static_cast<unsigned>(index));
225 : }
226 5 : static StorageKeyName SubscriptionResumptionMaxCount() { return StorageKeyName::Formatted("g/sum"); }
227 :
228 : // Number of scenes stored in a given endpoint's scene table, across all fabrics.
229 : static StorageKeyName EndpointSceneCountKey(EndpointId endpoint) { return StorageKeyName::Formatted("g/scc/e/%x", endpoint); }
230 :
231 : // Stores the scene count for a fabric for the given endpoint and a map between scene storage ids (<sceneId, groupId>) and
232 : // sceneIndex for a specific Fabric and endpoint.
233 : static StorageKeyName FabricSceneDataKey(FabricIndex fabric, EndpointId endpoint)
234 : {
235 : return StorageKeyName::Formatted("f/%x/e/%x/sc", fabric, endpoint);
236 : }
237 :
238 : // Stores the actual scene data for a given scene on a given endpoint for a particular fabric.
239 : // idx corresponds to the indices read from FabricSceneDataKey.
240 : // SceneIndex
241 : static StorageKeyName FabricSceneKey(FabricIndex fabric, EndpointId endpoint, uint16_t idx)
242 : {
243 : return StorageKeyName::Formatted("f/%x/e/%x/sc/%x", fabric, endpoint, idx);
244 : }
245 :
246 : // Time synchronization cluster
247 : static StorageKeyName TSTrustedTimeSource() { return StorageKeyName::FromConst("g/ts/tts"); }
248 : static StorageKeyName TSDefaultNTP() { return StorageKeyName::FromConst("g/ts/dntp"); }
249 : static StorageKeyName TSTimeZone() { return StorageKeyName::FromConst("g/ts/tz"); }
250 : static StorageKeyName TSDSTOffset() { return StorageKeyName::FromConst("g/ts/dsto"); }
251 :
252 : // FabricICDClientInfoCounter is only used by DefaultICDClientStorage
253 : // Records the number of ClientInfos for a particular fabric
254 144 : static StorageKeyName FabricICDClientInfoCounter(FabricIndex fabric) { return StorageKeyName::Formatted("f/%x/icdc", fabric); }
255 :
256 : // ICDClientInfoKey is only used by DefaultICDClientStorage
257 : // Stores/Loads all ICD clientInfos for a particular fabric
258 84 : static StorageKeyName ICDClientInfoKey(FabricIndex fabric) { return StorageKeyName::Formatted("f/%x/icdk", fabric); }
259 :
260 : // ICDFabricList is only used by DefaultICDClientStorage
261 : // when new fabric is created, this list needs to be updated,
262 : // when client init DefaultICDClientStorage, this table needs to be loaded.
263 31 : static StorageKeyName ICDFabricList() { return StorageKeyName::FromConst("g/icdfl"); }
264 :
265 : // Terms and Conditions Acceptance Key
266 : // Stores the terms and conditions acceptance including terms and conditions revision, TLV encoded
267 11 : static StorageKeyName TermsAndConditionsAcceptance() { return StorageKeyName::FromConst("g/tc"); }
268 : };
269 :
270 : } // namespace chip
|