@@ -95,6 +95,15 @@ void InteractionModelEngine::Shutdown()
95
95
return true ;
96
96
});
97
97
98
+ mTimedHandlers .ForEachActiveObject ([this ](TimedHandler * obj) -> bool {
99
+ // This calls back into us and deallocates |obj|. As above, this is not
100
+ // really guaranteed, and we should do something better here (like
101
+ // ignoring the calls to OnTimedInteractionFailed and then doing a
102
+ // DeallocateAll.
103
+ mpExchangeMgr->CloseAllContextsForDelegate (obj);
104
+ return true ;
105
+ });
106
+
98
107
for (auto & readClient : mReadClients )
99
108
{
100
109
if (!readClient.IsFree ())
@@ -277,7 +286,7 @@ void InteractionModelEngine::OnDone(CommandHandler & apCommandObj)
277
286
278
287
CHIP_ERROR InteractionModelEngine::OnInvokeCommandRequest (Messaging::ExchangeContext * apExchangeContext,
279
288
const PayloadHeader & aPayloadHeader,
280
- System::PacketBufferHandle && aPayload,
289
+ System::PacketBufferHandle && aPayload, bool aIsTimedInvoke,
281
290
Protocols::InteractionModel::Status & aStatus)
282
291
{
283
292
CommandHandler * commandHandler = mCommandHandlerObjs .CreateObject (this );
@@ -287,7 +296,8 @@ CHIP_ERROR InteractionModelEngine::OnInvokeCommandRequest(Messaging::ExchangeCon
287
296
aStatus = Protocols::InteractionModel::Status::Busy;
288
297
return CHIP_ERROR_NO_MEMORY;
289
298
}
290
- ReturnErrorOnFailure (commandHandler->OnInvokeCommandRequest (apExchangeContext, aPayloadHeader, std::move (aPayload)));
299
+ ReturnErrorOnFailure (
300
+ commandHandler->OnInvokeCommandRequest (apExchangeContext, aPayloadHeader, std::move (aPayload), aIsTimedInvoke));
291
301
aStatus = Protocols::InteractionModel::Status::Success;
292
302
return CHIP_NO_ERROR;
293
303
}
@@ -360,6 +370,25 @@ CHIP_ERROR InteractionModelEngine::OnWriteRequest(Messaging::ExchangeContext * a
360
370
return CHIP_NO_ERROR;
361
371
}
362
372
373
+ CHIP_ERROR InteractionModelEngine::OnTimedRequest (Messaging::ExchangeContext * apExchangeContext,
374
+ const PayloadHeader & aPayloadHeader, System::PacketBufferHandle && aPayload,
375
+ Protocols::InteractionModel::Status & aStatus)
376
+ {
377
+ TimedHandler * handler = mTimedHandlers .CreateObject ();
378
+ if (handler == nullptr )
379
+ {
380
+ ChipLogProgress (InteractionModel, " no resource for Timed interaction" );
381
+ aStatus = Protocols::InteractionModel::Status::Busy;
382
+ return CHIP_ERROR_NO_MEMORY;
383
+ }
384
+
385
+ // The timed handler takes over handling of this exchange and will do its
386
+ // own status reporting as needed.
387
+ aStatus = Protocols::InteractionModel::Status::Success;
388
+ apExchangeContext->SetDelegate (handler);
389
+ return handler->OnMessageReceived (apExchangeContext, aPayloadHeader, std::move (aPayload));
390
+ }
391
+
363
392
CHIP_ERROR InteractionModelEngine::OnUnsolicitedReportData (Messaging::ExchangeContext * apExchangeContext,
364
393
const PayloadHeader & aPayloadHeader,
365
394
System::PacketBufferHandle && aPayload)
@@ -392,12 +421,15 @@ CHIP_ERROR InteractionModelEngine::OnUnsolicitedReportData(Messaging::ExchangeCo
392
421
CHIP_ERROR InteractionModelEngine::OnMessageReceived (Messaging::ExchangeContext * apExchangeContext,
393
422
const PayloadHeader & aPayloadHeader, System::PacketBufferHandle && aPayload)
394
423
{
424
+ using namespace Protocols ::InteractionModel;
425
+
395
426
CHIP_ERROR err = CHIP_NO_ERROR;
396
427
Protocols::InteractionModel::Status status = Protocols::InteractionModel::Status::Failure;
397
428
398
429
if (aPayloadHeader.HasMessageType (Protocols::InteractionModel::MsgType::InvokeCommandRequest))
399
430
{
400
- SuccessOrExit (OnInvokeCommandRequest (apExchangeContext, aPayloadHeader, std::move (aPayload), status));
431
+ SuccessOrExit (
432
+ OnInvokeCommandRequest (apExchangeContext, aPayloadHeader, std::move (aPayload), /* aIsTimedInvoke = */ false , status));
401
433
}
402
434
else if (aPayloadHeader.HasMessageType (Protocols::InteractionModel::MsgType::ReadRequest))
403
435
{
@@ -418,6 +450,10 @@ CHIP_ERROR InteractionModelEngine::OnMessageReceived(Messaging::ExchangeContext
418
450
ReturnErrorOnFailure (OnUnsolicitedReportData (apExchangeContext, aPayloadHeader, std::move (aPayload)));
419
451
status = Protocols::InteractionModel::Status::Success;
420
452
}
453
+ else if (aPayloadHeader.HasMessageType (MsgType::TimedRequest))
454
+ {
455
+ SuccessOrExit (OnTimedRequest (apExchangeContext, aPayloadHeader, std::move (aPayload), status));
456
+ }
421
457
else
422
458
{
423
459
ChipLogProgress (InteractionModel, " Msg type %d not supported" , aPayloadHeader.GetMessageType ());
@@ -550,6 +586,9 @@ void InteractionModelEngine::DispatchCommand(CommandHandler & apCommandObj, cons
550
586
551
587
if (handler)
552
588
{
589
+ // TODO: Figure out who is responsible for handling checking
590
+ // apCommandObj->IsTimedInvoke() for commands that require a timed
591
+ // invoke and have a CommandHandlerInterface handling them.
553
592
CommandHandlerInterface::HandlerContext context (apCommandObj, aCommandPath, apPayload);
554
593
handler->InvokeCommand (context);
555
594
@@ -657,5 +696,31 @@ CommandHandlerInterface * InteractionModelEngine::FindCommandHandler(EndpointId
657
696
return nullptr ;
658
697
}
659
698
699
+ void InteractionModelEngine::OnTimedInteractionFailed (TimedHandler * apTimedHandler)
700
+ {
701
+ mTimedHandlers .Deallocate (apTimedHandler);
702
+ }
703
+
704
+ void InteractionModelEngine::OnTimedInvoke (TimedHandler * apTimedHandler, Messaging::ExchangeContext * apExchangeContext,
705
+ const PayloadHeader & aPayloadHeader, System::PacketBufferHandle && aPayload)
706
+ {
707
+ using namespace Protocols ::InteractionModel;
708
+
709
+ // Reset the ourselves as the exchange delegate for now, to match what we'd
710
+ // do with an initial unsolicited invoke.
711
+ apExchangeContext->SetDelegate (this );
712
+ mTimedHandlers .Deallocate (apTimedHandler);
713
+
714
+ VerifyOrDie (aPayloadHeader.HasMessageType (MsgType::InvokeCommandRequest));
715
+ VerifyOrDie (!apExchangeContext->IsGroupExchangeContext ());
716
+
717
+ Status status = Status::Failure;
718
+ OnInvokeCommandRequest (apExchangeContext, aPayloadHeader, std::move (aPayload), /* aIsTimedInvoke = */ true , status);
719
+ if (status != Status::Success)
720
+ {
721
+ StatusResponse::SendStatusResponse (status, apExchangeContext, /* aExpectResponse = */ false );
722
+ }
723
+ }
724
+
660
725
} // namespace app
661
726
} // namespace chip
0 commit comments