Skip to content

Commit

Permalink
CommandSender and CommandHandler reserves space for Finalize to succeed
Browse files Browse the repository at this point in the history
  • Loading branch information
tehampson committed Dec 18, 2023
1 parent 9310a37 commit 1ddb9fe
Show file tree
Hide file tree
Showing 11 changed files with 174 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/app/CommandHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ CHIP_ERROR CommandHandler::AllocateBuffer()

mInvokeResponseBuilder.CreateInvokeResponses();
ReturnErrorOnFailure(mInvokeResponseBuilder.GetError());

auto * tlvWriter = mInvokeResponseBuilder.GetWriter();
ReturnErrorOnFailure(tlvWriter->ReserveBuffer(mInvokeResponseBuilder.GetInvokeResponses().GetSizeToEndInvokeResponses()));
ReturnErrorOnFailure(tlvWriter->ReserveBuffer(mInvokeResponseBuilder.GetSizeToEndInvokeResponseMessage()));
mBufferAllocated = true;
}

Expand Down Expand Up @@ -651,6 +655,9 @@ CHIP_ERROR CommandHandler::FinishCommand(bool aStartDataStruct)
ReturnErrorOnFailure(commandData.Ref(mRefForResponse.Value()));
}

auto * tlvWriter = mInvokeResponseBuilder.GetWriter();
ReturnErrorOnFailure(tlvWriter->UnreserveBuffer(mInvokeResponseBuilder.GetInvokeResponses().GetSizeToEndInvokeResponses()));
ReturnErrorOnFailure(tlvWriter->UnreserveBuffer(mInvokeResponseBuilder.GetSizeToEndInvokeResponseMessage()));
ReturnErrorOnFailure(commandData.EndOfCommandDataIB());
ReturnErrorOnFailure(mInvokeResponseBuilder.GetInvokeResponses().GetInvokeResponse().EndOfInvokeResponseIB());
MoveToState(State::AddedCommand);
Expand Down
9 changes: 9 additions & 0 deletions src/app/CommandSender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ CHIP_ERROR CommandSender::AllocateBuffer()
mInvokeRequestBuilder.CreateInvokeRequests();
ReturnErrorOnFailure(mInvokeRequestBuilder.GetError());

auto * tlvWriter = mInvokeRequestBuilder.GetWriter();
ReturnErrorOnFailure(tlvWriter->ReserveBuffer(mInvokeRequestBuilder.GetInvokeRequests().GetSizeToEndInvokeRequests()));
ReturnErrorOnFailure(tlvWriter->ReserveBuffer(mInvokeRequestBuilder.GetSizeToEndInvokeRequestMessage()));

mBufferAllocated = true;
}

Expand Down Expand Up @@ -508,6 +512,11 @@ CHIP_ERROR CommandSender::FinishCommand(const Optional<uint16_t> & aTimedInvokeT
CHIP_ERROR CommandSender::Finalize(System::PacketBufferHandle & commandPacket)
{
VerifyOrReturnError(mState == State::AddedCommand, CHIP_ERROR_INCORRECT_STATE);

auto * tlvWriter = mInvokeRequestBuilder.GetWriter();
ReturnErrorOnFailure(tlvWriter->UnreserveBuffer(mInvokeRequestBuilder.GetInvokeRequests().GetSizeToEndInvokeRequests()));
ReturnErrorOnFailure(tlvWriter->UnreserveBuffer(mInvokeRequestBuilder.GetSizeToEndInvokeRequestMessage()));

ReturnErrorOnFailure(mInvokeRequestBuilder.GetInvokeRequests().EndOfInvokeRequests());
ReturnErrorOnFailure(mInvokeRequestBuilder.EndOfInvokeRequestMessage());
return mCommandMessageWriter.Finalize(&commandPacket);
Expand Down
9 changes: 9 additions & 0 deletions src/app/MessageDef/InvokeRequestMessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,5 +152,14 @@ CHIP_ERROR InvokeRequestMessage::Builder::EndOfInvokeRequestMessage()
}
return GetError();
}

