@@ -275,6 +275,14 @@ class MockInteractionModelApp : public chip::app::ReadClient::Callback
275
275
mReadError = true ;
276
276
}
277
277
278
+ void OnSubscriptionEstablished (SubscriptionId aSubscriptionId) override { mOnSubscriptionEstablishedCount ++; }
279
+
280
+ CHIP_ERROR OnResubscriptionNeeded (ReadClient * apReadClient, CHIP_ERROR aTerminationCause) override
281
+ {
282
+ mOnResubscriptionsAttempted ++;
283
+ return apReadClient->ScheduleResubscription (apReadClient->ComputeTimeTillNextSubscription (), NullOptional, false );
284
+ }
285
+
278
286
void OnDone (chip::app::ReadClient *) override {}
279
287
280
288
void OnDeallocatePaths (chip::app::ReadPrepareParams && aReadPrepareParams) override
@@ -374,6 +382,7 @@ class MockInteractionModelApp : public chip::app::ReadClient::Callback
374
382
mError = CHIP_NO_ERROR;
375
383
mReceivedAttributePaths .clear ();
376
384
mReceivedListSizes .clear ();
385
+
377
386
}
378
387
379
388
bool CapturesMatchExactly (chip::Span<const AttributeCaptureAssertion> captures)
@@ -421,6 +430,8 @@ class MockInteractionModelApp : public chip::app::ReadClient::Callback
421
430
return true ;
422
431
}
423
432
433
+ int32_t mOnSubscriptionEstablishedCount = 0 ;
434
+ int32_t mOnResubscriptionsAttempted = 0 ;
424
435
int mNumDataElementIndex = 0 ;
425
436
bool mGotEventResponse = false ;
426
437
int mNumReadEventFailureStatusReceived = 0 ;
@@ -4643,6 +4654,104 @@ void TestReadInteraction::TestSubscribeClientReceiveInvalidSubscribeResponseMess
4643
4654
CreateSessionBobToAlice ();
4644
4655
}
4645
4656
4657
+ TEST_F_FROM_FIXTURE_NO_BODY (TestReadInteraction, TestSubscribeClientReceiveInvalidSubscribeResponseMessageResubWhenCheckIn)
4658
+ TEST_F_FROM_FIXTURE_NO_BODY (TestReadInteractionSync, TestSubscribeClientReceiveInvalidSubscribeResponseMessageResubWhenCheckIn)
4659
+ void TestReadInteraction::TestSubscribeClientReceiveInvalidSubscribeResponseMessageResubWhenCheckIn ()
4660
+ {
4661
+
4662
+ Messaging::ReliableMessageMgr * rm = GetExchangeManager ().GetReliableMessageMgr ();
4663
+ // Shouldn't have anything in the retransmit table when starting the test.
4664
+ EXPECT_EQ (rm->TestGetCountRetransTable (), 0 );
4665
+
4666
+ MockInteractionModelApp delegate;
4667
+ auto * engine = chip::app::InteractionModelEngine::GetInstance ();
4668
+ EXPECT_EQ (engine->Init (&GetExchangeManager (), &GetFabricTable (), gReportScheduler ), CHIP_NO_ERROR);
4669
+
4670
+ ReadPrepareParams readPrepareParams (GetSessionBobToAlice ());
4671
+
4672
+ chip::app::AttributePathParams attributePathParams[2 ];
4673
+ readPrepareParams.mpAttributePathParamsList = attributePathParams;
4674
+ readPrepareParams.mpAttributePathParamsList [0 ].mEndpointId = kTestEndpointId ;
4675
+ readPrepareParams.mpAttributePathParamsList [0 ].mClusterId = kTestClusterId ;
4676
+ readPrepareParams.mpAttributePathParamsList [0 ].mAttributeId = 1 ;
4677
+
4678
+ readPrepareParams.mpAttributePathParamsList [1 ].mEndpointId = kTestEndpointId ;
4679
+ readPrepareParams.mpAttributePathParamsList [1 ].mClusterId = kTestClusterId ;
4680
+ readPrepareParams.mpAttributePathParamsList [1 ].mAttributeId = 2 ;
4681
+
4682
+ readPrepareParams.mAttributePathParamsListSize = 2 ;
4683
+
4684
+ readPrepareParams.mMinIntervalFloorSeconds = 2 ;
4685
+ readPrepareParams.mMaxIntervalCeilingSeconds = 5 ;
4686
+ readPrepareParams.mIsPeerLIT = true ;
4687
+
4688
+ {
4689
+ app::ReadClient readClient (chip::app::InteractionModelEngine::GetInstance (), &GetExchangeManager (), delegate,
4690
+ chip::app::ReadClient::InteractionType::Subscribe);
4691
+
4692
+ GetLoopback ().mSentMessageCount = 0 ;
4693
+ GetLoopback ().mNumMessagesToDrop = 1 ;
4694
+ GetLoopback ().mNumMessagesToAllowBeforeDropping = 3 ;
4695
+ GetLoopback ().mDroppedMessageCount = 0 ;
4696
+
4697
+ EXPECT_EQ (readClient.SendRequest (readPrepareParams), CHIP_NO_ERROR);
4698
+
4699
+ DrainAndServiceIO ();
4700
+
4701
+ System::PacketBufferHandle msgBuf = System::PacketBufferHandle::New (kMaxSecureSduLengthBytes );
4702
+ EXPECT_FALSE (msgBuf.IsNull ());
4703
+ System::PacketBufferTLVWriter writer;
4704
+ writer.Init (std::move (msgBuf));
4705
+ SubscribeResponseMessage::Builder response;
4706
+ response.Init (&writer);
4707
+ response.SubscriptionId (readClient.mSubscriptionId + 1 );
4708
+ response.MaxInterval (1 );
4709
+ response.EndOfSubscribeResponseMessage ();
4710
+ EXPECT_EQ (writer.Finalize (&msgBuf), CHIP_NO_ERROR);
4711
+ PayloadHeader payloadHeader;
4712
+ payloadHeader.SetExchangeID (0 );
4713
+ payloadHeader.SetMessageType (chip::Protocols::InteractionModel::MsgType::SubscribeResponse);
4714
+
4715
+ // Since we are dropping packets, things are not getting acked. Set up
4716
+ // our MRP state to look like what it would have looked like if the
4717
+ // packet had not gotten dropped.
4718
+ PretendWeGotReplyFromServer (*this , readClient.mExchange .Get ());
4719
+
4720
+ EXPECT_EQ (GetLoopback ().mSentMessageCount , 4u );
4721
+ EXPECT_EQ (GetLoopback ().mDroppedMessageCount , 1u );
4722
+ EXPECT_EQ (engine->GetNumActiveReadHandlers (), 1u );
4723
+ ASSERT_NE (engine->ActiveHandlerAt (0 ), nullptr );
4724
+
4725
+ GetLoopback ().mSentMessageCount = 0 ;
4726
+ GetLoopback ().mNumMessagesToDrop = 0 ;
4727
+ GetLoopback ().mNumMessagesToAllowBeforeDropping = 0 ;
4728
+ GetLoopback ().mDroppedMessageCount = 0 ;
4729
+
4730
+ readClient.OnMessageReceived (readClient.mExchange .Get (), payloadHeader, std::move (msgBuf));
4731
+ DrainAndServiceIO ();
4732
+
4733
+ // TODO: Need to validate what status is being sent to the ReadHandler
4734
+ // The ReadHandler's exchange is still open when we synthesize the subscribe response.
4735
+ // Since we synthesized the subscribe response to the ReadClient, instead of sending it from the ReadHandler,
4736
+ // the only messages here are the ReadClient's StatusResponse to the unexpected message and an MRP ack.
4737
+ EXPECT_EQ (GetLoopback ().mSentMessageCount , 2u );
4738
+
4739
+ EXPECT_EQ (delegate.mOnSubscriptionEstablishedCount , 0 );
4740
+ EXPECT_EQ (delegate.mOnResubscriptionsAttempted , 1 );
4741
+
4742
+ InteractionModelEngine::GetInstance ()->OnActiveModeNotification (
4743
+ ScopedNodeId (readClient.GetPeerNodeId (), readClient.GetFabricIndex ()));
4744
+ DrainAndServiceIO ();
4745
+ EXPECT_EQ (callback.mOnSubscriptionEstablishedCount , 1 );
4746
+ }
4747
+ EXPECT_EQ (engine->GetNumActiveReadClients (), 0u );
4748
+ engine->Shutdown ();
4749
+ ExpireSessionAliceToBob ();
4750
+ ExpireSessionBobToAlice ();
4751
+ CreateSessionAliceToBob ();
4752
+ CreateSessionBobToAlice ();
4753
+ }
4754
+
4646
4755
// Read Client create the subscription, handler sends unsolicited malformed report with invalid subscription id to client,
4647
4756
// InteractionModelEngine::OnUnsolicitedReportData would process this malformed report and sends out status report
4648
4757
TEST_F_FROM_FIXTURE_NO_BODY (TestReadInteraction, TestSubscribeClientReceiveUnsolicitedReportMessageWithInvalidSubscriptionId)
0 commit comments