LCOV - code coverage report
Current view: top level - libs/bsw/cpp2ethernet/include/tcp/socket - AbstractSocket.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 9 9
Test Date: 2026-06-18 08:29:03 Functions: 100.0 % 4 4

            Line data    Source code
       1              : /********************************************************************************
       2              :  * Copyright (c) 2025 Accenture
       3              :  *
       4              :  * This program and the accompanying materials are made available under the
       5              :  * terms of the Apache License Version 2.0 which is available at
       6              :  * https://www.apache.org/licenses/LICENSE-2.0
       7              :  *
       8              :  * SPDX-License-Identifier: Apache-2.0
       9              :  ********************************************************************************/
      10              : 
      11              : #pragma once
      12              : 
      13              : #include <etl/delegate.h>
      14              : #include <etl/span.h>
      15              : #include <ip/IPAddress.h>
      16              : 
      17              : #include <cstdint>
      18              : 
      19              : namespace tcp
      20              : {
      21              : class IDataListener;
      22              : class IDataSendNotificationListener;
      23              : 
      24              : /**
      25              :  * Abstract base class for all sockets.
      26              :  *
      27              :  * \section Overview
      28              :  * The AbstractSocket is designed to be a socket abstraction to
      29              :  * a TCP stack.
      30              :  * The socket class can be used to connect to a remote system. It is also
      31              :  * returned to an ISocketConnectionListener by AbstractServerSocket
      32              :  * (using its ISocketProvider) once a connection from a remote system
      33              :  * is accepted. An active socket is used to receive and transmit data
      34              :  * from and to a remote system.
      35              :  *
      36              :  * \section Receive
      37              :  * The application that wants to receive data from a socket has to register
      38              :  * through the setDataListener method as an IDataListener.
      39              :  * After that the application is notified through its dataReceived
      40              :  * method.
      41              :  *
      42              :  * \section Send
      43              :  * Sending data through a socket is usually asynchronous. Because of that
      44              :  * it is possible to register an IDataSendNotificationListener who is
      45              :  * notified when the data passed to the send method is written to the
      46              :  * TCP-stack.
      47              :  * <b>This is not the time when the ACK package from the remote
      48              :  * system, is received!</b>
      49              :  *
      50              :  * \see     AbstractServerSocket
      51              :  * \see     ISocketProvidingConnectionListener
      52              :  * \see     IDataListener
      53              :  * \see     IDataSendNotificationListener
      54              :  */
      55              : class AbstractSocket
      56              : {
      57              : public:
      58              :     // [AbstractSocket]
      59              :     /**
      60              :      * all ErrorCodes used by socket
      61              :      * \enum   ErrorCode
      62              :      */
      63              :     enum class ErrorCode : uint8_t
      64              :     {
      65              :         /** everything ok */
      66              :         SOCKET_ERR_OK,
      67              :         /** an error occurred */
      68              :         SOCKET_ERR_NOT_OK,
      69              :         /** socket not open to send */
      70              :         SOCKET_ERR_NOT_OPEN,
      71              :         /** no more outgoing buffer available */
      72              :         SOCKET_ERR_NO_MORE_BUFFER,
      73              :         /** socket is full, flush before continuing */
      74              :         SOCKET_FLUSH
      75              :     };
      76              : 
      77              :     using ConnectedDelegate = ::etl::delegate<void(ErrorCode)>;
      78              : 
      79              :     /**
      80              :      * constructor
      81              :      * \post    fpDataListener == 0L
      82              :      * \post    fpSendNotificationListener == 0L
      83              :      */
      84              :     AbstractSocket();
      85              : 
      86              :     AbstractSocket(AbstractSocket const&)            = delete;
      87              :     AbstractSocket& operator=(AbstractSocket const&) = delete;
      88              : 
      89              :     /**
      90              :      * binds to a local address and port
      91              :      * \param   ipAddr  local ip address
      92              :      * \param   port    local port
      93              :      */
      94              :     virtual ErrorCode bind(ip::IPAddress const& ipAddr, uint16_t port) = 0;
      95              : 
      96              :     /**
      97              :      * connects to a remote host
      98              :      * \param   ipAddr  remote ip address
      99              :      * \param   port    remote port
     100              :      */
     101              :     virtual ErrorCode
     102              :     connect(ip::IPAddress const& ipAddr, uint16_t port, ConnectedDelegate delegate)
     103              :         = 0;
     104              : 
     105              :     /**
     106              :      * closes the socket by sending a FIN packet
     107              :      */
     108              :     virtual ErrorCode close() = 0;
     109              : 
     110              :     /**
     111              :      * aborts the socket by sending a RST packet
     112              :      */
     113              :     virtual void abort() = 0;
     114              : 
     115              :     /**
     116              :      * flushes enqueued data
     117              :      */
     118              :     virtual ErrorCode flush() = 0;
     119              : 
     120              :     /**
     121              :      * discards any received data without ack
     122              :      */
     123              :     virtual void discardData() = 0;
     124              : 
     125              :     /**
     126              :      * \return  number of bytes available in outgoing buffer
     127              :      */
     128              :     virtual size_t available() = 0;
     129              : 
     130              :     /**
     131              :      * reads a single byte
     132              :      * \param   byte   byte to read
     133              :      * \return  number of bytes read
     134              :      *          - 0: an error occurred reading from the socket
     135              :      *          - 1: byte read
     136              :      */
     137              :     virtual uint8_t read(uint8_t& byte) = 0;
     138              : 
     139              :     /**
     140              :      * reads a given number of bytes from the socket
     141              :      * \param   buffer  buffer to receive data to. If 0L is passed the n
     142              :      * bytes should be skipped, i.e. the input stream has to advance by
     143              :      * n bytes.
     144              :      * \param   n    number of bytes to receive
     145              :      * \return  number of bytes really read
     146              :      *          - 0: an error occurred reading from the socket
     147              :      *          - else: bytes read
     148              :      */
     149              :     virtual size_t read(uint8_t* buffer, size_t n) = 0;
     150              : 
     151              :     /**
     152              :      * sends an amount of data
     153              :      * \param   data  data to send
     154              :      * \return  status of transmission
     155              :      *          - SOCKET_OK when data was sent to TCP stack
     156              :      *          - SOCKET_CLOSED when socket has not been opened
     157              :      * \note
     158              :      * Sending the data may be asynchronous. For this reason the
     159              :      * IDataSendNotificationListener has an appropriate callback.
     160              :      */
     161              :     virtual ErrorCode send(::etl::span<uint8_t const> const& data) = 0;
     162              : 
     163              :     /**
     164              :      * sets the listener to this socket instance
     165              :      * \param  pListener  IDataListener to attach
     166              :      */
     167              :     void setDataListener(IDataListener* pListener);
     168              : 
     169              :     IDataListener* getDataListener() const;
     170              : 
     171              :     /**
     172              :      * sets the IDataSendNotificationListener of this socket
     173              :      * \param  pListener   listener that gets notified when data has been
     174              :      * copied completely to TCP stack
     175              :      */
     176              :     void setSendNotificationListener(IDataSendNotificationListener* pListener);
     177              : 
     178              :     IDataSendNotificationListener* getSendNotificationListener() const;
     179              : 
     180              :     virtual ip::IPAddress getRemoteIPAddress() const = 0;
     181              : 
     182              :     virtual ip::IPAddress getLocalIPAddress() const = 0;
     183              : 
     184              :     virtual uint16_t getRemotePort() const = 0;
     185              : 
     186              :     virtual uint16_t getLocalPort() const = 0;
     187              : 
     188              :     virtual bool isClosed() const = 0;
     189              : 
     190              :     virtual bool isEstablished() const = 0;
     191              : 
     192              :     /**
     193              :      * Permanently disables NAGLE algorithm for this socket.
     194              :      */
     195              :     virtual void disableNagleAlgorithm() = 0;
     196              : 
     197              :     /**
     198              :      * Enables TCP keepalive for this socket.
     199              :      * \param idle the length of time to keep an idle TCP connection active
     200              :      * \param interval the interval between packets sent to validate the TCP connection
     201              :      * \param probes the number of keepalive probes to be sent before terminating the connection
     202              :      */
     203              :     virtual void enableKeepAlive(uint32_t idle, uint32_t interval, uint32_t probes) = 0;
     204              : 
     205              :     /**
     206              :      * Disables TCP keepalive for this socket.
     207              :      */
     208              :     virtual void disableKeepAlive() = 0;
     209              :     // [AbstractSocket]
     210              : 
     211              : protected:
     212              :     IDataListener* _dataListener;
     213              :     IDataSendNotificationListener* _sendNotificationListener;
     214              : };
     215              : 
     216              : /*
     217              :  * inline methods
     218              :  */
     219           47 : inline void AbstractSocket::setDataListener(IDataListener* const pListener)
     220              : {
     221           47 :     _dataListener = pListener;
     222           47 : }
     223              : 
     224              : inline void
     225           47 : AbstractSocket::setSendNotificationListener(IDataSendNotificationListener* const pListener)
     226              : {
     227           47 :     _sendNotificationListener = pListener;
     228           47 : }
     229              : 
     230           57 : inline IDataListener* AbstractSocket::getDataListener() const { return _dataListener; }
     231              : 
     232           44 : inline IDataSendNotificationListener* AbstractSocket::getSendNotificationListener() const
     233              : {
     234           44 :     return _sendNotificationListener;
     235              : }
     236              : 
     237              : } // namespace tcp
        

Generated by: LCOV version 2.0-1