Matter SDK Coverage Report
Current view: top level - transport/raw - TCP.h (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 76.0 % 25 19
Test Date: 2025-01-17 19:00:11 Functions: 76.9 % 13 10

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

Generated by: LCOV version 2.0-1