00001 #ifndef artdaq_DAQrate_detail_RequestMessage_hh
00002 #define artdaq_DAQrate_detail_RequestMessage_hh
00003
00004 #include "artdaq-core/Data/Fragment.hh"
00005 #define MAX_REQUEST_MESSAGE_SIZE 65000
00006
00007 namespace artdaq
00008 {
00009 namespace detail
00010 {
00011 struct RequestPacket;
00012 struct RequestHeader;
00013 class RequestMessage;
00014
00018 enum class RequestMessageMode : uint8_t
00019 {
00020 Normal = 0,
00021 EndOfRun = 1,
00022 };
00023
00030 inline std::ostream& operator<<(std::ostream& o, RequestMessageMode m)
00031 {
00032 switch (m)
00033 {
00034 case RequestMessageMode::Normal:
00035 o << "Normal";
00036 break;
00037 case RequestMessageMode::EndOfRun:
00038 o << "EndOfRun";
00039 break;
00040 }
00041 return o;
00042 }
00043
00044 }
00045 }
00046
00050 struct artdaq::detail::RequestPacket
00051 {
00052 public:
00054 uint32_t header;
00055 Fragment::sequence_id_t sequence_id;
00056 Fragment::timestamp_t timestamp;
00057
00061 RequestPacket()
00062 : header(0)
00063 , sequence_id(Fragment::InvalidSequenceID)
00064 , timestamp(Fragment::InvalidTimestamp)
00065 {}
00066
00072 RequestPacket(const Fragment::sequence_id_t& seq, const Fragment::timestamp_t& ts)
00073 : header(0x54524947)
00074 , sequence_id(seq)
00075 , timestamp(ts)
00076 {}
00077
00082 bool isValid() const { return header == 0x54524947; }
00083 };
00084
00088 struct artdaq::detail::RequestHeader
00089 {
00091 uint32_t header;
00092 uint32_t packet_count;
00093 int rank;
00094 RequestMessageMode mode;
00095
00099 RequestHeader() : header(0x48454452)
00100 , packet_count(0)
00101 , rank(my_rank)
00102 , mode(RequestMessageMode::Normal)
00103 {}
00104
00109 bool isValid() const { return header == 0x48454452; }
00110 };
00111
00115 class artdaq::detail::RequestMessage
00116 {
00117 public:
00121 RequestMessage() : header_()
00122 , packets_()
00123 {}
00124
00125 std::vector<uint8_t> GetMessage()
00126 {
00127 auto size = sizeof(RequestHeader) + packets_.size() * sizeof(RequestPacket);
00128 header_.packet_count = packets_.size();
00129 assert(size < MAX_REQUEST_MESSAGE_SIZE);
00130 auto output = std::vector<uint8_t>(size);
00131 memcpy(&output[0], &header_, sizeof(RequestHeader));
00132 memcpy(&output[sizeof(RequestHeader)], &packets_[0], packets_.size() * sizeof(RequestPacket));
00133
00134 return output;
00135 }
00136
00141 void setMode(RequestMessageMode mode)
00142 {
00143 header_.mode = mode;
00144 }
00145
00150 size_t size() const { return packets_.size(); }
00151
00157 void addRequest(const Fragment::sequence_id_t& seq, const Fragment::timestamp_t& time)
00158 {
00159 packets_.emplace_back(RequestPacket(seq, time));
00160 }
00161
00162 private:
00163 RequestHeader header_;
00164 std::vector<RequestPacket> packets_;
00165 };
00166
00167 #endif // artdaq_DAQrate_detail_RequestMessage