diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp index 21eb83f65ad584..fdeac7ed454518 100644 --- a/src/app/ReadClient.cpp +++ b/src/app/ReadClient.cpp @@ -940,6 +940,19 @@ CHIP_ERROR ReadClient::SendAutoResubscribeRequest(ReadPrepareParams && aReadPrep return err; } +CHIP_ERROR ReadClient::SendAutoResubscribeRequest(const ScopedNodeId & aPublisherId, ReadPrepareParams && aReadPrepareParams) +{ + mPeer = aPublisherId; + mReadPrepareParams = std::move(aReadPrepareParams); + CHIP_ERROR err = EstablishSessionToPeer(); + if (err != CHIP_NO_ERROR) + { + // Make sure we call our callback's OnDeallocatePaths. + StopResubscription(); + } + return err; +} + CHIP_ERROR ReadClient::SendSubscribeRequest(const ReadPrepareParams & aReadPrepareParams) { VerifyOrReturnError(aReadPrepareParams.mMinIntervalFloorSeconds <= aReadPrepareParams.mMaxIntervalCeilingSeconds, @@ -1118,12 +1131,8 @@ void ReadClient::OnResubscribeTimerCallback(System::Layer * /* If this starts be { // We don't have an active CASE session. We need to go ahead and set // one up, if we can. - ChipLogProgress(DataManagement, "Trying to establish a CASE session"); - auto * caseSessionManager = InteractionModelEngine::GetInstance()->GetCASESessionManager(); - if (caseSessionManager) + if (_this->EstablishSessionToPeer() == CHIP_NO_ERROR) { - caseSessionManager->FindOrEstablishSession(_this->mPeer, &_this->mOnConnectedCallback, - &_this->mOnConnectionFailureCallback); return; } @@ -1209,5 +1218,14 @@ Optional ReadClient::GetSubscriptionTimeout() return MakeOptional(timeout); } +CHIP_ERROR ReadClient::EstablishSessionToPeer() +{ + ChipLogProgress(DataManagement, "Trying to establish a CASE session for subscription"); + auto * caseSessionManager = InteractionModelEngine::GetInstance()->GetCASESessionManager(); + VerifyOrReturnError(caseSessionManager != nullptr, CHIP_ERROR_INCORRECT_STATE); + caseSessionManager->FindOrEstablishSession(mPeer, &mOnConnectedCallback, &mOnConnectionFailureCallback); + return CHIP_NO_ERROR; +} + } // namespace app } // namespace chip diff --git a/src/app/ReadClient.h b/src/app/ReadClient.h index f45b8b1448cc2e..a27e831339652e 100644 --- a/src/app/ReadClient.h +++ b/src/app/ReadClient.h @@ -352,12 +352,23 @@ class ReadClient : public Messaging::ExchangeDelegate * OnDeallocatePaths. Note: At a given time in the system, you can either have a single subscription with re-sub enabled that * has mKeepSubscriptions = false, OR, multiple subs with re-sub enabled with mKeepSubscriptions = true. You shall not * have a mix of both simultaneously. If SendAutoResubscribeRequest is called at all, it guarantees that it will call - * OnDeallocatePaths when OnDone is called. SendAutoResubscribeRequest is the only case that calls OnDeallocatePaths, since - * that's the only case when the consumer moved a ReadParams into the client. + * OnDeallocatePaths (either befor returning error, or when OnDone is called). SendAutoResubscribeRequest is the only case + * that calls OnDeallocatePaths, since that's the only case when the consumer moved a ReadParams into the client. * */ CHIP_ERROR SendAutoResubscribeRequest(ReadPrepareParams && aReadPrepareParams); + /** + * Like SendAutoResubscribeRequest above, but without a session being + * available in the ReadPrepareParams. When this is used, the ReadClient is + * responsible for setting up the CASE session itself. + * + * When using this version of SendAutoResubscribeRequest, the + * ReadPrepareParams should have a reference to a session, and if it does + * have one that session will be ignored. + */ + CHIP_ERROR SendAutoResubscribeRequest(const ScopedNodeId & aPublisherId, ReadPrepareParams && aReadPrepareParams); + /** * This provides a standard re-subscription policy implementation that given a termination cause, does the following: * - Calculates the time till next subscription with fibonacci back-off (implemented by ComputeTimeTillNextSubscription()). @@ -538,6 +549,13 @@ class ReadClient : public Messaging::ExchangeDelegate CHIP_ERROR GetMinEventNumber(const ReadPrepareParams & aReadPrepareParams, Optional & aEventMin); + /** + * Start setting up a CASE session to our peer, if we can locate a + * CASESessionManager. Returns error if we did not even manage to kick off + * a CASE attempt. + */ + CHIP_ERROR EstablishSessionToPeer(); + Messaging::ExchangeManager * mpExchangeMgr = nullptr; Messaging::ExchangeHolder mExchange; Callback & mpCallback;