Skip to content

Commit

Permalink
Fix issue 14566 (#15222)
Browse files Browse the repository at this point in the history
Send status report when engine cannot put oversized attribute in report
  • Loading branch information
yunhanw-google authored and pull[bot] committed Oct 17, 2023
1 parent 54cf9aa commit 1768260
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 4 deletions.
20 changes: 20 additions & 0 deletions src/app/ReadHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,26 @@ CHIP_ERROR ReadHandler::OnStatusResponse(Messaging::ExchangeContext * apExchange
return err;
}

CHIP_ERROR ReadHandler::SendStatusReport(Protocols::InteractionModel::Status aStatus)
{
VerifyOrReturnLogError(IsReportable(), CHIP_ERROR_INCORRECT_STATE);
if (IsPriming() || IsChunkedReport())
{
mSessionHandle.Grab(mpExchangeCtx->GetSessionHandle());
}
else
{
VerifyOrReturnLogError(mpExchangeCtx == nullptr, CHIP_ERROR_INCORRECT_STATE);
VerifyOrReturnLogError(mSessionHandle, CHIP_ERROR_INCORRECT_STATE);
mpExchangeCtx = mpExchangeMgr->NewContext(mSessionHandle.Get(), this);
}
VerifyOrReturnLogError(mpExchangeCtx != nullptr, CHIP_ERROR_INCORRECT_STATE);
mpExchangeCtx->SetResponseTimeout(kImMessageTimeout);

return StatusResponse::Send(aStatus, mpExchangeCtx,
/* aExpectResponse = */ false);
}

CHIP_ERROR ReadHandler::SendReportData(System::PacketBufferHandle && aPayload, bool aMoreChunks)
{
VerifyOrReturnLogError(IsReportable(), CHIP_ERROR_INCORRECT_STATE);
Expand Down
1 change: 1 addition & 0 deletions src/app/ReadHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ class ReadHandler : public Messaging::ExchangeDelegate
const AttributeValueEncoder::AttributeEncodeState & GetAttributeEncodeState() const { return mAttributeEncoderState; }
void SetAttributeEncodeState(const AttributeValueEncoder::AttributeEncodeState & aState) { mAttributeEncoderState = aState; }
uint32_t GetLastWrittenEventsBytes() { return mLastWrittenEventsBytes; }
CHIP_ERROR SendStatusReport(Protocols::InteractionModel::Status aStatus);

private:
friend class TestReadInteraction;
Expand Down
12 changes: 9 additions & 3 deletions src/app/reporting/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ CHIP_ERROR Engine::BuildAndSendSingleReportData(ReadHandler * apReadHandler)
chip::System::PacketBufferHandle bufHandle = System::PacketBufferHandle::New(chip::app::kMaxSecureSduLengthBytes);
uint16_t reservedSize = 0;
bool hasMoreChunks = false;
bool needCloseReadHandler = false;

// Reserved size for the MoreChunks boolean flag, which takes up 1 byte for the control tag and 1 byte for the context tag.
const uint32_t kReservedSizeForMoreChunksFlag = 1 + 1;
Expand Down Expand Up @@ -420,8 +421,13 @@ CHIP_ERROR Engine::BuildAndSendSingleReportData(ReadHandler * apReadHandler)
if (!hasEncodedAttributes && !hasEncodedEvents && hasMoreChunks)
{
ChipLogError(DataManagement,
"No data actually encoded but hasMoreChunks flag is set, abort report! (attribute too big?)");
ExitNow(err = CHIP_ERROR_INCORRECT_STATE);
"No data actually encoded but hasMoreChunks flag is set, close read handler! (attribute too big?)");
err = apReadHandler->SendStatusReport(Protocols::InteractionModel::Status::ResourceExhausted);
if (err == CHIP_NO_ERROR)
{
needCloseReadHandler = true;
}
ExitNow();
}
}

Expand Down Expand Up @@ -465,7 +471,7 @@ CHIP_ERROR Engine::BuildAndSendSingleReportData(ReadHandler * apReadHandler)
//
apReadHandler->Abort();
}
else if (apReadHandler->IsType(ReadHandler::InteractionType::Read) && !hasMoreChunks)
else if ((apReadHandler->IsType(ReadHandler::InteractionType::Read) && !hasMoreChunks) || needCloseReadHandler)
{
//
// In the case of successful report generation and we're on the last chunk of a read, we don't expect
Expand Down
2 changes: 1 addition & 1 deletion src/controller/tests/TestReadChunking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ void TestCommandInteraction::TestBadChunking(nlTestSuite * apSuite, void * apCon
NL_TEST_ASSERT(apSuite, readCallback.mAttributeCount == 0);

// The server should shutted down, while the client is still alive (pending for the attribute data.)
NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 1);
NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
}

// Sanity check
Expand Down

0 comments on commit 1768260

Please sign in to comment.