Skip to content

Commit

Permalink
Allow reserving space for MoreChunkedMessages in InvokeResponseMessage (
Browse files Browse the repository at this point in the history
  • Loading branch information
tehampson authored Jan 9, 2024
1 parent 62d38c5 commit 158502f
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 3 deletions.
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 Reserved space in TLVWriter for MoreChunkedMessages
* @return CHIP_NO_ERROR upon successfully reserving space for MoreChunkedMessages
* @return other CHIP error see TLVWriter::ReserveBuffer for more details.
*/
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

0 comments on commit 158502f

Please sign in to comment.