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 3842fbd4eb0d47..d384e46632b515 100644 --- a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp +++ b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp @@ -354,12 +354,14 @@ bool emberAfOperationalCredentialsClusterRemoveFabricCallback(app::CommandHandle FabricIndex currentFabricIndex = commandObj->GetAccessingFabricIndex(); if (currentFabricIndex == fabricBeingRemoved) { - // If the current fabric is being removed, expiring all the secure sessions causes crashes as - // the message sent by emberAfSendImmediateDefaultResponse() is still in the queue. Also, RMP - // retries to send the message and runs into issues. - // We are hijacking the exchange delegate here (as no more messages should be received on this exchange), - // and wait for it to close, before expiring the secure sessions for the fabric. + // If the current fabric is being removed, don't expire the secure sessions immediately as they are + // still needed to send a pending message generated by emberAfSendImmediateDefaultResponse(). + // Hijack the exchange delegate here (as no more messages should be received on this exchange), + // and wait for it to close, before expiring the secure sessions for the fabric. Also, suppress MRP + // usage since the MRP engine still holds an exchange even after it's closed, and the engine references + // the associated session object. // TODO: https://github.com/project-chip/connectedhomeip/issues/9642 + ec->SetAutoRequestAck(false); ec->SetDelegate(&gFabricCleanupExchangeDelegate); } else diff --git a/src/messaging/ExchangeContext.cpp b/src/messaging/ExchangeContext.cpp index 8ec3b67989aff8..d40edc288373a0 100644 --- a/src/messaging/ExchangeContext.cpp +++ b/src/messaging/ExchangeContext.cpp @@ -317,6 +317,13 @@ bool ExchangeContext::MatchExchange(const SessionHandle & session, const PacketH void ExchangeContext::OnSessionReleased() { + if (mFlags.Has(Flags::kFlagClosed)) + { + // Exchange is already being closed. It may occur when closing an exchange after sending + // RemoveFabric response which triggers removal of all sessions for the given fabric. + return; + } + ExchangeHandle ref(*this); if (IsResponseExpected())