Skip to content

Commit ce03884

Browse files
yunhanw-googlerestyled-commits
authored andcommitted
[ICD] Re-activate subscription when receiving check-in message if subscription fails and resub is scheduled (project-chip#37481)
* Resubscribe when check-in is received and it is not in inactive state * Restyled by whitespace * address comments * add test * Restyled by clang-format --------- Co-authored-by: Restyled.io <commits@restyled.io>
1 parent c89ba56 commit ce03884

File tree

2 files changed

+70
-5
lines changed

2 files changed

+70
-5
lines changed

src/app/ReadClient.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -484,14 +484,16 @@ CHIP_ERROR ReadClient::GenerateDataVersionFilterList(DataVersionFilterIBs::Build
484484

485485
void ReadClient::OnActiveModeNotification()
486486
{
487-
// This function just tries to complete the deferred resubscription logic in `OnLivenessTimeoutCallback`.
488487
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());
491-
492488
// When we reach here, the subscription definitely exceeded the liveness timeout. Just continue the unfinished resubscription
493489
// logic in `OnLivenessTimeoutCallback`.
494-
TriggerResubscriptionForLivenessTimeout(CHIP_ERROR_TIMEOUT);
490+
if (IsInactiveICDSubscription())
491+
{
492+
TriggerResubscriptionForLivenessTimeout(CHIP_ERROR_TIMEOUT);
493+
return;
494+
}
495+
496+
TriggerResubscribeIfScheduled("check-in message");
495497
}
496498

497499
void ReadClient::OnPeerTypeChange(PeerType aType)

src/controller/tests/data_model/TestRead.cpp

+63
Original file line numberDiff line numberDiff line change
@@ -2354,6 +2354,69 @@ TEST_F(TestRead, TestSubscribe_OnActiveModeNotification)
23542354
EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
23552355
}
23562356

2357+
TEST_F(TestRead, TestSubscribeFailed_OnActiveModeNotification)
2358+
{
2359+
auto sessionHandle = GetSessionBobToAlice();
2360+
2361+
SetMRPMode(MessagingContext::MRPMode::kResponsive);
2362+
2363+
{
2364+
TestResubscriptionCallback callback;
2365+
ReadClient readClient(InteractionModelEngine::GetInstance(), &GetExchangeManager(), callback,
2366+
ReadClient::InteractionType::Subscribe);
2367+
2368+
callback.mScheduleLITResubscribeImmediately = false;
2369+
callback.SetReadClient(&readClient);
2370+
2371+
ReadPrepareParams readPrepareParams(GetSessionBobToAlice());
2372+
2373+
AttributePathParams attributePathParams[1];
2374+
readPrepareParams.mpAttributePathParamsList = attributePathParams;
2375+
readPrepareParams.mAttributePathParamsListSize = MATTER_ARRAY_SIZE(attributePathParams);
2376+
attributePathParams[0].mEndpointId = kTestEndpointId;
2377+
attributePathParams[0].mClusterId = Clusters::UnitTesting::Id;
2378+
attributePathParams[0].mAttributeId = Clusters::UnitTesting::Attributes::Boolean::Id;
2379+
2380+
constexpr uint16_t maxIntervalCeilingSeconds = 1;
2381+
2382+
readPrepareParams.mMaxIntervalCeilingSeconds = maxIntervalCeilingSeconds;
2383+
readPrepareParams.mIsPeerLIT = true;
2384+
2385+
auto err = readClient.SendAutoResubscribeRequest(std::move(readPrepareParams));
2386+
EXPECT_EQ(err, CHIP_NO_ERROR);
2387+
2388+
GetLoopback().mNumMessagesToDrop = LoopbackTransport::kUnlimitedMessageCount;
2389+
GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(6000),
2390+
[&]() { return callback.mOnResubscriptionsAttempted == 1; });
2391+
EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 0);
2392+
2393+
GetLoopback().mNumMessagesToDrop = 0;
2394+
callback.ClearCounters();
2395+
InteractionModelEngine::GetInstance()->OnActiveModeNotification(
2396+
ScopedNodeId(readClient.GetPeerNodeId(), readClient.GetFabricIndex()));
2397+
//
2398+
// Drive servicing IO till we have established a subscription.
2399+
//
2400+
GetIOContext().DriveIOUntil(System::Clock::Milliseconds32(2000),
2401+
[&]() { return callback.mOnSubscriptionEstablishedCount == 1; });
2402+
EXPECT_EQ(callback.mOnSubscriptionEstablishedCount, 1);
2403+
2404+
//
2405+
// With re-sub enabled, we shouldn't have encountered any errors
2406+
//
2407+
EXPECT_EQ(callback.mOnError, 0);
2408+
EXPECT_EQ(callback.mOnDone, 0);
2409+
2410+
GetLoopback().mNumMessagesToDrop = 0;
2411+
callback.ClearCounters();
2412+
}
2413+
2414+
SetMRPMode(MessagingContext::MRPMode::kDefault);
2415+
2416+
InteractionModelEngine::GetInstance()->ShutdownActiveReads();
2417+
EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
2418+
}
2419+
23572420
/**
23582421
* When the liveness timeout of a subscription to ICD is reached, the subscription will enter "InactiveICDSubscription" state, the
23592422
* client should call "OnActiveModeNotification" to re-activate it again when the check-in message is received from the ICD.

0 commit comments

Comments
 (0)