Skip to content

Commit d9619ea

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 55ef609 commit d9619ea

File tree

2 files changed

+60
-57
lines changed

2 files changed

+60
-57
lines changed

src/app/InteractionModelEngine.cpp

+55-51
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);
342+
}
343+
else if (err == CHIP_ERROR_END_OF_TLV)
344+
{
345+
err = CHIP_NO_ERROR;
336346
}
337-
else if (err != CHIP_ERROR_END_OF_TLV)
347+
if (err != CHIP_NO_ERROR)
338348
{
339-
aStatus = Protocols::InteractionModel::Status::InvalidAction;
340-
return CHIP_NO_ERROR;
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
{
@@ -386,40 +398,35 @@ CHIP_ERROR InteractionModelEngine::OnReadInitialRequest(Messaging::ExchangeConte
386398
!HasActiveRead())
387399
{
388400
ChipLogDetail(InteractionModel, "Reserve the last ReadHandler for IM read Interaction");
389-
aStatus = Protocols::InteractionModel::Status::ResourceExhausted;
390-
return CHIP_NO_ERROR;
401+
return Status::ResourceExhausted;
391402
}
392403

393404
#if CONFIG_IM_BUILD_FOR_UNIT_TEST
394405
if ((handlerPoolCapacity - GetNumActiveReadHandlers()) == 0)
395406
{
396-
aStatus = Protocols::InteractionModel::Status::ResourceExhausted;
397-
return CHIP_NO_ERROR;
407+
return Status::ResourceExhausted;
398408
}
399409
#endif
400410

401411
// We have already reserved enough resources for read requests, and have granted enough resources for current subscriptions, so
402412
// we should be able to allocate resources requested by this request.
403413
ReadHandler * handler = mReadHandlers.CreateObject(*this, apExchangeContext, aInteractionType);
404-
if (handler)
414+
if (handler == nullptr)
405415
{
406-
CHIP_ERROR err = handler->OnInitialRequest(std::move(aPayload));
407-
if (err == CHIP_ERROR_NO_MEMORY)
408-
{
409-
aStatus = Protocols::InteractionModel::Status::ResourceExhausted;
410-
}
411-
else
412-
{
413-
aStatus = StatusIB(err).mStatus;
414-
}
415-
return err;
416+
ChipLogProgress(InteractionModel, "no resource for %s interaction",
417+
aInteractionType == ReadHandler::InteractionType::Subscribe ? "Subscribe" : "Read");
418+
return Status::ResourceExhausted;
416419
}
417420

418-
ChipLogProgress(InteractionModel, "no resource for %s interaction",
419-
aInteractionType == ReadHandler::InteractionType::Subscribe ? "Subscribe" : "Read");
420-
aStatus = Protocols::InteractionModel::Status::ResourceExhausted;
421+
CHIP_ERROR err = handler->OnInitialRequest(std::move(aPayload));
422+
if (err == CHIP_ERROR_NO_MEMORY)
423+
{
424+
return Status::ResourceExhausted;
425+
}
421426

422-
return CHIP_NO_ERROR;
427+
// TODO: Should probably map various TLV errors into InvalidAction, here
428+
// or inside the read handler.
429+
return StatusIB(err).mStatus;
423430
}
424431

425432
Protocols::InteractionModel::Status InteractionModelEngine::OnWriteRequest(Messaging::ExchangeContext * apExchangeContext,
@@ -506,7 +513,6 @@ CHIP_ERROR InteractionModelEngine::OnMessageReceived(Messaging::ExchangeContext
506513
{
507514
using namespace Protocols::InteractionModel;
508515

509-
CHIP_ERROR err = CHIP_NO_ERROR;
510516
Protocols::InteractionModel::Status status = Protocols::InteractionModel::Status::Failure;
511517

512518
// Group Message can only be an InvokeCommandRequest or WriteRequest
@@ -515,27 +521,25 @@ CHIP_ERROR InteractionModelEngine::OnMessageReceived(Messaging::ExchangeContext
515521
!aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::WriteRequest))
516522
{
517523
ChipLogProgress(InteractionModel, "Msg type %d not supported for group message", aPayloadHeader.GetMessageType());
518-
return err;
524+
return CHIP_NO_ERROR;
519525
}
520526

521527
if (aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::InvokeCommandRequest))
522528
{
523-
SuccessOrExit(
524-
OnInvokeCommandRequest(apExchangeContext, aPayloadHeader, std::move(aPayload), /* aIsTimedInvoke = */ false, status));
529+
OnInvokeCommandRequest(apExchangeContext, aPayloadHeader, std::move(aPayload), /* aIsTimedInvoke = */ false, status);
525530
}
526531
else if (aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::ReadRequest))
527532
{
528-
SuccessOrExit(OnReadInitialRequest(apExchangeContext, aPayloadHeader, std::move(aPayload),
529-
ReadHandler::InteractionType::Read, status));
533+
status = OnReadInitialRequest(apExchangeContext, aPayloadHeader, std::move(aPayload), ReadHandler::InteractionType::Read);
530534
}
531535
else if (aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::WriteRequest))
532536
{
533537
status = OnWriteRequest(apExchangeContext, aPayloadHeader, std::move(aPayload), /* aIsTimedWrite = */ false);
534538
}
535539
else if (aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::SubscribeRequest))
536540
{
537-
SuccessOrExit(OnReadInitialRequest(apExchangeContext, aPayloadHeader, std::move(aPayload),
538-
ReadHandler::InteractionType::Subscribe, status));
541+
status =
542+
OnReadInitialRequest(apExchangeContext, aPayloadHeader, std::move(aPayload), ReadHandler::InteractionType::Subscribe);
539543
}
540544
else if (aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::ReportData))
541545
{
@@ -544,19 +548,19 @@ CHIP_ERROR InteractionModelEngine::OnMessageReceived(Messaging::ExchangeContext
544548
}
545549
else if (aPayloadHeader.HasMessageType(MsgType::TimedRequest))
546550
{
547-
SuccessOrExit(OnTimedRequest(apExchangeContext, aPayloadHeader, std::move(aPayload), status));
551+
OnTimedRequest(apExchangeContext, aPayloadHeader, std::move(aPayload), status);
548552
}
549553
else
550554
{
551555
ChipLogProgress(InteractionModel, "Msg type %d not supported", aPayloadHeader.GetMessageType());
552556
}
553557

554-
exit:
555558
if (status != Protocols::InteractionModel::Status::Success && !apExchangeContext->IsGroupExchangeContext())
556559
{
557-
err = StatusResponse::Send(status, apExchangeContext, false /*aExpectResponse*/);
560+
return StatusResponse::Send(status, apExchangeContext, false /*aExpectResponse*/);
558561
}
559-
return err;
562+
563+
return CHIP_NO_ERROR;
560564
}
561565

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

src/app/InteractionModelEngine.h

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

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

385384
/**
386385
* Called when Interaction Model receives a Write Request message. Errors processing

0 commit comments

Comments
 (0)