Skip to content

Commit ec99391

Browse files
Make the error-handling in OnReadInitialRequest clearer.
Instead of having both a status outparam and an error return, just use a status return. Also fixes some bugs where we were not checking the results of some TLV parsing operations, and not converting some TVL parsing failures to the right status. Fixes project-chip#11724 Fixes project-chip#17623
1 parent a3fdd05 commit ec99391

File tree

2 files changed

+59
-55
lines changed

2 files changed

+59
-55
lines changed

src/app/InteractionModelEngine.cpp

+54-49
Original file line numberDiff line numberDiff line change
@@ -280,11 +280,10 @@ CHIP_ERROR InteractionModelEngine::OnInvokeCommandRequest(Messaging::ExchangeCon
280280
return CHIP_NO_ERROR;
281281
}
282282

283-
CHIP_ERROR InteractionModelEngine::OnReadInitialRequest(Messaging::ExchangeContext * apExchangeContext,
284-
const PayloadHeader & aPayloadHeader,
285-
System::PacketBufferHandle && aPayload,
286-
ReadHandler::InteractionType aInteractionType,
287-
Protocols::InteractionModel::Status & aStatus)
283+
Protocols::InteractionModel::Status InteractionModelEngine::OnReadInitialRequest(Messaging::ExchangeContext * apExchangeContext,
284+
const PayloadHeader & aPayloadHeader,
285+
System::PacketBufferHandle && aPayload,
286+
ReadHandler::InteractionType aInteractionType)
288287
{
289288
ChipLogDetail(InteractionModel, "Received %s request",
290289
aInteractionType == ReadHandler::InteractionType::Subscribe ? "Subscribe" : "Read");
@@ -301,55 +300,68 @@ CHIP_ERROR InteractionModelEngine::OnReadInitialRequest(Messaging::ExchangeConte
301300
if (apExchangeContext->GetSessionHandle()->GetFabricIndex() == kUndefinedFabricIndex)
302301
{
303302
// Subscriptions must be associated to a fabric.
304-
aStatus = Protocols::InteractionModel::Status::UnsupportedAccess;
305-
return CHIP_NO_ERROR;
303+
return Status::UnsupportedAccess;
306304
}
307305

308306
reader.Init(aPayload.Retain());
309307

310308
SubscribeRequestMessage::Parser subscribeRequestParser;
311-
ReturnErrorOnFailure(subscribeRequestParser.Init(reader));
309+
CHIP_ERROR err = subscribeRequestParser.Init(reader);
310+
if (err != CHIP_NO_ERROR)
311+
{
312+
return Status::InvalidAction;
313+
}
312314

313315
{
314316
size_t requestedAttributePathCount = 0;
315317
size_t requestedEventPathCount = 0;
316318
AttributePathIBs::Parser attributePathListParser;
317-
CHIP_ERROR err = subscribeRequestParser.GetAttributeRequests(&attributePathListParser);
319+
err = subscribeRequestParser.GetAttributeRequests(&attributePathListParser);
318320
if (err == CHIP_NO_ERROR)
319321
{
320322
TLV::TLVReader pathReader;
321323
attributePathListParser.GetReader(&pathReader);
322-
TLV::Utilities::Count(pathReader, requestedAttributePathCount, false);
324+
err = TLV::Utilities::Count(pathReader, requestedAttributePathCount, false);
323325
}
324-
else if (err != CHIP_ERROR_END_OF_TLV)
326+
else if (err == CHIP_ERROR_END_OF_TLV)
325327
{
326-
aStatus = Protocols::InteractionModel::Status::InvalidAction;
327-
return CHIP_NO_ERROR;
328+
err = CHIP_NO_ERROR;
328329
}
330+
if (err != CHIP_NO_ERROR)
331+
{
332+
return Status::InvalidAction;
333+
}
334+
329335
EventPathIBs::Parser eventpathListParser;
330336
err = subscribeRequestParser.GetEventRequests(&eventpathListParser);
331337
if (err == CHIP_NO_ERROR)
332338
{
333339
TLV::TLVReader pathReader;
334340
eventpathListParser.GetReader(&pathReader);
335-
TLV::Utilities::Count(pathReader, requestedEventPathCount, false);
341+
err = TLV::Utilities::Count(pathReader, requestedEventPathCount, false);
336342
}
337-
else if (err != CHIP_ERROR_END_OF_TLV)
343+
else if (err == CHIP_ERROR_END_OF_TLV)
338344
{
339-
aStatus = Protocols::InteractionModel::Status::InvalidAction;
340-
return CHIP_NO_ERROR;
345+
err = CHIP_NO_ERROR;
346+
}
347+
if (err != CHIP_NO_ERROR)
348+
{
349+
return Status::InvalidAction;
341350
}
342351

343352
// The following cast is safe, since we can only hold a few tens of paths in one request.
344353
if (!EnsureResourceForSubscription(apExchangeContext->GetSessionHandle()->GetFabricIndex(), requestedAttributePathCount,
345354
requestedEventPathCount))
346355
{
347-
aStatus = Protocols::InteractionModel::Status::PathsExhausted;
348-
return CHIP_NO_ERROR;
356+
return Status::PathsExhausted;
349357
}
350358
}
351359

352-
ReturnErrorOnFailure(subscribeRequestParser.GetKeepSubscriptions(&keepExistingSubscriptions));
360+
err = subscribeRequestParser.GetKeepSubscriptions(&keepExistingSubscriptions);
361+
if (err != CHIP_NO_ERROR)
362+
{
363+
return Status::InvalidAction;
364+
}
353365

354366
if (!keepExistingSubscriptions)
355367
{
@@ -381,33 +393,29 @@ CHIP_ERROR InteractionModelEngine::OnReadInitialRequest(Messaging::ExchangeConte
381393

382394
if ((handlerPoolCapacity - GetNumActiveReadHandlers()) == 0)
383395
{
384-
aStatus = Protocols::InteractionModel::Status::ResourceExhausted;
385-
return CHIP_NO_ERROR;
396+
return Status::ResourceExhausted;
386397
}
387398
#endif
388399

389400
// We have already reserved enough resources for read requests, and have granted enough resources for current subscriptions, so
390401
// we should be able to allocate resources requested by this request.
391402
ReadHandler * handler = mReadHandlers.CreateObject(*this, apExchangeContext, aInteractionType);
392-
if (handler)
403+
if (handler == nullptr)
393404
{
394-
CHIP_ERROR err = handler->OnInitialRequest(std::move(aPayload));
395-
if (err == CHIP_ERROR_NO_MEMORY)
396-
{
397-
aStatus = Protocols::InteractionModel::Status::ResourceExhausted;
398-
}
399-
else
400-
{
401-
aStatus = StatusIB(err).mStatus;
402-
}
403-
return err;
405+
ChipLogProgress(InteractionModel, "no resource for %s interaction",
406+
aInteractionType == ReadHandler::InteractionType::Subscribe ? "Subscribe" : "Read");
407+
return Status::ResourceExhausted;
404408
}
405409

406-
ChipLogProgress(InteractionModel, "no resource for %s interaction",
407-
aInteractionType == ReadHandler::InteractionType::Subscribe ? "Subscribe" : "Read");
408-
aStatus = Protocols::InteractionModel::Status::ResourceExhausted;
410+
CHIP_ERROR err = handler->OnInitialRequest(std::move(aPayload));
411+
if (err == CHIP_ERROR_NO_MEMORY)
412+
{
413+
return Status::ResourceExhausted;
414+
}
409415

410-
return CHIP_NO_ERROR;
416+
// TODO: Should probably map various TLV errors into InvalidAction, here
417+
// or inside the read handler.
418+
return StatusIB(err).mStatus;
411419
}
412420

413421
Protocols::InteractionModel::Status InteractionModelEngine::OnWriteRequest(Messaging::ExchangeContext * apExchangeContext,
@@ -494,7 +502,6 @@ CHIP_ERROR InteractionModelEngine::OnMessageReceived(Messaging::ExchangeContext
494502
{
495503
using namespace Protocols::InteractionModel;
496504

497-
CHIP_ERROR err = CHIP_NO_ERROR;
498505
Protocols::InteractionModel::Status status = Protocols::InteractionModel::Status::Failure;
499506

500507
// Group Message can only be an InvokeCommandRequest or WriteRequest
@@ -503,27 +510,25 @@ CHIP_ERROR InteractionModelEngine::OnMessageReceived(Messaging::ExchangeContext
503510
!aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::WriteRequest))
504511
{
505512
ChipLogProgress(InteractionModel, "Msg type %d not supported for group message", aPayloadHeader.GetMessageType());
506-
return err;
513+
return CHIP_NO_ERROR;
507514
}
508515

509516
if (aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::InvokeCommandRequest))
510517
{
511-
SuccessOrExit(
512-
OnInvokeCommandRequest(apExchangeContext, aPayloadHeader, std::move(aPayload), /* aIsTimedInvoke = */ false, status));
518+
OnInvokeCommandRequest(apExchangeContext, aPayloadHeader, std::move(aPayload), /* aIsTimedInvoke = */ false, status);
513519
}
514520
else if (aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::ReadRequest))
515521
{
516-
SuccessOrExit(OnReadInitialRequest(apExchangeContext, aPayloadHeader, std::move(aPayload),
517-
ReadHandler::InteractionType::Read, status));
522+
status = OnReadInitialRequest(apExchangeContext, aPayloadHeader, std::move(aPayload), ReadHandler::InteractionType::Read);
518523
}
519524
else if (aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::WriteRequest))
520525
{
521526
status = OnWriteRequest(apExchangeContext, aPayloadHeader, std::move(aPayload), /* aIsTimedWrite = */ false);
522527
}
523528
else if (aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::SubscribeRequest))
524529
{
525-
SuccessOrExit(OnReadInitialRequest(apExchangeContext, aPayloadHeader, std::move(aPayload),
526-
ReadHandler::InteractionType::Subscribe, status));
530+
status =
531+
OnReadInitialRequest(apExchangeContext, aPayloadHeader, std::move(aPayload), ReadHandler::InteractionType::Subscribe);
527532
}
528533
else if (aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::ReportData))
529534
{
@@ -532,19 +537,19 @@ CHIP_ERROR InteractionModelEngine::OnMessageReceived(Messaging::ExchangeContext
532537
}
533538
else if (aPayloadHeader.HasMessageType(MsgType::TimedRequest))
534539
{
535-
SuccessOrExit(OnTimedRequest(apExchangeContext, aPayloadHeader, std::move(aPayload), status));
540+
OnTimedRequest(apExchangeContext, aPayloadHeader, std::move(aPayload), status);
536541
}
537542
else
538543
{
539544
ChipLogProgress(InteractionModel, "Msg type %d not supported", aPayloadHeader.GetMessageType());
540545
}
541546

542-
exit:
543547
if (status != Protocols::InteractionModel::Status::Success && !apExchangeContext->IsGroupExchangeContext())
544548
{
545-
err = StatusResponse::Send(status, apExchangeContext, false /*aExpectResponse*/);
549+
return StatusResponse::Send(status, apExchangeContext, false /*aExpectResponse*/);
546550
}
547-
return err;
551+
552+
return CHIP_NO_ERROR;
548553
}
549554

550555
void InteractionModelEngine::OnResponseTimeout(Messaging::ExchangeContext * ec)

src/app/InteractionModelEngine.h

+5-6
Original file line numberDiff line numberDiff line change
@@ -377,13 +377,12 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler,
377377

378378
/**
379379
* Called when Interaction Model receives a Read Request message. Errors processing
380-
* the Read Request are handled entirely within this function. The caller pre-sets status to failure and the callee is
381-
* expected to set it to success if it does not want an automatic status response message to be sent.
380+
* the Read Request are handled entirely within this function. If the
381+
* status returned is not Status::Success, the caller will send a status
382+
* response message with that status.
382383
*/
383-
384-
CHIP_ERROR OnReadInitialRequest(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader,
385-
System::PacketBufferHandle && aPayload, ReadHandler::InteractionType aInteractionType,
386-
Protocols::InteractionModel::Status & aStatus);
384+
Status OnReadInitialRequest(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader,
385+
System::PacketBufferHandle && aPayload, ReadHandler::InteractionType aInteractionType);
387386

388387
/**
389388
* Called when Interaction Model receives a Write Request message. Errors processing

0 commit comments

Comments
 (0)