LCOV - code coverage report
Current view: top level - artdaq/DAQrate/detail - RequestMessage.hh (source / functions) Coverage Total Hit
Test: artdaq.info.cleaned Lines: 77.8 % 45 35
Test Date: 2025-09-04 00:45:34 Functions: 85.7 % 14 12

            Line data    Source code
       1              : #ifndef artdaq_DAQrate_detail_RequestMessage_hh
       2              : #define artdaq_DAQrate_detail_RequestMessage_hh
       3              : 
       4              : #include "TRACE/tracemf.h"  // Pre-empt TRACE/trace.h from Fragment.hh.
       5              : #include "artdaq-core/Data/Fragment.hh"
       6              : #define MAX_REQUEST_MESSAGE_SIZE 65000
       7              : 
       8              : #include "artdaq/DAQdata/Globals.hh"
       9              : 
      10              : #include <iostream>
      11              : #include <vector>
      12              : 
      13              : namespace artdaq {
      14              : namespace detail {
      15              : struct RequestPacket;
      16              : struct RequestHeader;
      17              : class RequestMessage;
      18              : 
      19              : /**
      20              :  * \brief Mode used to indicate current run conditions to the request receiver
      21              :  */
      22              : enum class RequestMessageMode : uint8_t
      23              : {
      24              :         Normal = 0,    ///< Normal running
      25              :         EndOfRun = 1,  ///< End of Run mode (Used to end request processing on receiver)
      26              : };
      27              : 
      28              : /**
      29              :  * \brief Converts the RequestMessageMode to a string and sends it to the output stream
      30              :  * \param o Stream to send string to
      31              :  * \param m RequestMessageMode to convert to string
      32              :  * \return o with string sent to it
      33              :  */
      34            0 : inline std::ostream& operator<<(std::ostream& o, RequestMessageMode m)
      35              : {
      36            0 :         switch (m)
      37              :         {
      38            0 :                 case RequestMessageMode::Normal:
      39            0 :                         o << "Normal";
      40            0 :                         break;
      41            0 :                 case RequestMessageMode::EndOfRun:
      42            0 :                         o << "EndOfRun";
      43            0 :                         break;
      44              :         }
      45            0 :         return o;
      46              : }
      47              : 
      48              : }  // namespace detail
      49              : }  // namespace artdaq
      50              : 
      51              : /**
      52              :  * \brief The RequestPacket contains information about a single data request
      53              :  */
      54              : struct artdaq::detail::RequestPacket
      55              : {
      56              : public:
      57              :         /** The magic bytes for the request packet */
      58              :         uint32_t header{0};                                                // TRIG, or 0x54524947
      59              :         Fragment::sequence_id_t sequence_id{Fragment::InvalidSequenceID};  ///< The sequence ID that responses to this request should use
      60              :         Fragment::timestamp_t timestamp{Fragment::InvalidTimestamp};       ///< The timestamp of the request
      61              : 
      62            6 :         RequestPacket() = default;
      63              : 
      64              :         /**
      65              :          * \brief Create a RequestPacket using the given sequence ID and timestmap
      66              :          * \param seq Sequence ID of RequestPacket
      67              :          * \param ts Timestamp of RequestPAcket
      68              :          */
      69            6 :         RequestPacket(const Fragment::sequence_id_t& seq, const Fragment::timestamp_t& ts)
      70            6 :             : header(0x54524947)
      71            6 :             , sequence_id(seq)
      72            6 :             , timestamp(ts)
      73            6 :         {}
      74              : 
      75              :         /**
      76              :          * \brief Check the magic bytes of the packet
      77              :          * \return Whether the correct magic bytes were found
      78              :          */
      79           18 :         bool isValid() const { return header == 0x54524947; }
      80              : };
      81              : 
      82              : /**
      83              :  * \brief Header of a RequestMessage. Contains magic bytes for validation and a count of expected RequestPackets
      84              :  */
      85              : struct artdaq::detail::RequestHeader
      86              : {
      87              :         /** The magic bytes for the request header */
      88              :         uint32_t header{0x48454452};                          // HEDR, or 0x48454452
      89              :         uint32_t packet_count{0};                             ///< The number of RequestPackets in this Request message
      90              :         int rank{my_rank};                                    ///< Rank of the sender
      91              :         uint32_t run_number{0};                               ///< The Run with which this request should be associated
      92              :         RequestMessageMode mode{RequestMessageMode::Normal};  ///< Communicates additional information to the Request receiver
      93              : 
      94            8 :         RequestHeader() = default;
      95              : 
      96              :         /**
      97              :          * \brief Check the magic bytes of the packet
      98              :          * \return Whether the correct magic bytes were found
      99              :          */
     100           16 :         bool isValid() const { return header == 0x48454452; }
     101              : };
     102              : 
     103              : /**
     104              :  * \brief A RequestMessage consists of a RequestHeader and zero or more RequestPackets. They will usually be sent in two calls to send()
     105              :  */
     106              : class artdaq::detail::RequestMessage
     107              : {
     108              : public:
     109              :         /**
     110              :          * \brief Default Constructor
     111              :          */
     112            4 :         RequestMessage()
     113            4 :             : header_()
     114            4 :             , packets_()
     115            4 :         {}
     116              : 
     117              :         /**
     118              :          * \brief Get the contents of the RequestMessage
     119              :          * \return Vector of bytes corresponding to the full RequestMessage (may span multiple packets)
     120              :          */
     121            4 :         std::vector<uint8_t> GetMessage()
     122              :         {
     123            4 :                 auto size = sizeof(RequestHeader) + packets_.size() * sizeof(RequestPacket);
     124            4 :                 header_.packet_count = packets_.size();
     125            4 :                 assert(size < MAX_REQUEST_MESSAGE_SIZE);
     126            4 :                 auto output = std::vector<uint8_t>(size);
     127            4 :                 memcpy(&output[0], &header_, sizeof(RequestHeader));
     128            4 :                 memcpy(&output[sizeof(RequestHeader)], &packets_[0], packets_.size() * sizeof(RequestPacket));
     129              : 
     130            4 :                 return output;
     131              :         }
     132              : 
     133              :         /**
     134              :          * \brief Set the Request Message Mode for this request
     135              :          * \param mode Mode for this Request Message
     136              :          */
     137            4 :         void setMode(RequestMessageMode mode)
     138              :         {
     139            4 :                 header_.mode = mode;
     140            4 :         }
     141              : 
     142              :         /**
     143              :          * \brief Set the rank in the header for this request. This will be the rank from which the request originates.
     144              :          * \param rank Rank for this Request Message
     145              :          */
     146            4 :         void setRank(int rank)
     147              :         {
     148            4 :                 header_.rank = rank;
     149            4 :         }
     150              : 
     151              :         /**
     152              :          * \brief Set the run number in the header for this request.
     153              :          * This will be the Run for which the request is valid.
     154              :          * \param run Run number for this Request Message
     155              :          */
     156            4 :         void setRunNumber(int run)
     157              :         {
     158            4 :                 header_.run_number = run;
     159            4 :         }
     160              : 
     161              :         /**
     162              :          * \brief Get the number of RequestPackets in the RequestMessage
     163              :          * \return The number of RequestPackets in the RequestMessage
     164              :          */
     165            0 :         size_t size() const { return packets_.size(); }
     166              : 
     167              :         /**
     168              :          * \brief Add a request for a sequence ID and timestamp combination
     169              :          * \param seq Sequence ID to request
     170              :          * \param time Timestamp of request
     171              :          */
     172            6 :         void addRequest(const Fragment::sequence_id_t& seq, const Fragment::timestamp_t& time)
     173              :         {
     174            6 :                 packets_.emplace_back(RequestPacket(seq, time));
     175            6 :         }
     176              : 
     177              :         /**
     178              :          * @brief Get the maximum number of requests that can be sent in a single RequestMessage
     179              :          * @return The maximum number of reqeusts that fit in a single UDP datagram
     180              :          */
     181          446 :         static size_t max_request_count()
     182              :         {
     183          446 :                 return (MAX_REQUEST_MESSAGE_SIZE - sizeof(RequestHeader)) / sizeof(RequestPacket);
     184              :         }
     185              : 
     186              : private:
     187              :         RequestHeader header_;
     188              :         std::vector<RequestPacket> packets_;
     189              : };
     190              : 
     191              : #endif  // artdaq_DAQrate_detail_RequestMessage
        

Generated by: LCOV version 2.0-1