diff --git a/src/app/CommandHandler.cpp b/src/app/CommandHandler.cpp index 6b694ba8a4b14d..6444a2faba9951 100644 --- a/src/app/CommandHandler.cpp +++ b/src/app/CommandHandler.cpp @@ -93,6 +93,8 @@ void CommandHandler::OnInvokeCommandRequest(Messaging::ExchangeContext * ec, con StatusResponse::Send(status, mExchangeCtx.Get(), false /*aExpectResponse*/); mSentStatusResponse = true; } + + mGoneAsync = true; } Status CommandHandler::ProcessInvokeRequest(System::PacketBufferHandle && payload, bool isTimedInvoke) @@ -577,6 +579,7 @@ TLV::TLVWriter * CommandHandler::GetCommandDataIBTLVWriter() FabricIndex CommandHandler::GetAccessingFabricIndex() const { + VerifyOrDie(!mGoneAsync); return mExchangeCtx->GetSessionHandle()->GetFabricIndex(); } diff --git a/src/app/CommandHandler.h b/src/app/CommandHandler.h index 054deebe85e4dd..cc175a9a125cd8 100644 --- a/src/app/CommandHandler.h +++ b/src/app/CommandHandler.h @@ -182,6 +182,13 @@ class CommandHandler : public Messaging::ExchangeDelegate CHIP_ERROR PrepareStatus(const ConcreteCommandPath & aCommandPath); CHIP_ERROR FinishStatus(); TLV::TLVWriter * GetCommandDataIBTLVWriter(); + + /** + * GetAccessingFabricIndex() may only be called during synchronous command + * processing. Anything that runs async (while holding a + * CommandHandler::Handle or equivalent) must not call this method, because + * it will not work right if the session we're using was evicted. + */ FabricIndex GetAccessingFabricIndex() const; /** @@ -272,7 +279,17 @@ class CommandHandler : public Messaging::ExchangeDelegate msgContext->FlushAcks(); } - Access::SubjectDescriptor GetSubjectDescriptor() const { return mExchangeCtx->GetSessionHandle()->GetSubjectDescriptor(); } + /** + * GetSubjectDescriptor() may only be called during synchronous command + * processing. Anything that runs async (while holding a + * CommandHandler::Handle or equivalent) must not call this method, because + * it might not work right if the session we're using was evicted. + */ + Access::SubjectDescriptor GetSubjectDescriptor() const + { + VerifyOrDie(!mGoneAsync); + return mExchangeCtx->GetSessionHandle()->GetSubjectDescriptor(); + } private: friend class TestCommandInteraction; @@ -394,6 +411,10 @@ class CommandHandler : public Messaging::ExchangeDelegate chip::System::PacketBufferTLVWriter mCommandMessageWriter; TLV::TLVWriter mBackupWriter; bool mBufferAllocated = false; + // If mGoneAsync is true, we have finished out initial processing of the + // incoming invoke. After this point, our session could go away at any + // time. + bool mGoneAsync = false; }; } // namespace app