Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow reserving space for MoreChunkedMessages in InvokeResponseMessage #31301

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions src/app/MessageDef/InvokeResponseMessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,32 @@ InvokeResponseIBs::Builder & InvokeResponseMessage::Builder::CreateInvokeRespons

InvokeResponseMessage::Builder & InvokeResponseMessage::Builder::MoreChunkedMessages(const bool aMoreChunkedMessages)
{
// If any changes are made to how we encoded MoreChunkedMessage that involves how many
// bytes are needed, a corresponding change to GetSizeForMoreChunkResponses indicating
// the new size that will be required.

// skip if error has already been set
if (mError == CHIP_NO_ERROR)
SuccessOrExit(mError);

if (mIsMoreChunkMessageBufferReserved)
{
mError = mpWriter->PutBoolean(TLV::ContextTag(Tag::kMoreChunkedMessages), aMoreChunkedMessages);
mError = GetWriter()->UnreserveBuffer(GetSizeForMoreChunkResponses());
SuccessOrExit(mError);
mIsMoreChunkMessageBufferReserved = false;
}

mError = mpWriter->PutBoolean(TLV::ContextTag(Tag::kMoreChunkedMessages), aMoreChunkedMessages);
exit:
return *this;
}

CHIP_ERROR InvokeResponseMessage::Builder::ReserveSpaceForMoreChunkedMessages()
{
ReturnErrorOnFailure(GetWriter()->ReserveBuffer(GetSizeForMoreChunkResponses()));
mIsMoreChunkMessageBufferReserved = true;
return CHIP_NO_ERROR;
}

CHIP_ERROR InvokeResponseMessage::Builder::EndOfInvokeResponseMessage()
{
// If any changes are made to how we end the invoke response message that involves how many
Expand All @@ -177,6 +195,15 @@ CHIP_ERROR InvokeResponseMessage::Builder::EndOfInvokeResponseMessage()
return GetError();
}

uint32_t InvokeResponseMessage::Builder::GetSizeForMoreChunkResponses()
{
// MoreChunkedMessages() encodes a uint8_t with context tag 0x02. This means 1 control byte,
// 1 byte for the tag. For booleans the value is encoded in control byte.
uint32_t kEncodeMoreChunkedMessages = 1 + 1;

return kEncodeMoreChunkedMessages;
}

uint32_t InvokeResponseMessage::Builder::GetSizeToEndInvokeResponseMessage()
{
// EncodeInteractionModelRevision() encodes a uint8_t with context tag 0xFF. This means 1 control byte,
Expand Down
17 changes: 16 additions & 1 deletion src/app/MessageDef/InvokeResponseMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,27 @@ class Builder : public MessageBuilder
*/
InvokeResponseMessage::Builder & MoreChunkedMessages(const bool aMoreChunkedMessages);

/**
* @brief Set True if the set of InvokeResponseIB have to be sent across multiple packets in a single transaction
* @param [in] aMoreChunkedMessages true if more chunked messages are needed
* @return A reference to *this
*/
CHIP_ERROR ReserveSpaceForMoreChunkedMessages();

/**
* @brief Mark the end of this InvokeResponseMessage
*
* @return The builder's final status.
*/
CHIP_ERROR EndOfInvokeResponseMessage();

/**
* @brief Get number of bytes required in the buffer by MoreChunkedMessages
*
* @return Expected number of bytes required in the buffer by MoreChunkedMessages()
*/
uint32_t GetSizeForMoreChunkResponses();

/**
* @brief Get number of bytes required in the buffer by EndOfInvokeResponseMessage()
*
Expand All @@ -126,7 +140,8 @@ class Builder : public MessageBuilder

private:
InvokeResponseIBs::Builder mInvokeResponses;
bool mIsEndBufferReserved = false;
bool mIsEndBufferReserved = false;
bool mIsMoreChunkMessageBufferReserved = false;
};
} // namespace InvokeResponseMessage
} // namespace app
Expand Down
24 changes: 24 additions & 0 deletions src/app/tests/TestMessageDef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2136,6 +2136,29 @@ void InvokeResponseMessageEndOfMessageReservationTest(nlTestSuite * apSuite, voi
NL_TEST_ASSERT(apSuite, remainingLengthAfterInitWithReservation == remainingLengthAfterEndingInvokeResponseMessage);
}

void InvokeResponseMessageReservationForEndandMoreChunkTest(nlTestSuite * apSuite, void * apContext)
{
CHIP_ERROR err = CHIP_NO_ERROR;
chip::System::PacketBufferTLVWriter writer;
InvokeResponseMessage::Builder invokeResponseMessageBuilder;
const uint32_t kSmallBufferSize = 100;
writer.Init(chip::System::PacketBufferHandle::New(kSmallBufferSize, /* aReservedSize = */ 0), /* useChainedBuffers = */ false);
err = invokeResponseMessageBuilder.InitWithEndBufferReserved(&writer);
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
err = invokeResponseMessageBuilder.ReserveSpaceForMoreChunkedMessages();
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

uint32_t remainingLengthAllReservations = writer.GetRemainingFreeLength();

invokeResponseMessageBuilder.MoreChunkedMessages(/* aMoreChunkedMessages = */ true);
NL_TEST_ASSERT(apSuite, invokeResponseMessageBuilder.GetError() == CHIP_NO_ERROR);
err = invokeResponseMessageBuilder.EndOfInvokeResponseMessage();
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

uint32_t remainingLengthAfterEndingInvokeResponseMessage = writer.GetRemainingFreeLength();
NL_TEST_ASSERT(apSuite, remainingLengthAllReservations == remainingLengthAfterEndingInvokeResponseMessage);
}

void InvokeResponsesEndOfResponseReservationTest(nlTestSuite * apSuite, void * apContext)
{
CHIP_ERROR err = CHIP_NO_ERROR;
Expand Down Expand Up @@ -2373,6 +2396,7 @@ const nlTest sTests[] =
NL_TEST_DEF("InvokeRequestsEndOfRequestReservationTest", InvokeRequestsEndOfRequestReservationTest),
NL_TEST_DEF("InvokeInvokeResponseMessageTest", InvokeInvokeResponseMessageTest),
NL_TEST_DEF("InvokeResponseMessageEndOfMessageReservationTest", InvokeResponseMessageEndOfMessageReservationTest),
NL_TEST_DEF("InvokeResponseMessageReservationForEndandMoreChunkTest", InvokeResponseMessageReservationForEndandMoreChunkTest),
NL_TEST_DEF("InvokeResponsesEndOfResponseReservationTest", InvokeResponsesEndOfResponseReservationTest),
NL_TEST_DEF("ReportDataMessageTest", ReportDataMessageTest),
NL_TEST_DEF("ReadRequestMessageTest", ReadRequestMessageTest),
Expand Down
Loading