From 9f7bed765e255e4695b92937c8d02c85f436e4d9 Mon Sep 17 00:00:00 2001 From: Yunhan Wang Date: Fri, 28 Feb 2025 18:55:38 -0800 Subject: [PATCH 01/10] Trigger resubscription when receiving check-in and subscription has not yet become abnoaml in client --- src/app/ReadClient.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp index da127253cf7d12..5fdae799955e71 100644 --- a/src/app/ReadClient.cpp +++ b/src/app/ReadClient.cpp @@ -484,6 +484,7 @@ CHIP_ERROR ReadClient::GenerateDataVersionFilterList(DataVersionFilterIBs::Build void ReadClient::OnActiveModeNotification() { + // Note: this API only works when issuing subscription via SendAutoResubscribeRequest. VerifyOrDie(mpImEngine->InActiveReadClientList(this)); // When we reach here, the subscription definitely exceeded the liveness timeout. Just continue the unfinished resubscription // logic in `OnLivenessTimeoutCallback`. @@ -493,6 +494,18 @@ void ReadClient::OnActiveModeNotification() return; } + // If the server sends out check-in message, and there is no reschedule subscription yet in client side at the same time, it means + // current client does not realize subscription has gone, and we should forcibly timeout current subscription, and schedule a new one. + if (!mIsResubscriptionScheduled) + { + // Closing will ultimately trigger ScheduleResubscription with the aReestablishCASE argument set to true, effectively + // rendering the session defunct. + Close(CHIP_ERROR_TIMEOUT); + return; + } + + // If the server sends a check-in message and a subscription is already scheduled, it indicates a client-side subscription timeout or failure. + // Cancel the scheduled subscription and initiate a new one immediately. TriggerResubscribeIfScheduled("check-in message"); } From 2a2df3eb6aaf0c62d787b64ec7bfd45b007616f8 Mon Sep 17 00:00:00 2001 From: Yunhan Wang Date: Fri, 28 Feb 2025 20:31:44 -0800 Subject: [PATCH 02/10] fix OnPeerTypeChange --When sit transition to lit, check-in would be sent and activate the subscription. if any client subscribe to operating mode, and detect it becoems sit, just update the operating mode, there is no need to re-activate the subscription. --- src/app/ReadClient.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp index 5fdae799955e71..bf20a179f9a5fa 100644 --- a/src/app/ReadClient.cpp +++ b/src/app/ReadClient.cpp @@ -516,12 +516,6 @@ void ReadClient::OnPeerTypeChange(PeerType aType) mIsPeerLIT = (aType == PeerType::kLITICD); ChipLogProgress(DataManagement, "Peer is now %s LIT ICD.", mIsPeerLIT ? "a" : "not a"); - - // If the peer is no longer LIT, try to wake up the subscription and do resubscribe when necessary. - if (!mIsPeerLIT) - { - OnActiveModeNotification(); - } } CHIP_ERROR ReadClient::OnMessageReceived(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader, From e49f9a6fff50c5539a29232263ec89c8cf7a2b48 Mon Sep 17 00:00:00 2001 From: Yunhan Wang Date: Fri, 7 Mar 2025 12:06:47 -0800 Subject: [PATCH 03/10] address comments --- src/app/InteractionModelEngine.h | 3 +-- src/app/ReadClient.cpp | 17 +++++++++++------ src/app/ReadClient.h | 12 +++++++++--- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/app/InteractionModelEngine.h b/src/app/InteractionModelEngine.h index 1f286f7dce2974..a307b55e21483a 100644 --- a/src/app/InteractionModelEngine.h +++ b/src/app/InteractionModelEngine.h @@ -236,8 +236,7 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler, /** * Activate the idle subscriptions. * - * When subscribing to ICD and liveness timeout reached, the read client will move to `InactiveICDSubscription` state and - * resubscription can be triggered via OnActiveModeNotification(). + * See ReadClient::OnActiveModeNotification */ void OnActiveModeNotification(ScopedNodeId aPeer); diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp index bf20a179f9a5fa..91903be4c34f4a 100644 --- a/src/app/ReadClient.cpp +++ b/src/app/ReadClient.cpp @@ -484,8 +484,12 @@ CHIP_ERROR ReadClient::GenerateDataVersionFilterList(DataVersionFilterIBs::Build void ReadClient::OnActiveModeNotification() { - // Note: this API only works when issuing subscription via SendAutoResubscribeRequest. VerifyOrDie(mpImEngine->InActiveReadClientList(this)); + + // Note: this API only works when issuing subscription via SendAutoResubscribeRequest, when SendAutoResubscribeRequest is + // called, either mEventPathParamsListSize or mAttributePathParamsListSize is not 0. + VerifyOrDie(mReadPrepareParams.mEventPathParamsListSize != 0 || mReadPrepareParams.mAttributePathParamsListSize != 0); + // When we reach here, the subscription definitely exceeded the liveness timeout. Just continue the unfinished resubscription // logic in `OnLivenessTimeoutCallback`. if (IsInactiveICDSubscription()) @@ -494,18 +498,19 @@ void ReadClient::OnActiveModeNotification() return; } - // If the server sends out check-in message, and there is no reschedule subscription yet in client side at the same time, it means - // current client does not realize subscription has gone, and we should forcibly timeout current subscription, and schedule a new one. + // If the server sends out check-in message, and there is no reschedule subscription yet in client side at the same time, it + // means current client does not realize subscription has gone, and we should forcibly timeout current subscription, and + // schedule a new one. if (!mIsResubscriptionScheduled) { - // Closing will ultimately trigger ScheduleResubscription with the aReestablishCASE argument set to true, effectively + // Closing will ultimately trigger ScheduleResubscription with the aReestablishCASE argument set to true, effectively // rendering the session defunct. Close(CHIP_ERROR_TIMEOUT); return; } - // If the server sends a check-in message and a subscription is already scheduled, it indicates a client-side subscription timeout or failure. - // Cancel the scheduled subscription and initiate a new one immediately. + // If the server sends a check-in message and a subscription is already scheduled, it indicates a client-side subscription + // timeout or failure. Cancel the scheduled subscription and initiate a new one immediately. TriggerResubscribeIfScheduled("check-in message"); } diff --git a/src/app/ReadClient.h b/src/app/ReadClient.h index d8b8a971db8c28..e46f0002cf505c 100644 --- a/src/app/ReadClient.h +++ b/src/app/ReadClient.h @@ -351,11 +351,17 @@ class ReadClient : public Messaging::ExchangeDelegate * Re-activate an inactive subscription. * * When subscribing to LIT-ICD and liveness timeout reached and OnResubscriptionNeeded returns - * CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT, the read client will move to the InactiveICDSubscription state and - * resubscription can be triggered via OnActiveModeNotification(). + * CHIP_ERROR_LIT_SUBSCRIBE_INACTIVE_TIMEOUT, the read client will move to the InactiveICDSubscription state and + * resubscription can be triggered via OnActiveModeNotification(). * * If the subscription is not in the `InactiveICDSubscription` state, this function will do nothing. So it is always safe to - * call this function when a check-in message is received. + * call this function when a check-in message is received. + * + * If the server sends out check-in message, and there is no reschedule subscription yet in client side at the same time, it + * means current client does not realize subscription has gone, and we should forcibly timeout current subscription, and + * schedule a new one. + * + * This API only works when issuing subscription via SendAutoResubscribeRequest. */ void OnActiveModeNotification(); From 8dce4be3aad2236dfb348bd4daf08dc1181cadbd Mon Sep 17 00:00:00 2001 From: Yunhan Wang Date: Fri, 7 Mar 2025 17:20:49 -0800 Subject: [PATCH 04/10] add monitor subject check for subscription activation If caseTag for current subscription does not match with the one set in ICDManagementCluster::RegisterClient for check-in, when receiving check-in message, OnActiveModeNotification would do nothing for current subscription. --- src/app/InteractionModelEngine.cpp | 8 ++++++-- src/app/InteractionModelEngine.h | 2 +- src/app/ReadClient.h | 6 ++++++ src/app/icd/client/CheckInHandler.cpp | 2 +- src/app/icd/client/RefreshKeySender.cpp | 2 +- src/controller/tests/data_model/TestRead.cpp | 4 ++-- 6 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/app/InteractionModelEngine.cpp b/src/app/InteractionModelEngine.cpp index 9a64332aea3fa9..b64e6b62c84523 100644 --- a/src/app/InteractionModelEngine.cpp +++ b/src/app/InteractionModelEngine.cpp @@ -1069,14 +1069,18 @@ void InteractionModelEngine::OnResponseTimeout(Messaging::ExchangeContext * ec) } #if CHIP_CONFIG_ENABLE_READ_CLIENT -void InteractionModelEngine::OnActiveModeNotification(ScopedNodeId aPeer) +void InteractionModelEngine::OnActiveModeNotification(ScopedNodeId aPeer, uint64_t aMonitoredSubject) { for (ReadClient * pListItem = mpActiveReadClientList; pListItem != nullptr;) { auto pNextItem = pListItem->GetNextClient(); // It is possible that pListItem is destroyed by the app in OnActiveModeNotification. // Get the next item before invoking `OnActiveModeNotification`. - if (ScopedNodeId(pListItem->GetPeerNodeId(), pListItem->GetFabricIndex()) == aPeer) + // If caseTag for current subscription does not match with the one set in ICDManagementCluster::RegisterClient for check-in, + // when receiving check-in message, OnActiveModeNotification would do nothing for current subscription. + if (ScopedNodeId(pListItem->GetPeerNodeId(), pListItem->GetFabricIndex()) == aPeer && + pListItem->GetSubjectDescriptor().HasValue() && pListItem->GetSubjectDescriptor().cats.CheckSubjectAgainstCATs(aMonitoredSubject) && + pListItem->GetSubjectDescriptor().subject == aMonitoredSubject) { pListItem->OnActiveModeNotification(); } diff --git a/src/app/InteractionModelEngine.h b/src/app/InteractionModelEngine.h index a307b55e21483a..40c1696ff72738 100644 --- a/src/app/InteractionModelEngine.h +++ b/src/app/InteractionModelEngine.h @@ -238,7 +238,7 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler, * * See ReadClient::OnActiveModeNotification */ - void OnActiveModeNotification(ScopedNodeId aPeer); + void OnActiveModeNotification(ScopedNodeId aPeer, uint64_t aMonitoredSubject); /** * Used to notify when a peer becomes LIT ICD or vice versa. diff --git a/src/app/ReadClient.h b/src/app/ReadClient.h index e46f0002cf505c..fdab2c2b4617cd 100644 --- a/src/app/ReadClient.h +++ b/src/app/ReadClient.h @@ -509,6 +509,12 @@ class ReadClient : public Messaging::ExchangeDelegate */ Optional GetSubscriptionTimeout(); + Optional GetSubjectDescriptor() const + { + VerifyOrReturnValue(mReadPrepareParams.mSessionHolder, NullOptional); + return MakeOptional(mReadPrepareParams.mSessionHolder->AsSecureSession()->GetSubjectDescriptor()); + } + private: friend class TestReadInteraction; friend class InteractionModelEngine; diff --git a/src/app/icd/client/CheckInHandler.cpp b/src/app/icd/client/CheckInHandler.cpp index f4eaa48b114116..7b5d213f7cd7d6 100644 --- a/src/app/icd/client/CheckInHandler.cpp +++ b/src/app/icd/client/CheckInHandler.cpp @@ -138,7 +138,7 @@ CHIP_ERROR CheckInHandler::OnMessageReceived(Messaging::ExchangeContext * ec, co mpICDClientStorage->StoreEntry(clientInfo); mpCheckInDelegate->OnCheckInComplete(clientInfo); #if CHIP_CONFIG_ENABLE_READ_CLIENT - mpImEngine->OnActiveModeNotification(clientInfo.peer_node); + mpImEngine->OnActiveModeNotification(clientInfo.peer_node, clientInfo.monitored_subject); #endif // CHIP_CONFIG_ENABLE_READ_CLIENT } diff --git a/src/app/icd/client/RefreshKeySender.cpp b/src/app/icd/client/RefreshKeySender.cpp index de145b6182187e..6abdbb2d44c397 100644 --- a/src/app/icd/client/RefreshKeySender.cpp +++ b/src/app/icd/client/RefreshKeySender.cpp @@ -69,7 +69,7 @@ CHIP_ERROR RefreshKeySender::RegisterClientWithNewKey(Messaging::ExchangeManager mpCheckInDelegate->OnCheckInComplete(mICDClientInfo); #if CHIP_CONFIG_ENABLE_READ_CLIENT - mpImEngine->OnActiveModeNotification(mICDClientInfo.peer_node); + mpImEngine->OnActiveModeNotification(mICDClientInfo.peer_node, mICDClientInfo.monitored_subject); #endif // CHIP_CONFIG_ENABLE_READ_CLIENT mpCheckInDelegate->OnKeyRefreshDone(this, CHIP_NO_ERROR); }; diff --git a/src/controller/tests/data_model/TestRead.cpp b/src/controller/tests/data_model/TestRead.cpp index 4cb6cd1acf5679..4690c027518b80 100644 --- a/src/controller/tests/data_model/TestRead.cpp +++ b/src/controller/tests/data_model/TestRead.cpp @@ -2330,7 +2330,7 @@ TEST_F(TestRead, TestSubscribe_OnActiveModeNotification) GetLoopback().mNumMessagesToDrop = 0; callback.ClearCounters(); InteractionModelEngine::GetInstance()->OnActiveModeNotification( - ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex())); + ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex()), readClient.GetSubjectDescriptor().Value().subject); EXPECT_EQ(callback.mOnResubscriptionsAttempted, 1); EXPECT_EQ(callback.mLastError, CHIP_ERROR_TIMEOUT); @@ -2393,7 +2393,7 @@ TEST_F(TestRead, TestSubscribeFailed_OnActiveModeNotification) GetLoopback().mNumMessagesToDrop = 0; callback.ClearCounters(); InteractionModelEngine::GetInstance()->OnActiveModeNotification( - ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex())); + ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex()), readClient.GetSubjectDescriptor().Value().subject); // // Drive servicing IO till we have established a subscription. // From 086087076ba168c8f32bdb803c2167baab1c12a8 Mon Sep 17 00:00:00 2001 From: Yunhan Wang Date: Fri, 7 Mar 2025 19:49:54 -0800 Subject: [PATCH 05/10] fix compilation --- src/app/InteractionModelEngine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/InteractionModelEngine.cpp b/src/app/InteractionModelEngine.cpp index b64e6b62c84523..5d1fe852e35f99 100644 --- a/src/app/InteractionModelEngine.cpp +++ b/src/app/InteractionModelEngine.cpp @@ -1079,8 +1079,8 @@ void InteractionModelEngine::OnActiveModeNotification(ScopedNodeId aPeer, uint64 // If caseTag for current subscription does not match with the one set in ICDManagementCluster::RegisterClient for check-in, // when receiving check-in message, OnActiveModeNotification would do nothing for current subscription. if (ScopedNodeId(pListItem->GetPeerNodeId(), pListItem->GetFabricIndex()) == aPeer && - pListItem->GetSubjectDescriptor().HasValue() && pListItem->GetSubjectDescriptor().cats.CheckSubjectAgainstCATs(aMonitoredSubject) && - pListItem->GetSubjectDescriptor().subject == aMonitoredSubject) + pListItem->GetSubjectDescriptor().HasValue() && pListItem->GetSubjectDescriptor().Value().cats.CheckSubjectAgainstCATs(aMonitoredSubject) && + pListItem->GetSubjectDescriptor().Value().subject == aMonitoredSubject) { pListItem->OnActiveModeNotification(); } From 9cda64928604a1612eb82faf7463ee4ec5d9c860 Mon Sep 17 00:00:00 2001 From: Yunhan Wang Date: Mon, 10 Mar 2025 11:48:41 -0700 Subject: [PATCH 06/10] introduce mCatsMatchCheckIn to indicate whether cats for icd registration matched with the current subscription --- src/app/InteractionModelEngine.cpp | 8 ++------ src/app/InteractionModelEngine.h | 2 +- src/app/ReadClient.cpp | 4 ++++ src/app/ReadClient.h | 6 ------ src/app/ReadPrepareParams.h | 5 +++++ src/app/icd/client/CheckInHandler.cpp | 2 +- src/app/icd/client/RefreshKeySender.cpp | 2 +- src/controller/tests/data_model/TestRead.cpp | 4 ++-- 8 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/app/InteractionModelEngine.cpp b/src/app/InteractionModelEngine.cpp index 5d1fe852e35f99..9a64332aea3fa9 100644 --- a/src/app/InteractionModelEngine.cpp +++ b/src/app/InteractionModelEngine.cpp @@ -1069,18 +1069,14 @@ void InteractionModelEngine::OnResponseTimeout(Messaging::ExchangeContext * ec) } #if CHIP_CONFIG_ENABLE_READ_CLIENT -void InteractionModelEngine::OnActiveModeNotification(ScopedNodeId aPeer, uint64_t aMonitoredSubject) +void InteractionModelEngine::OnActiveModeNotification(ScopedNodeId aPeer) { for (ReadClient * pListItem = mpActiveReadClientList; pListItem != nullptr;) { auto pNextItem = pListItem->GetNextClient(); // It is possible that pListItem is destroyed by the app in OnActiveModeNotification. // Get the next item before invoking `OnActiveModeNotification`. - // If caseTag for current subscription does not match with the one set in ICDManagementCluster::RegisterClient for check-in, - // when receiving check-in message, OnActiveModeNotification would do nothing for current subscription. - if (ScopedNodeId(pListItem->GetPeerNodeId(), pListItem->GetFabricIndex()) == aPeer && - pListItem->GetSubjectDescriptor().HasValue() && pListItem->GetSubjectDescriptor().Value().cats.CheckSubjectAgainstCATs(aMonitoredSubject) && - pListItem->GetSubjectDescriptor().Value().subject == aMonitoredSubject) + if (ScopedNodeId(pListItem->GetPeerNodeId(), pListItem->GetFabricIndex()) == aPeer) { pListItem->OnActiveModeNotification(); } diff --git a/src/app/InteractionModelEngine.h b/src/app/InteractionModelEngine.h index 40c1696ff72738..a307b55e21483a 100644 --- a/src/app/InteractionModelEngine.h +++ b/src/app/InteractionModelEngine.h @@ -238,7 +238,7 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler, * * See ReadClient::OnActiveModeNotification */ - void OnActiveModeNotification(ScopedNodeId aPeer, uint64_t aMonitoredSubject); + void OnActiveModeNotification(ScopedNodeId aPeer); /** * Used to notify when a peer becomes LIT ICD or vice versa. diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp index 91903be4c34f4a..9edd16735b5f81 100644 --- a/src/app/ReadClient.cpp +++ b/src/app/ReadClient.cpp @@ -490,6 +490,10 @@ void ReadClient::OnActiveModeNotification() // called, either mEventPathParamsListSize or mAttributePathParamsListSize is not 0. VerifyOrDie(mReadPrepareParams.mEventPathParamsListSize != 0 || mReadPrepareParams.mAttributePathParamsListSize != 0); + // If mCatsMatchCheckIn is true, it means cats used in icd registration matches with the one in current subscription, OnActiveModeNotification + // continues to revive the subscription as needed, otherwise, do nothing. + VerifyOrReturn(mReadPrepareParams.mCatsMatchCheckIn); + // When we reach here, the subscription definitely exceeded the liveness timeout. Just continue the unfinished resubscription // logic in `OnLivenessTimeoutCallback`. if (IsInactiveICDSubscription()) diff --git a/src/app/ReadClient.h b/src/app/ReadClient.h index fdab2c2b4617cd..e46f0002cf505c 100644 --- a/src/app/ReadClient.h +++ b/src/app/ReadClient.h @@ -509,12 +509,6 @@ class ReadClient : public Messaging::ExchangeDelegate */ Optional GetSubscriptionTimeout(); - Optional GetSubjectDescriptor() const - { - VerifyOrReturnValue(mReadPrepareParams.mSessionHolder, NullOptional); - return MakeOptional(mReadPrepareParams.mSessionHolder->AsSecureSession()->GetSubjectDescriptor()); - } - private: friend class TestReadInteraction; friend class InteractionModelEngine; diff --git a/src/app/ReadPrepareParams.h b/src/app/ReadPrepareParams.h index 7f927f9ea47dac..592f696b78bb76 100644 --- a/src/app/ReadPrepareParams.h +++ b/src/app/ReadPrepareParams.h @@ -49,6 +49,9 @@ struct ReadPrepareParams bool mIsFabricFiltered = true; bool mIsPeerLIT = false; + // see ReadClient::OnActiveModeNotification + bool mCatsMatchCheckIn = true; + ReadPrepareParams() {} ReadPrepareParams(const SessionHandle & sessionHandle) { mSessionHolder.Grab(sessionHandle); } ReadPrepareParams(ReadPrepareParams && other) : mSessionHolder(other.mSessionHolder) @@ -66,6 +69,7 @@ struct ReadPrepareParams mTimeout = other.mTimeout; mIsFabricFiltered = other.mIsFabricFiltered; mIsPeerLIT = other.mIsPeerLIT; + mCatsMatchCheckIn = other.mCatsMatchCheckIn; other.mpEventPathParamsList = nullptr; other.mEventPathParamsListSize = 0; other.mpAttributePathParamsList = nullptr; @@ -91,6 +95,7 @@ struct ReadPrepareParams mTimeout = other.mTimeout; mIsFabricFiltered = other.mIsFabricFiltered; mIsPeerLIT = other.mIsPeerLIT; + mCatsMatchCheckIn = other.mCatsMatchCheckIn; other.mpEventPathParamsList = nullptr; other.mEventPathParamsListSize = 0; other.mpAttributePathParamsList = nullptr; diff --git a/src/app/icd/client/CheckInHandler.cpp b/src/app/icd/client/CheckInHandler.cpp index 7b5d213f7cd7d6..f4eaa48b114116 100644 --- a/src/app/icd/client/CheckInHandler.cpp +++ b/src/app/icd/client/CheckInHandler.cpp @@ -138,7 +138,7 @@ CHIP_ERROR CheckInHandler::OnMessageReceived(Messaging::ExchangeContext * ec, co mpICDClientStorage->StoreEntry(clientInfo); mpCheckInDelegate->OnCheckInComplete(clientInfo); #if CHIP_CONFIG_ENABLE_READ_CLIENT - mpImEngine->OnActiveModeNotification(clientInfo.peer_node, clientInfo.monitored_subject); + mpImEngine->OnActiveModeNotification(clientInfo.peer_node); #endif // CHIP_CONFIG_ENABLE_READ_CLIENT } diff --git a/src/app/icd/client/RefreshKeySender.cpp b/src/app/icd/client/RefreshKeySender.cpp index 6abdbb2d44c397..de145b6182187e 100644 --- a/src/app/icd/client/RefreshKeySender.cpp +++ b/src/app/icd/client/RefreshKeySender.cpp @@ -69,7 +69,7 @@ CHIP_ERROR RefreshKeySender::RegisterClientWithNewKey(Messaging::ExchangeManager mpCheckInDelegate->OnCheckInComplete(mICDClientInfo); #if CHIP_CONFIG_ENABLE_READ_CLIENT - mpImEngine->OnActiveModeNotification(mICDClientInfo.peer_node, mICDClientInfo.monitored_subject); + mpImEngine->OnActiveModeNotification(mICDClientInfo.peer_node); #endif // CHIP_CONFIG_ENABLE_READ_CLIENT mpCheckInDelegate->OnKeyRefreshDone(this, CHIP_NO_ERROR); }; diff --git a/src/controller/tests/data_model/TestRead.cpp b/src/controller/tests/data_model/TestRead.cpp index 4690c027518b80..4cb6cd1acf5679 100644 --- a/src/controller/tests/data_model/TestRead.cpp +++ b/src/controller/tests/data_model/TestRead.cpp @@ -2330,7 +2330,7 @@ TEST_F(TestRead, TestSubscribe_OnActiveModeNotification) GetLoopback().mNumMessagesToDrop = 0; callback.ClearCounters(); InteractionModelEngine::GetInstance()->OnActiveModeNotification( - ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex()), readClient.GetSubjectDescriptor().Value().subject); + ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex())); EXPECT_EQ(callback.mOnResubscriptionsAttempted, 1); EXPECT_EQ(callback.mLastError, CHIP_ERROR_TIMEOUT); @@ -2393,7 +2393,7 @@ TEST_F(TestRead, TestSubscribeFailed_OnActiveModeNotification) GetLoopback().mNumMessagesToDrop = 0; callback.ClearCounters(); InteractionModelEngine::GetInstance()->OnActiveModeNotification( - ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex()), readClient.GetSubjectDescriptor().Value().subject); + ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex())); // // Drive servicing IO till we have established a subscription. // From 287a09333b3e14471d96847dad8ede0cd68859f0 Mon Sep 17 00:00:00 2001 From: Yunhan Wang Date: Mon, 10 Mar 2025 15:41:25 -0700 Subject: [PATCH 07/10] address comments and add tests --- src/app/ReadClient.cpp | 8 +- src/app/ReadClient.h | 4 +- src/controller/tests/data_model/TestRead.cpp | 133 +++++++++++++++++++ 3 files changed, 139 insertions(+), 6 deletions(-) diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp index 9edd16735b5f81..77f00af1424a14 100644 --- a/src/app/ReadClient.cpp +++ b/src/app/ReadClient.cpp @@ -486,9 +486,9 @@ void ReadClient::OnActiveModeNotification() { VerifyOrDie(mpImEngine->InActiveReadClientList(this)); - // Note: this API only works when issuing subscription via SendAutoResubscribeRequest, when SendAutoResubscribeRequest is + // Note: this API only works when issuing subscription via SendAutoResubscribeRequest. When SendAutoResubscribeRequest is // called, either mEventPathParamsListSize or mAttributePathParamsListSize is not 0. - VerifyOrDie(mReadPrepareParams.mEventPathParamsListSize != 0 || mReadPrepareParams.mAttributePathParamsListSize != 0); + VerifyOrReturn(mReadPrepareParams.mEventPathParamsListSize != 0 || mReadPrepareParams.mAttributePathParamsListSize != 0); // If mCatsMatchCheckIn is true, it means cats used in icd registration matches with the one in current subscription, OnActiveModeNotification // continues to revive the subscription as needed, otherwise, do nothing. @@ -502,8 +502,8 @@ void ReadClient::OnActiveModeNotification() return; } - // If the server sends out check-in message, and there is no reschedule subscription yet in client side at the same time, it - // means current client does not realize subscription has gone, and we should forcibly timeout current subscription, and + // If the server sends out check-in message, and there is a tracked active subscription in client side at the same time, it + // means current client does not realize this tracked subscription has gone, and we should forcibly timeout current subscription, and // schedule a new one. if (!mIsResubscriptionScheduled) { diff --git a/src/app/ReadClient.h b/src/app/ReadClient.h index e46f0002cf505c..34dce00ea62e5a 100644 --- a/src/app/ReadClient.h +++ b/src/app/ReadClient.h @@ -357,8 +357,8 @@ class ReadClient : public Messaging::ExchangeDelegate * If the subscription is not in the `InactiveICDSubscription` state, this function will do nothing. So it is always safe to * call this function when a check-in message is received. * - * If the server sends out check-in message, and there is no reschedule subscription yet in client side at the same time, it - * means current client does not realize subscription has gone, and we should forcibly timeout current subscription, and + * If the server sends out check-in message, and there is a active tracked active subscription in client side at the same time, it + * means current client does not realize this tracked subscription has gone, and we should forcibly timeout current subscription, and * schedule a new one. * * This API only works when issuing subscription via SendAutoResubscribeRequest. diff --git a/src/controller/tests/data_model/TestRead.cpp b/src/controller/tests/data_model/TestRead.cpp index 4cb6cd1acf5679..ffd79c0525a2a2 100644 --- a/src/controller/tests/data_model/TestRead.cpp +++ b/src/controller/tests/data_model/TestRead.cpp @@ -2354,6 +2354,139 @@ TEST_F(TestRead, TestSubscribe_OnActiveModeNotification) EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); } +/** + * When all tracked subscriptions go away in server, check-in message is received and OnActiveModeNotification is called in client side, the tracked + * subscription would be torn down and a new one would be rescheduled in client side. + */ +TEST_F(TestRead, TestSubscribe_SubGoAwayInserverOnActiveModeNotification) +{ + auto sessionHandle = GetSessionBobToAlice(); + + SetMRPMode(MessagingContext::MRPMode::kResponsive); + + { + TestResubscriptionCallback callback; + ReadClient readClient(InteractionModelEngine::GetInstance(), &GetExchangeManager(), callback, + ReadClient::InteractionType::Subscribe); + + callback.mScheduleLITResubscribeImmediately = false; + callback.SetReadClient(&readClient); + + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); + + // Read full wildcard paths, repeat twice to ensure chunking. + AttributePathParams attributePathParams[1]; + readPrepareParams.mpAttributePathParamsList = attributePathParams; + readPrepareParams.mAttributePathParamsListSize = MATTER_ARRAY_SIZE(attributePathParams); + attributePathParams[0].mEndpointId = kTestEndpointId; + attributePathParams[0].mClusterId = Clusters::UnitTesting::Id; + attributePathParams[0].mAttributeId = Clusters::UnitTesting::Attributes::Boolean::Id; + + constexpr uint16_t maxIntervalCeilingSeconds = 1; + + readPrepareParams.mMaxIntervalCeilingSeconds = maxIntervalCeilingSeconds; + readPrepareParams.mIsPeerLIT = true; + + auto err = readClient.SendAutoResubscribeRequest(std::move(readPrepareParams)); + EXPECT_EQ(err, CHIP_NO_ERROR); + + // + // Drive servicing IO till we have established a subscription. + // + GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), + [&]() { return callback.mOnSubscriptionEstablishedCount >= 1; }); + EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1); + EXPECT_EQ(callback.mOnError, 0); + EXPECT_EQ(callback.mOnResubscriptionsAttempted, 0); + + GetLoopback().mNumMessagesToDrop = 0; + callback.ClearCounters(); + InteractionModelEngine::GetInstance()->OnActiveModeNotification( + ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex())); + EXPECT_EQ(callback.mOnResubscriptionsAttempted, 1); + EXPECT_EQ(callback.mLastError, CHIP_ERROR_TIMEOUT); + + // + // Drive servicing IO till we have established a subscription. + // + GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), + [&]() { return callback.mOnSubscriptionEstablishedCount == 1; }); + EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1); + + // + // With re-sub enabled, we shouldn't have encountered any errors + // + EXPECT_EQ(callback.mOnError, 0); + EXPECT_EQ(callback.mOnDone, 0); + } + + SetMRPMode(MessagingContext::MRPMode::kDefault); + + InteractionModelEngine::GetInstance()->ShutdownActiveReads(); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); +} + +/** + * When all tracked subscriptions go away in server, check-in message is received and OnActiveModeNotification is called in client side, the + * untracked subscription would be kept. + */ +TEST_F(TestRead, TestSubscribe_MismatchedSubGoAwayInserverOnActiveModeNotification) +{ + auto sessionHandle = GetSessionBobToAlice(); + + SetMRPMode(MessagingContext::MRPMode::kResponsive); + + { + TestResubscriptionCallback callback; + ReadClient readClient(InteractionModelEngine::GetInstance(), &GetExchangeManager(), callback, + ReadClient::InteractionType::Subscribe); + + callback.mScheduleLITResubscribeImmediately = false; + callback.SetReadClient(&readClient); + + ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); + + // Read full wildcard paths, repeat twice to ensure chunking. + AttributePathParams attributePathParams[1]; + readPrepareParams.mpAttributePathParamsList = attributePathParams; + readPrepareParams.mAttributePathParamsListSize = MATTER_ARRAY_SIZE(attributePathParams); + attributePathParams[0].mEndpointId = kTestEndpointId; + attributePathParams[0].mClusterId = Clusters::UnitTesting::Id; + attributePathParams[0].mAttributeId = Clusters::UnitTesting::Attributes::Boolean::Id; + readPrepareParams.mCatsMatchCheckIn = false; + constexpr uint16_t maxIntervalCeilingSeconds = 1; + + readPrepareParams.mMaxIntervalCeilingSeconds = maxIntervalCeilingSeconds; + readPrepareParams.mIsPeerLIT = true; + + auto err = readClient.SendAutoResubscribeRequest(std::move(readPrepareParams)); + EXPECT_EQ(err, CHIP_NO_ERROR); + + // + // Drive servicing IO till we have established a subscription. + // + GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000), + [&]() { return callback.mOnSubscriptionEstablishedCount >= 1; }); + EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1); + EXPECT_EQ(callback.mOnError, 0); + EXPECT_EQ(callback.mOnResubscriptionsAttempted, 0); + + GetLoopback().mNumMessagesToDrop = 0; + callback.ClearCounters(); + InteractionModelEngine::GetInstance()->OnActiveModeNotification( + ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex())); + EXPECT_EQ(callback.mOnResubscriptionsAttempted, 0); + EXPECT_EQ(callback.mLastError, CHIP_NO_ERROR); + EXPECT_EQ(callback.mOnError, 0); + EXPECT_EQ(callback.mOnDone, 0); + } + + SetMRPMode(MessagingContext::MRPMode::kDefault); + + InteractionModelEngine::GetInstance()->ShutdownActiveReads(); + EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); +} + TEST_F(TestRead, TestSubscribeFailed_OnActiveModeNotification) { auto sessionHandle = GetSessionBobToAlice(); From 2b29328684fb05ef054661e83b4672da9fd35e60 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Mon, 10 Mar 2025 22:42:16 +0000 Subject: [PATCH 08/10] Restyled by whitespace --- src/controller/tests/data_model/TestRead.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controller/tests/data_model/TestRead.cpp b/src/controller/tests/data_model/TestRead.cpp index ffd79c0525a2a2..af7925780253b4 100644 --- a/src/controller/tests/data_model/TestRead.cpp +++ b/src/controller/tests/data_model/TestRead.cpp @@ -2427,7 +2427,7 @@ TEST_F(TestRead, TestSubscribe_SubGoAwayInserverOnActiveModeNotification) } /** - * When all tracked subscriptions go away in server, check-in message is received and OnActiveModeNotification is called in client side, the + * When all tracked subscriptions go away in server, check-in message is received and OnActiveModeNotification is called in client side, the * untracked subscription would be kept. */ TEST_F(TestRead, TestSubscribe_MismatchedSubGoAwayInserverOnActiveModeNotification) From 6a97e2cf096409723c49f6a32c246e0957c9f7b8 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Mon, 10 Mar 2025 22:42:21 +0000 Subject: [PATCH 09/10] Restyled by clang-format --- src/app/ReadClient.cpp | 8 ++++---- src/app/ReadClient.h | 6 +++--- src/app/ReadPrepareParams.h | 2 +- src/controller/tests/data_model/TestRead.cpp | 10 +++++----- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp index 77f00af1424a14..82ebe4f6988189 100644 --- a/src/app/ReadClient.cpp +++ b/src/app/ReadClient.cpp @@ -490,8 +490,8 @@ void ReadClient::OnActiveModeNotification() // called, either mEventPathParamsListSize or mAttributePathParamsListSize is not 0. VerifyOrReturn(mReadPrepareParams.mEventPathParamsListSize != 0 || mReadPrepareParams.mAttributePathParamsListSize != 0); - // If mCatsMatchCheckIn is true, it means cats used in icd registration matches with the one in current subscription, OnActiveModeNotification - // continues to revive the subscription as needed, otherwise, do nothing. + // If mCatsMatchCheckIn is true, it means cats used in icd registration matches with the one in current subscription, + // OnActiveModeNotification continues to revive the subscription as needed, otherwise, do nothing. VerifyOrReturn(mReadPrepareParams.mCatsMatchCheckIn); // When we reach here, the subscription definitely exceeded the liveness timeout. Just continue the unfinished resubscription @@ -503,8 +503,8 @@ void ReadClient::OnActiveModeNotification() } // If the server sends out check-in message, and there is a tracked active subscription in client side at the same time, it - // means current client does not realize this tracked subscription has gone, and we should forcibly timeout current subscription, and - // schedule a new one. + // means current client does not realize this tracked subscription has gone, and we should forcibly timeout current + // subscription, and schedule a new one. if (!mIsResubscriptionScheduled) { // Closing will ultimately trigger ScheduleResubscription with the aReestablishCASE argument set to true, effectively diff --git a/src/app/ReadClient.h b/src/app/ReadClient.h index 34dce00ea62e5a..9cc62ab3d8177a 100644 --- a/src/app/ReadClient.h +++ b/src/app/ReadClient.h @@ -357,9 +357,9 @@ class ReadClient : public Messaging::ExchangeDelegate * If the subscription is not in the `InactiveICDSubscription` state, this function will do nothing. So it is always safe to * call this function when a check-in message is received. * - * If the server sends out check-in message, and there is a active tracked active subscription in client side at the same time, it - * means current client does not realize this tracked subscription has gone, and we should forcibly timeout current subscription, and - * schedule a new one. + * If the server sends out check-in message, and there is a active tracked active subscription in client side at the same time, + * it means current client does not realize this tracked subscription has gone, and we should forcibly timeout current + * subscription, and schedule a new one. * * This API only works when issuing subscription via SendAutoResubscribeRequest. */ diff --git a/src/app/ReadPrepareParams.h b/src/app/ReadPrepareParams.h index 592f696b78bb76..9a1b8df540cc5b 100644 --- a/src/app/ReadPrepareParams.h +++ b/src/app/ReadPrepareParams.h @@ -50,7 +50,7 @@ struct ReadPrepareParams bool mIsPeerLIT = false; // see ReadClient::OnActiveModeNotification - bool mCatsMatchCheckIn = true; + bool mCatsMatchCheckIn = true; ReadPrepareParams() {} ReadPrepareParams(const SessionHandle & sessionHandle) { mSessionHolder.Grab(sessionHandle); } diff --git a/src/controller/tests/data_model/TestRead.cpp b/src/controller/tests/data_model/TestRead.cpp index af7925780253b4..e3bafa05722d10 100644 --- a/src/controller/tests/data_model/TestRead.cpp +++ b/src/controller/tests/data_model/TestRead.cpp @@ -2355,8 +2355,8 @@ TEST_F(TestRead, TestSubscribe_OnActiveModeNotification) } /** - * When all tracked subscriptions go away in server, check-in message is received and OnActiveModeNotification is called in client side, the tracked - * subscription would be torn down and a new one would be rescheduled in client side. + * When all tracked subscriptions go away in server, check-in message is received and OnActiveModeNotification is called in client + * side, the tracked subscription would be torn down and a new one would be rescheduled in client side. */ TEST_F(TestRead, TestSubscribe_SubGoAwayInserverOnActiveModeNotification) { @@ -2427,8 +2427,8 @@ TEST_F(TestRead, TestSubscribe_SubGoAwayInserverOnActiveModeNotification) } /** - * When all tracked subscriptions go away in server, check-in message is received and OnActiveModeNotification is called in client side, the - * untracked subscription would be kept. + * When all tracked subscriptions go away in server, check-in message is received and OnActiveModeNotification is called in client + * side, the untracked subscription would be kept. */ TEST_F(TestRead, TestSubscribe_MismatchedSubGoAwayInserverOnActiveModeNotification) { @@ -2454,7 +2454,7 @@ TEST_F(TestRead, TestSubscribe_MismatchedSubGoAwayInserverOnActiveModeNotificati attributePathParams[0].mClusterId = Clusters::UnitTesting::Id; attributePathParams[0].mAttributeId = Clusters::UnitTesting::Attributes::Boolean::Id; readPrepareParams.mCatsMatchCheckIn = false; - constexpr uint16_t maxIntervalCeilingSeconds = 1; + constexpr uint16_t maxIntervalCeilingSeconds = 1; readPrepareParams.mMaxIntervalCeilingSeconds = maxIntervalCeilingSeconds; readPrepareParams.mIsPeerLIT = true; From 1fca04a9e88295463afd849d4de21b3525279bd6 Mon Sep 17 00:00:00 2001 From: Yunhan Wang Date: Mon, 17 Mar 2025 17:14:37 -0700 Subject: [PATCH 10/10] address comments --- src/app/InteractionModelEngine.cpp | 6 ++++-- src/app/InteractionModelEngine.h | 4 ++-- src/app/ReadClient.cpp | 15 ++++++++------- src/app/ReadPrepareParams.h | 5 ----- src/app/icd/client/CheckInHandler.cpp | 2 +- src/app/icd/client/RefreshKeySender.cpp | 2 +- src/controller/tests/data_model/TestRead.cpp | 9 ++++----- 7 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/app/InteractionModelEngine.cpp b/src/app/InteractionModelEngine.cpp index 9a64332aea3fa9..5ce4c3771ad0f2 100644 --- a/src/app/InteractionModelEngine.cpp +++ b/src/app/InteractionModelEngine.cpp @@ -1069,14 +1069,16 @@ void InteractionModelEngine::OnResponseTimeout(Messaging::ExchangeContext * ec) } #if CHIP_CONFIG_ENABLE_READ_CLIENT -void InteractionModelEngine::OnActiveModeNotification(ScopedNodeId aPeer) +void InteractionModelEngine::OnActiveModeNotification(ScopedNodeId aPeer, uint64_t aMonitoredSubject) { for (ReadClient * pListItem = mpActiveReadClientList; pListItem != nullptr;) { auto pNextItem = pListItem->GetNextClient(); // It is possible that pListItem is destroyed by the app in OnActiveModeNotification. // Get the next item before invoking `OnActiveModeNotification`. - if (ScopedNodeId(pListItem->GetPeerNodeId(), pListItem->GetFabricIndex()) == aPeer) + CATValues cats; + mpFabricTable->FetchCATs(pListItem->GetFabricIndex(), cats); + if (ScopedNodeId(pListItem->GetPeerNodeId(), pListItem->GetFabricIndex()) == aPeer && cats.CheckSubjectAgainstCATs(aMonitoredSubject)) { pListItem->OnActiveModeNotification(); } diff --git a/src/app/InteractionModelEngine.h b/src/app/InteractionModelEngine.h index a307b55e21483a..7bb9e60b40d813 100644 --- a/src/app/InteractionModelEngine.h +++ b/src/app/InteractionModelEngine.h @@ -238,13 +238,13 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler, * * See ReadClient::OnActiveModeNotification */ - void OnActiveModeNotification(ScopedNodeId aPeer); + void OnActiveModeNotification(ScopedNodeId aPeer, uint64_t aMonitoredSubject); /** * Used to notify when a peer becomes LIT ICD or vice versa. * * ReadClient will call this function when it finds any updates of the OperatingMode attribute from ICD management - * cluster. The application doesn't need to call this function, usually. + * cluster. The application doesn't need to call this function, usually. */ void OnPeerTypeChange(ScopedNodeId aPeer, ReadClient::PeerType aType); diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp index 82ebe4f6988189..cec540b097645b 100644 --- a/src/app/ReadClient.cpp +++ b/src/app/ReadClient.cpp @@ -490,10 +490,6 @@ void ReadClient::OnActiveModeNotification() // called, either mEventPathParamsListSize or mAttributePathParamsListSize is not 0. VerifyOrReturn(mReadPrepareParams.mEventPathParamsListSize != 0 || mReadPrepareParams.mAttributePathParamsListSize != 0); - // If mCatsMatchCheckIn is true, it means cats used in icd registration matches with the one in current subscription, - // OnActiveModeNotification continues to revive the subscription as needed, otherwise, do nothing. - VerifyOrReturn(mReadPrepareParams.mCatsMatchCheckIn); - // When we reach here, the subscription definitely exceeded the liveness timeout. Just continue the unfinished resubscription // logic in `OnLivenessTimeoutCallback`. if (IsInactiveICDSubscription()) @@ -502,9 +498,8 @@ void ReadClient::OnActiveModeNotification() return; } - // If the server sends out check-in message, and there is a tracked active subscription in client side at the same time, it - // means current client does not realize this tracked subscription has gone, and we should forcibly timeout current - // subscription, and schedule a new one. + // When receiving check-in message, it means all tracked subscriptions for this node has gone in server side, if there is a related active subscription + // and subscription has not yet rescheduled in client side, we should forcibly timeout the current subscription, and schedule a new one. if (!mIsResubscriptionScheduled) { // Closing will ultimately trigger ScheduleResubscription with the aReestablishCASE argument set to true, effectively @@ -525,6 +520,12 @@ void ReadClient::OnPeerTypeChange(PeerType aType) mIsPeerLIT = (aType == PeerType::kLITICD); ChipLogProgress(DataManagement, "Peer is now %s LIT ICD.", mIsPeerLIT ? "a" : "not a"); + + // If the peer is no longer LIT and in inactive ICD subscription status, try to wake up the subscription and do resubscribe. + if (!mIsPeerLIT && IsInactiveICDSubscription()) + { + TriggerResubscriptionForLivenessTimeout(CHIP_ERROR_TIMEOUT); + } } CHIP_ERROR ReadClient::OnMessageReceived(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader, diff --git a/src/app/ReadPrepareParams.h b/src/app/ReadPrepareParams.h index 9a1b8df540cc5b..7f927f9ea47dac 100644 --- a/src/app/ReadPrepareParams.h +++ b/src/app/ReadPrepareParams.h @@ -49,9 +49,6 @@ struct ReadPrepareParams bool mIsFabricFiltered = true; bool mIsPeerLIT = false; - // see ReadClient::OnActiveModeNotification - bool mCatsMatchCheckIn = true; - ReadPrepareParams() {} ReadPrepareParams(const SessionHandle & sessionHandle) { mSessionHolder.Grab(sessionHandle); } ReadPrepareParams(ReadPrepareParams && other) : mSessionHolder(other.mSessionHolder) @@ -69,7 +66,6 @@ struct ReadPrepareParams mTimeout = other.mTimeout; mIsFabricFiltered = other.mIsFabricFiltered; mIsPeerLIT = other.mIsPeerLIT; - mCatsMatchCheckIn = other.mCatsMatchCheckIn; other.mpEventPathParamsList = nullptr; other.mEventPathParamsListSize = 0; other.mpAttributePathParamsList = nullptr; @@ -95,7 +91,6 @@ struct ReadPrepareParams mTimeout = other.mTimeout; mIsFabricFiltered = other.mIsFabricFiltered; mIsPeerLIT = other.mIsPeerLIT; - mCatsMatchCheckIn = other.mCatsMatchCheckIn; other.mpEventPathParamsList = nullptr; other.mEventPathParamsListSize = 0; other.mpAttributePathParamsList = nullptr; diff --git a/src/app/icd/client/CheckInHandler.cpp b/src/app/icd/client/CheckInHandler.cpp index f4eaa48b114116..7b5d213f7cd7d6 100644 --- a/src/app/icd/client/CheckInHandler.cpp +++ b/src/app/icd/client/CheckInHandler.cpp @@ -138,7 +138,7 @@ CHIP_ERROR CheckInHandler::OnMessageReceived(Messaging::ExchangeContext * ec, co mpICDClientStorage->StoreEntry(clientInfo); mpCheckInDelegate->OnCheckInComplete(clientInfo); #if CHIP_CONFIG_ENABLE_READ_CLIENT - mpImEngine->OnActiveModeNotification(clientInfo.peer_node); + mpImEngine->OnActiveModeNotification(clientInfo.peer_node, clientInfo.monitored_subject); #endif // CHIP_CONFIG_ENABLE_READ_CLIENT } diff --git a/src/app/icd/client/RefreshKeySender.cpp b/src/app/icd/client/RefreshKeySender.cpp index de145b6182187e..2907d55792b0b4 100644 --- a/src/app/icd/client/RefreshKeySender.cpp +++ b/src/app/icd/client/RefreshKeySender.cpp @@ -69,7 +69,7 @@ CHIP_ERROR RefreshKeySender::RegisterClientWithNewKey(Messaging::ExchangeManager mpCheckInDelegate->OnCheckInComplete(mICDClientInfo); #if CHIP_CONFIG_ENABLE_READ_CLIENT - mpImEngine->OnActiveModeNotification(mICDClientInfo.peer_node); + mpImEngine->OnActiveModeNotification(mICDClientInfo.peer_node,mICDClientInfo.monitored_subject); #endif // CHIP_CONFIG_ENABLE_READ_CLIENT mpCheckInDelegate->OnKeyRefreshDone(this, CHIP_NO_ERROR); }; diff --git a/src/controller/tests/data_model/TestRead.cpp b/src/controller/tests/data_model/TestRead.cpp index e3bafa05722d10..9aca9cd648e754 100644 --- a/src/controller/tests/data_model/TestRead.cpp +++ b/src/controller/tests/data_model/TestRead.cpp @@ -2330,7 +2330,7 @@ TEST_F(TestRead, TestSubscribe_OnActiveModeNotification) GetLoopback().mNumMessagesToDrop = 0; callback.ClearCounters(); InteractionModelEngine::GetInstance()->OnActiveModeNotification( - ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex())); + ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex()), static_cast(0)); EXPECT_EQ(callback.mOnResubscriptionsAttempted, 1); EXPECT_EQ(callback.mLastError, CHIP_ERROR_TIMEOUT); @@ -2402,7 +2402,7 @@ TEST_F(TestRead, TestSubscribe_SubGoAwayInserverOnActiveModeNotification) GetLoopback().mNumMessagesToDrop = 0; callback.ClearCounters(); InteractionModelEngine::GetInstance()->OnActiveModeNotification( - ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex())); + ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex()), static_cast(0)); EXPECT_EQ(callback.mOnResubscriptionsAttempted, 1); EXPECT_EQ(callback.mLastError, CHIP_ERROR_TIMEOUT); @@ -2453,7 +2453,6 @@ TEST_F(TestRead, TestSubscribe_MismatchedSubGoAwayInserverOnActiveModeNotificati attributePathParams[0].mEndpointId = kTestEndpointId; attributePathParams[0].mClusterId = Clusters::UnitTesting::Id; attributePathParams[0].mAttributeId = Clusters::UnitTesting::Attributes::Boolean::Id; - readPrepareParams.mCatsMatchCheckIn = false; constexpr uint16_t maxIntervalCeilingSeconds = 1; readPrepareParams.mMaxIntervalCeilingSeconds = maxIntervalCeilingSeconds; @@ -2474,7 +2473,7 @@ TEST_F(TestRead, TestSubscribe_MismatchedSubGoAwayInserverOnActiveModeNotificati GetLoopback().mNumMessagesToDrop = 0; callback.ClearCounters(); InteractionModelEngine::GetInstance()->OnActiveModeNotification( - ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex())); + ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex()), static_cast(0)); EXPECT_EQ(callback.mOnResubscriptionsAttempted, 0); EXPECT_EQ(callback.mLastError, CHIP_NO_ERROR); EXPECT_EQ(callback.mOnError, 0); @@ -2526,7 +2525,7 @@ TEST_F(TestRead, TestSubscribeFailed_OnActiveModeNotification) GetLoopback().mNumMessagesToDrop = 0; callback.ClearCounters(); InteractionModelEngine::GetInstance()->OnActiveModeNotification( - ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex())); + ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex()), static_cast(0)); // // Drive servicing IO till we have established a subscription. //