LCOV - code coverage report
Current view: top level - asiolibs/plugins - SocketReaderModule.hpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 1 0
Test Date: 2026-07-12 15:23:06 Functions: 0.0 % 1 0

            Line data    Source code
       1              : /**
       2              :  * @file SocketReaderModule.hpp Boost.Asio-based socket reader plugin for low-bandwidth devices
       3              :  *
       4              :  * This is part of the DUNE DAQ , copyright 2020.
       5              :  * Licensing/copyright details are in the COPYING file that you should have
       6              :  * received with this code.
       7              :  */
       8              : #ifndef ASIOLIBS_PLUGINS_SOCKETREADERMODULE_HPP_
       9              : #define ASIOLIBS_PLUGINS_SOCKETREADERMODULE_HPP_
      10              : 
      11              : #include "appfwk/DAQModule.hpp"
      12              : 
      13              : #include <boost/array.hpp>
      14              : #include <boost/asio.hpp>
      15              : 
      16              : #include <map>
      17              : #include <memory>
      18              : #include <string>
      19              : #include <vector>
      20              : #include <utility>
      21              : 
      22              : namespace dunedaq::asiolibs {
      23              : 
      24              : class SourceConcept;
      25              : 
      26              : class SocketReaderModule : public dunedaq::appfwk::DAQModule
      27              : {
      28              : public:
      29              :   using remote_t = std::pair<std::string, uint32_t>; // NOLINT(build/unsigned)
      30              :   using remote_stream_pair_t = std::pair<remote_t, uint32_t>; // NOLINT(build/unsigned)
      31              :   using remote_source_map_t = std::map<remote_stream_pair_t, std::shared_ptr<SourceConcept>>;
      32              : 
      33              :   /**
      34              :    * @brief SocketReaderModule constructor
      35              :    * @param name DAQ module instance name
      36              :    */
      37              :   explicit SocketReaderModule(const std::string& name);
      38            0 :   ~SocketReaderModule() = default;
      39              : 
      40              :   SocketReaderModule(const SocketReaderModule&) = delete;            ///< SocketReaderModule is not copy-constructible
      41              :   SocketReaderModule& operator=(const SocketReaderModule&) = delete; ///< SocketReaderModule is not copy-assignable
      42              :   SocketReaderModule(SocketReaderModule&&) = delete;                 ///< SocketReaderModule is not move-constructible
      43              :   SocketReaderModule& operator=(SocketReaderModule&&) = delete;      ///< SocketReaderModule is not move-assignable
      44              : 
      45              :   /**
      46              :    * @brief Handles initialization on boot
      47              :    * @param mcfg DAQ configuration data
      48              :    */
      49              :   void init(const std::shared_ptr<appfwk::ConfigurationManager> mcfg) override;
      50              : 
      51              : private:
      52              :   enum class SocketType
      53              :   {
      54              :     TCP,
      55              :     UDP,
      56              :     INVALID
      57              :   };
      58              : 
      59              :   struct SocketStats
      60              :   {
      61              :     /**
      62              :      * @brief Received packets
      63              :      */
      64              :     std::atomic<uint64_t> packets_received{ 0 }; // NOLINT(build/unsigned)
      65              : 
      66              :     /**
      67              :      * @brief Received bytes
      68              :      */
      69              :     std::atomic<uint64_t> bytes_received{ 0 }; // NOLINT(build/unsigned)
      70              : 
      71              :     /**
      72              :      * @brief Counts packets since last opmon data generation
      73              :      */
      74              :     std::atomic<int> stats_packet_count{ 0 };        
      75              :   };
      76              : 
      77              :   struct ReaderInfo
      78              :   {
      79              :     /**
      80              :      * @brief Source IP address
      81              :      */
      82              :     std::string local_ip;
      83              : 
      84              :     /**
      85              :      * @brief Source port number
      86              :      */
      87              :     uint32_t local_port; // NOLINT(build/unsigned)
      88              : 
      89              :     /**
      90              :      * @brief Statistics of socket traffic
      91              :      */
      92              :     std::shared_ptr<SocketStats> socket_stats;
      93              :   };
      94              : 
      95              :   class TCPReader
      96              :   {
      97              :   public:
      98              :     /**
      99              :      * @brief Asynchronously creates and connects a TCP socket
     100              :      * @param io_context I/O context for socket creation
     101              :      * @param reader_info TCP reader info
     102              :      * @throws boost::system::system_error on failure
     103              :      */
     104              :     void configure(boost::asio::io_context& io_context, std::shared_ptr<ReaderInfo> reader_info);
     105              : 
     106              :     /**
     107              :      * @brief Asynchronously receives payloads from the socket in a loop
     108              :      * @param sources Data sources
     109              :      * @return Coroutine handle
     110              :      */
     111              :     boost::asio::awaitable<void> start(const remote_source_map_t& remote_to_source);
     112              : 
     113              :     /**
     114              :      * @brief Closes the socket
     115              :      */
     116              :     void stop();
     117              : 
     118              :   private:
     119              :     /**
     120              :      * @brief TCP socket
     121              :      */
     122              :     std::unique_ptr<boost::asio::ip::tcp::socket> m_socket;
     123              : 
     124              :     /**
     125              :      * @brief Connected remote
     126              :      */    
     127              :     remote_t m_remote;
     128              : 
     129              :     /**
     130              :      * @brief Statistics of socket traffic
     131              :      */
     132              :     std::shared_ptr<SocketStats> m_socket_stats;
     133              :   };
     134              : 
     135              :   class UDPReader
     136              :   {
     137              :   public:
     138              :     /**
     139              :      * @brief Creates a UDP socket
     140              :      * @param io_context I/O context for socket creation
     141              :      * @param reader_info UDP reader info
     142              :      */
     143              :     void configure(boost::asio::io_context& io_context, std::shared_ptr<ReaderInfo> reader_info);
     144              : 
     145              :     /**
     146              :      * @brief Asynchronously receives payloads from the socket in a loop
     147              :      * @param sources Data sources
     148              :      * @return Coroutine handle
     149              :      */
     150              :     boost::asio::awaitable<void> start(const remote_source_map_t& remote_to_source);
     151              : 
     152              :     /**
     153              :      * @brief Closes the socket
     154              :      */
     155              :     void stop();
     156              : 
     157              :   private:
     158              :     /**
     159              :      * @brief UDP socket
     160              :      */
     161              :     std::unique_ptr<boost::asio::ip::udp::socket> m_socket;
     162              : 
     163              :     /**
     164              :      * @brief Statistics of socket traffic
     165              :      */
     166              :     std::shared_ptr<SocketStats> m_socket_stats;
     167              :   };
     168              : 
     169              :   // Commands
     170              :   void do_configure(const CommandData_t&);
     171              :   void do_start(const CommandData_t&);
     172              :   void do_stop(const CommandData_t&);
     173              : 
     174              :   void generate_opmon_data() override;
     175              : 
     176              :   /**
     177              :    * @brief Converts a socket type string to an enum
     178              :    * @param socket_type Socket type as a string
     179              :    * @return Corresponding SocketType enum
     180              :    */
     181              :   SocketType string_to_socket_type(const std::string& socket_type) const;
     182              : 
     183              :   /**
     184              :    * @brief I/O context for socket operations
     185              :    */
     186              :   boost::asio::io_context m_io_context;
     187              : 
     188              :   /**
     189              :    * @brief Prevents I/O context from exiting prematurely
     190              :    */
     191              :   boost::asio::executor_work_guard<boost::asio::io_context::executor_type> m_work_guard;
     192              : 
     193              :   /**
     194              :    * @brief Socket readers
     195              :    */
     196              :   std::vector<std::shared_ptr<std::variant<TCPReader, UDPReader>>> m_readers;
     197              : 
     198              :   /**
     199              :    * @brief Background thread to keep the I/O context running
     200              :    */
     201              :   std::jthread m_io_thread;
     202              : 
     203              :   /**
     204              :    * @brief Socket reader infos
     205              :    */
     206              :   std::vector<std::shared_ptr<ReaderInfo>> m_reader_infos;
     207              : 
     208              :   // Sinks (SourceConcepts)
     209              :   using sid_to_source_map_t = std::map<uint32_t, std::shared_ptr<SourceConcept>>; // NOLINT(build/unsigned)
     210              :   /**
     211              :    * @brief Data sources
     212              :    */
     213              :   sid_to_source_map_t m_sources;
     214              : 
     215              :   /**
     216              :    * @brief Map between a pair of {remote, stream} and the corresponding source
     217              :    */    
     218              :   remote_source_map_t m_remote_to_source;  
     219              : 
     220              : };
     221              : 
     222              : } // namespace dunedaq::asiolibs
     223              : 
     224              : #endif // ASIOLIBS_PLUGINS_SOCKETREADERMODULE_HPP_
        

Generated by: LCOV version 2.0-1