Matter SDK Coverage Report
Current view: top level - transport/raw - ActiveTCPConnectionState.h (source / functions) Coverage Total Hit
Test: SHA:db08debc068562b264a2df3a7f3a8cc1d0b3aba1 Lines: 80.0 % 35 28
Test Date: 2025-10-02 07:10:30 Functions: 62.5 % 16 10

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2023 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 defines the CHIP Active Connection object that maintains TCP connections.
      22              :  */
      23              : 
      24              : #pragma once
      25              : 
      26              : #include <functional>
      27              : #include <inet/IPAddress.h>
      28              : #include <inet/InetInterface.h>
      29              : #include <inet/TCPEndPoint.h>
      30              : #include <lib/core/CHIPCore.h>
      31              : #include <lib/core/ReferenceCounted.h>
      32              : #include <lib/support/AutoRelease.h>
      33              : #include <transport/raw/PeerAddress.h>
      34              : #include <transport/raw/TCPConfig.h>
      35              : 
      36              : namespace chip {
      37              : namespace Transport {
      38              : 
      39              : // Forward declaration of friend class for test access.
      40              : template <size_t kActiveConnectionsSize, size_t kPendingPacketSize>
      41              : class TCPBaseTestAccess;
      42              : 
      43              : /**
      44              :  *  The State of the TCP connection
      45              :  */
      46              : enum class TCPState : uint8_t
      47              : {
      48              :     kNotReady    = 0, /**< State before initialization. */
      49              :     kInitialized = 1, /**< State after class is listening and ready. */
      50              :     kConnecting  = 3, /**< Connection with peer has been initiated. */
      51              :     kConnected   = 4, /**< Connected with peer and ready for Send/Receive. */
      52              :     kClosed      = 5, /**< Connection is closed. */
      53              : };
      54              : 
      55              : struct AppTCPConnectionCallbackCtxt;
      56              : 
      57              : // Templatized to force inlining
      58              : template <typename State>
      59              : class ActiveTCPConnectionStateDeleter
      60              : {
      61              : public:
      62           23 :     inline static void Release(State * entry) { entry->mReleaseConnection(*entry); }
      63              : };
      64              : 
      65              : /**
      66              :  *  State for each active TCP connection
      67              :  */
      68              : class ActiveTCPConnectionHolder;
      69              : struct ActiveTCPConnectionState
      70              :     : public ReferenceCounted<ActiveTCPConnectionState, ActiveTCPConnectionStateDeleter<ActiveTCPConnectionState>, 0, uint16_t>
      71              : {
      72              :     using ReleaseFnType = std::function<void(ActiveTCPConnectionState & connection)>;
      73              : 
      74          215 :     bool InUse() const { return mEndPoint != nullptr; }
      75              : 
      76          170 :     bool IsConnected() const { return (mEndPoint != nullptr && mConnectionState == TCPState::kConnected); }
      77              : 
      78            0 :     bool IsConnecting() const { return (mEndPoint != nullptr && mConnectionState == TCPState::kConnecting); }
      79              : 
      80              :     inline bool operator==(const ActiveTCPConnectionHolder & other) const;
      81              :     inline bool operator!=(const ActiveTCPConnectionHolder & other) const;
      82              : 
      83              :     // Peer Node Address
      84              :     PeerAddress mPeerAddr;
      85              : 
      86              :     // Buffers received but not yet consumed.
      87              :     System::PacketBufferHandle mReceived;
      88              : 
      89              :     // Current state of the connection
      90              :     TCPState mConnectionState;
      91              : 
      92              :     // A pointer to an application-specific state object. It should
      93              :     // represent an object that is at a layer above the SessionManager. The
      94              :     // SessionManager would accept this object at the time of connecting to
      95              :     // the peer, and percolate it down to the TransportManager that then,
      96              :     // should store this state in the corresponding connection object that
      97              :     // is created.
      98              :     // At various connection events, this state is passed back to the
      99              :     // corresponding application.
     100              :     AppTCPConnectionCallbackCtxt * mAppState = nullptr;
     101              : 
     102              :     // KeepAlive interval in seconds
     103              :     uint16_t mTCPKeepAliveIntervalSecs = CHIP_CONFIG_TCP_KEEPALIVE_INTERVAL_SECS;
     104              :     uint16_t mTCPMaxNumKeepAliveProbes = CHIP_CONFIG_MAX_TCP_KEEPALIVE_PROBES;
     105              : 
     106              :     // This is bad and should not normally be done; we are explicitly closing the TCP connection
     107              :     // instead of gracefully releasing our reference, which will theoretically cause anyone
     108              :     // holding a reference (who should have a listener for connection closing) to release their reference
     109              :     void ForceDisconnect() { mReleaseConnection(*this); }
     110              : 
     111              : private:
     112              :     template <size_t kActiveConnectionsSize, size_t kPendingPacketSize>
     113              :     friend class TCP;
     114              :     friend class TCPBase;
     115              :     friend class ActiveTCPConnectionStateDeleter<ActiveTCPConnectionState>;
     116              :     // Allow tests to access private members.
     117              :     template <size_t kActiveConnectionsSize, size_t kPendingPacketSize>
     118              :     friend class TCPBaseTestAccess;
     119              : 
     120              :     // Associated endpoint.
     121              :     Inet::TCPEndPoint * mEndPoint;
     122              :     ReleaseFnType mReleaseConnection;
     123              : 
     124          132 :     void Init(Inet::TCPEndPoint * endPoint, const PeerAddress & peerAddr, ReleaseFnType releaseConnection)
     125              :     {
     126          132 :         mEndPoint          = endPoint;
     127          132 :         mPeerAddr          = peerAddr;
     128          132 :         mReceived          = nullptr;
     129          132 :         mAppState          = nullptr;
     130          132 :         mReleaseConnection = releaseConnection;
     131          132 :     }
     132              : 
     133           24 :     void Free()
     134              :     {
     135           24 :         if (mEndPoint)
     136              :         {
     137           24 :             mEndPoint->Free();
     138              :         }
     139           24 :         mPeerAddr          = PeerAddress::Uninitialized();
     140           24 :         mEndPoint          = nullptr;
     141           24 :         mReceived          = nullptr;
     142           24 :         mAppState          = nullptr;
     143           24 :         mReleaseConnection = [](auto &) {};
     144           24 :     }
     145              : };
     146              : 
     147              : /**
     148              :  * A holder for ActiveTCPConnectionState which properly ref-counts on ctor/copy/dtor.
     149              :  */
     150              : class ActiveTCPConnectionHolder : private AutoRelease<ActiveTCPConnectionState>
     151              : {
     152              :     friend class TCPBase;
     153              :     friend struct ActiveTCPConnectionState;
     154              : 
     155              : public:
     156              :     using AutoRelease<ActiveTCPConnectionState>::operator->;
     157              :     using AutoRelease<ActiveTCPConnectionState>::IsNull;
     158              :     using AutoRelease<ActiveTCPConnectionState>::Release;
     159              : 
     160       135921 :     ActiveTCPConnectionHolder() : AutoRelease<ActiveTCPConnectionState>(nullptr) {}
     161           75 :     ActiveTCPConnectionHolder(ActiveTCPConnectionState * releasable) :
     162           75 :         AutoRelease<ActiveTCPConnectionState>(releasable ? releasable->Retain() : nullptr)
     163           75 :     {}
     164              : 
     165            0 :     ActiveTCPConnectionHolder(const ActiveTCPConnectionHolder & src) : ActiveTCPConnectionHolder(src.mReleasable) {}
     166              : 
     167          102 :     inline AutoRelease & operator=(const ActiveTCPConnectionHolder & src)
     168              :     {
     169          102 :         if (mReleasable != src.mReleasable)
     170              :         {
     171           92 :             Set(src.IsNull() ? nullptr : src.mReleasable->Retain());
     172              :         }
     173          102 :         return *this;
     174              :     }
     175              : 
     176           36 :     inline bool operator==(const ActiveTCPConnectionHolder & other) const { return mReleasable == other.mReleasable; }
     177            0 :     inline bool operator!=(const ActiveTCPConnectionHolder & other) const { return mReleasable != other.mReleasable; }
     178            0 :     inline bool operator==(const ActiveTCPConnectionState & other) const { return mReleasable == &other; }
     179              :     inline bool operator!=(const ActiveTCPConnectionState & other) const { return mReleasable != &other; }
     180              : 
     181              :     // For printing
     182            0 :     inline operator const void *() const { return mReleasable; }
     183              : };
     184              : 
     185            0 : inline bool ActiveTCPConnectionState::operator==(const ActiveTCPConnectionHolder & other) const
     186              : {
     187            0 :     return this == other.mReleasable;
     188              : }
     189              : inline bool ActiveTCPConnectionState::operator!=(const ActiveTCPConnectionHolder & other) const
     190              : {
     191              :     return this != other.mReleasable;
     192              : }
     193              : 
     194              : // Functors for callbacks into higher layers
     195              : using OnTCPConnectionReceivedCallback = void (*)(ActiveTCPConnectionState & conn);
     196              : 
     197              : using OnTCPConnectionCompleteCallback = void (*)(ActiveTCPConnectionHolder & conn, CHIP_ERROR conErr);
     198              : 
     199              : using OnTCPConnectionClosedCallback = void (*)(ActiveTCPConnectionState & conn, CHIP_ERROR conErr);
     200              : 
     201              : /*
     202              :  *  Application callback state that is passed down at connection establishment
     203              :  *  stage.
     204              :  * */
     205              : struct AppTCPConnectionCallbackCtxt
     206              : {
     207              :     void * appContext                              = nullptr; // A pointer to an application context object.
     208              :     OnTCPConnectionReceivedCallback connReceivedCb = nullptr;
     209              :     OnTCPConnectionCompleteCallback connCompleteCb = nullptr;
     210              :     OnTCPConnectionClosedCallback connClosedCb     = nullptr;
     211              : };
     212              : 
     213              : } // namespace Transport
     214              : } // namespace chip
        

Generated by: LCOV version 2.0-1