uint32_t InvokeRequestMessage::Builder::GetSizeToEndInvokeRequestMessage()
{
// This encodes uint8_t into Tag 0xFF. This means 1 bytes for tag, 1 byte for length, 1 byte for value
uint32_t kEncodeInteractionModelSize = 1 + 1 + 1;
uint32_t kEndOfContainerSize = 1;

return kEncodeInteractionModelSize + kEndOfContainerSize;
}
}; // namespace app
}; // namespace chip
7 changes: 7 additions & 0 deletions src/app/MessageDef/InvokeRequestMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ class Builder : public MessageBuilder
*/
CHIP_ERROR EndOfInvokeRequestMessage();

/**
* @brief Get number of bytes required to call EndOfInvokeRequestMessage()
*
* @return Expected number of bytes required to call EndOfInvokeRequestMessage()
*/
uint32_t GetSizeToEndInvokeRequestMessage();

private:
InvokeRequests::Builder mInvokeRequests;
};
Expand Down
6 changes: 6 additions & 0 deletions src/app/MessageDef/InvokeRequests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,11 @@ CHIP_ERROR InvokeRequests::Builder::EndOfInvokeRequests()
EndOfContainer();
return GetError();
}

uint32_t InvokeRequests::Builder::GetSizeToEndInvokeRequests()
{
uint32_t kEndOfContainerSize = 1;
return kEndOfContainerSize;
}
} // namespace app
} // namespace chip
7 changes: 7 additions & 0 deletions src/app/MessageDef/InvokeRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ class Builder : public ArrayBuilder
*/
CHIP_ERROR EndOfInvokeRequests();

/**
* @brief Get number of bytes required to call EndOfInvokeRequests()
*
* @return Expected number of bytes required to call EndOfInvokeRequests()
*/
uint32_t GetSizeToEndInvokeRequests();

private:
CommandDataIB::Builder mCommandData;
};
Expand Down
6 changes: 6 additions & 0 deletions src/app/MessageDef/InvokeResponseIBs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,11 @@ CHIP_ERROR InvokeResponseIBs::Builder::EndOfInvokeResponses()
EndOfContainer();
return GetError();
}

uint32_t InvokeResponseIBs::Builder::GetSizeToEndInvokeResponses()
{
uint32_t kEndOfContainerSize = 1;
return kEndOfContainerSize;
}
} // namespace app
} // namespace chip
7 changes: 7 additions & 0 deletions src/app/MessageDef/InvokeResponseIBs.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ class Builder : public ArrayBuilder
*/
CHIP_ERROR EndOfInvokeResponses();

/**
* @brief Get number of bytes required to call EndOfInvokeResponses()
*
* @return Expected number of bytes required to call EndOfInvokeResponses()
*/
uint32_t GetSizeToEndInvokeResponses();

private:
InvokeResponseIB::Builder mInvokeResponse;
};
Expand Down
9 changes: 9 additions & 0 deletions src/app/MessageDef/InvokeResponseMessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,5 +152,14 @@ CHIP_ERROR InvokeResponseMessage::Builder::EndOfInvokeResponseMessage()
}
return GetError();
}

uint32_t InvokeResponseMessage::Builder::GetSizeToEndInvokeResponseMessage()
{
// This encodes uint8_t into Tag 0xFF. This means 1 bytes for tag, 1 byte for length, 1 byte for value
uint32_t kEncodeInteractionModelSize = 1 + 1 + 1;
uint32_t kEndOfContainerSize = 1;

return kEncodeInteractionModelSize + kEndOfContainerSize;
}
} // namespace app
} // namespace chip
7 changes: 7 additions & 0 deletions src/app/MessageDef/InvokeResponseMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ class Builder : public MessageBuilder
*/
CHIP_ERROR EndOfInvokeResponseMessage();

/**
* @brief Get number of bytes required to call EndOfInvokeResponseMessage()
*
* @return Expected number of bytes required to call EndOfInvokeResponseMessage()
*/
uint32_t GetSizeToEndInvokeResponseMessage();

private:
InvokeResponseIBs::Builder mInvokeResponses;
};
Expand Down
100 changes: 100 additions & 0 deletions src/app/tests/TestMessageDef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2057,6 +2057,54 @@ void InvokeInvokeRequestMessageTest(nlTestSuite * apSuite, void * apContext)
ParseInvokeRequestMessage(apSuite, reader);
}

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

uint32_t sizeToReserve = invokeRequestMessageBuilder.GetSizeToEndInvokeRequestMessage();
err = writer.ReserveBuffer(sizeToReserve);
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
uint32_t remianingLengthAfterReservation = writer.GetRemainingFreeLength();

