@@ -208,13 +208,11 @@ void ReadClient::Close(CHIP_ERROR aError, bool allowResubscription)
208
208
aError = mpCallback.OnResubscriptionNeeded (this , aError);
209
209
if (aError == CHIP_NO_ERROR)
210
210
{
211
- return ;
212
- }
213
- if (aError == CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT)
214
- {
215
- VerifyOrDie (originalReason == CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT);
216
- ChipLogProgress (DataManagement, " ICD device is inactive mark subscription as InactiveICDSubscription" );
217
- MoveToState (ClientState::InactiveICDSubscription);
211
+ if (originalReason == CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT)
212
+ {
213
+ ChipLogProgress (DataManagement, " ICD device is unreachable, mark subscription as InactiveICDSubscription, retrying is scheduled" );
214
+ MoveToState (ClientState::InactiveICDSubscription);
215
+ }
218
216
return ;
219
217
}
220
218
}
@@ -484,26 +482,25 @@ CHIP_ERROR ReadClient::GenerateDataVersionFilterList(DataVersionFilterIBs::Build
484
482
485
483
void ReadClient::OnActiveModeNotification ()
486
484
{
487
- // This function just tries to complete the deferred resubscription logic in `OnLivenessTimeoutCallback`.
488
485
VerifyOrDie (mpImEngine->InActiveReadClientList (this ));
489
- // If we are not in InactiveICDSubscription state, that means the liveness timeout has not been reached. Simply do nothing.
486
+ // If we are in InactiveICDSubscription state, it means the LIT ICD device was unreachable, and ClearActiveSubscriptionState
487
+ // should have been cleared in previous close call, now it transitions to the reachable status, client needs to cancel
488
+ // scheduled resubscription and trigger a new one immediately. Case session should have been defunct when going
489
+ // into InactiveICDSubscription state during previous close call,
490
490
VerifyOrReturn (IsInactiveICDSubscription ());
491
-
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 );
491
+ CloseSession ();
492
+ CancelResubscribeTimer ();
493
+ MoveToState (ClientState::Idle);
494
+ OnResubscribeTimerCallback ( nullptr , this );
495
495
}
496
496
497
- void ReadClient::OnPeerTypeChange (PeerType aType )
497
+ void ReadClient::OnPeerOperatingModeChange (PeerOperatingMode aMode )
498
498
{
499
499
VerifyOrDie (mpImEngine->InActiveReadClientList (this ));
500
+ ChipLogProgress (DataManagement, " Peer operation mode is now %s LIT ICD." , mPeerOperatingMode == PeerOperatingMode::kLITICD ? " a" : " not a" );
500
501
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 )
502
+ // If the peer operating mode is no longer LIT, try to wake up the subscription and do resubscribe when necessary.
503
+ if (mPeerOperatingMode == PeerOperatingMode::kNormal )
507
504
{
508
505
OnActiveModeNotification ();
509
506
}
@@ -720,10 +717,18 @@ void ReadClient::OnResponseTimeout(Messaging::ExchangeContext * apExchangeContex
720
717
ChipLogError (DataManagement, " Time out! failed to receive report data from Exchange: " ChipLogFormatExchange,
721
718
ChipLogValueExchange (apExchangeContext));
722
719
723
- Close (CHIP_ERROR_TIMEOUT);
720
+ if (IsPeerLIT ())
721
+ {
722
+ Close (CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT);
723
+ }
724
+ else
725
+ {
726
+ Close (CHIP_ERROR_TIMEOUT);
727
+ }
728
+
724
729
}
725
730
726
- CHIP_ERROR ReadClient::ReadICDOperatingModeFromAttributeDataIB (TLV::TLVReader && aReader, PeerType & aType )
731
+ CHIP_ERROR ReadClient::ReadICDOperatingModeFromAttributeDataIB (TLV::TLVReader && aReader, PeerOperatingMode & aMode )
727
732
{
728
733
Clusters::IcdManagement::Attributes::OperatingMode::TypeInfo::DecodableType operatingMode;
729
734
@@ -733,10 +738,12 @@ CHIP_ERROR ReadClient::ReadICDOperatingModeFromAttributeDataIB(TLV::TLVReader &&
733
738
switch (operatingMode)
734
739
{
735
740
case Clusters::IcdManagement::OperatingModeEnum::kSit :
736
- aType = PeerType ::kNormal ;
741
+ aMode = PeerOperatingMode ::kNormal ;
737
742
break ;
738
743
case Clusters::IcdManagement::OperatingModeEnum::kLit :
739
- aType = PeerType::kLITICD ;
744
+ aMode = PeerOperatingMode::kLITICD ;
745
+ // If operating mode is LIT, this device should be LIT ICD.
746
+ mIsPeerLIT = true ;
740
747
break ;
741
748
default :
742
749
err = CHIP_ERROR_INVALID_ARGUMENT;
@@ -843,14 +850,14 @@ CHIP_ERROR ReadClient::ProcessAttributeReportIBs(TLV::TLVReader & aAttributeRepo
843
850
if (attributePath.MatchesConcreteAttributePath (ConcreteAttributePath (
844
851
kRootEndpointId , Clusters::IcdManagement::Id, Clusters::IcdManagement::Attributes::OperatingMode::Id)))
845
852
{
846
- PeerType peerType ;
853
+ PeerOperatingMode peerMode ;
847
854
TLV::TLVReader operatingModeTlvReader;
848
855
operatingModeTlvReader.Init (dataReader);
849
- if (CHIP_NO_ERROR == ReadICDOperatingModeFromAttributeDataIB (std::move (operatingModeTlvReader), peerType ))
856
+ if (CHIP_NO_ERROR == ReadICDOperatingModeFromAttributeDataIB (std::move (operatingModeTlvReader), peerMode ))
850
857
{
851
- // It is safe to call `OnPeerTypeChange ` since we are in the middle of parsing the attribute data, And
858
+ // It is safe to call `OnPeerOperatingModeChange ` since we are in the middle of parsing the attribute data, And
852
859
// the subscription should be active so `OnActiveModeNotification` is a no-op in this case.
853
- InteractionModelEngine::GetInstance ()->OnPeerTypeChange (mPeer , peerType );
860
+ InteractionModelEngine::GetInstance ()->OnPeerOperatingModeChange (mPeer , peerMode );
854
861
}
855
862
else
856
863
{
@@ -1029,15 +1036,16 @@ void ReadClient::OnLivenessTimeoutCallback(System::Layer * apSystemLayer, void *
1029
1036
" Subscription Liveness timeout with SubscriptionID = 0x%08" PRIx32 " , Peer = %02x:" ChipLogFormatX64,
1030
1037
_this->mSubscriptionId , _this->GetFabricIndex (), ChipLogValueX64 (_this->GetPeerNodeId ()));
1031
1038
1032
- if (_this->mIsPeerLIT )
1039
+ if (_this->IsPeerLIT () )
1033
1040
{
1034
1041
subscriptionTerminationCause = CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT;
1035
1042
}
1036
1043
1037
- _this->TriggerResubscriptionForLivenessTimeout (subscriptionTerminationCause);
1044
+ _this->CloseSession ();
1045
+ _this->Close (subscriptionTerminationCause);
1038
1046
}
1039
1047
1040
- void ReadClient::TriggerResubscriptionForLivenessTimeout (CHIP_ERROR aReason )
1048
+ void ReadClient::CloseSession ( )
1041
1049
{
1042
1050
// We didn't get a message from the server on time; it's possible that it no
1043
1051
// longer has a useful CASE session to us. Mark defunct all sessions that
@@ -1060,8 +1068,6 @@ void ReadClient::TriggerResubscriptionForLivenessTimeout(CHIP_ERROR aReason)
1060
1068
session->MarkAsDefunct ();
1061
1069
});
1062
1070
}
1063
-
1064
- Close (aReason);
1065
1071
}
1066
1072
1067
1073
CHIP_ERROR ReadClient::ProcessSubscribeResponse (System::PacketBufferHandle && aPayload)
@@ -1265,12 +1271,6 @@ CHIP_ERROR ReadClient::SendSubscribeRequestImpl(const ReadPrepareParams & aReadP
1265
1271
1266
1272
CHIP_ERROR ReadClient::DefaultResubscribePolicy (CHIP_ERROR aTerminationCause)
1267
1273
{
1268
- if (aTerminationCause == CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT)
1269
- {
1270
- ChipLogProgress (DataManagement, " ICD device is inactive, skipping scheduling resubscribe within DefaultResubscribePolicy" );
1271
- return CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT;
1272
- }
1273
-
1274
1274
VerifyOrReturnError (IsIdle (), CHIP_ERROR_INCORRECT_STATE);
1275
1275
1276
1276
auto timeTillNextResubscription = ComputeTimeTillNextSubscription ();
@@ -1305,9 +1305,9 @@ void ReadClient::HandleDeviceConnectionFailure(void * context, const Operational
1305
1305
{
1306
1306
ReadClient * const _this = static_cast <ReadClient *>(context);
1307
1307
VerifyOrDie (_this != nullptr );
1308
-
1308
+ CHIP_ERROR err = failureInfo. error ;
1309
1309
ChipLogError (DataManagement, " Failed to establish CASE for re-subscription with error '%" CHIP_ERROR_FORMAT " '" ,
1310
- failureInfo. error .Format ());
1310
+ err .Format ());
1311
1311
1312
1312
#if CHIP_CONFIG_ENABLE_BUSY_HANDLING_FOR_OPERATIONAL_SESSION_SETUP
1313
1313
#if CHIP_DETAIL_LOGGING
@@ -1322,7 +1322,11 @@ void ReadClient::HandleDeviceConnectionFailure(void * context, const Operational
1322
1322
_this->mMinimalResubscribeDelay = System::Clock::kZero ;
1323
1323
#endif // CHIP_CONFIG_ENABLE_BUSY_HANDLING_FOR_OPERATIONAL_SESSION_SETUP
1324
1324
1325
- _this->Close (failureInfo.error );
1325
+ if (_this->IsPeerLIT () && err == CHIP_ERROR_TIMEOUT)
1326
+ {
1327
+ err = CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT;
1328
+ }
1329
+ _this->Close (err);
1326
1330
}
1327
1331
1328
1332
void ReadClient::OnResubscribeTimerCallback (System::Layer * /* If this starts being used, fix callers that pass nullptr */ ,
@@ -1334,7 +1338,6 @@ void ReadClient::OnResubscribeTimerCallback(System::Layer * /* If this starts be
1334
1338
_this->mIsResubscriptionScheduled = false ;
1335
1339
1336
1340
CHIP_ERROR err;
1337
-
1338
1341
ChipLogProgress (DataManagement, " OnResubscribeTimerCallback: ForceCASE = %d" , _this->mForceCaseOnNextResub );
1339
1342
_this->mNumRetries ++;
1340
1343
0 commit comments