@@ -109,10 +109,9 @@ enum class ForcedSizeBufferLengthHint
109
109
kSizeGreaterThan255 ,
110
110
};
111
111
112
- struct ForcedSizeBuffer
112
+ class ForcedSizeBuffer : public app ::DataModel::EncodableToTLV
113
113
{
114
- chip::Platform::ScopedMemoryBufferWithSize<uint8_t > mBuffer ;
115
-
114
+ public:
116
115
ForcedSizeBuffer (uint32_t size)
117
116
{
118
117
if (mBuffer .Alloc (size))
@@ -124,7 +123,7 @@ struct ForcedSizeBuffer
124
123
125
124
// No significance with using 0x12 as the CommandId, just using a value.
126
125
static constexpr chip::CommandId GetCommandId () { return 0x12 ; }
127
- CHIP_ERROR Encode (TLV::TLVWriter & aWriter, TLV::Tag aTag) const
126
+ CHIP_ERROR EncodeTo (TLV::TLVWriter & aWriter, TLV::Tag aTag) const override
128
127
{
129
128
VerifyOrReturnError (mBuffer , CHIP_ERROR_NO_MEMORY);
130
129
@@ -133,6 +132,9 @@ struct ForcedSizeBuffer
133
132
ReturnErrorOnFailure (app::DataModel::Encode (aWriter, TLV::ContextTag (1 ), ByteSpan (mBuffer .Get (), mBuffer .AllocatedSize ())));
134
133
return aWriter.EndContainer (outerContainerType);
135
134
}
135
+
136
+ private:
137
+ chip::Platform::ScopedMemoryBufferWithSize<uint8_t > mBuffer ;
136
138
};
137
139
138
140
struct Fields
@@ -387,6 +389,7 @@ class TestCommandInteraction : public ::testing::Test
387
389
void TestCommandSender_WithProcessReceivedMsg ();
388
390
void TestCommandSender_ExtendableApiWithProcessReceivedMsg ();
389
391
void TestCommandSender_ExtendableApiWithProcessReceivedMsgContainingInvalidCommandRef ();
392
+ void TestCommandSender_ValidateSecondLargeAddRequestDataRollbacked ();
390
393
void TestCommandHandler_WithoutResponderCallingAddStatus ();
391
394
void TestCommandHandler_WithoutResponderCallingAddResponse ();
392
395
void TestCommandHandler_WithoutResponderCallingDirectPrepareFinishCommandApis ();
@@ -632,7 +635,8 @@ uint32_t TestCommandInteraction::GetAddResponseDataOverheadSizeForPath(const Con
632
635
// When ForcedSizeBuffer exceeds 255, an extra byte is needed for length, affecting the overhead size required by
633
636
// AddResponseData. In order to have this accounted for in overhead calculation we set the length to be 256.
634
637
uint32_t sizeOfForcedSizeBuffer = aBufferSizeHint == ForcedSizeBufferLengthHint::kSizeGreaterThan255 ? 256 : 0 ;
635
- EXPECT_EQ (commandHandler.AddResponseData (aRequestCommandPath, ForcedSizeBuffer (sizeOfForcedSizeBuffer)), CHIP_NO_ERROR);
638
+ ForcedSizeBuffer responseData (sizeOfForcedSizeBuffer);
639
+ EXPECT_EQ (commandHandler.AddResponseData (aRequestCommandPath, responseData.GetCommandId (), responseData), CHIP_NO_ERROR);
636
640
uint32_t remainingSizeAfter = commandHandler.mInvokeResponseBuilder .GetWriter ()->GetRemainingFreeLength ();
637
641
uint32_t delta = remainingSizeBefore - remainingSizeAfter - sizeOfForcedSizeBuffer;
638
642
@@ -657,7 +661,8 @@ void TestCommandInteraction::FillCurrentInvokeResponseBuffer(CommandHandlerImpl
657
661
// Validating assumption. If this fails, it means overheadSizeNeededForAddingResponse is likely too large.
658
662
EXPECT_GE (sizeToFill, 256u );
659
663
660
- EXPECT_EQ (apCommandHandler->AddResponseData (aRequestCommandPath, ForcedSizeBuffer (sizeToFill)), CHIP_NO_ERROR);
664
+ ForcedSizeBuffer responseData (sizeToFill);
665
+ EXPECT_EQ (apCommandHandler->AddResponseData (aRequestCommandPath, responseData.GetCommandId (), responseData), CHIP_NO_ERROR);
661
666
}
662
667
663
668
void TestCommandInteraction::ValidateCommandHandlerEncodeInvokeResponseMessage (bool aNeedStatusCode)
@@ -1087,6 +1092,47 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandSender_ExtendableApiWithP
1087
1092
EXPECT_EQ (mockCommandSenderExtendedDelegate.onErrorCalledTimes , 0 );
1088
1093
}
1089
1094
1095
+ TEST_F_FROM_FIXTURE (TestCommandInteraction, TestCommandSender_ValidateSecondLargeAddRequestDataRollbacked)
1096
+ {
1097
+ mockCommandSenderExtendedDelegate.ResetCounter ();
1098
+ PendingResponseTrackerImpl pendingResponseTracker;
1099
+ app::CommandSender commandSender (kCommandSenderTestOnlyMarker , &mockCommandSenderExtendedDelegate,
1100
+ &mpTestContext->GetExchangeManager (), &pendingResponseTracker);
1101
+
1102
+ app::CommandSender::AddRequestDataParameters addRequestDataParams;
1103
+
1104
+ CommandSender::ConfigParameters config;
1105
+ config.SetRemoteMaxPathsPerInvoke (2 );
1106
+ EXPECT_EQ (commandSender.SetCommandSenderConfig (config), CHIP_NO_ERROR);
1107
+
1108
+ // The specific values chosen here are arbitrary.
1109
+ uint16_t firstCommandRef = 1 ;
1110
+ uint16_t secondCommandRef = 2 ;
1111
+ auto commandPathParams = MakeTestCommandPath ();
1112
+ SimpleTLVPayload simplePayloadWriter;
1113
+ addRequestDataParams.SetCommandRef (firstCommandRef);
1114
+
1115
+ EXPECT_EQ (commandSender.AddRequestData (commandPathParams, simplePayloadWriter, addRequestDataParams), CHIP_NO_ERROR);
1116
+
1117
+ uint32_t remainingSize = commandSender.mInvokeRequestBuilder .GetWriter ()->GetRemainingFreeLength ();
1118
+ // Because request is made of both request data and request path (commandPathParams), using
1119
+ // `remainingSize` is large enough fail.
1120
+ ForcedSizeBuffer requestData (remainingSize);
1121
+
1122
+ addRequestDataParams.SetCommandRef (secondCommandRef);
1123
+ EXPECT_EQ (commandSender.AddRequestData (commandPathParams, requestData, addRequestDataParams), CHIP_ERROR_NO_MEMORY);
1124
+
1125
+ // Confirm that we can still send out a request with the first command.
1126
+ EXPECT_EQ (commandSender.SendCommandRequest (mpTestContext->GetSessionBobToAlice ()), CHIP_NO_ERROR);
1127
+ EXPECT_EQ (commandSender.GetInvokeResponseMessageCount (), 0u );
1128
+
1129
+ mpTestContext->DrainAndServiceIO ();
1130
+
1131
+ EXPECT_EQ (mockCommandSenderExtendedDelegate.onResponseCalledTimes , 1 );
1132
+ EXPECT_EQ (mockCommandSenderExtendedDelegate.onFinalCalledTimes , 1 );
1133
+ EXPECT_EQ (mockCommandSenderExtendedDelegate.onErrorCalledTimes , 0 );
1134
+ }
1135
+
1090
1136
TEST_F (TestCommandInteraction, TestCommandHandlerEncodeSimpleCommandData)
1091
1137
{
1092
1138
// Send response which has simple command data and command path
@@ -1188,7 +1234,8 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_WithoutResponderC
1188
1234
CommandHandlerImpl commandHandler (&mockCommandHandlerDelegate);
1189
1235
1190
1236
uint32_t sizeToFill = 50 ; // This is an arbitrary number, we need to select a non-zero value.
1191
- EXPECT_EQ (commandHandler.AddResponseData (requestCommandPath, ForcedSizeBuffer (sizeToFill)), CHIP_NO_ERROR);
1237
+ ForcedSizeBuffer responseData (sizeToFill);
1238
+ EXPECT_EQ (commandHandler.AddResponseData (requestCommandPath, responseData.GetCommandId (), responseData), CHIP_NO_ERROR);
1192
1239
1193
1240
// Since calling AddResponseData is supposed to be a no-operation when there is no responder, it is
1194
1241
// hard to validate. Best way is to check that we are still in an Idle state afterwards
@@ -1813,7 +1860,8 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_FillUpInvokeRespo
1813
1860
EXPECT_EQ (remainingSize, sizeToLeave);
1814
1861
1815
1862
uint32_t sizeToFill = 50 ;
1816
- EXPECT_EQ (commandHandler.AddResponseData (requestCommandPath2, ForcedSizeBuffer (sizeToFill)), CHIP_NO_ERROR);
1863
+ ForcedSizeBuffer responseData (sizeToFill);
1864
+ EXPECT_EQ (commandHandler.AddResponseData (requestCommandPath2, responseData.GetCommandId (), responseData), CHIP_NO_ERROR);
1817
1865
1818
1866
remainingSize = commandHandler.mInvokeResponseBuilder .GetWriter ()->GetRemainingFreeLength ();
1819
1867
EXPECT_GT (remainingSize, sizeToLeave);
0 commit comments