17 namespace itk::fragment {
22 FelixPacket make_packet(uint64_t fid, std::span<const uint64_t> data, uint8_t
status) {
27 pkt.data =
reinterpret_cast<const uint8_t*
>(data.data());
28 pkt.size = data.size()*8;
42 std::vector<uint32_t> data;
43 std::vector<uint32_t>
status;
45 inline uint32_t get_data_size() {
return data.size(); }
47 inline uint32_t get_status_size() {
return status.size(); }
63 std::vector<FelixPacket> packets;
64 std::vector<uint32_t>
status;
66 uint64_t start_time = 0;
67 uint32_t source_id = 0;
69 inline uint32_t get_data_size() {
71 for (
auto& packet : packets)
size += get_packet_size(packet);
75 inline uint32_t get_status_size() {
return status.size(); }
78 inline void write(T& out) {
79 log.
debug(
"PacketPayload.data");
81 log.
debug(
"PacketPayload.status");
94 header.
elink_id = (packet.fid >> 16);
96 auto felix_source = packet.fid >> 36;
103 auto data32 =
reinterpret_cast<const uint32_t*
>(packet.
data);
104 auto packet_size = packet.size;
106 while (packet_size) {
108 if (packet_size < FLX::MAX_DATA32_SIZE*4) {
109 size32 = (packet_size + 3)/4;
114 size32 = FLX::MAX_DATA32_SIZE;
116 packet_size -= FLX::MAX_DATA32_SIZE*4;
120 out.write_rec(header);
121 out.write(data32, size32);
126 inline uint32_t get_packet_size(
FelixPacket& packet) {
127 return sizeof(
FLX::Header)/4 + (packet.size + 3)/4;
131 void write_packets(T& out) {
132 for (
auto& packet : packets) write(out, packet);
142 template<
typename Payload>
149 inline uint32_t get_size() {
150 return ROD::HEADER_SIZE + ROD::TRAILER_SIZE +
151 payload.get_data_size() + payload.get_status_size();
157 log.
debug(
"ROD.Header");
158 out.write_rec(header);
160 log.
debug(
"ROD.Payload");
163 trailer.
data_size = payload.get_data_size();
164 trailer.status_size = payload.get_status_size();
167 log.
debug(
"ROD.Trailer");
168 out.write_rec(trailer);
181 template<
int n,
typename RODFragment>
188 uint32_t get_size() {
189 uint32_t frag_size = header.
HEADER_SIZE + rod.get_size();
196 auto start_pos = out.get_size();
199 uint32_t subdet_id = 0x16;
200 uint32_t module_id = 0x0001;
201 header.
source_id = subdet_id << 16 | module_id;
206 log.
debug(
"ROB.Header");
207 out.write_rec(header);
213 log.
debug(
"ROB.CheckSum: 0x{:08x}", checksum);
216 auto end_pos = out.get_size();
219 log.
error(
"start: {}, end: {}, frag_size: {}", start_pos, end_pos,
int(header.
fragment_size));
223 uint32_t checksum_CRC16() {
227 uint32_t checksum_Adler32() {
231 uint32_t calc_checksum(uint32_t type) {
247 inline size_t get_size() {
251 inline void write(uint32_t data) {
252 log.
trace(
"{:3}: write: 0x{:08x}", frag.size(), data);
253 frag.push_back(data);
256 inline void write(
const uint32_t* data,
size_t size) {
257 for (uint32_t i = 0; i <
size; i++) write(data[i]);
260 inline void write(
const void* ptr,
size_t size) {
261 auto buff =
reinterpret_cast<const uint32_t*
>(ptr);
265 inline void write(
const std::span<const uint32_t> buff) {
266 write(buff.data(), buff.size());
270 inline void write_rec(
const T& rec) {
271 assert(
sizeof(rec) % 4 == 0);
272 auto ptr =
reinterpret_cast<const uint32_t*
>(&rec);
273 write(ptr,
sizeof(rec)/4);
276 std::vector<uint32_t> frag;
283 template<
typename DataCallback>
286 DataCallback& cb_data;
288 FragReader(DataCallback& cb_data) : cb_data(cb_data) {}
290 inline uint32_t read() {
297 inline std::array<uint32_t, n> read() {
302 void read_rob(T& buff) {
304 if (buff.size() < ROB::BASE_HEADER_SIZE) {
307 if (buff[0] != ROB::HEADER_MARKER) {
311 assert(buff.size() > ROB::BASE_HEADER_SIZE);
312 assert(buff[0] == ROB::HEADER_MARKER);
318 auto generic_size = ROD::HEADER_SIZE + header.
status_size + 1;
323 assert(header.
fragment_size <= buff.size() &&
"Truncated fragment");
325 assert(generic_size <= header.
header_size &&
"Incorrect header sizes");
330 auto specific_size = header.
header_size - generic_size;
332 std::span<const uint32_t> specific {
333 buff.data() + generic_size,
337 std::span<const uint32_t> payload {
346 void read_rod(T& buff) {
348 if (buff.size() < ROD::HEADER_SIZE) {
351 if (buff[0] != ROD::HEADER_MARKER) {
355 assert(buff.size() >= ROD::HEADER_SIZE);
356 assert(buff[0] == ROD::HEADER_MARKER);
358 auto& header = *
reinterpret_cast<const ROD::Header*
>(buff.data());
361 (buff.data() + buff.size() - ROD::TRAILER_SIZE));
363 std::span<const uint32_t> data {
364 buff.data() + ROD::HEADER_SIZE + (trailer.status_pos & 0x1 ? 0 : trailer.status_size),
368 std::span<const uint32_t>
status {
369 buff.data() + ROD::HEADER_SIZE + (trailer.status_pos & 0x1 ? trailer.data_size : 0),
377 void read_packets(T& buff) {
382 auto buff_data = buff.data();
383 int buff_size = buff.size();
385 while (buff_size > 0) {
386 assert(buff_size >= FLX::HEADER_SIZE);
388 uint64_t rob_fid = 0x1000000000000000L;
399 auto data =
reinterpret_cast<const uint8_t*
>(buff_data + FLX::HEADER_SIZE);
402 uint64_t fid = rob_fid | (uint64_t(header.
elink_id) << 16);
412 std::vector<uint32_t> frag;
Definition: fragformat.hpp:284
Definition: fragformat.hpp:243
Definition: fragformat.hpp:182
Definition: fragformat.hpp:143
Definition: fragformat.hpp:61
Logger class definition, wrapper around CoreLogger, adds templated methods for different logging leve...
Definition: logger.hpp:108
void error(fmt::format_string< Args... > fmt, Args &&...args)
Logs a message with error level.
Definition: logger.hpp:164
void debug(fmt::format_string< Args... > fmt, Args &&...args)
Logs a message with debug level.
Definition: logger.hpp:140
void trace(fmt::format_string< Args... > fmt, Args &&...args)
Logs a message with trace level.
Definition: logger.hpp:132
Felix Packet structure.
Definition: fragheader.hpp:26
uint64_t time
FELIX ID.
Definition: fragheader.hpp:28
const uint8_t * data
timestamp in BC
Definition: fragheader.hpp:29
Definition: fragformat.hpp:41
Definition: fragheader.hpp:172
uint32_t data_size
number of status elements
Definition: fragheader.hpp:174
uint32_t status_pos
number of data elements
Definition: fragheader.hpp:175