@@ -213,10 +213,18 @@ void ReadClient::Close(CHIP_ERROR aError, bool allowResubscription)
213
213
if (aError == CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT)
214
214
{
215
215
VerifyOrDie (originalReason == CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT);
216
- ChipLogProgress (DataManagement, " ICD device is inactive mark subscription as InactiveICDSubscription" );
216
+ ChipLogProgress (DataManagement, " ICD device is inactive, mark subscription as InactiveICDSubscription" );
217
217
MoveToState (ClientState::InactiveICDSubscription);
218
218
return ;
219
219
}
220
+ if (aError == CHIP_ERROR_LIT_CASE_SUBSCRIBE_PRIMING_TIMEOUT)
221
+ {
222
+ ChipLogProgress (
223
+ DataManagement,
224
+ " ICD device is unreachable, mark subscription as FailedICDSubscription, retrying is scheduled" );
225
+ MoveToState (ClientState::FailedICDSubscription);
226
+ return ;
227
+ }
220
228
}
221
229
222
230
//
@@ -250,6 +258,8 @@ const char * ReadClient::GetStateStr() const
250
258
return " SubscriptionActive" ;
251
259
case ClientState::InactiveICDSubscription:
252
260
return " InactiveICDSubscription" ;
261
+ case ClientState::FailedICDSubscription:
262
+ return " FailedICDSubscription" ;
253
263
}
254
264
#endif // CHIP_DETAIL_LOGGING
255
265
return " N/A" ;
@@ -484,26 +494,27 @@ CHIP_ERROR ReadClient::GenerateDataVersionFilterList(DataVersionFilterIBs::Build
484
494
485
495
void ReadClient::OnActiveModeNotification ()
486
496
{
487
- // This function just tries to complete the deferred resubscription logic in `OnLivenessTimeoutCallback`.
488
497
VerifyOrDie (mpImEngine->InActiveReadClientList (this ));
489
- // If we are not in InactiveICDSubscription state, that means the liveness timeout has not been reached. Simply do nothing.
490
- VerifyOrReturn (IsInactiveICDSubscription ());
498
+ // If the current state is InactiveICDSubscription (LIT ICD unreachable) or FailedICDSubscription (session/subscription creation failed),
499
+ // the previous close call should have executed ClearActiveSubscriptionState.
500
+ // Upon receiving a check-in, cancel pending resubscription if any and initiate a new one immediately.
501
+ // Case sessions need to be invalidated.
502
+ VerifyOrReturn (IsInactiveICDSubscription () && IsFailedICDSubscription ());
491
503
492
- // When we reach here, the subscription definitely exceeded the liveness timeout. Just continue the unfinished resubscription
493
- // logic in `OnLivenessTimeoutCallback`.
494
- TriggerResubscriptionForLivenessTimeout (CHIP_ERROR_TIMEOUT);
504
+ CloseSession ();
505
+ CancelResubscribeTimer ();
506
+ MoveToState (ClientState::Idle);
507
+ OnResubscribeTimerCallback (nullptr , this );
495
508
}
496
509
497
- void ReadClient::OnPeerTypeChange (PeerType aType )
510
+ void ReadClient::OnPeerOperatingModeChange (PeerOperatingMode aMode )
498
511
{
499
512
VerifyOrDie (mpImEngine->InActiveReadClientList (this ));
513
+ ChipLogProgress (DataManagement, " Peer operation mode is now %s LIT ICD." ,
514
+ mPeerOperatingMode == PeerOperatingMode::kLITICD ? " a" : " not a" );
500
515
501
- mIsPeerLIT = (aType == PeerType::kLITICD );
502
-
503
- ChipLogProgress (DataManagement, " Peer is now %s LIT ICD." , mIsPeerLIT ? " a" : " not a" );
504
-
505
- // If the peer is no longer LIT, try to wake up the subscription and do resubscribe when necessary.
506
- if (!mIsPeerLIT )
516
+ // If the peer operating mode is no longer LIT, try to wake up the subscription and do resubscribe when necessary.
517
+ if (mPeerOperatingMode == PeerOperatingMode::kNormal )
507
518
{
508
519
OnActiveModeNotification ();
509
520
}
@@ -720,10 +731,18 @@ void ReadClient::OnResponseTimeout(Messaging::ExchangeContext * apExchangeContex
720
731
ChipLogError (DataManagement, " Time out! failed to receive report data from Exchange: " ChipLogFormatExchange,
721
732
ChipLogValueExchange (apExchangeContext));
722
733
723
- Close (CHIP_ERROR_TIMEOUT);
734
+ if (IsPeerLIT () && (IsIdle () || IsAwaitingInitialReport () || IsAwaitingSubscribeResponse ()))
735
+ {
736
+ ChipLogError (DataManagement, " LIT ICD device is unreachable during Subscription establishment procedure with state %s" , GetStateStr ());
737
+ Close (CHIP_ERROR_LIT_CASE_SUBSCRIBE_PRIMING_TIMEOUT);
738
+ }
739
+ else
740
+ {
741
+ Close (CHIP_ERROR_TIMEOUT);
742
+ }
724
743
}
725
744
726
- CHIP_ERROR ReadClient::ReadICDOperatingModeFromAttributeDataIB (TLV::TLVReader && aReader, PeerType & aType )
745
+ CHIP_ERROR ReadClient::ReadICDOperatingModeFromAttributeDataIB (TLV::TLVReader && aReader, PeerOperatingMode & aMode )
727
746
{
728
747
Clusters::IcdManagement::Attributes::OperatingMode::TypeInfo::DecodableType operatingMode;
729
748
@@ -733,10 +752,12 @@ CHIP_ERROR ReadClient::ReadICDOperatingModeFromAttributeDataIB(TLV::TLVReader &&
733
752
switch (operatingMode)
734
753
{
735
754
case Clusters::IcdManagement::OperatingModeEnum::kSit :
736
- aType = PeerType ::kNormal ;
755
+ aMode = PeerOperatingMode ::kNormal ;
737
756
break ;
738
757
case Clusters::IcdManagement::OperatingModeEnum::kLit :
739
- aType = PeerType::kLITICD ;
758
+ aMode = PeerOperatingMode::kLITICD ;
759
+ // If operating mode is LIT, this device should be LIT ICD.
760
+ mIsPeerLIT = true ;
740
761
break ;
741
762
default :
742
763
err = CHIP_ERROR_INVALID_ARGUMENT;
@@ -843,14 +864,14 @@ CHIP_ERROR ReadClient::ProcessAttributeReportIBs(TLV::TLVReader & aAttributeRepo
843
864
if (attributePath.MatchesConcreteAttributePath (ConcreteAttributePath (
844
865
kRootEndpointId , Clusters::IcdManagement::Id, Clusters::IcdManagement::Attributes::OperatingMode::Id)))
845
866
{
846
- PeerType peerType ;
867
+ PeerOperatingMode peerMode ;
847
868
TLV::TLVReader operatingModeTlvReader;
848
869
operatingModeTlvReader.Init (dataReader);
849
- if (CHIP_NO_ERROR == ReadICDOperatingModeFromAttributeDataIB (std::move (operatingModeTlvReader), peerType ))
870
+ if (CHIP_NO_ERROR == ReadICDOperatingModeFromAttributeDataIB (std::move (operatingModeTlvReader), peerMode ))
850
871
{
851
- // It is safe to call `OnPeerTypeChange ` since we are in the middle of parsing the attribute data, And
872
+ // It is safe to call `OnPeerOperatingModeChange ` since we are in the middle of parsing the attribute data, And
852
873
// the subscription should be active so `OnActiveModeNotification` is a no-op in this case.
853
- InteractionModelEngine::GetInstance ()->OnPeerTypeChange (mPeer , peerType );
874
+ InteractionModelEngine::GetInstance ()->OnPeerOperatingModeChange (mPeer , peerMode );
854
875
}
855
876
else
856
877
{
@@ -1029,15 +1050,16 @@ void ReadClient::OnLivenessTimeoutCallback(System::Layer * apSystemLayer, void *
1029
1050
" Subscription Liveness timeout with SubscriptionID = 0x%08" PRIx32 " , Peer = %02x:" ChipLogFormatX64,
1030
1051
_this->mSubscriptionId , _this->GetFabricIndex (), ChipLogValueX64 (_this->GetPeerNodeId ()));
1031
1052
1032
- if (_this->mIsPeerLIT )
1053
+ if (_this->IsPeerLIT () )
1033
1054
{
1034
1055
subscriptionTerminationCause = CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT;
1035
1056
}
1036
1057
1037
- _this->TriggerResubscriptionForLivenessTimeout (subscriptionTerminationCause);
1058
+ _this->CloseSession ();
1059
+ _this->Close (subscriptionTerminationCause);
1038
1060
}
1039
1061
1040
- void ReadClient::TriggerResubscriptionForLivenessTimeout (CHIP_ERROR aReason )
1062
+ void ReadClient::CloseSession ( )
1041
1063
{
1042
1064
// We didn't get a message from the server on time; it's possible that it no
1043
1065
// longer has a useful CASE session to us. Mark defunct all sessions that
@@ -1060,8 +1082,6 @@ void ReadClient::TriggerResubscriptionForLivenessTimeout(CHIP_ERROR aReason)
1060
1082
session->MarkAsDefunct ();
1061
1083
});
1062
1084
}
1063
-
1064
- Close (aReason);
1065
1085
}
1066
1086
1067
1087
CHIP_ERROR ReadClient::ProcessSubscribeResponse (System::PacketBufferHandle && aPayload)
@@ -1270,9 +1290,7 @@ CHIP_ERROR ReadClient::DefaultResubscribePolicy(CHIP_ERROR aTerminationCause)
1270
1290
ChipLogProgress (DataManagement, " ICD device is inactive, skipping scheduling resubscribe within DefaultResubscribePolicy" );
1271
1291
return CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT;
1272
1292
}
1273
-
1274
1293
VerifyOrReturnError (IsIdle (), CHIP_ERROR_INCORRECT_STATE);
1275
-
1276
1294
auto timeTillNextResubscription = ComputeTimeTillNextSubscription ();
1277
1295
ChipLogProgress (DataManagement,
1278
1296
" Will try to resubscribe to %02x:" ChipLogFormatX64 " at retry index %" PRIu32 " after %" PRIu32
@@ -1305,9 +1323,8 @@ void ReadClient::HandleDeviceConnectionFailure(void * context, const Operational
1305
1323
{
1306
1324
ReadClient * const _this = static_cast <ReadClient *>(context);
1307
1325
VerifyOrDie (_this != nullptr );
1308
-
1309
- ChipLogError (DataManagement, " Failed to establish CASE for re-subscription with error '%" CHIP_ERROR_FORMAT " '" ,
1310
- failureInfo.error .Format ());
1326
+ CHIP_ERROR err = failureInfo.error ;
1327
+ ChipLogError (DataManagement, " Failed to establish CASE for re-subscription with error '%" CHIP_ERROR_FORMAT " '" , err.Format ());
1311
1328
1312
1329
#if CHIP_CONFIG_ENABLE_BUSY_HANDLING_FOR_OPERATIONAL_SESSION_SETUP
1313
1330
#if CHIP_DETAIL_LOGGING
@@ -1322,7 +1339,13 @@ void ReadClient::HandleDeviceConnectionFailure(void * context, const Operational
1322
1339
_this->mMinimalResubscribeDelay = System::Clock::kZero ;
1323
1340
#endif // CHIP_CONFIG_ENABLE_BUSY_HANDLING_FOR_OPERATIONAL_SESSION_SETUP
1324
1341
1325
- _this->Close (failureInfo.error );
1342
+ if (_this->IsPeerLIT () && err == CHIP_ERROR_TIMEOUT && _this->IsIdle ())
1343
+ {
1344
+ ChipLogError (DataManagement, " LIT ICD device is unreachable during CASE establishment procedure" );
1345
+ err = CHIP_ERROR_LIT_CASE_SUBSCRIBE_PRIMING_TIMEOUT;
1346
+ }
1347
+
1348
+ _this->Close (err);
1326
1349
}
1327
1350
1328
1351
void ReadClient::OnResubscribeTimerCallback (System::Layer * /* If this starts being used, fix callers that pass nullptr */ ,
@@ -1334,7 +1357,6 @@ void ReadClient::OnResubscribeTimerCallback(System::Layer * /* If this starts be
1334
1357
_this->mIsResubscriptionScheduled = false ;
1335
1358
1336
1359
CHIP_ERROR err;
1337
-
1338
1360
ChipLogProgress (DataManagement, " OnResubscribeTimerCallback: ForceCASE = %d" , _this->mForceCaseOnNextResub );
1339
1361
_this->mNumRetries ++;
1340
1362
0 commit comments