// Copyright (2019-2022) Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-or-later #include #include "ProcessJFPacket.h" #include "jf_packet.h" #include "../common/JFJochException.h" ProcessJFPacket::ProcessJFPacket(ThreadSafeFIFO &in_c, ThreadSafeFIFO &in_wr, uint32_t nmodules) : m(2 * nmodules), c_fifo(in_c), wr_fifo(in_wr), module_info(2 * nmodules) { for (auto &i: module_info) i.c.frame_number = UINT64_MAX; } ProcessJFPacket::~ProcessJFPacket() { for (auto &i: module_info) { if (i.c.frame_number != UINT64_MAX) c_fifo.Put(i.c); } } void ProcessJFPacket::ProcessPacket(jf_udp_payload *datagram, uint32_t src_ip) { if (datagram->framenum == 0) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Frame number cannot be zero"); uint64_t frame_number = datagram->framenum - 1; uint32_t ipv4_src_addr_host = src_ip >> 24; uint32_t module_number = (ipv4_src_addr_host % 32) / 2; bool second_half_module = (ipv4_src_addr_host % 2 == 1); uint32_t packetnum = datagram->packetnum | (second_half_module ? 64 : 0); uint64_t module_info_location = (module_number * 2) | (frame_number % 2); if (module_info_location > module_info.size()) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Module number out of bounds"); { std::unique_lock ul(m[module_info_location]); if (module_info[module_info_location].c.frame_number != frame_number) { if (module_info[module_info_location].c.frame_number != UINT64_MAX) c_fifo.Put(module_info[module_info_location].c); auto wr = wr_fifo.GetBlocking(); module_info[module_info_location].c.type = Completion::Type::Image; module_info[module_info_location].c.frame_number = frame_number; module_info[module_info_location].c.timestamp = datagram->timestamp; module_info[module_info_location].c.bunchid = datagram->bunchid; module_info[module_info_location].c.debug = datagram->debug; module_info[module_info_location].c.packet_mask[0] = 0; module_info[module_info_location].c.packet_mask[1] = 0; module_info[module_info_location].c.packet_count = 0; module_info[module_info_location].c.module = module_number; module_info[module_info_location].c.handle = wr.handle; module_info[module_info_location].ptr = wr.ptr; } module_info[module_info_location].c.packet_count++; module_info[module_info_location].c.packet_mask[packetnum >= 64 ? 1 : 0] |= (1LU << (packetnum % 64)); memcpy(module_info[module_info_location].ptr + 4096 * packetnum, datagram->data, 4096 * sizeof(uint16_t)); } packet_counter++; } uint64_t ProcessJFPacket::GetCounter() { return packet_counter; }