Matter SDK Coverage Report
Current view: top level - app - OperationalSessionSetup.h (source / functions) Coverage Total Hit
Test: SHA:f1767a8b0a3778fdf31b1d979afbdf544892fd94 Lines: 43.6 % 39 17
Test Date: 2026-06-03 07:35:21 Functions: 50.0 % 16 8

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020-2021 Project CHIP Authors
       4              :  *    All rights reserved.
       5              :  *
       6              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       7              :  *    you may not use this file except in compliance with the License.
       8              :  *    You may obtain a copy of the License at
       9              :  *
      10              :  *        http://www.apache.org/licenses/LICENSE-2.0
      11              :  *
      12              :  *    Unless required by applicable law or agreed to in writing, software
      13              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      14              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15              :  *    See the License for the specific language governing permissions and
      16              :  *    limitations under the License.
      17              :  */
      18              : 
      19              : /**
      20              :  *  @file
      21              :  *    This file contains definitions for Device class. The objects of this
      22              :  *    class will be used by Controller applications to interact with CHIP
      23              :  *    devices. The class provides mechanism to construct, send and receive
      24              :  *    messages to and from the corresponding CHIP devices.
      25              :  */
      26              : 
      27              : #pragma once
      28              : 
      29              : #include <app/AppConfig.h>
      30              : #include <app/CASEClient.h>
      31              : #include <app/CASEClientPool.h>
      32              : #include <app/DeviceProxy.h>
      33              : #include <app/util/basic-types.h>
      34              : #include <credentials/GroupDataProvider.h>
      35              : #include <lib/address_resolve/AddressResolve.h>
      36              : #include <lib/core/GroupedCallbackList.h>
      37              : #include <messaging/ExchangeContext.h>
      38              : #include <messaging/ExchangeDelegate.h>
      39              : #include <messaging/ExchangeMgr.h>
      40              : #include <messaging/Flags.h>
      41              : #include <messaging/ReliableMessageProtocolConfig.h>
      42              : #include <platform/CHIPDeviceConfig.h>
      43              : #include <protocols/secure_channel/CASESession.h>
      44              : #include <system/SystemClock.h>
      45              : #include <system/SystemLayer.h>
      46              : #include <transport/SessionManager.h>
      47              : #include <transport/TransportMgr.h>
      48              : #include <transport/raw/MessageHeader.h>
      49              : #include <transport/raw/UDP.h>
      50              : 
      51              : namespace chip {
      52              : 
      53              : class OperationalSessionSetup;
      54              : 
      55              : /**
      56              :  * @brief Delegate provided when creating OperationalSessionSetup.
      57              :  *
      58              :  * Once OperationalSessionSetup establishes a connection (or errors out) and has notified all
      59              :  * registered application callbacks via OnDeviceConnected/OnDeviceConnectionFailure, this delegate
      60              :  * is used to deallocate the OperationalSessionSetup.
      61              :  */
      62              : class OperationalSessionReleaseDelegate
      63              : {
      64              : public:
      65          159 :     virtual ~OperationalSessionReleaseDelegate()                        = default;
      66              :     virtual void ReleaseSession(OperationalSessionSetup * sessionSetup) = 0;
      67              : };
      68              : 
      69              : /**
      70              :  * @brief Minimal implementation of DeviceProxy that encapsulates a SessionHolder to track a CASE session.
      71              :  *
      72              :  * Deprecated - Avoid using this object.
      73              :  *
      74              :  * OperationalDeviceProxy is a minimal implementation of DeviceProxy. It is meant to provide a transition
      75              :  * for existing consumers of OperationalDeviceProxy that were delivered a reference to that object in
      76              :  * their respective OnDeviceConnected callback, but were incorrectly holding onto that object past
      77              :  * the function call. OperationalDeviceProxy can be held on for as long as is desired, while still
      78              :  * minimizing the code changes needed to transition to a more final solution by virtue of
      79              :  * implementing DeviceProxy.
      80              :  */
      81              : class OperationalDeviceProxy : public DeviceProxy
      82              : {
      83              : public:
      84            0 :     OperationalDeviceProxy(Messaging::ExchangeManager * exchangeMgr, const SessionHandle & sessionHandle) :
      85            0 :         mExchangeMgr(exchangeMgr), mSecureSession(sessionHandle), mPeerScopedNodeId(sessionHandle->GetPeer())
      86            0 :     {}
      87           43 :     OperationalDeviceProxy() {}
      88              : 
      89            0 :     void Disconnect() override
      90              :     {
      91            0 :         if (IsSecureConnected())
      92              :         {
      93            0 :             GetSecureSession().Value()->AsSecureSession()->MarkAsDefunct();
      94              :         }
      95            0 :         mSecureSession.Release();
      96            0 :         mExchangeMgr      = nullptr;
      97            0 :         mPeerScopedNodeId = ScopedNodeId();
      98            0 :     }
      99            0 :     Messaging::ExchangeManager * GetExchangeManager() const override { return mExchangeMgr; }
     100            0 :     chip::Optional<SessionHandle> GetSecureSession() const override { return mSecureSession.Get(); }
     101            0 :     NodeId GetDeviceId() const override { return mPeerScopedNodeId.GetNodeId(); }
     102              :     ScopedNodeId GetPeerScopedNodeId() const { return mPeerScopedNodeId; }
     103              : 
     104              :     bool ConnectionReady() const { return (mExchangeMgr != nullptr && IsSecureConnected()); }
     105              : 
     106              : private:
     107            0 :     bool IsSecureConnected() const override { return static_cast<bool>(mSecureSession); }
     108              : 
     109              :     Messaging::ExchangeManager * mExchangeMgr = nullptr;
     110              :     SessionHolder mSecureSession;
     111              :     ScopedNodeId mPeerScopedNodeId;
     112              : };
     113              : 
     114              : /**
     115              :  * @brief Callback prototype when secure session is established.
     116              :  *
     117              :  * Callback implementations are not supposed to store the exchangeMgr or the sessionHandle. Older
     118              :  * application code does incorrectly hold onto this information so do not follow those incorrect
     119              :  * implementations as an example.
     120              :  */
     121              : typedef void (*OnDeviceConnected)(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
     122              : 
     123              : /**
     124              :  * Callback prototype when secure session establishment fails.
     125              :  */
     126              : typedef void (*OnDeviceConnectionFailure)(void * context, const ScopedNodeId & peerId, CHIP_ERROR error);
     127              : 
     128              : /**
     129              :  * Callback prototype when secure session establishement has failed and will be
     130              :  * retried.  retryTimeout indicates how much time will pass before we know
     131              :  * whether the retry has timed out waiting for a response to our Sigma1 message.
     132              :  */
     133              : typedef void (*OnDeviceConnectionRetry)(void * context, const ScopedNodeId & peerId, CHIP_ERROR error,
     134              :                                         System::Clock::Seconds16 retryTimeout);
     135              : 
     136              : /**
     137              :  * Object used to either establish a connection to peer or performing address lookup to a peer.
     138              :  *
     139              :  * OperationalSessionSetup is capable of either:
     140              :  *    1. Establishing a CASE session connection to a peer. Upon success or failure, the OnDeviceConnected or
     141              :  *       OnDeviceConnectionFailure callback will be called to notify the caller the results of trying to
     142              :  *       estblish a CASE session. Some additional details about the steps to establish a connection are:
     143              :  *          - Discover the device using DNSSD (find out what IP address to use and what
     144              :  *            communication parameters are appropriate for it)
     145              :  *          - Establish a secure channel to it via CASE
     146              :  *          - Expose to consumers the secure session for talking to the device via OnDeviceConnected
     147              :  *            callback.
     148              :  *    2. Performing an address lookup for given a scoped nodeid. On success, it will call into
     149              :  *       SessionManager to update the addresses for all matching sessions in the session table.
     150              :  *
     151              :  * OperationalSessionSetup has a very limited lifetime. Once it has completed its purpose outlined above,
     152              :  * it will use `releaseDelegate` to release itself.
     153              :  *
     154              :  * It is possible to determine which of the two purposes the OperationalSessionSetup is for by calling
     155              :  * IsForAddressUpdate().
     156              :  */
     157              : class DLL_EXPORT OperationalSessionSetup : public SessionEstablishmentDelegate, public AddressResolve::NodeListener
     158              : {
     159              : public:
     160              :     // Grants tests controlled access to private state (e.g. forcing mState)
     161              :     // so they can exercise state-dependent behavior such as
     162              :     // IsEstablishingSession() without driving a full CASE handshake.
     163              :     friend class TestOperationalSessionSetupAccess;
     164              : 
     165              :     struct ConnectionFailureInfo
     166              :     {
     167              :         const ScopedNodeId peerId;
     168              :         CHIP_ERROR error;
     169              :         SessionEstablishmentStage sessionStage;
     170              : 
     171              :         // When the response was BUSY, error will be CHIP_ERROR_BUSY and
     172              :         // requestedBusyDelay will be set, if handling of BUSY responses is
     173              :         // enabled.
     174              : #if CHIP_CONFIG_ENABLE_BUSY_HANDLING_FOR_OPERATIONAL_SESSION_SETUP
     175              :         Optional<System::Clock::Milliseconds16> requestedBusyDelay;
     176              : #endif // CHIP_CONFIG_ENABLE_BUSY_HANDLING_FOR_OPERATIONAL_SESSION_SETUP
     177              : 
     178            0 :         ConnectionFailureInfo(const ScopedNodeId & peer, CHIP_ERROR err, SessionEstablishmentStage stage) :
     179            0 :             peerId(peer), error(err), sessionStage(stage)
     180            0 :         {}
     181              :     };
     182              : 
     183              :     using OnSetupFailure = void (*)(void * context, const ConnectionFailureInfo & failureInfo);
     184              : 
     185              :     ~OperationalSessionSetup() override;
     186              : 
     187           20 :     OperationalSessionSetup(const CASEClientInitParams & params, CASEClientPoolDelegate * clientPool, ScopedNodeId peerId,
     188              :                             OperationalSessionReleaseDelegate * releaseDelegate)
     189           20 :     {
     190           20 :         mInitParams = params;
     191           40 :         if (params.Validate() != CHIP_NO_ERROR || clientPool == nullptr || releaseDelegate == nullptr)
     192              :         {
     193           20 :             mState = State::Uninitialized;
     194           20 :             return;
     195              :         }
     196              : 
     197            0 :         mClientPool      = clientPool;
     198            0 :         mPeerId          = peerId;
     199            0 :         mReleaseDelegate = releaseDelegate;
     200            0 :         mState           = State::NeedsAddress;
     201            0 :         mAddressLookupHandle.SetListener(this);
     202              :     }
     203              : 
     204              :     /*
     205              :      * This function can be called to establish a secure session with the device.
     206              :      *
     207              :      * The device is expected to have been commissioned, A CASE session
     208              :      * setup will be triggered.
     209              :      *
     210              :      * If session setup succeeds, the callback function `onConnection` will be called.
     211              :      * If session setup fails, `onFailure` will be called.
     212              :      *
     213              :      * If the session already exists, `onConnection` will be called immediately,
     214              :      * before the Connect call returns.
     215              :      *
     216              :      * `onFailure` may be called before the Connect call returns, for error
     217              :      * cases that are detected synchronously (e.g. inability to start an address
     218              :      * lookup).
     219              :      *
     220              :      * `transportPayloadCapability` is set to kLargePayload when the session needs to be established
     221              :      * over a transport that allows large payloads to be transferred, e.g., TCP.
     222              :      */
     223              :     void Connect(Callback::Callback<OnDeviceConnected> * onConnection, Callback::Callback<OnDeviceConnectionFailure> * onFailure,
     224              :                  TransportPayloadCapability transportPayloadCapability = TransportPayloadCapability::kMRPPayload);
     225              : 
     226              :     /*
     227              :      * This function can be called to establish a secure session with the device.
     228              :      *
     229              :      * The device is expected to have been commissioned, A CASE session
     230              :      * setup will be triggered.
     231              :      *
     232              :      * If session setup succeeds, the callback function `onConnection` will be called.
     233              :      * If session setup fails, `onSetupFailure` will be called.
     234              :      *
     235              :      * If the session already exists, `onConnection` will be called immediately,
     236              :      * before the Connect call returns.
     237              :      *
     238              :      * `onSetupFailure` may be called before the Connect call returns, for error cases that are detected synchronously
     239              :      * (e.g. inability to start an address lookup).
     240              :      *
     241              :      * `transportPayloadCapability` is set to kLargePayload when the session needs to be established
     242              :      * over a transport that allows large payloads to be transferred, e.g., TCP.
     243              :      */
     244              :     void Connect(Callback::Callback<OnDeviceConnected> * onConnection, Callback::Callback<OnSetupFailure> * onSetupFailure,
     245              :                  TransportPayloadCapability transportPayloadCapability = TransportPayloadCapability::kMRPPayload);
     246              : 
     247           40 :     bool IsForAddressUpdate() const { return mPerformingAddressUpdate; }
     248              : 
     249              :     /**
     250              :      * Returns true iff this setup object is actively trying to establish a
     251              :      * session (as opposed to idle, uninitialized, or fully connected).
     252              :      */
     253           40 :     bool IsEstablishingSession() const
     254              :     {
     255           38 :         return mState == State::NeedsAddress || mState == State::ResolvingAddress || mState == State::HasAddress ||
     256           78 :             mState == State::Connecting || mState == State::WaitingForRetry;
     257              :     }
     258              : 
     259              :     //////////// SessionEstablishmentDelegate Implementation ///////////////
     260              :     void OnSessionEstablished(const SessionHandle & session) override;
     261              :     void OnSessionEstablishmentError(CHIP_ERROR error, SessionEstablishmentStage stage) override;
     262              :     void OnResponderBusy(System::Clock::Milliseconds16 requestedDelay) override;
     263              : 
     264           47 :     ScopedNodeId GetPeerId() const { return mPeerId; }
     265              : 
     266              :     static Transport::PeerAddress ToPeerAddress(const Dnssd::ResolvedNodeData & nodeData)
     267              :     {
     268              :         Inet::InterfaceId interfaceId = Inet::InterfaceId::Null();
     269              : 
     270              :         // TODO - Revisit usage of InterfaceID only for addresses that are IPv6 LLA
     271              :         // Only use the DNS-SD resolution's InterfaceID for addresses that are IPv6 LLA.
     272              :         // For all other addresses, we should rely on the device's routing table to route messages sent.
     273              :         // Forcing messages down an InterfaceId might fail. For example, in bridged networks like Thread,
     274              :         // mDNS advertisements are not usually received on the same interface the peer is reachable on.
     275              :         if (nodeData.resolutionData.ipAddress[0].IsIPv6LinkLocal())
     276              :         {
     277              :             interfaceId = nodeData.resolutionData.interfaceId;
     278              :         }
     279              : 
     280              :         return Transport::PeerAddress::UDP(nodeData.resolutionData.ipAddress[0], nodeData.resolutionData.port, interfaceId);
     281              :     }
     282              : 
     283              :     /**
     284              :      * @brief Get the fabricIndex
     285              :      */
     286           15 :     FabricIndex GetFabricIndex() const { return mPeerId.GetFabricIndex(); }
     287              : 
     288              :     void PerformAddressUpdate();
     289              : 
     290              :     // AddressResolve::NodeListener - notifications when dnssd finds a node IP address
     291              :     void OnNodeAddressResolved(const PeerId & peerId, const AddressResolve::ResolveResult & result) override;
     292              :     void OnNodeAddressResolutionFailed(const PeerId & peerId, CHIP_ERROR reason) override;
     293              : 
     294              : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
     295              :     // Update our remaining attempt count to be at least the given value.
     296              :     void UpdateAttemptCount(uint8_t attemptCount);
     297              : 
     298              :     // Add a retry handler for this session setup.
     299              :     void AddRetryHandler(Callback::Callback<OnDeviceConnectionRetry> * onRetry);
     300              : #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
     301              : 
     302              : #if CHIP_CONFIG_ENABLE_ADDRESS_RESOLVE_FALLBACK
     303              :     /**
     304              :      * Set a fallback resolve result to use if address resolution times out.
     305              :      * This should be called before Connect() to enable the fallback mechanism.
     306              :      */
     307              :     void SetFallbackResolveResult(const AddressResolve::ResolveResult & result);
     308              : #endif // CHIP_CONFIG_ENABLE_ADDRESS_RESOLVE_FALLBACK
     309              : 
     310              : private:
     311              :     enum class State : uint8_t
     312              :     {
     313              :         Uninitialized,    // Error state: OperationalSessionSetup is useless
     314              :         NeedsAddress,     // No address known, lookup not started yet.
     315              :         ResolvingAddress, // Address lookup in progress.
     316              :         HasAddress,       // Have an address, CASE handshake not started yet.
     317              :         Connecting,       // CASE handshake in progress.
     318              :         SecureConnected,  // CASE session established.
     319              :         WaitingForRetry,  // No address known, but a retry is pending.  Added at
     320              :                           // end to make logs easier to understand.
     321              :     };
     322              : 
     323              :     CASEClientInitParams mInitParams;
     324              :     CASEClientPoolDelegate * mClientPool = nullptr;
     325              : 
     326              :     // mCASEClient is only non-null if we are in State::Connecting or just
     327              :     // allocated it as part of an attempt to enter State::Connecting.
     328              :     CASEClient * mCASEClient = nullptr;
     329              : 
     330              :     ScopedNodeId mPeerId;
     331              : 
     332              :     Transport::PeerAddress mDeviceAddress = Transport::PeerAddress::UDP(Inet::IPAddress::Any);
     333              : 
     334              :     SessionHolder mSecureSession;
     335              : 
     336              :     typedef Callback::GroupedCallbackList<OnDeviceConnected, OnDeviceConnectionFailure, OnSetupFailure> SuccessFailureCallbackList;
     337              :     SuccessFailureCallbackList mCallbacks;
     338              : 
     339              :     OperationalSessionReleaseDelegate * mReleaseDelegate;
     340              : 
     341              :     /// This is used when a node address is required.
     342              :     chip::AddressResolve::NodeLookupHandle mAddressLookupHandle;
     343              : 
     344              :     State mState = State::Uninitialized;
     345              : 
     346              :     bool mPerformingAddressUpdate = false;
     347              : 
     348              : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES || CHIP_CONFIG_ENABLE_BUSY_HANDLING_FOR_OPERATIONAL_SESSION_SETUP
     349              :     System::Clock::Milliseconds16 mRequestedBusyDelay = System::Clock::kZero;
     350              : #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES || CHIP_CONFIG_ENABLE_BUSY_HANDLING_FOR_OPERATIONAL_SESSION_SETUP
     351              : 
     352              :     TransportPayloadCapability mTransportPayloadCapability = TransportPayloadCapability::kMRPPayload;
     353              : 
     354              : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
     355              :     // When we TryNextResult on the resolver, it will synchronously call back
     356              :     // into our OnNodeAddressResolved when it succeeds.  We need to track
     357              :     // whether the OnNodeAddressResolved is coming from handling a session
     358              :     // establishment error or whether it's happening because we didn't even
     359              :     // manage to start a session establishment at all.  Use this member to keep
     360              :     // track of that.
     361              :     bool mTryingNextResultDueToSessionEstablishmentError = false;
     362              : 
     363              :     uint8_t mRemainingAttempts = 0;
     364              :     uint8_t mAttemptsDone      = 0;
     365              : 
     366              :     uint8_t mResolveAttemptsAllowed = 0;
     367              : 
     368              :     Callback::CallbackDeque mConnectionRetry;
     369              : #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
     370              : 
     371              : #if CHIP_CONFIG_ENABLE_ADDRESS_RESOLVE_FALLBACK
     372              :     // Fallback address resolve result to use if normal address resolution times out
     373              :     Optional<AddressResolve::ResolveResult> mFallbackResolveResult;
     374              :     System::Clock::Timeout mFallbackTimeout = System::Clock::Seconds16(CHIP_CONFIG_ADDRESS_RESOLVE_FALLBACK_TIMEOUT_SECONDS);
     375              : #endif // CHIP_CONFIG_ENABLE_ADDRESS_RESOLVE_FALLBACK
     376              : 
     377              :     void MoveToState(State aTargetState);
     378              : 
     379              :     CHIP_ERROR EstablishConnection(const AddressResolve::ResolveResult & result);
     380              : 
     381              :     /*
     382              :      * This checks to see if an existing CASE session exists to the peer within the SessionManager
     383              :      * and if one exists, to load that into mSecureSession.
     384              :      *
     385              :      * Returns true if a valid session was found, false otherwise.
     386              :      *
     387              :      */
     388              :     bool AttachToExistingSecureSession();
     389              : 
     390              :     void CleanupCASEClient();
     391              : 
     392              :     void Connect(Callback::Callback<OnDeviceConnected> * onConnection, Callback::Callback<OnDeviceConnectionFailure> * onFailure,
     393              :                  Callback::Callback<OnSetupFailure> * onSetupFailure,
     394              :                  TransportPayloadCapability transportPayloadCapability = TransportPayloadCapability::kMRPPayload);
     395              : 
     396              :     void EnqueueConnectionCallbacks(Callback::Callback<OnDeviceConnected> * onConnection,
     397              :                                     Callback::Callback<OnDeviceConnectionFailure> * onFailure,
     398              :                                     Callback::Callback<OnSetupFailure> * onSetupFailure);
     399              : 
     400              :     enum class ReleaseBehavior
     401              :     {
     402              :         Release,
     403              :         DoNotRelease
     404              :     };
     405              : 
     406              :     /*
     407              :      * This dequeues all failure and success callbacks and appropriately invokes either set depending
     408              :      * on the value of error.
     409              :      *
     410              :      * If error == CHIP_NO_ERROR, only success callbacks are invoked. Otherwise, only failure callbacks are invoked.
     411              :      *
     412              :      * The state offers additional context regarding the failure, indicating the specific state in which
     413              :      * the error occurs. It is only relayed through failure callbacks when the error is not equal to CHIP_NO_ERROR.
     414              :      *
     415              :      * If releaseBehavior is Release, this uses mReleaseDelegate to release
     416              :      * ourselves (aka `this`). As a result any caller should return right away
     417              :      * without touching `this`.
     418              :      *
     419              :      * Setting releaseBehavior to DoNotRelease is meant for use from the destructor
     420              :      */
     421              :     void DequeueConnectionCallbacks(CHIP_ERROR error, SessionEstablishmentStage stage,
     422              :                                     ReleaseBehavior releaseBehavior = ReleaseBehavior::Release);
     423              : 
     424           20 :     void DequeueConnectionCallbacks(CHIP_ERROR error, ReleaseBehavior releaseBehavior = ReleaseBehavior::Release)
     425              :     {
     426              :         // NOLINTNEXTLINE(clang-analyzer-core.StackAddressEscape): TODO #41631
     427           20 :         this->DequeueConnectionCallbacks(error, SessionEstablishmentStage::kNotInKeyExchange, releaseBehavior);
     428           20 :     }
     429              : 
     430              :     /**
     431              :      * Helper for DequeueConnectionCallbacks that handles the actual callback
     432              :      * notifications. This happens after the object has been released, if it's
     433              :      * being released.
     434              :      */
     435              :     static void NotifyConnectionCallbacks(SuccessFailureCallbackList & ready, CHIP_ERROR error, SessionEstablishmentStage stage,
     436              :                                           const ScopedNodeId & peerId, Messaging::ExchangeManager * exchangeMgr,
     437              :                                           const Optional<SessionHandle> & optionalSessionHandle,
     438              :                                           // requestedBusyDelay will be 0 if not
     439              :                                           // CHIP_CONFIG_ENABLE_BUSY_HANDLING_FOR_OPERATIONAL_SESSION_SETUP,
     440              :                                           // and only has a meaningful value
     441              :                                           // when the error is CHIP_ERROR_BUSY.
     442              :                                           System::Clock::Milliseconds16 requestedBusyDelay);
     443              : 
     444              :     /**
     445              :      * Triggers a DNSSD lookup to find a usable peer address.
     446              :      */
     447              :     CHIP_ERROR LookupPeerAddress();
     448              : 
     449              :     /**
     450              :      * This function will set new IP address, port and MRP retransmission intervals of the device.
     451              :      */
     452              :     void UpdateDeviceData(const AddressResolve::ResolveResult & result);
     453              : 
     454              : #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
     455              :     /**
     456              :      * Schedule a setup reattempt, if possible.  The outparam indicates how long
     457              :      * it will be before the reattempt happens.
     458              :      */
     459              :     CHIP_ERROR ScheduleSessionSetupReattempt(System::Clock::Seconds16 & timerDelay);
     460              : 
     461              :     /**
     462              :      * Cancel a scheduled setup reattempt, if we can (i.e. if we still have
     463              :      * access to the SystemLayer).
     464              :      */
     465              :     void CancelSessionSetupReattempt();
     466              : 
     467              :     /**
     468              :      * Helper for our backoff retry timer.
     469              :      */
     470              :     static void TrySetupAgain(System::Layer * systemLayer, void * state);
     471              : 
     472              :     /**
     473              :      * Helper to notify our retry callbacks that a setup error occurred and we
     474              :      * will retry.
     475              :      */
     476              :     void NotifyRetryHandlers(CHIP_ERROR error, const ReliableMessageProtocolConfig & remoteMrpConfig,
     477              :                              System::Clock::Seconds16 retryDelay);
     478              : 
     479              :     /**
     480              :      * A version of NotifyRetryHandlers that passes in a retry timeout estimate
     481              :      * directly.
     482              :      */
     483              :     void NotifyRetryHandlers(CHIP_ERROR error, System::Clock::Seconds16 timeoutEstimate);
     484              : #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
     485              : 
     486              : #if CHIP_CONFIG_ENABLE_ADDRESS_RESOLVE_FALLBACK
     487              :     /**
     488              :      * Timer callback invoked when DNS-SD resolution doesn't complete within the configured timeout.
     489              :      *
     490              :      * When this fires:
     491              :      * - Cancels the ongoing DNS-SD lookup to prevent race conditions
     492              :      * - Uses the cached IP/port from the successful PASE session seconds ago
     493              :      * - Assumes the cached address is still valid (IP hasn't changed)
     494              :      */
     495              :     static void OnFallbackTimeout(System::Layer * systemLayer, void * appState);
     496              : 
     497              :     /**
     498              :      * Cancel the fallback timeout timer if it's running.
     499              :      */
     500              :     void CancelFallbackTimer();
     501              : 
     502              :     /**
     503              :      * Start the fallback timeout timer.
     504              :      */
     505              :     CHIP_ERROR StartFallbackTimer();
     506              : 
     507              :     /**
     508              :      * Helper to get the System::Layer from the session manager.
     509              :      * Returns nullptr if not available.
     510              :      */
     511              :     System::Layer * GetSystemLayer();
     512              : #endif // CHIP_CONFIG_ENABLE_ADDRESS_RESOLVE_FALLBACK
     513              : };
     514              : 
     515              : } // namespace chip
        

Generated by: LCOV version 2.0-1