diff --git a/src/app/TimedHandler.cpp b/src/app/TimedHandler.cpp index ae71dcbc03d8ef..52400bce8feb71 100644 --- a/src/app/TimedHandler.cpp +++ b/src/app/TimedHandler.cpp @@ -17,6 +17,7 @@ */ #include "TimedHandler.h" +#include #include #include #include @@ -122,10 +123,13 @@ CHIP_ERROR TimedHandler::HandleTimedRequestAction(Messaging::ExchangeContext * a ChipLogDetail(DataManagement, "Got Timed Request with timeout %" PRIu16 ": handler %p exchange " ChipLogFormatExchange, timeoutMs, this, ChipLogValueExchange(aExchangeContext)); - // Tell the exchange to close after the timeout passes, so we don't get - // stuck waiting forever if the client never sends another message. + // Use at least our default IM timeout, because if we close our exchange as + // soon as we know the delay has passed we won't be able to send the + // UNSUPPORTED_ACCESS status code the spec tells us to send (and in fact + // will send nothing and the other side will have to time out to realize + // it's missed its window). auto delay = System::Clock::Milliseconds32(timeoutMs); - aExchangeContext->SetResponseTimeout(delay); + aExchangeContext->SetResponseTimeout(std::max(delay, kImMessageTimeout)); ReturnErrorOnFailure(StatusResponse::Send(Status::Success, aExchangeContext, /* aExpectResponse = */ true)); // Now just wait for the client. diff --git a/src/app/tests/TestTimedHandler.cpp b/src/app/tests/TestTimedHandler.cpp index cf6dfd9c775945..63d7f1958f42e7 100644 --- a/src/app/tests/TestTimedHandler.cpp +++ b/src/app/tests/TestTimedHandler.cpp @@ -124,6 +124,8 @@ void TestTimedHandler::TestFollowingMessageFastEnough(nlTestSuite * aSuite, void CHIP_ERROR err = exchange->SendMessage(MsgType::TimedRequest, std::move(payload), SendMessageFlags::kExpectResponse); NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + + ctx.DrainAndServiceIO(); NL_TEST_ASSERT(aSuite, delegate.mNewMessageReceived); NL_TEST_ASSERT(aSuite, delegate.mLastMessageWasStatus); NL_TEST_ASSERT(aSuite, delegate.mStatus.mStatus == Status::Success); @@ -136,8 +138,10 @@ void TestTimedHandler::TestFollowingMessageFastEnough(nlTestSuite * aSuite, void delegate.mKeepExchangeOpen = false; delegate.mNewMessageReceived = false; - err = exchange->SendMessage(aMsgType, std::move(payload)); + err = exchange->SendMessage(aMsgType, std::move(payload), SendMessageFlags::kExpectResponse); NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + + ctx.DrainAndServiceIO(); NL_TEST_ASSERT(aSuite, delegate.mNewMessageReceived); NL_TEST_ASSERT(aSuite, delegate.mLastMessageWasStatus); NL_TEST_ASSERT(aSuite, delegate.mStatus.mStatus != Status::UnsupportedAccess); @@ -170,6 +174,8 @@ void TestTimedHandler::TestFollowingMessageTooSlow(nlTestSuite * aSuite, void * CHIP_ERROR err = exchange->SendMessage(MsgType::TimedRequest, std::move(payload), SendMessageFlags::kExpectResponse); NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + + ctx.DrainAndServiceIO(); NL_TEST_ASSERT(aSuite, delegate.mNewMessageReceived); NL_TEST_ASSERT(aSuite, delegate.mLastMessageWasStatus); NL_TEST_ASSERT(aSuite, delegate.mStatus.mStatus == Status::Success); @@ -185,8 +191,10 @@ void TestTimedHandler::TestFollowingMessageTooSlow(nlTestSuite * aSuite, void * delegate.mKeepExchangeOpen = false; delegate.mNewMessageReceived = false; - err = exchange->SendMessage(aMsgType, std::move(payload)); + err = exchange->SendMessage(aMsgType, std::move(payload), SendMessageFlags::kExpectResponse); NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + + ctx.DrainAndServiceIO(); NL_TEST_ASSERT(aSuite, delegate.mNewMessageReceived); NL_TEST_ASSERT(aSuite, delegate.mLastMessageWasStatus); NL_TEST_ASSERT(aSuite, delegate.mStatus.mStatus == Status::UnsupportedAccess); @@ -217,6 +225,8 @@ void TestTimedHandler::TestInvokeNeverComes(nlTestSuite * aSuite, void * aContex CHIP_ERROR err = exchange->SendMessage(MsgType::TimedRequest, std::move(payload), SendMessageFlags::kExpectResponse); NL_TEST_ASSERT(aSuite, err == CHIP_NO_ERROR); + + ctx.DrainAndServiceIO(); NL_TEST_ASSERT(aSuite, delegate.mNewMessageReceived); NL_TEST_ASSERT(aSuite, delegate.mLastMessageWasStatus); NL_TEST_ASSERT(aSuite, delegate.mStatus.mStatus == Status::Success); @@ -249,7 +259,7 @@ nlTestSuite sSuite = { "TestTimedHandler", &sTests[0], - TestContext::Initialize, + TestContext::InitializeAsync, TestContext::Finalize }; // clang-format on