From 6e57c4ef299761a8b3b9584221f6b64425ed1e03 Mon Sep 17 00:00:00 2001 From: Nivi Sarkar <55898241+nivi-apple@users.noreply.github.com> Date: Thu, 30 Jan 2025 10:11:45 -0800 Subject: [PATCH] Handle output event of type TransferSession::OutputEventType::kInternalError in the ProcessOutputEvents API. - If the state machine generates this event, indicating that the session is in a bad state and cannot continue, terminate the BDX session. --- .../bdx/AsyncTransferFacilitator.cpp | 22 +++++++++++-------- src/protocols/bdx/AsyncTransferFacilitator.h | 6 ++++- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/protocols/bdx/AsyncTransferFacilitator.cpp b/src/protocols/bdx/AsyncTransferFacilitator.cpp index 2730e17481caa6..7d9166c7b283ce 100644 --- a/src/protocols/bdx/AsyncTransferFacilitator.cpp +++ b/src/protocols/bdx/AsyncTransferFacilitator.cpp @@ -45,6 +45,7 @@ CHIP_ERROR AsyncTransferFacilitator::Init(System::Layer * layer, Messaging::Exch */ void AsyncTransferFacilitator::ProcessOutputEvents() { + if (mProcessingOutputEvents) { ChipLogDetail(BDX, @@ -63,6 +64,16 @@ void AsyncTransferFacilitator::ProcessOutputEvents() mTransfer.GetNextAction(outEvent); while (outEvent.EventType != TransferSession::OutputEventType::kNone) { + + // If the transfer session state machine generates an event of type TransferSession::OutputEventType::kInternalError, + // indicating that the session is in a bad state, we do not want to process any more events and terminate the session. + // In that case, set mDestroySelfAfterProcessingEvents to true and break from the loop so we can call DestroySelf() to clean up. + if (outEvent.EventType == TransferSession::OutputEventType::kInternalError) + { + mDestroySelfAfterProcessingEvents = true; + break; + } + if (outEvent.EventType == TransferSession::OutputEventType::kMsgToSend) { CHIP_ERROR err = SendMessage(outEvent.msgTypeData, outEvent.MsgData); @@ -170,27 +181,20 @@ void AsyncResponder::NotifyEventHandled(const TransferSession::OutputEventType e ChipLogDetail(BDX, "NotifyEventHandled : Event %s Error %" CHIP_ERROR_FORMAT, TransferSession::OutputEvent::TypeToString(eventType), status.Format()); - // If we are handling a status report, we should destroy ourselves and hence, terminate the transfer. - if (eventType == TransferSession::OutputEventType::kStatusReceived) - { - DestroySelf(); - return; - } - // If this is the end of the transfer (whether a clean end, or some sort of error condition), ensure that // we destroy ourselves after processing any output events that might have been generated by // the transfer session to handle end-of-transfer (e.g. in some error conditions it might want to send // out a status report). if (eventType == TransferSession::OutputEventType::kAckEOFReceived || + eventType == TransferSession::OutputEventType::kStatusReceived || eventType == TransferSession::OutputEventType::kInternalError || eventType == TransferSession::OutputEventType::kTransferTimeout) { mDestroySelfAfterProcessingEvents = true; } - // If there was an error handling the output event, this should notify the transfer object to abort transfer so it can send a // status report across the exchange when we call ProcessOutputEvents below. - if (status != CHIP_NO_ERROR) + else if (status != CHIP_NO_ERROR) { mTransfer.AbortTransfer(GetBdxStatusCodeFromChipError(status)); } diff --git a/src/protocols/bdx/AsyncTransferFacilitator.h b/src/protocols/bdx/AsyncTransferFacilitator.h index 1ad95d39e98d2d..e8928664a56743 100644 --- a/src/protocols/bdx/AsyncTransferFacilitator.h +++ b/src/protocols/bdx/AsyncTransferFacilitator.h @@ -72,7 +72,11 @@ class AsyncTransferFacilitator : public Messaging::ExchangeDelegate */ virtual void DestroySelf() = 0; - // Calling ProcessOutputEvents can destroy this object before the call returns. + /** + * Calling ProcessOutputEvents can destroy this object before the call returns for certain cases + * where the state machine either receives a message indicating termination of the transfer session (StatusReport + * or BlockAckEOF) or generates an InternalError for various error scenarios including timeout. + */ void ProcessOutputEvents(); // The transfer session corresponding to this AsyncTransferFacilitator object.