diff --git a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp index db51829d763a07..7b78ce16ab832e 100644 --- a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp +++ b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp @@ -343,20 +343,12 @@ void OnPlatformEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, in // As per specifications section 11.22.5.1. Constant RESP_MAX constexpr size_t kMaxRspLen = 900; -// TODO: The code currently has two sources of truths for fabrics, the fabricInfo table + the attributes. There should only be one, -// the attributes list. Currently the attributes are not persisted so we are keeping the fabric table to have the -// fabrics/admrins be persisted. Once attributes are persisted, there should only be one sorce of truth, the attributes list and -// only that should be modifed to perosst/read/write fabrics. -// TODO: Once attributes are persisted, implement reading/writing/manipulation fabrics around that and remove fabricTable -// logic. class OpCredsFabricTableDelegate : public chip::FabricTable::Delegate { public: - // Gets called when a fabric is deleted from KVS store - void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) override + // Gets called when a fabric is about to be deleted + void FabricWillBeRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) override { - ChipLogProgress(Zcl, "OpCreds: Fabric index 0x%x was removed", static_cast(fabricIndex)); - // The Leave event SHOULD be emitted by a Node prior to permanently leaving the Fabric. for (auto endpoint : EnabledEndpointsWithServerCluster(Basic::Id)) { @@ -377,8 +369,14 @@ class OpCredsFabricTableDelegate : public chip::FabricTable::Delegate // - removing the fabric removes all associated access control entries, so generating // subsequent reports containing the leave event will fail the access control check. InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleUrgentEventDeliverySync(); - EventManagement::GetInstance().FabricRemoved(fabricIndex); + } + // Gets called when a fabric is deleted + void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) override + { + ChipLogProgress(Zcl, "OpCreds: Fabric index 0x%x was removed", static_cast(fabricIndex)); + + EventManagement::GetInstance().FabricRemoved(fabricIndex); NotifyFabricTableChanged(); } diff --git a/src/credentials/FabricTable.cpp b/src/credentials/FabricTable.cpp index 1829541e635e8a..b9f4952ed74968 100644 --- a/src/credentials/FabricTable.cpp +++ b/src/credentials/FabricTable.cpp @@ -907,6 +907,18 @@ CHIP_ERROR FabricTable::Delete(FabricIndex fabricIndex) VerifyOrReturnError(mStorage != nullptr, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(IsValidFabricIndex(fabricIndex), CHIP_ERROR_INVALID_ARGUMENT); + { + FabricTable::Delegate * delegate = mDelegateListRoot; + while (delegate) + { + // It is possible that delegate will remove itself from the list in FabricWillBeRemoved, + // so we grab the next delegate in the list now. + FabricTable::Delegate * nextDelegate = delegate->next; + delegate->FabricWillBeRemoved(*this, fabricIndex); + delegate = nextDelegate; + } + } + FabricInfo * fabricInfo = GetMutableFabricByIndex(fabricIndex); if (fabricInfo == &mPendingFabric) { diff --git a/src/credentials/FabricTable.h b/src/credentials/FabricTable.h index 4c0fbb4a3bf61b..068c6b98a19359 100644 --- a/src/credentials/FabricTable.h +++ b/src/credentials/FabricTable.h @@ -360,6 +360,13 @@ class DLL_EXPORT FabricTable Delegate() {} virtual ~Delegate() {} + /** + * Gets called when a fabric is about to be deleted, such as on + * FabricTable::Delete(). This allows actions to be taken that need the + * fabric to still be around before we delete it. + **/ + virtual void FabricWillBeRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) {} + /** * Gets called when a fabric is deleted, such as on FabricTable::Delete(). **/