err = writer.UnreserveBuffer(sizeToReserve);
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
err = invokeRequestMessageBuilder.EndOfInvokeRequestMessage();
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

uint32_t remianingLengthAfterEndingInvokeRequestMessage = writer.GetRemainingFreeLength();
NL_TEST_ASSERT(apSuite, remianingLengthAfterReservation == remianingLengthAfterEndingInvokeRequestMessage);
}

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

uint32_t sizeToReserve = invokeRequestsBuilder.GetSizeToEndInvokeRequests();
err = writer.ReserveBuffer(sizeToReserve);
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
uint32_t remianingLengthAfterReservation = writer.GetRemainingFreeLength();

err = writer.UnreserveBuffer(sizeToReserve);
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
err = invokeRequestsBuilder.EndOfInvokeRequests();
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

uint32_t remianingLengthAfterEndingInvokeRequests = writer.GetRemainingFreeLength();
NL_TEST_ASSERT(apSuite, remianingLengthAfterReservation == remianingLengthAfterEndingInvokeRequests);
}

void InvokeInvokeResponseMessageTest(nlTestSuite * apSuite, void * apContext)
{
CHIP_ERROR err = CHIP_NO_ERROR;
Expand All @@ -2074,6 +2122,54 @@ void InvokeInvokeResponseMessageTest(nlTestSuite * apSuite, void * apContext)
ParseInvokeResponseMessage(apSuite, reader);
}

void InvokeResponseMessageEndOfMessageReservationTest(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.Init(&writer);
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

uint32_t sizeToReserve = invokeResponseMessageBuilder.GetSizeToEndInvokeResponseMessage();
err = writer.ReserveBuffer(sizeToReserve);
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
uint32_t remianingLengthAfterReservation = writer.GetRemainingFreeLength();

err = writer.UnreserveBuffer(sizeToReserve);
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
err = invokeResponseMessageBuilder.EndOfInvokeResponseMessage();
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

uint32_t remianingLengthAfterEndingInvokeResponseMessage = writer.GetRemainingFreeLength();
NL_TEST_ASSERT(apSuite, remianingLengthAfterReservation == remianingLengthAfterEndingInvokeResponseMessage);
}

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

uint32_t sizeToReserve = invokeResponsesBuilder.GetSizeToEndInvokeResponses();
err = writer.ReserveBuffer(sizeToReserve);
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
uint32_t remianingLengthAfterReservation = writer.GetRemainingFreeLength();

err = writer.UnreserveBuffer(sizeToReserve);
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
err = invokeResponsesBuilder.EndOfInvokeResponses();
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);

uint32_t remianingLengthAfterEndingInvokeResponses = writer.GetRemainingFreeLength();
NL_TEST_ASSERT(apSuite, remianingLengthAfterReservation == remianingLengthAfterEndingInvokeResponses);
}

void ReportDataMessageTest(nlTestSuite * apSuite, void * apContext)
{
CHIP_ERROR err = CHIP_NO_ERROR;
Expand Down Expand Up @@ -2283,7 +2379,11 @@ const nlTest sTests[] =
NL_TEST_DEF("InvokeRequestsTest", InvokeRequestsTest),
NL_TEST_DEF("InvokeResponsesTest", InvokeResponsesTest),
NL_TEST_DEF("InvokeInvokeRequestMessageTest", InvokeInvokeRequestMessageTest),
NL_TEST_DEF("InvokeRequestMessageEndOfMessageReservationTest", InvokeRequestMessageEndOfMessageReservationTest),
NL_TEST_DEF("InvokeRequestsEndOfRequestReservationTest", InvokeRequestsEndOfRequestReservationTest),
NL_TEST_DEF("InvokeInvokeResponseMessageTest", InvokeInvokeResponseMessageTest),
NL_TEST_DEF("InvokeResponseMessageEndOfMessageReservationTest", InvokeResponseMessageEndOfMessageReservationTest),
NL_TEST_DEF("InvokeResponsesEndOfResponseReservationTest", InvokeResponsesEndOfResponseReservationTest),
NL_TEST_DEF("ReportDataMessageTest", ReportDataMessageTest),
NL_TEST_DEF("ReadRequestMessageTest", ReadRequestMessageTest),
NL_TEST_DEF("WriteRequestMessageTest", WriteRequestMessageTest),
Expand Down

0 comments on commit 1ddb9fe

Please sign in to comment.