Matter SDK Coverage Report
Current view: top level - transport/raw - TCP.h (source / functions) Coverage Total Hit
Test: SHA:e98a48c2e59f85a25417956e1d105721433aa5d1 Lines: 90.0 % 30 27
Test Date: 2026-01-09 16:53:50 Functions: 82.4 % 17 14

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020-2025 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 Connection object that maintains TCP connections.
      22              :  *      It binds to any available local addr and port and begins listening.
      23              :  */
      24              : 
      25              : #pragma once
      26              : 
      27              : #include <algorithm>
      28              : #include <new>
      29              : #include <utility>
      30              : 
      31              : #include <inet/IPAddress.h>
      32              : #include <inet/InetInterface.h>
      33              : #include <inet/TCPEndPoint.h>
      34              : #include <lib/core/CHIPCore.h>
      35              : #include <lib/support/CodeUtils.h>
      36              : #include <lib/support/PoolWrapper.h>
      37              : #include <transport/raw/ActiveTCPConnectionState.h>
      38              : #include <transport/raw/Base.h>
      39              : #include <transport/raw/TCPConfig.h>
      40              : 
      41              : namespace chip {
      42              : namespace Transport {
      43              : 
      44              : /** Defines listening parameters for setting up a TCP transport */
      45              : class TcpListenParameters
      46              : {
      47              : public:
      48           23 :     explicit TcpListenParameters(Inet::EndPointManager<Inet::TCPEndPoint> * endPointManager) : mEndPointManager(endPointManager) {}
      49            1 :     TcpListenParameters(const TcpListenParameters &) = default;
      50              :     TcpListenParameters(TcpListenParameters &&)      = default;
      51              : 
      52           23 :     Inet::EndPointManager<Inet::TCPEndPoint> * GetEndPointManager() { return mEndPointManager; }
      53              : 
      54           45 :     Inet::IPAddressType GetAddressType() const { return mAddressType; }
      55           23 :     TcpListenParameters & SetAddressType(Inet::IPAddressType type)
      56              :     {
      57           23 :         mAddressType = type;
      58              : 
      59           23 :         return *this;
      60              :     }
      61              : 
      62           44 :     uint16_t GetListenPort() const { return mListenPort; }
      63           23 :     TcpListenParameters & SetListenPort(uint16_t port)
      64              :     {
      65           23 :         mListenPort = port;
      66              : 
      67           23 :         return *this;
      68              :     }
      69              : 
      70           22 :     Inet::InterfaceId GetInterfaceId() const { return mInterfaceId; }
      71              :     TcpListenParameters & SetInterfaceId(Inet::InterfaceId id)
      72              :     {
      73              :         mInterfaceId = id;
      74              : 
      75              :         return *this;
      76              :     }
      77              : 
      78           26 :     bool IsServerListenEnabled() const { return mServerListenEnabled; }
      79            1 :     TcpListenParameters & SetServerListenEnabled(bool listenEnable)
      80              :     {
      81            1 :         mServerListenEnabled = listenEnable;
      82              : 
      83            1 :         return *this;
      84              :     }
      85              : 
      86              : private:
      87              :     Inet::EndPointManager<Inet::TCPEndPoint> * mEndPointManager;   ///< Associated endpoint factory
      88              :     Inet::IPAddressType mAddressType = Inet::IPAddressType::kIPv6; ///< type of listening socket
      89              :     uint16_t mListenPort             = CHIP_PORT;                  ///< TCP listen port
      90              :     Inet::InterfaceId mInterfaceId   = Inet::InterfaceId::Null();  ///< Interface to listen on
      91              :     bool mServerListenEnabled        = true;                       ///< TCP Server mode enabled
      92              : };
      93              : 
      94              : /**
      95              :  * Packets scheduled for sending once a connection has been established.
      96              :  */
      97              : struct PendingPacket
      98              : {
      99            5 :     PendingPacket(const PeerAddress & peerAddress, System::PacketBufferHandle && packetBuffer) :
     100            5 :         mPeerAddress(peerAddress), mPacketBuffer(std::move(packetBuffer))
     101            5 :     {}
     102              : 
     103              :     PeerAddress mPeerAddress;                 // where the packet is being sent to
     104              :     System::PacketBufferHandle mPacketBuffer; // what data needs to be sent
     105              : };
     106              : 
     107              : /** Implements a transport using TCP. */
     108              : class DLL_EXPORT TCPBase : public Base
     109              : {
     110              : 
     111              : protected:
     112              :     enum class ShouldAbort : uint8_t
     113              :     {
     114              :         Yes,
     115              :         No
     116              :     };
     117              : 
     118              :     enum class SuppressCallback : uint8_t
     119              :     {
     120              :         Yes,
     121              :         No
     122              :     };
     123              : 
     124              : public:
     125              :     using PendingPacketPoolType = PoolInterface<PendingPacket, const PeerAddress &, System::PacketBufferHandle &&>;
     126           53 :     TCPBase(ActiveTCPConnectionState * activeConnectionsBuffer, size_t bufferSize, PendingPacketPoolType & packetBuffers) :
     127           53 :         mActiveConnections(activeConnectionsBuffer), mActiveConnectionsSize(bufferSize), mPendingPackets(packetBuffers)
     128              :     {
     129              :         // activeConnectionsBuffer must be initialized by the caller.
     130           53 :     }
     131              :     ~TCPBase() override;
     132              : 
     133              :     /**
     134              :      * Initialize a TCP transport on a given port.
     135              :      *
     136              :      * @param params        TCP configuration parameters for this transport
     137              :      *
     138              :      * @details
     139              :      *   Generally send and receive ports should be the same and equal to CHIP_PORT.
     140              :      *   The class allows separate definitions to allow local execution of several
     141              :      *   Nodes.
     142              :      */
     143              :     CHIP_ERROR Init(TcpListenParameters & params);
     144              : 
     145              :     /**
     146              :      * Set the timeout (in milliseconds) for the node to wait for the TCP
     147              :      * connection attempt to complete.
     148              :      *
     149              :      */
     150              :     void SetConnectTimeout(const uint32_t connTimeoutMsecs) { mConnectTimeout = connTimeoutMsecs; }
     151              : 
     152              :     /**
     153              :      * Close the open endpoint without destroying the object
     154              :      */
     155              :     void Close() override;
     156              : 
     157              :     CHIP_ERROR SendMessage(const PeerAddress & address, System::PacketBufferHandle && msgBuf) override;
     158              :     CHIP_ERROR SendMessage(const ActiveTCPConnectionHandle & connection, System::PacketBufferHandle && msgBuf);
     159              : 
     160              :     /*
     161              :      * Connect to the given peerAddress over TCP.
     162              :      *
     163              :      * @param address           The address of the peer.
     164              :      *
     165              :      * @param appState          Context passed in by the application to be sent back
     166              :      *                          via the connection attempt complete callback when
     167              :      *                          connection attempt with peer completes.
     168              :      *
     169              :      * @param outPeerConnState  Pointer to pointer to the active TCP connection state. This is
     170              :      *                          an output parameter that is allocated by the
     171              :      *                          transport layer and held by the caller object.
     172              :      *                          This allows the caller object to abort the
     173              :      *                          connection attempt if the caller object dies
     174              :      *                          before the attempt completes.
     175              :      *
     176              :      */
     177              :     CHIP_ERROR TCPConnect(const PeerAddress & address, Transport::AppTCPConnectionCallbackCtxt * appState,
     178              :                           Transport::ActiveTCPConnectionHandle & outPeerConnState) override;
     179              : 
     180            0 :     bool CanSendToPeer(const PeerAddress & address) override
     181              :     {
     182            0 :         return (mState == TCPState::kInitialized) && (address.GetTransportType() == Type::kTcp) &&
     183            0 :             (address.GetIPAddress().Type() == mEndpointType);
     184              :     }
     185              : 
     186              :     const Optional<PeerAddress> GetConnectionPeerAddress(const Inet::TCPEndPointHandle & con)
     187              :     {
     188              :         ActiveTCPConnectionHandle activeConState = FindActiveConnection(con);
     189              : 
     190              :         return !activeConState.IsNull() ? MakeOptional<PeerAddress>(activeConState->mPeerAddr) : Optional<PeerAddress>::Missing();
     191              :     }
     192              : 
     193              :     /**
     194              :      * Helper method to determine if IO processing is still required for a TCP transport
     195              :      * before everything is cleaned up (socket closing is async, so after calling 'Close' on
     196              :      * the transport, some time may be needed to actually be able to close.)
     197              :      */
     198              :     bool HasActiveConnections() const;
     199              : 
     200              :     /**
     201              :      * Close all active connections.
     202              :      */
     203              :     void CloseActiveConnections();
     204              : 
     205              : #if INET_CONFIG_TEST
     206              :     static bool sForceFailureInDoHandleIncomingConnection;
     207              : #endif
     208              : 
     209              : private:
     210              :     // Allow tests to access private members.
     211              :     template <size_t kActiveConnectionsSize, size_t kPendingPacketSize>
     212              :     friend class TCPBaseTestAccess;
     213              : 
     214              :     /**
     215              :      * Allocate and initialize a connection from the pool.
     216              :      */
     217              :     ActiveTCPConnectionState * AllocateConnection(const Inet::TCPEndPointHandle & endpoint, const PeerAddress & address);
     218              :     /**
     219              :      * Find an active connection to the given peer or return nullptr if
     220              :      * no active connection exists.
     221              :      */
     222              :     ActiveTCPConnectionHandle FindInUseConnection(const PeerAddress & addr);
     223              :     ActiveTCPConnectionState * FindActiveConnection(const Inet::TCPEndPointHandle & endPoint);
     224              : 
     225              :     /**
     226              :      * Find an allocated connection that matches the corresponding TCPEndPoint.
     227              :      */
     228              :     ActiveTCPConnectionHandle FindInUseConnection(const Inet::TCPEndPoint & endPoint);
     229              : 
     230              :     /**
     231              :      * Sends the specified message once a connection has been established.
     232              :      *
     233              :      * @param existing - an already-existing connection; must not be empty
     234              :      * @param msg - what buffer to send once a connection has been established.
     235              :      *
     236              :      * Ownership of msg is taken over and will be freed at some unspecified time
     237              :      * in the future (once connection succeeds/fails).
     238              :      */
     239              :     CHIP_ERROR SendAfterConnect(const ActiveTCPConnectionHandle & existing, System::PacketBufferHandle && msg);
     240              : 
     241              :     /**
     242              :      * Process a single received buffer from the specified peer address.
     243              :      *
     244              :      * @param endPoint the source end point from which the data comes from
     245              :      * @param peerAddress the peer the data is coming from
     246              :      * @param buffer the actual data
     247              :      *
     248              :      * Ownership of buffer is taken over and will be freed (or re-enqueued to the endPoint receive queue)
     249              :      * as needed during processing.
     250              :      */
     251              :     CHIP_ERROR ProcessReceivedBuffer(const Inet::TCPEndPointHandle & endPoint, const PeerAddress & peerAddress,
     252              :                                      System::PacketBufferHandle && buffer);
     253              : 
     254              :     /**
     255              :      * Process a single message of the specified size from a buffer.
     256              :      *
     257              :      * @param[in]     peerAddress   The peer the data is coming from.
     258              :      * @param[in,out] state         The connection state, which contains the message. On entry, the payload points to the message
     259              :      *                              body (after the length). On exit, it points after the message (or the queue is null, if there
     260              :      *                              is no other data).
     261              :      * @param[in]     messageSize   Size of the single message.
     262              :      */
     263              :     CHIP_ERROR ProcessSingleMessage(const PeerAddress & peerAddress, ActiveTCPConnectionState & state, size_t messageSize);
     264              : 
     265              :     /**
     266              :      * Initiate a connection to the given peer. On connection completion,
     267              :      * HandleTCPConnectComplete callback would be called.
     268              :      *
     269              :      */
     270              :     CHIP_ERROR StartConnect(const PeerAddress & addr, AppTCPConnectionCallbackCtxt * appState,
     271              :                             ActiveTCPConnectionHandle & outPeerConnState);
     272              : 
     273              :     // Close an active connection (corresponding to the passed
     274              :     // ActiveTCPConnectionState object)
     275              :     // and release from the pool.
     276              :     void TCPDisconnect(ActiveTCPConnectionState & conn, bool shouldAbort = false);
     277              : 
     278              :     /**
     279              :      * Gracefully Close or Abort a given connection.
     280              :      *
     281              :      */
     282              :     void CloseConnectionInternal(ActiveTCPConnectionState & connection, CHIP_ERROR err, SuppressCallback suppressCallback);
     283              : 
     284              :     // Close the listening socket endpoint
     285              :     void CloseListeningSocket();
     286              : 
     287              :     // Callback handler for TCPEndPoint. TCP message receive handler.
     288              :     // @see TCPEndpoint::OnDataReceivedFunct
     289              :     static CHIP_ERROR HandleTCPEndPointDataReceived(const Inet::TCPEndPointHandle & endPoint, System::PacketBufferHandle && buffer);
     290              : 
     291              :     // Callback handler for TCPEndPoint. Called when a connection has been completed.
     292              :     // @see TCPEndpoint::OnConnectCompleteFunct
     293              :     static void HandleTCPEndPointConnectComplete(const Inet::TCPEndPointHandle & endPoint, CHIP_ERROR err);
     294              : 
     295              :     // Callback handler for TCPEndPoint. Called when a connection has been closed.
     296              :     // @see TCPEndpoint::OnConnectionClosedFunct
     297              :     static void HandleTCPEndPointConnectionClosed(const Inet::TCPEndPointHandle & endPoint, CHIP_ERROR err);
     298              : 
     299              :     // Callback handler for TCPEndPoint. Called when a connection is received on the listening port.
     300              :     // @see TCPEndpoint::OnConnectionReceivedFunct
     301              :     static void HandleIncomingConnection(const Inet::TCPEndPointHandle & listenEndPoint, const Inet::TCPEndPointHandle & endPoint,
     302              :                                          const Inet::IPAddress & peerAddress, uint16_t peerPort);
     303              : 
     304              :     CHIP_ERROR DoHandleIncomingConnection(const Inet::TCPEndPointHandle & listenEndPoint, const Inet::TCPEndPointHandle & endPoint,
     305              :                                           const Inet::IPAddress & peerAddress, uint16_t peerPort);
     306              : 
     307              :     // Callback handler for handling accept error
     308              :     // @see TCPEndpoint::OnAcceptErrorFunct
     309              :     static void HandleAcceptError(const Inet::TCPEndPointHandle & endPoint, CHIP_ERROR err);
     310              : 
     311              :     void InitEndpoint(const Inet::TCPEndPointHandle & endpoint);
     312              :     CHIP_ERROR PrepareBuffer(System::PacketBufferHandle & msgBuf);
     313              : 
     314              :     Inet::TCPEndPointHandle mListenSocket;                             ///< TCP socket used by the transport
     315              :     Inet::IPAddressType mEndpointType = Inet::IPAddressType::kUnknown; ///< Socket listening type
     316              :     TCPState mState                   = TCPState::kNotReady;           ///< State of the TCP transport
     317              : 
     318              :     // The configured timeout for the connection attempt to the peer, before
     319              :     // giving up.
     320              :     uint32_t mConnectTimeout = CHIP_CONFIG_TCP_CONNECT_TIMEOUT_MSECS;
     321              : 
     322              :     // Number of active and 'pending connection' endpoints
     323              :     size_t mUsedEndPointCount = 0;
     324              : 
     325              :     // Currently active connections
     326              :     ActiveTCPConnectionState * mActiveConnections;
     327              :     const size_t mActiveConnectionsSize;
     328              : 
     329              :     // Data to be sent when connections succeed
     330              :     PendingPacketPoolType & mPendingPackets;
     331              : };
     332              : 
     333              : template <size_t kActiveConnectionsSize, size_t kPendingPacketSize>
     334              : class TCP : public TCPBase
     335              : {
     336              : public:
     337          265 :     TCP() : TCPBase(mConnectionsBuffer, kActiveConnectionsSize, mPendingPackets)
     338              :     {
     339          265 :         for (size_t i = 0; i < kActiveConnectionsSize; ++i)
     340              :         {
     341          212 :             mConnectionsBuffer[i].Init(nullptr, PeerAddress::Uninitialized(), [](auto &) {});
     342              :         }
     343           53 :     }
     344              : 
     345          265 :     ~TCP() override { mPendingPackets.ReleaseAll(); }
     346              : 
     347              : private:
     348              :     ActiveTCPConnectionState mConnectionsBuffer[kActiveConnectionsSize];
     349              :     PoolImpl<PendingPacket, kPendingPacketSize, ObjectPoolMem::kInline, PendingPacketPoolType::Interface> mPendingPackets;
     350              : };
     351              : 
     352              : } // namespace Transport
     353              : } // namespace chip
        

Generated by: LCOV version 2.0-1