From 79463246aef0a40916b871e0e5cc6912c3239595 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Sat, 7 Sep 2024 18:14:43 -0400 Subject: [PATCH] Abort BDX transfers as needed on controller shutdown. (#35466) If we're acting as a BDX transfer server, we should shut down transfers for a fabric index when the corresponding DeviceController shuts down. --- src/controller/CHIPDeviceController.cpp | 3 +++ .../bdx/BdxTransferDiagnosticLog.cpp | 20 +++++++++++++++++++ src/protocols/bdx/BdxTransferDiagnosticLog.h | 12 ++++++++++- .../bdx/BdxTransferDiagnosticLogPool.h | 15 ++++++++++++-- src/protocols/bdx/BdxTransferServer.h | 3 +++ 5 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 7c43d50c082389..346867226e4261 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -403,6 +403,9 @@ void DeviceController::Shutdown() // assume that all sessions for our fabric belong to us here. mSystemState->CASESessionMgr()->ReleaseSessionsForFabric(mFabricIndex); + // Shut down any bdx transfers we're acting as the server for. + mSystemState->BDXTransferServer()->AbortTransfersForFabric(mFabricIndex); + // TODO: The CASE session manager does not shut down existing CASE // sessions. It just shuts down any ongoing CASE session establishment // we're in the middle of as initiator. Maybe it should shut down diff --git a/src/protocols/bdx/BdxTransferDiagnosticLog.cpp b/src/protocols/bdx/BdxTransferDiagnosticLog.cpp index 51e56fba9ac254..4804a01c578c26 100644 --- a/src/protocols/bdx/BdxTransferDiagnosticLog.cpp +++ b/src/protocols/bdx/BdxTransferDiagnosticLog.cpp @@ -18,6 +18,8 @@ #include "BdxTransferDiagnosticLog.h" +#include + namespace chip { namespace bdx { @@ -201,5 +203,23 @@ void BdxTransferDiagnosticLog::OnExchangeClosing(Messaging::ExchangeContext * ec LogErrorOnFailure(OnTransferSessionEnd(CHIP_ERROR_INTERNAL)); } +bool BdxTransferDiagnosticLog::IsForFabric(FabricIndex fabricIndex) const +{ + if (mExchangeCtx == nullptr || !mExchangeCtx->HasSessionHandle()) + { + return false; + } + + auto session = mExchangeCtx->GetSessionHandle(); + return session->GetFabricIndex() == fabricIndex; +} + +void BdxTransferDiagnosticLog::AbortTransfer() +{ + // No need to mTransfer.AbortTransfer() here, since that just tries to async + // send a StatusReport to the other side, but we are going away here. + Reset(); +} + } // namespace bdx } // namespace chip diff --git a/src/protocols/bdx/BdxTransferDiagnosticLog.h b/src/protocols/bdx/BdxTransferDiagnosticLog.h index bc7a8773cd2dff..0f62aff7f837e5 100644 --- a/src/protocols/bdx/BdxTransferDiagnosticLog.h +++ b/src/protocols/bdx/BdxTransferDiagnosticLog.h @@ -18,14 +18,17 @@ #pragma once -#include +#include #include +#include #include #include namespace chip { namespace bdx { +class BdxTransferDiagnosticLogPoolDelegate; + class BdxTransferDiagnosticLog : public Responder { public: @@ -45,6 +48,13 @@ class BdxTransferDiagnosticLog : public Responder void OnExchangeClosing(Messaging::ExchangeContext * ec) override; + /** + * Lifetime management, to allow us to abort transfers when a fabric + * identity is being shut down. + */ + bool IsForFabric(FabricIndex fabricIndex) const; + void AbortTransfer(); + protected: /** * Called when a BDX message is received over the exchange context diff --git a/src/protocols/bdx/BdxTransferDiagnosticLogPool.h b/src/protocols/bdx/BdxTransferDiagnosticLogPool.h index a2d7d3f5d11105..70f8fdfaceb55a 100644 --- a/src/protocols/bdx/BdxTransferDiagnosticLogPool.h +++ b/src/protocols/bdx/BdxTransferDiagnosticLogPool.h @@ -18,15 +18,15 @@ #pragma once +#include #include +#include #include #include namespace chip { namespace bdx { -class BdxTransferDiagnosticLog; - class BdxTransferDiagnosticLogPoolDelegate { public: @@ -50,6 +50,17 @@ class BdxTransferDiagnosticLogPool : public BdxTransferDiagnosticLogPoolDelegate void Release(BdxTransferDiagnosticLog * transfer) override { mTransferPool.ReleaseObject(transfer); } + void AbortTransfersForFabric(FabricIndex fabricIndex) + { + mTransferPool.ForEachActiveObject([fabricIndex](BdxTransferDiagnosticLog * transfer) { + if (transfer->IsForFabric(fabricIndex)) + { + transfer->AbortTransfer(); + } + return Loop::Continue; + }); + } + private: ObjectPool mTransferPool; }; diff --git a/src/protocols/bdx/BdxTransferServer.h b/src/protocols/bdx/BdxTransferServer.h index 0fac0e88b672de..0bc3cf10e124e9 100644 --- a/src/protocols/bdx/BdxTransferServer.h +++ b/src/protocols/bdx/BdxTransferServer.h @@ -20,6 +20,7 @@ #include +#include #include #include #include @@ -42,6 +43,8 @@ class BDXTransferServer : public Messaging::UnsolicitedMessageHandler void SetDelegate(BDXTransferServerDelegate * delegate) { mDelegate = delegate; } + void AbortTransfersForFabric(FabricIndex fabricIndex) { mPoolDelegate.AbortTransfersForFabric(fabricIndex); } + protected: CHIP_ERROR OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader, Messaging::ExchangeDelegate *& newDelegate) override;