Skip to content

Commit ec8547a

Browse files
authored
Changes to CommandSender and CommandHandler for supporting commands (#33889)
with large payloads.
1 parent 2f284f4 commit ec8547a

7 files changed

+63
-12
lines changed

src/app/CommandHandlerExchangeInterface.h

+12
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,18 @@ class CommandHandlerExchangeInterface
102102
* Called by CommandHandler to relay this information to the requester.
103103
*/
104104
virtual void ResponseDropped() = 0;
105+
106+
/**
107+
* @brief Gets the maximum size of a packet buffer to encode a Command
108+
* Response message. This size depends on the underlying session used
109+
* by the exchange.
110+
*
111+
* The size returned here is the size not including the prepended headers.
112+
*
113+
* Called by CommandHandler when allocating buffer for encoding the Command
114+
* response.
115+
*/
116+
virtual size_t GetCommandResponseMaxBufferSize() = 0;
105117
};
106118

107119
} // namespace app

src/app/CommandHandlerImpl.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ CHIP_ERROR CommandHandlerImpl::AllocateBuffer()
6767
{
6868
mCommandMessageWriter.Reset();
6969

70-
System::PacketBufferHandle commandPacket = System::PacketBufferHandle::New(chip::app::kMaxSecureSduLengthBytes);
70+
const size_t commandBufferMaxSize = mpResponder->GetCommandResponseMaxBufferSize();
71+
auto commandPacket = System::PacketBufferHandle::New(commandBufferMaxSize);
72+
7173
VerifyOrReturnError(!commandPacket.IsNull(), CHIP_ERROR_NO_MEMORY);
7274

7375
mCommandMessageWriter.Init(std::move(commandPacket));

src/app/CommandResponseSender.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,22 @@ void CommandResponseSender::OnInvokeCommandRequest(Messaging::ExchangeContext *
226226
}
227227
}
228228

229+
size_t CommandResponseSender::GetCommandResponseMaxBufferSize()
230+
{
231+
if (!mExchangeCtx || !mExchangeCtx->HasSessionHandle())
232+
{
233+
ChipLogError(DataManagement, "Session not available. Unable to infer session-specific buffer capacities.");
234+
return kMaxSecureSduLengthBytes;
235+
}
236+
237+
if (mExchangeCtx->GetSessionHandle()->AllowsLargePayload())
238+
{
239+
return kMaxLargeSecureSduLengthBytes;
240+
}
241+
242+
return kMaxSecureSduLengthBytes;
243+
}
244+
229245
#if CHIP_WITH_NLFAULTINJECTION
230246

