Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2025 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 :
18 : #pragma once
19 :
20 : #include <app-common/zap-generated/cluster-objects.h>
21 : #include <app/data-model-provider/MetadataTypes.h>
22 : #include <credentials/CHIPCert.h>
23 : #include <functional>
24 : #include <lib/core/CHIPPersistentStorageDelegate.h>
25 : #include <lib/core/CHIPVendorIdentifiers.hpp>
26 : #include <lib/core/NodeId.h>
27 : #include <lib/support/ReadOnlyBuffer.h>
28 : #include <map>
29 : #include <unordered_map>
30 : #include <utility>
31 : #include <vector>
32 :
33 : namespace chip {
34 :
35 : // Forward declaration for friend class
36 : class JFAManager;
37 :
38 : namespace app {
39 :
40 : namespace datastore {
41 :
42 : struct AccessControlEntryStruct
43 : {
44 : Clusters::JointFabricDatastore::DatastoreAccessControlEntryPrivilegeEnum privilege =
45 : static_cast<Clusters::JointFabricDatastore::DatastoreAccessControlEntryPrivilegeEnum>(0);
46 : Clusters::JointFabricDatastore::DatastoreAccessControlEntryAuthModeEnum authMode =
47 : static_cast<Clusters::JointFabricDatastore::DatastoreAccessControlEntryAuthModeEnum>(0);
48 : std::vector<uint64_t> subjects;
49 : std::vector<Clusters::JointFabricDatastore::Structs::DatastoreAccessControlTargetStruct::Type> targets;
50 : };
51 :
52 : struct ACLEntryStruct
53 : {
54 : chip::NodeId nodeID = static_cast<chip::NodeId>(0);
55 : uint16_t listID = static_cast<uint16_t>(0);
56 : AccessControlEntryStruct ACLEntry;
57 : Clusters::JointFabricDatastore::Structs::DatastoreStatusEntryStruct::Type statusEntry;
58 : };
59 :
60 : } // namespace datastore
61 :
62 : enum RefreshState
63 : {
64 : kIdle,
65 : kRefreshingEndpoints,
66 : kRefreshingGroups,
67 : kRefreshingBindings,
68 : kFetchingGroupKeySetList,
69 : kFetchingGroupKeySets,
70 : kRefreshingGroupKeySets,
71 : kRefreshingACLs,
72 : };
73 :
74 : /**
75 : * A struct which extends the DatastoreNodeInformationEntry type with FriendlyName buffer reservation.
76 : */
77 : struct GenericDatastoreNodeInformationEntry
78 : : public Clusters::JointFabricDatastore::Structs::DatastoreNodeInformationEntryStruct::Type
79 : {
80 8 : GenericDatastoreNodeInformationEntry(NodeId nodeId = 0,
81 : Clusters::JointFabricDatastore::DatastoreStateEnum state =
82 : Clusters::JointFabricDatastore::DatastoreStateEnum::kUnknownEnumValue,
83 : Optional<CharSpan> label = NullOptional)
84 8 : {
85 8 : Set(nodeId, state, label);
86 8 : }
87 :
88 8 : GenericDatastoreNodeInformationEntry(const GenericDatastoreNodeInformationEntry & op) { *this = op; }
89 :
90 8 : GenericDatastoreNodeInformationEntry & operator=(const GenericDatastoreNodeInformationEntry & op)
91 : {
92 8 : Set(op.nodeID, op.commissioningStatusEntry.state, MakeOptional(op.friendlyName));
93 8 : return *this;
94 : }
95 :
96 16 : void Set(NodeId nodeId, Clusters::JointFabricDatastore::DatastoreStateEnum state, Optional<CharSpan> label = NullOptional)
97 : {
98 16 : this->nodeID = nodeId;
99 16 : this->commissioningStatusEntry.state = state;
100 16 : Set(label);
101 16 : }
102 :
103 17 : void Set(Optional<CharSpan> label = NullOptional)
104 : {
105 17 : if (label.HasValue())
106 : {
107 17 : memset(mFriendlyNameBuffer, 0, sizeof(mFriendlyNameBuffer));
108 17 : if (label.Value().size() > sizeof(mFriendlyNameBuffer))
109 : {
110 0 : memcpy(mFriendlyNameBuffer, label.Value().data(), sizeof(mFriendlyNameBuffer));
111 0 : this->friendlyName = CharSpan(mFriendlyNameBuffer, sizeof(mFriendlyNameBuffer));
112 : }
113 : else
114 : {
115 17 : memcpy(mFriendlyNameBuffer, label.Value().data(), label.Value().size());
116 17 : this->friendlyName = CharSpan(mFriendlyNameBuffer, label.Value().size());
117 : }
118 : }
119 : else
120 : {
121 0 : this->friendlyName = CharSpan();
122 : }
123 17 : }
124 :
125 : private:
126 : static constexpr size_t kFriendlyNameMaxSize = 32u;
127 :
128 : char mFriendlyNameBuffer[kFriendlyNameMaxSize];
129 : };
130 :
131 : class JointFabricDatastore
132 : {
133 : public:
134 : static JointFabricDatastore & GetInstance()
135 : {
136 : static JointFabricDatastore sInstance;
137 : return sInstance;
138 : }
139 :
140 : class Delegate
141 : {
142 : public:
143 9 : Delegate() {}
144 9 : virtual ~Delegate() {}
145 :
146 : virtual CHIP_ERROR
147 0 : SyncNode(NodeId nodeId,
148 : const Clusters::JointFabricDatastore::Structs::DatastoreEndpointGroupIDEntryStruct::Type & endpointGroupIDEntry,
149 : std::function<void()> onSuccess)
150 : {
151 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
152 : }
153 :
154 : virtual CHIP_ERROR
155 0 : SyncNode(NodeId nodeId,
156 : const Clusters::JointFabricDatastore::Structs::DatastoreNodeKeySetEntryStruct::Type & nodeKeySetEntry,
157 : std::function<void()> onSuccess)
158 : {
159 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
160 : }
161 :
162 : virtual CHIP_ERROR
163 0 : SyncNode(NodeId nodeId,
164 : const Clusters::JointFabricDatastore::Structs::DatastoreEndpointBindingEntryStruct::Type & bindingEntry,
165 : std::function<void()> onSuccess)
166 : {
167 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
168 : }
169 :
170 : virtual CHIP_ERROR
171 0 : SyncNode(NodeId nodeId,
172 : std::vector<Clusters::JointFabricDatastore::Structs::DatastoreEndpointBindingEntryStruct::Type> & bindingEntries,
173 : std::function<void()> onSuccess)
174 : {
175 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
176 : }
177 :
178 0 : virtual CHIP_ERROR SyncNode(NodeId nodeId,
179 : const Clusters::JointFabricDatastore::Structs::DatastoreACLEntryStruct::Type & aclEntry,
180 : std::function<void()> onSuccess)
181 : {
182 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
183 : }
184 :
185 : virtual CHIP_ERROR
186 0 : SyncNode(NodeId nodeId,
187 : const std::vector<app::Clusters::JointFabricDatastore::Structs::DatastoreACLEntryStruct::Type> & aclEntries,
188 : std::function<void()> onSuccess)
189 : {
190 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
191 : }
192 :
193 0 : virtual CHIP_ERROR SyncNode(NodeId nodeId,
194 : const Clusters::JointFabricDatastore::Structs::DatastoreGroupKeySetStruct::Type & groupKeySet,
195 : std::function<void()> onSuccess)
196 : {
197 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
198 : }
199 :
200 0 : virtual CHIP_ERROR FetchEndpointList(
201 : NodeId nodeId,
202 : std::function<void(CHIP_ERROR,
203 : const std::vector<Clusters::JointFabricDatastore::Structs::DatastoreEndpointEntryStruct::Type> &)>
204 : onSuccess)
205 : {
206 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
207 : }
208 :
209 0 : virtual CHIP_ERROR FetchEndpointGroupList(
210 : NodeId nodeId, EndpointId endpointId,
211 : std::function<
212 : void(CHIP_ERROR,
213 : const std::vector<Clusters::JointFabricDatastore::Structs::DatastoreGroupInformationEntryStruct::Type> &)>
214 : onSuccess)
215 : {
216 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
217 : }
218 :
219 0 : virtual CHIP_ERROR FetchEndpointBindingList(
220 : NodeId nodeId, EndpointId endpointId,
221 : std::function<
222 : void(CHIP_ERROR,
223 : const std::vector<Clusters::JointFabricDatastore::Structs::DatastoreEndpointBindingEntryStruct::Type> &)>
224 : onSuccess)
225 : {
226 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
227 : }
228 :
229 0 : virtual CHIP_ERROR FetchGroupKeySetList(NodeId nodeId,
230 : std::function<void(CHIP_ERROR, const std::vector<uint16_t> &)> onSuccess)
231 : {
232 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
233 : }
234 :
235 0 : virtual CHIP_ERROR FetchGroupKeySet(
236 : NodeId nodeId, uint16_t groupKeySetID,
237 : std::function<void(CHIP_ERROR, const app::Clusters::JointFabricDatastore::Structs::DatastoreGroupKeySetStruct::Type &)>
238 : onSuccess)
239 : {
240 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
241 : }
242 :
243 0 : virtual CHIP_ERROR FetchACLList(
244 : NodeId nodeId,
245 : std::function<void(CHIP_ERROR,
246 : const std::vector<Clusters::JointFabricDatastore::Structs::DatastoreACLEntryStruct::Type> &)>
247 : onSuccess)
248 : {
249 0 : return CHIP_ERROR_NOT_IMPLEMENTED;
250 : }
251 : };
252 :
253 : CHIP_ERROR SetAnchorRootCA(const ByteSpan & anchorRootCA)
254 : {
255 : if (anchorRootCA.size() >= sizeof(mAnchorRootCA))
256 : {
257 : return CHIP_ERROR_INVALID_ARGUMENT;
258 : }
259 : mAnchorRootCALength = anchorRootCA.size();
260 : memcpy(mAnchorRootCA, anchorRootCA.data(), mAnchorRootCALength);
261 : return CHIP_NO_ERROR;
262 : }
263 : ByteSpan GetAnchorRootCA() const { return ByteSpan(mAnchorRootCA, mAnchorRootCALength); }
264 :
265 : CHIP_ERROR SetAnchorNodeId(NodeId anchorNodeId)
266 : {
267 : mAnchorNodeId = anchorNodeId;
268 : return CHIP_NO_ERROR;
269 : }
270 : NodeId GetAnchorNodeId() { return mAnchorNodeId; }
271 :
272 : CHIP_ERROR SetAnchorVendorId(VendorId anchorVendorId)
273 : {
274 : mAnchorVendorId = anchorVendorId;
275 : return CHIP_NO_ERROR;
276 : }
277 : VendorId GetAnchorVendorId() { return mAnchorVendorId; }
278 :
279 : CHIP_ERROR SetFriendlyName(const CharSpan & friendlyName)
280 : {
281 : if (friendlyName.size() >= sizeof(mFriendlyNameBuffer))
282 : {
283 : return CHIP_ERROR_INVALID_ARGUMENT;
284 : }
285 : mFriendlyNameBufferLength = friendlyName.size();
286 : memcpy(mFriendlyNameBuffer, friendlyName.data(), mFriendlyNameBufferLength);
287 : mFriendlyNameBuffer[mFriendlyNameBufferLength] = '\0'; // Ensure null-termination
288 : return CHIP_NO_ERROR;
289 : }
290 : CharSpan GetFriendlyName() const { return CharSpan(mFriendlyNameBuffer, mFriendlyNameBufferLength); }
291 :
292 2 : const std::vector<Clusters::JointFabricDatastore::Structs::DatastoreGroupInformationEntryStruct::Type> & GetGroupEntries()
293 : {
294 2 : return mGroupInformationEntries;
295 : }
296 :
297 : void SetStatus(Clusters::JointFabricDatastore::DatastoreStateEnum state, uint32_t updateTimestamp, uint8_t failureCode)
298 : {
299 : mDatastoreStatusEntry.state = state;
300 : mDatastoreStatusEntry.updateTimestamp = updateTimestamp;
301 : mDatastoreStatusEntry.failureCode = failureCode;
302 : }
303 : Clusters::JointFabricDatastore::Structs::DatastoreStatusEntryStruct::Type & GetStatus() { return mDatastoreStatusEntry; }
304 :
305 2 : std::vector<Clusters::JointFabricDatastore::Structs::DatastoreEndpointGroupIDEntryStruct::Type> & GetEndpointGroupIDList()
306 : {
307 2 : return mEndpointGroupIDEntries;
308 : }
309 :
310 5 : std::vector<Clusters::JointFabricDatastore::Structs::DatastoreEndpointBindingEntryStruct::Type> & GetEndpointBindingList()
311 : {
312 5 : return mEndpointBindingEntries;
313 : }
314 :
315 2 : std::vector<Clusters::JointFabricDatastore::Structs::DatastoreNodeKeySetEntryStruct::Type> & GetNodeKeySetList()
316 : {
317 2 : return mNodeKeySetEntries;
318 : }
319 :
320 5 : std::vector<datastore::ACLEntryStruct> & GetNodeACLList() { return mACLEntries; }
321 :
322 3 : std::vector<Clusters::JointFabricDatastore::Structs::DatastoreEndpointEntryStruct::Type> & GetNodeEndpointList()
323 : {
324 3 : return mEndpointEntries;
325 : }
326 :
327 : CHIP_ERROR AddPendingNode(NodeId nodeId, const CharSpan & friendlyName);
328 : CHIP_ERROR UpdateNode(NodeId nodeId, const CharSpan & friendlyName);
329 : CHIP_ERROR RemoveNode(NodeId nodeId);
330 : CHIP_ERROR RefreshNode(NodeId nodeId);
331 : CHIP_ERROR ContinueRefresh();
332 :
333 : CHIP_ERROR SetNode(NodeId nodeId, Clusters::JointFabricDatastore::DatastoreStateEnum state);
334 :
335 : CHIP_ERROR AddGroupKeySetEntry(const Clusters::JointFabricDatastore::Structs::DatastoreGroupKeySetStruct::Type & groupKeySet);
336 : bool IsGroupKeySetEntryPresent(uint16_t groupKeySetId);
337 : CHIP_ERROR RemoveGroupKeySetEntry(uint16_t groupKeySetId);
338 : CHIP_ERROR UpdateGroupKeySetEntry(Clusters::JointFabricDatastore::Structs::DatastoreGroupKeySetStruct::Type & groupKeySet);
339 :
340 : CHIP_ERROR
341 : AddAdmin(const Clusters::JointFabricDatastore::Structs::DatastoreAdministratorInformationEntryStruct::Type & adminId);
342 : bool IsAdminEntryPresent(NodeId nodeId);
343 : CHIP_ERROR UpdateAdmin(NodeId nodeId, Optional<CharSpan> friendlyName, Optional<ByteSpan> icac);
344 : CHIP_ERROR RemoveAdmin(NodeId nodeId);
345 :
346 : CHIP_ERROR AddGroup(const Clusters::JointFabricDatastore::Commands::AddGroup::DecodableType & commandData);
347 : CHIP_ERROR UpdateGroup(const Clusters::JointFabricDatastore::Commands::UpdateGroup::DecodableType & commandData);
348 : CHIP_ERROR RemoveGroup(const Clusters::JointFabricDatastore::Commands::RemoveGroup::DecodableType & commandData);
349 :
350 : CHIP_ERROR UpdateEndpointForNode(NodeId nodeId, EndpointId endpointId, CharSpan friendlyName);
351 :
352 : CHIP_ERROR AddGroupIDToEndpointForNode(NodeId nodeId, EndpointId endpointId, GroupId groupId);
353 : CHIP_ERROR RemoveGroupIDFromEndpointForNode(NodeId nodeId, EndpointId endpointId, GroupId groupId);
354 :
355 : CHIP_ERROR
356 : AddBindingToEndpointForNode(NodeId nodeId, EndpointId endpointId,
357 : const Clusters::JointFabricDatastore::Structs::DatastoreBindingTargetStruct::Type & binding);
358 : CHIP_ERROR
359 : RemoveBindingFromEndpointForNode(uint16_t listId, NodeId nodeId, EndpointId endpointId);
360 :
361 : CHIP_ERROR
362 : AddACLToNode(NodeId nodeId,
363 : const Clusters::JointFabricDatastore::Structs::DatastoreAccessControlEntryStruct::DecodableType & aclEntry);
364 : CHIP_ERROR RemoveACLFromNode(uint16_t listId, NodeId nodeId);
365 :
366 : CHIP_ERROR TestAddNodeKeySetEntry(GroupId groupId, uint16_t groupKeySetId, NodeId nodeId);
367 : CHIP_ERROR TestAddEndpointEntry(EndpointId endpointId, NodeId nodeId, CharSpan friendlyName);
368 :
369 : CHIP_ERROR ForceAddNodeKeySetEntry(uint16_t groupKeySetId, NodeId nodeId);
370 :
371 4 : const std::vector<Clusters::JointFabricDatastore::Structs::DatastoreGroupKeySetStruct::Type> & GetGroupKeySetList()
372 : {
373 4 : return mGroupKeySetList;
374 : }
375 4 : const std::vector<GenericDatastoreNodeInformationEntry> & GetNodeInformationEntries() { return mNodeInformationEntries; }
376 : const std::vector<Clusters::JointFabricDatastore::Structs::DatastoreAdministratorInformationEntryStruct::Type> &
377 4 : GetAdminEntries()
378 : {
379 4 : return mAdminEntries;
380 : }
381 :
382 : /**
383 : * Used to notify of changes in the node list and more TODO.
384 : */
385 : class Listener
386 : {
387 : public:
388 3 : virtual ~Listener() = default;
389 :
390 : /**
391 : * Notifies of a change in the node list.
392 : */
393 : virtual void MarkNodeListChanged() = 0;
394 :
395 : private:
396 : Listener * mNext = nullptr;
397 :
398 : friend class JointFabricDatastore;
399 : };
400 :
401 : /**
402 : * Add a listener to be notified of changes in the Joint Fabric Datastore.
403 : *
404 : * @param [in] listener The listener to add.
405 : */
406 : void AddListener(Listener & listener);
407 :
408 : /**
409 : * Remove a listener from being notified of changes in the Joint Fabric Datastore.
410 : *
411 : * @param [in] listener The listener to remove.
412 : */
413 : void RemoveListener(Listener & listener);
414 :
415 9 : CHIP_ERROR SetDelegate(Delegate * delegate)
416 : {
417 9 : VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
418 9 : mDelegate = delegate;
419 :
420 9 : return CHIP_NO_ERROR;
421 : }
422 :
423 : private:
424 : struct GroupKeySetStorage
425 : {
426 : std::vector<uint8_t> epochKey0;
427 : std::vector<uint8_t> epochKey1;
428 : std::vector<uint8_t> epochKey2;
429 : };
430 :
431 : struct GroupInformationStorage
432 : {
433 : // Friendly names are surfaced as CharSpan and may come from non-null-terminated buffers.
434 : // Keep raw owned bytes in vector<char> to preserve exact length semantics for Span use.
435 : std::vector<char> friendlyName;
436 : };
437 :
438 : struct AdminEntryStorage
439 : {
440 : // Friendly names are stored as owned raw bytes for CharSpan (not C-string) semantics.
441 : std::vector<char> friendlyName;
442 : std::vector<uint8_t> icac;
443 : };
444 :
445 : static constexpr size_t kMaxNodes = 256;
446 : static constexpr size_t kMaxAdminNodes = 32;
447 : static constexpr size_t kMaxGroups = kMaxNodes / 16;
448 : static constexpr size_t kMaxGroupKeySet = kMaxGroups * 16;
449 : static constexpr size_t kMaxFriendlyNameSize = 32;
450 : static constexpr size_t kMaxACLs = 64;
451 :
452 : uint8_t mAnchorRootCA[Credentials::kMaxDERCertLength] = { 0 };
453 : size_t mAnchorRootCALength = 0;
454 : char mFriendlyNameBuffer[kMaxFriendlyNameSize] = { 0 };
455 : size_t mFriendlyNameBufferLength = 0;
456 : NodeId mAnchorNodeId = kUndefinedNodeId;
457 : VendorId mAnchorVendorId = VendorId::NotSpecified;
458 : Clusters::JointFabricDatastore::Structs::DatastoreStatusEntryStruct::Type mDatastoreStatusEntry;
459 :
460 : // TODO: Persist these members to local storage
461 : std::vector<GenericDatastoreNodeInformationEntry> mNodeInformationEntries;
462 : std::vector<Clusters::JointFabricDatastore::Structs::DatastoreGroupKeySetStruct::Type> mGroupKeySetList;
463 : std::unordered_map<uint16_t, GroupKeySetStorage> mGroupKeySetStorage;
464 : std::vector<Clusters::JointFabricDatastore::Structs::DatastoreAdministratorInformationEntryStruct::Type> mAdminEntries;
465 : std::unordered_map<NodeId, AdminEntryStorage> mAdminEntryStorage;
466 : std::vector<Clusters::JointFabricDatastore::Structs::DatastoreGroupInformationEntryStruct::Type> mGroupInformationEntries;
467 : std::unordered_map<GroupId, GroupInformationStorage> mGroupInformationStorage;
468 : std::vector<Clusters::JointFabricDatastore::Structs::DatastoreEndpointGroupIDEntryStruct::Type> mEndpointGroupIDEntries;
469 : std::vector<Clusters::JointFabricDatastore::Structs::DatastoreEndpointBindingEntryStruct::Type> mEndpointBindingEntries;
470 : std::vector<Clusters::JointFabricDatastore::Structs::DatastoreNodeKeySetEntryStruct::Type> mNodeKeySetEntries;
471 : std::vector<datastore::ACLEntryStruct> mACLEntries;
472 : std::vector<Clusters::JointFabricDatastore::Structs::DatastoreEndpointEntryStruct::Type> mEndpointEntries;
473 : std::map<std::pair<NodeId, EndpointId>, std::vector<char>> mEndpointFriendlyNameStorage;
474 :
475 : Listener * mListeners = nullptr;
476 :
477 : friend class chip::JFAManager;
478 :
479 : CHIP_ERROR
480 : ForceAddGroup(const Clusters::JointFabricDatastore::Commands::AddGroup::DecodableType & commandData);
481 :
482 : CHIP_ERROR IsNodeIDInDatastore(NodeId nodeId, size_t & index);
483 :
484 : CHIP_ERROR UpdateNodeKeySetList(Clusters::JointFabricDatastore::Structs::DatastoreGroupKeySetStruct::Type & groupKeySet);
485 : CHIP_ERROR RemoveKeySet(uint16_t groupKeySetId);
486 :
487 : CHIP_ERROR IsGroupIDInDatastore(GroupId groupId, size_t & index);
488 : CHIP_ERROR IsNodeIdInNodeInformationEntries(NodeId nodeId, size_t & index);
489 : CHIP_ERROR IsNodeIdAndEndpointInEndpointInformationEntries(NodeId nodeId, EndpointId endpointId, size_t & index);
490 :
491 : CHIP_ERROR GenerateAndAssignAUniqueListID(uint16_t & listId);
492 : bool BindingMatches(const Clusters::JointFabricDatastore::Structs::DatastoreBindingTargetStruct::Type & binding1,
493 : const Clusters::JointFabricDatastore::Structs::DatastoreBindingTargetStruct::Type & binding2);
494 : bool ACLMatches(const datastore::AccessControlEntryStruct & acl1,
495 : const Clusters::JointFabricDatastore::Structs::DatastoreAccessControlEntryStruct::DecodableType & acl2);
496 : bool ACLTargetMatches(const Clusters::JointFabricDatastore::Structs::DatastoreAccessControlTargetStruct::Type & target1,
497 : const Clusters::JointFabricDatastore::Structs::DatastoreAccessControlTargetStruct::Type & target2);
498 :
499 : CHIP_ERROR AddNodeKeySetEntry(GroupId groupId, uint16_t groupKeySetId);
500 : CHIP_ERROR RemoveNodeKeySetEntry(GroupId groupId, uint16_t groupKeySetId);
501 :
502 : void CopyGroupKeySetWithOwnedSpans(const Clusters::JointFabricDatastore::Structs::DatastoreGroupKeySetStruct::Type & source,
503 : Clusters::JointFabricDatastore::Structs::DatastoreGroupKeySetStruct::Type & destination);
504 : void RemoveGroupKeySetStorage(uint16_t groupKeySetId);
505 :
506 : void SetGroupInformationFriendlyNameWithOwnedStorage(
507 : GroupId groupId, const CharSpan & friendlyName,
508 : Clusters::JointFabricDatastore::Structs::DatastoreGroupInformationEntryStruct::Type & destination);
509 : void RemoveGroupInformationStorage(GroupId groupId);
510 :
511 : CHIP_ERROR SetAdminEntryWithOwnedStorage(
512 : NodeId nodeId, const CharSpan & friendlyName, const ByteSpan & icac,
513 : Clusters::JointFabricDatastore::Structs::DatastoreAdministratorInformationEntryStruct::Type & destination);
514 : void RemoveAdminEntryStorage(NodeId nodeId);
515 :
516 : void SetEndpointFriendlyNameWithOwnedStorage(
517 : NodeId nodeId, EndpointId endpointId, const CharSpan & friendlyName,
518 : Clusters::JointFabricDatastore::Structs::DatastoreEndpointEntryStruct::Type & destination);
519 : void RemoveEndpointFriendlyNameStorage(NodeId nodeId, EndpointId endpointId);
520 :
521 : // Helper methods for copying optional ByteSpan and simple nullable values
522 : void CopyByteSpanWithOwnedStorage(const DataModel::Nullable<ByteSpan> & source, std::vector<uint8_t> & storage,
523 : DataModel::Nullable<ByteSpan> & destination);
524 :
525 : template <typename T>
526 6 : void CopyNullableValue(const DataModel::Nullable<T> & source, DataModel::Nullable<T> & destination)
527 : {
528 : // Only update destination if source has a value; leave destination unchanged if source is null.
529 6 : if (!source.IsNull())
530 : {
531 0 : static_cast<void>(destination.Update(source));
532 : }
533 6 : }
534 :
535 : Delegate * mDelegate = nullptr;
536 :
537 : NodeId mRefreshingNodeId = kUndefinedNodeId;
538 : RefreshState mRefreshState = kIdle;
539 : size_t mRefreshingEndpointIndex = 0;
540 : size_t mRefreshingGroupKeySetIndex = 0;
541 :
542 : std::vector<Clusters::JointFabricDatastore::Structs::DatastoreEndpointEntryStruct::Type> mRefreshingEndpointsList;
543 : std::vector<Clusters::JointFabricDatastore::Structs::DatastoreEndpointBindingEntryStruct::Type> mRefreshingBindingEntries;
544 : std::vector<Clusters::JointFabricDatastore::Structs::DatastoreACLEntryStruct::Type> mRefreshingACLEntries;
545 : std::vector<uint16_t> mRefreshingGroupKeySetIDs;
546 : };
547 :
548 : } // namespace app
549 : } // namespace chip
|