Skip to content

Commit

Permalink
Enable ReadHandler to support large payloads (#33814)
Browse files Browse the repository at this point in the history
* ReadHandler changes for large payloads

When sending reports, if the session established with the peer
supports large payloads, the ReadHandler will allocate a large
buffer to, potentially, fit more attribute and event data.

* Address comments and apply suggestions from code review

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Update src/app/ReadHandler.cpp

Co-authored-by: Andrei Litvin <andy314@gmail.com>

---------

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
Co-authored-by: Andrei Litvin <andy314@gmail.com>
  • Loading branch information
3 people authored Jun 12, 2024
1 parent 3a21d25 commit 1a8c6d2
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 6 deletions.
10 changes: 10 additions & 0 deletions src/app/ReadHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -919,5 +919,15 @@ void ReadHandler::ClearStateFlag(ReadHandlerFlags aFlag)
SetStateFlag(aFlag, false);
}

size_t ReadHandler::GetReportBufferMaxSize()
{
Transport::SecureSession * session = GetSession();
if (session && session->AllowsLargePayload())
{
return kMaxLargeSecureSduLengthBytes;
}
return kMaxSecureSduLengthBytes;
}

} // namespace app
} // namespace chip
9 changes: 9 additions & 0 deletions src/app/ReadHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,15 @@ class ReadHandler : public Messaging::ExchangeDelegate
*/
CHIP_ERROR SendReportData(System::PacketBufferHandle && aPayload, bool aMoreChunks);

/*
* Get the appropriate size of a packet buffer to allocate for encoding a Report message.
* This size might depend on the underlying session used by the ReadHandler.
*
* The size returned here is the size not including the various prepended headers
* (what System::PacketBuffer calls the "available size").
*/
size_t GetReportBufferMaxSize();

/**
* Returns whether this ReadHandler represents a subscription that was created by the other side of the provided exchange.
*/
Expand Down
3 changes: 2 additions & 1 deletion src/app/StatusResponse.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@

namespace chip {
namespace app {
static constexpr size_t kMaxSecureSduLengthBytes = kMaxAppMessageLen + kMaxTagLen;
static constexpr size_t kMaxSecureSduLengthBytes = kMaxAppMessageLen + kMaxTagLen;
static constexpr size_t kMaxLargeSecureSduLengthBytes = kMaxLargeAppMessageLen + kMaxTagLen;

class StatusResponse
{
Expand Down
15 changes: 10 additions & 5 deletions src/app/reporting/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -492,10 +492,11 @@ CHIP_ERROR Engine::BuildAndSendSingleReportData(ReadHandler * apReadHandler)
CHIP_ERROR err = CHIP_NO_ERROR;
chip::System::PacketBufferTLVWriter reportDataWriter;
ReportDataMessage::Builder reportDataBuilder;
chip::System::PacketBufferHandle bufHandle = System::PacketBufferHandle::New(chip::app::kMaxSecureSduLengthBytes);
chip::System::PacketBufferHandle bufHandle = nullptr;
uint16_t reservedSize = 0;
bool hasMoreChunks = false;
bool needCloseReadHandler = false;
size_t reportBufferMaxSize = 0;

// 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 All @@ -512,11 +513,15 @@ CHIP_ERROR Engine::BuildAndSendSingleReportData(ReadHandler * apReadHandler)

VerifyOrExit(apReadHandler != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrExit(apReadHandler->GetSession() != nullptr, err = CHIP_ERROR_INCORRECT_STATE);

reportBufferMaxSize = apReadHandler->GetReportBufferMaxSize();

bufHandle = System::PacketBufferHandle::New(reportBufferMaxSize);
VerifyOrExit(!bufHandle.IsNull(), err = CHIP_ERROR_NO_MEMORY);

if (bufHandle->AvailableDataLength() > kMaxSecureSduLengthBytes)
if (bufHandle->AvailableDataLength() > reportBufferMaxSize)
{
reservedSize = static_cast<uint16_t>(bufHandle->AvailableDataLength() - kMaxSecureSduLengthBytes);
reservedSize = static_cast<uint16_t>(bufHandle->AvailableDataLength() - reportBufferMaxSize);
}

reportDataWriter.Init(std::move(bufHandle));
Expand All @@ -525,8 +530,8 @@ CHIP_ERROR Engine::BuildAndSendSingleReportData(ReadHandler * apReadHandler)
reportDataWriter.ReserveBuffer(mReservedSize);
#endif

// Always limit the size of the generated packet to fit within kMaxSecureSduLengthBytes regardless of the available buffer
// capacity.
// Always limit the size of the generated packet to fit within the max size returned by the ReadHandler regardless
// of the available buffer capacity.
// Also, we need to reserve some extra space for the MIC field.
reportDataWriter.ReserveBuffer(static_cast<uint32_t>(reservedSize + chip::Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES));

Expand Down

0 comments on commit 1a8c6d2

Please sign in to comment.