Matter SDK Coverage Report
Current view: top level - app - SubscriptionResumptionSessionEstablisher.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 0.0 % 65 0
Test Date: 2025-01-17 19:00:11 Functions: 0.0 % 8 0

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2023 Project CHIP Authors
       4              :  *
       5              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6              :  *    you may not use this file except in compliance with the License.
       7              :  *    You may obtain a copy of the License at
       8              :  *
       9              :  *        http://www.apache.org/licenses/LICENSE-2.0
      10              :  *
      11              :  *    Unless required by applicable law or agreed to in writing, software
      12              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              :  *    See the License for the specific language governing permissions and
      15              :  *    limitations under the License.
      16              :  */
      17              : 
      18              : #include <app/InteractionModelEngine.h>
      19              : #include <app/SubscriptionResumptionSessionEstablisher.h>
      20              : 
      21              : namespace chip {
      22              : namespace app {
      23              : 
      24              : class AutoDeleteEstablisher
      25              : {
      26              : public:
      27            0 :     AutoDeleteEstablisher(SubscriptionResumptionSessionEstablisher * sessionEstablisher) : mSessionEstablisher(sessionEstablisher)
      28            0 :     {}
      29            0 :     ~AutoDeleteEstablisher() { chip::Platform::Delete(mSessionEstablisher); }
      30              : 
      31            0 :     SubscriptionResumptionSessionEstablisher * operator->() const { return mSessionEstablisher; }
      32              : 
      33            0 :     SubscriptionResumptionSessionEstablisher & operator*() const { return *mSessionEstablisher; }
      34              : 
      35              : private:
      36              :     SubscriptionResumptionSessionEstablisher * mSessionEstablisher;
      37              : };
      38              : 
      39            0 : SubscriptionResumptionSessionEstablisher::SubscriptionResumptionSessionEstablisher() :
      40            0 :     mOnConnectedCallback(HandleDeviceConnected, this), mOnConnectionFailureCallback(HandleDeviceConnectionFailure, this)
      41            0 : {}
      42              : 
      43              : CHIP_ERROR
      44            0 : SubscriptionResumptionSessionEstablisher::ResumeSubscription(
      45              :     CASESessionManager & caseSessionManager, const SubscriptionResumptionStorage::SubscriptionInfo & subscriptionInfo)
      46              : {
      47            0 :     mSubscriptionInfo.mNodeId         = subscriptionInfo.mNodeId;
      48            0 :     mSubscriptionInfo.mFabricIndex    = subscriptionInfo.mFabricIndex;
      49            0 :     mSubscriptionInfo.mSubscriptionId = subscriptionInfo.mSubscriptionId;
      50            0 :     mSubscriptionInfo.mMinInterval    = subscriptionInfo.mMinInterval;
      51            0 :     mSubscriptionInfo.mMaxInterval    = subscriptionInfo.mMaxInterval;
      52            0 :     mSubscriptionInfo.mFabricFiltered = subscriptionInfo.mFabricFiltered;
      53              : #if CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
      54            0 :     mSubscriptionInfo.mResumptionRetries = subscriptionInfo.mResumptionRetries;
      55              : #endif
      56              :     // Copy the Attribute Paths and Event Paths
      57            0 :     if (subscriptionInfo.mAttributePaths.AllocatedSize() > 0)
      58              :     {
      59            0 :         mSubscriptionInfo.mAttributePaths.Alloc(subscriptionInfo.mAttributePaths.AllocatedSize());
      60            0 :         if (!mSubscriptionInfo.mAttributePaths.Get())
      61              :         {
      62            0 :             return CHIP_ERROR_NO_MEMORY;
      63              :         }
      64            0 :         for (size_t i = 0; i < mSubscriptionInfo.mAttributePaths.AllocatedSize(); ++i)
      65              :         {
      66            0 :             mSubscriptionInfo.mAttributePaths[i] = subscriptionInfo.mAttributePaths[i];
      67              :         }
      68              :     }
      69            0 :     if (subscriptionInfo.mEventPaths.AllocatedSize() > 0)
      70              :     {
      71            0 :         mSubscriptionInfo.mEventPaths.Alloc(subscriptionInfo.mEventPaths.AllocatedSize());
      72            0 :         if (!mSubscriptionInfo.mEventPaths.Get())
      73              :         {
      74            0 :             return CHIP_ERROR_NO_MEMORY;
      75              :         }
      76            0 :         for (size_t i = 0; i < mSubscriptionInfo.mEventPaths.AllocatedSize(); ++i)
      77              :         {
      78            0 :             mSubscriptionInfo.mEventPaths[i] = subscriptionInfo.mEventPaths[i];
      79              :         }
      80              :     }
      81              : 
      82            0 :     ScopedNodeId peerNode = ScopedNodeId(mSubscriptionInfo.mNodeId, mSubscriptionInfo.mFabricIndex);
      83            0 :     caseSessionManager.FindOrEstablishSession(peerNode, &mOnConnectedCallback, &mOnConnectionFailureCallback);
      84            0 :     return CHIP_NO_ERROR;
      85              : }
      86              : 
      87            0 : void SubscriptionResumptionSessionEstablisher::HandleDeviceConnected(void * context, Messaging::ExchangeManager & exchangeMgr,
      88              :                                                                      const SessionHandle & sessionHandle)
      89              : {
      90            0 :     AutoDeleteEstablisher establisher(static_cast<SubscriptionResumptionSessionEstablisher *>(context));
      91            0 :     SubscriptionResumptionStorage::SubscriptionInfo & subscriptionInfo = establisher->mSubscriptionInfo;
      92            0 :     InteractionModelEngine * imEngine                                  = InteractionModelEngine::GetInstance();
      93              : 
      94              :     // Decrement the number of subscriptions to resume since we have completed our retry attempt for a given subscription.
      95              :     // We do this before the readHandler creation since we do not care if the subscription has successfully been resumed or
      96              :     // not. Counter only tracks the number of individual subscriptions we will try to resume.
      97            0 :     imEngine->DecrementNumSubscriptionsToResume();
      98              : 
      99            0 :     if (!imEngine->EnsureResourceForSubscription(subscriptionInfo.mFabricIndex, subscriptionInfo.mAttributePaths.AllocatedSize(),
     100              :                                                  subscriptionInfo.mEventPaths.AllocatedSize()))
     101              :     {
     102              :         // TODO - Should we keep the subscription here?
     103            0 :         ChipLogProgress(InteractionModel, "no resource for subscription resumption");
     104            0 :         return;
     105              :     }
     106              :     ReadHandler * readHandler =
     107            0 :         imEngine->mReadHandlers.CreateObject(*imEngine, imEngine->GetReportScheduler(), imEngine->GetDataModelProvider());
     108            0 :     if (readHandler == nullptr)
     109              :     {
     110              :         // TODO - Should we keep the subscription here?
     111            0 :         ChipLogProgress(InteractionModel, "no resource for ReadHandler creation");
     112            0 :         return;
     113              :     }
     114            0 :     readHandler->OnSubscriptionResumed(sessionHandle, *establisher);
     115              : #if CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
     116              :     // Reset the resumption retries to 0 if subscription is resumed
     117            0 :     subscriptionInfo.mResumptionRetries  = 0;
     118            0 :     auto * subscriptionResumptionStorage = InteractionModelEngine::GetInstance()->GetSubscriptionResumptionStorage();
     119            0 :     if (subscriptionResumptionStorage)
     120              :     {
     121            0 :         subscriptionResumptionStorage->Save(subscriptionInfo);
     122              :     }
     123              : #endif // CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
     124            0 : }
     125              : 
     126            0 : void SubscriptionResumptionSessionEstablisher::HandleDeviceConnectionFailure(void * context, const ScopedNodeId & peerId,
     127              :                                                                              CHIP_ERROR error)
     128              : {
     129            0 :     AutoDeleteEstablisher establisher(static_cast<SubscriptionResumptionSessionEstablisher *>(context));
     130            0 :     InteractionModelEngine * imEngine                                  = InteractionModelEngine::GetInstance();
     131            0 :     SubscriptionResumptionStorage::SubscriptionInfo & subscriptionInfo = establisher->mSubscriptionInfo;
     132            0 :     ChipLogError(DataManagement, "Failed to establish CASE for subscription-resumption with error '%" CHIP_ERROR_FORMAT "'",
     133              :                  error.Format());
     134              : 
     135              :     // Decrement the number of subscriptions to resume since we have completed our retry attempt for a given subscription.
     136              :     // We do this here since we were not able to connect to the subscriber thus we have completed our resumption attempt.
     137              :     // Counter only tracks the number of individual subscriptions we will try to resume.
     138            0 :     imEngine->DecrementNumSubscriptionsToResume();
     139              : 
     140            0 :     auto * subscriptionResumptionStorage = imEngine->GetSubscriptionResumptionStorage();
     141            0 :     if (!subscriptionResumptionStorage)
     142              :     {
     143            0 :         ChipLogError(DataManagement, "Failed to get subscription resumption storage");
     144            0 :         return;
     145              :     }
     146              : #if CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
     147            0 :     if (subscriptionInfo.mResumptionRetries <= CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION_MAX_FIBONACCI_STEP_INDEX)
     148              :     {
     149            0 :         InteractionModelEngine::GetInstance()->TryToResumeSubscriptions();
     150            0 :         subscriptionInfo.mResumptionRetries++;
     151            0 :         subscriptionResumptionStorage->Save(subscriptionInfo);
     152              :     }
     153              :     else
     154              : #endif // CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
     155              :     {
     156              :         // If the device fails to establish the session several times, the subscriber might be offline and its subscription
     157              :         // read client will be deleted when the device reconnects to the subscriber. This subscription will be never used again.
     158              :         // Clean up the persistent subscription information storage.
     159            0 :         subscriptionResumptionStorage->Delete(subscriptionInfo.mNodeId, subscriptionInfo.mFabricIndex,
     160              :                                               subscriptionInfo.mSubscriptionId);
     161              :     }
     162            0 : }
     163              : 
     164              : } // namespace app
     165              : } // namespace chip
        

Generated by: LCOV version 2.0-1