231247
void CommandResponseSender::TestOnlyInvokeCommandRequestWithFaultsInjected(Messaging::ExchangeContext * ec,

src/app/CommandResponseSender.h

+2
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ class CommandResponseSender : public Messaging::ExchangeDelegate,
124124

125125
void ResponseDropped() override { mReportResponseDropped = true; }
126126

127+
size_t GetCommandResponseMaxBufferSize() override;
128+
127129
/*
128130
* Main entrypoint for this class to handle an invoke request.
129131
*

src/app/CommandSender.cpp

+20-5
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,19 @@ CHIP_ERROR GetRef(ParserT aParser, Optional<uint16_t> & aRef, bool commandRefReq
5555
} // namespace
5656

5757
CommandSender::CommandSender(Callback * apCallback, Messaging::ExchangeManager * apExchangeMgr, bool aIsTimedRequest,
58-
bool aSuppressResponse) :
58+
bool aSuppressResponse, bool aAllowLargePayload) :
5959
mExchangeCtx(*this),
60-
mCallbackHandle(apCallback), mpExchangeMgr(apExchangeMgr), mSuppressResponse(aSuppressResponse), mTimedRequest(aIsTimedRequest)
60+
mCallbackHandle(apCallback), mpExchangeMgr(apExchangeMgr), mSuppressResponse(aSuppressResponse), mTimedRequest(aIsTimedRequest),
61+
mAllowLargePayload(aAllowLargePayload)
6162
{
6263
assertChipStackLockedByCurrentThread();
6364
}
6465

6566
CommandSender::CommandSender(ExtendableCallback * apExtendableCallback, Messaging::ExchangeManager * apExchangeMgr,
66-
bool aIsTimedRequest, bool aSuppressResponse) :
67+
bool aIsTimedRequest, bool aSuppressResponse, bool aAllowLargePayload) :
6768
mExchangeCtx(*this),
6869
mCallbackHandle(apExtendableCallback), mpExchangeMgr(apExchangeMgr), mSuppressResponse(aSuppressResponse),
69-
mTimedRequest(aIsTimedRequest), mUseExtendableCallback(true)
70+
mTimedRequest(aIsTimedRequest), mUseExtendableCallback(true), mAllowLargePayload(aAllowLargePayload)
7071
{
7172
assertChipStackLockedByCurrentThread();
7273
#if CHIP_CONFIG_COMMAND_SENDER_BUILTIN_SUPPORT_FOR_BATCHED_COMMANDS
@@ -85,7 +86,15 @@ CHIP_ERROR CommandSender::AllocateBuffer()
8586
{
8687
mCommandMessageWriter.Reset();
8788

88-
System::PacketBufferHandle commandPacket = System::PacketBufferHandle::New(chip::app::kMaxSecureSduLengthBytes);
89+
System::PacketBufferHandle commandPacket;
90+
if (mAllowLargePayload)
91+
{
92+
commandPacket = System::PacketBufferHandle::New(kMaxLargeSecureSduLengthBytes);
93+
}
94+
else
95+
{
96+
commandPacket = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes);
97+
}
8998
VerifyOrReturnError(!commandPacket.IsNull(), CHIP_ERROR_NO_MEMORY);
9099

91100
mCommandMessageWriter.Init(std::move(commandPacket));
@@ -139,6 +148,12 @@ CHIP_ERROR CommandSender::TestOnlyCommandSenderTimedRequestFlagWithNoTimedInvoke
139148

140149
CHIP_ERROR CommandSender::SendCommandRequest(const SessionHandle & session, Optional<System::Clock::Timeout> timeout)
141150
{
151+
// If the command is expected to be large, ensure that the underlying
152+
// session supports it.
153+
if (mAllowLargePayload)
154+
{
155+
VerifyOrReturnError(session->AllowsLargePayload(), CHIP_ERROR_INCORRECT_STATE);
156+
}
142157

143158
if (mTimedRequest != mTimedInvokeTimeoutMs.HasValue())
144159
{

src/app/CommandSender.h

+8-6
Original file line numberDiff line numberDiff line change
@@ -308,18 +308,19 @@ class CommandSender final : public Messaging::ExchangeDelegate
308308
* If callbacks are passed the only one that will be called in a group sesttings is the onDone
309309
*/
310310
CommandSender(Callback * apCallback, Messaging::ExchangeManager * apExchangeMgr, bool aIsTimedRequest = false,
311-
bool aSuppressResponse = false);
311+
bool aSuppressResponse = false, bool aAllowLargePayload = false);
312312
CommandSender(std::nullptr_t, Messaging::ExchangeManager * apExchangeMgr, bool aIsTimedRequest = false,
313-
bool aSuppressResponse = false) :
314-
CommandSender(static_cast<Callback *>(nullptr), apExchangeMgr, aIsTimedRequest, aSuppressResponse)
313+
bool aSuppressResponse = false, bool aAllowLargePayload = false) :
314+
CommandSender(static_cast<Callback *>(nullptr), apExchangeMgr, aIsTimedRequest, aSuppressResponse, aAllowLargePayload)
315315
{}
316316
CommandSender(ExtendableCallback * apCallback, Messaging::ExchangeManager * apExchangeMgr, bool aIsTimedRequest = false,
317-
bool aSuppressResponse = false);
317+
bool aSuppressResponse = false, bool aAllowLargePayload = false);
318318
// TODO(#32138): After there is a macro that is always defined for all unit tests, the constructor with
319319
// TestOnlyMarker should only be compiled if that macro is defined.
320320
CommandSender(TestOnlyMarker aTestMarker, ExtendableCallback * apCallback, Messaging::ExchangeManager * apExchangeMgr,
321-
PendingResponseTracker * apPendingResponseTracker, bool aIsTimedRequest = false, bool aSuppressResponse = false) :
322-
CommandSender(apCallback, apExchangeMgr, aIsTimedRequest, aSuppressResponse)
321+
PendingResponseTracker * apPendingResponseTracker, bool aIsTimedRequest = false, bool aSuppressResponse = false,
322+
bool aAllowLargePayload = false) :
323+
CommandSender(apCallback, apExchangeMgr, aIsTimedRequest, aSuppressResponse, aAllowLargePayload)
323324
{
324325
mpPendingResponseTracker = apPendingResponseTracker;
325326
}
@@ -636,6 +637,7 @@ class CommandSender final : public Messaging::ExchangeDelegate
636637
bool mBufferAllocated = false;
637638
bool mBatchCommandsEnabled = false;
638639
bool mUseExtendableCallback = false;
640+
bool mAllowLargePayload = false;
639641
};
640642

641643
} // namespace app

src/app/tests/TestCommandInteraction.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,8 @@ class MockCommandResponder : public CommandHandlerExchangeInterface
330330
void AddInvokeResponseToSend(System::PacketBufferHandle && aPacket) override { mChunks.AddToEnd(std::move(aPacket)); }
331331
void ResponseDropped() override { mResponseDropped = true; }
332332

333+
size_t GetCommandResponseMaxBufferSize() override { return kMaxSecureSduLengthBytes; }
334+
333335
System::PacketBufferHandle mChunks;
334336
bool mResponseDropped = false;
335337
};

0 commit comments

Comments
 (0)