@@ -67,6 +67,7 @@ void ReadClient::ClearActiveSubscriptionState()
67
67
mMaxInterval = 0 ;
68
68
mSubscriptionId = 0 ;
69
69
mIsResubscriptionScheduled = false ;
70
+
70
71
MoveToState (ClientState::Idle);
71
72
}
72
73
@@ -187,11 +188,20 @@ void ReadClient::Close(CHIP_ERROR aError, bool allowResubscription)
187
188
if (allowResubscription &&
188
189
(mReadPrepareParams .mEventPathParamsListSize != 0 || mReadPrepareParams .mAttributePathParamsListSize != 0 ))
189
190
{
191
+ CHIP_ERROR originalReason = aError;
192
+
190
193
aError = mpCallback.OnResubscriptionNeeded (this , aError);
191
194
if (aError == CHIP_NO_ERROR)
192
195
{
193
196
return ;
194
197
}
198
+ if (aError == CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT)
199
+ {
200
+ VerifyOrDie (originalReason == CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT);
201
+ ChipLogProgress (DataManagement, " ICD device is inactive mark subscription as InactiveICDSubscription" );
202
+ MoveToState (ClientState::InactiveICDSubscription);
203
+ return ;
204
+ }
195
205
}
196
206
197
207
//
@@ -223,6 +233,8 @@ const char * ReadClient::GetStateStr() const
223
233
return " AwaitingSubscribeResponse" ;
224
234
case ClientState::SubscriptionActive:
225
235
return " SubscriptionActive" ;
236
+ case ClientState::InactiveICDSubscription:
237
+ return " InactiveICDSubscription" ;
226
238
}
227
239
#endif // CHIP_DETAIL_LOGGING
228
240
return " N/A" ;
@@ -427,6 +439,18 @@ CHIP_ERROR ReadClient::GenerateDataVersionFilterList(DataVersionFilterIBs::Build
427
439
return CHIP_NO_ERROR;
428
440
}
429
441
442
+ void ReadClient::OnActiveModeNotification ()
443
+ {
444
+ // This function just tries to complete the deferred resubscription logic in `OnLivenessTimeoutCallback`.
445
+ VerifyOrDie (mpImEngine->InActiveReadClientList (this ));
446
+ // If we are not in InactiveICDSubscription state, that means the liveness timeout has not been reached. Simply do nothing.
447
+ VerifyOrReturn (IsInactiveICDSubscription ());
448
+
449
+ // When we reach here, the subscription definitely exceeded the liveness timeout. Just continue the unfinished resubscription
450
+ // logic in `OnLivenessTimeoutCallback`.
451
+ TriggerResubscriptionForLivenessTimeout (CHIP_ERROR_TIMEOUT);
452
+ }
453
+
430
454
CHIP_ERROR ReadClient::OnMessageReceived (Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader,
431
455
System::PacketBufferHandle && aPayload)
432
456
{
@@ -884,6 +908,10 @@ void ReadClient::OnLivenessTimeoutCallback(System::Layer * apSystemLayer, void *
884
908
{
885
909
ReadClient * const _this = reinterpret_cast <ReadClient *>(apAppState);
886
910
911
+ // TODO: add a more specific error here for liveness timeout failure to distinguish between other classes of timeouts (i.e
912
+ // response timeouts).
913
+ CHIP_ERROR subscriptionTerminationCause = CHIP_ERROR_TIMEOUT;
914
+
887
915
//
888
916
// Might as well try to see if this instance exists in the tracked list in the IM.
889
917
// This might blow-up if either the client has since been free'ed (use-after-free), or if the engine has since
@@ -895,32 +923,39 @@ void ReadClient::OnLivenessTimeoutCallback(System::Layer * apSystemLayer, void *
895
923
" Subscription Liveness timeout with SubscriptionID = 0x%08" PRIx32 " , Peer = %02x:" ChipLogFormatX64,
896
924
_this->mSubscriptionId , _this->GetFabricIndex (), ChipLogValueX64 (_this->GetPeerNodeId ()));
897
925
926
+ if (_this->mIsPeerLIT )
927
+ {
928
+ subscriptionTerminationCause = CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT;
929
+ }
930
+
931
+ _this->TriggerResubscriptionForLivenessTimeout (subscriptionTerminationCause);
932
+ }
933
+
934
+ void ReadClient::TriggerResubscriptionForLivenessTimeout (CHIP_ERROR aReason)
935
+ {
898
936
// We didn't get a message from the server on time; it's possible that it no
899
937
// longer has a useful CASE session to us. Mark defunct all sessions that
900
938
// have not seen peer activity in at least as long as our session.
901
- const auto & holder = _this-> mReadPrepareParams .mSessionHolder ;
939
+ const auto & holder = mReadPrepareParams .mSessionHolder ;
902
940
if (holder)
903
941
{
904
942
System::Clock::Timestamp lastPeerActivity = holder->AsSecureSession ()->GetLastPeerActivityTime ();
905
- _this->mpImEngine ->GetExchangeManager ()->GetSessionManager ()->ForEachMatchingSession (
906
- _this->mPeer , [&lastPeerActivity](auto * session) {
907
- if (!session->IsCASESession ())
908
- {
909
- return ;
910
- }
943
+ mpImEngine->GetExchangeManager ()->GetSessionManager ()->ForEachMatchingSession (mPeer , [&lastPeerActivity](auto * session) {
944
+ if (!session->IsCASESession ())
945
+ {
946
+ return ;
947
+ }
911
948
912
- if (session->GetLastPeerActivityTime () > lastPeerActivity)
913
- {
914
- return ;
915
- }
949
+ if (session->GetLastPeerActivityTime () > lastPeerActivity)
950
+ {
951
+ return ;
952
+ }
916
953
917
- session->MarkAsDefunct ();
918
- });
954
+ session->MarkAsDefunct ();
955
+ });
919
956
}
920
957
921
- // TODO: add a more specific error here for liveness timeout failure to distinguish between other classes of timeouts (i.e
922
- // response timeouts).
923
- _this->Close (CHIP_ERROR_TIMEOUT);
958
+ Close (aReason);
924
959
}
925
960
926
961
CHIP_ERROR ReadClient::ProcessSubscribeResponse (System::PacketBufferHandle && aPayload)
@@ -999,6 +1034,8 @@ CHIP_ERROR ReadClient::SendSubscribeRequestImpl(const ReadPrepareParams & aReadP
999
1034
mReadPrepareParams .mSessionHolder = aReadPrepareParams.mSessionHolder ;
1000
1035
}
1001
1036
1037
+ mIsPeerLIT = aReadPrepareParams.mIsPeerLIT ;
1038
+
1002
1039
mMinIntervalFloorSeconds = aReadPrepareParams.mMinIntervalFloorSeconds ;
1003
1040
1004
1041
// Todo: Remove the below, Update span in ReadPrepareParams
@@ -1103,6 +1140,12 @@ CHIP_ERROR ReadClient::SendSubscribeRequestImpl(const ReadPrepareParams & aReadP
1103
1140
1104
1141
CHIP_ERROR ReadClient::DefaultResubscribePolicy (CHIP_ERROR aTerminationCause)
1105
1142
{
1143
+ if (aTerminationCause == CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT)
1144
+ {
1145
+ ChipLogProgress (DataManagement, " ICD device is inactive, skipping scheduling resubscribe within DefaultResubscribePolicy" );
1146
+ return CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT;
1147
+ }
1148
+
1106
1149
VerifyOrReturnError (IsIdle (), CHIP_ERROR_INCORRECT_STATE);
1107
1150
1108
1151
auto timeTillNextResubscription = ComputeTimeTillNextSubscription ();
@@ -1111,8 +1154,7 @@ CHIP_ERROR ReadClient::DefaultResubscribePolicy(CHIP_ERROR aTerminationCause)
1111
1154
" ms due to error %" CHIP_ERROR_FORMAT,
1112
1155
GetFabricIndex (), ChipLogValueX64 (GetPeerNodeId ()), mNumRetries , timeTillNextResubscription,
1113
1156
aTerminationCause.Format ());
1114
- ReturnErrorOnFailure (ScheduleResubscription (timeTillNextResubscription, NullOptional, aTerminationCause == CHIP_ERROR_TIMEOUT));
1115
- return CHIP_NO_ERROR;
1157
+ return ScheduleResubscription (timeTillNextResubscription, NullOptional, aTerminationCause == CHIP_ERROR_TIMEOUT);
1116
1158
}
1117
1159
1118
1160
void ReadClient::HandleDeviceConnected (void * context, Messaging::ExchangeManager & exchangeMgr,
0 commit comments