LCOV - code coverage report
Current view: top level - timinglibs/src - TimingController.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 89 0
Test Date: 2026-10-11 15:05:20 Functions: 0.0 % 11 0

            Line data    Source code
       1              : /**
       2              :  * @file TimingController.cpp TimingController class
       3              :  * implementation
       4              :  *
       5              :  * This is part of the DUNE DAQ Software Suite, copyright 2020.
       6              :  * Licensing/copyright details are in the COPYING file that you should have
       7              :  * received with this code.
       8              :  */
       9              : 
      10              : #include "timinglibs/TimingController.hpp"
      11              : #include "timinglibs/TimingIssues.hpp"
      12              : #include "timinglibs/timingcmd/Nljs.hpp"
      13              : #include "timinglibs/timingcmd/Structs.hpp"
      14              : #include "timinglibs/timingcmd/msgp.hpp"
      15              : 
      16              : #include "appfwk/cmd/Nljs.hpp"
      17              : #include "confmodel/Connection.hpp"
      18              : #include "ers/Issue.hpp"
      19              : #include "iomanager/IOManager.hpp"
      20              : #include "logging/Logging.hpp"
      21              : 
      22              : #include <chrono>
      23              : #include <cstdlib>
      24              : #include <string>
      25              : #include <thread>
      26              : #include <vector>
      27              : 
      28              : namespace dunedaq {
      29              : 
      30            0 : DUNE_DAQ_SERIALIZABLE(timinglibs::timingcmd::TimingHwCmd, "TimingHwCmd");
      31            0 : DUNE_DAQ_SERIALIZABLE(nlohmann::json, "JSON");
      32              : 
      33              : namespace timinglibs {
      34              : 
      35            0 : TimingController::TimingController(const std::string& name, uint number_hw_commands)
      36              :   : dunedaq::appfwk::DAQModule(name)
      37            0 :   , m_hw_command_out_connection("timing_cmds")
      38            0 :   , m_hw_cmd_out_timeout(100)
      39            0 :   , m_hw_command_sender(nullptr)
      40            0 :   , m_timing_device("")
      41            0 :   , m_timing_session_name("")
      42            0 :   , m_device_info_receiver(nullptr)
      43            0 :   , m_number_hw_commands(number_hw_commands)
      44            0 :   , m_sent_hw_command_counters(m_number_hw_commands)
      45            0 :   , m_device_ready_timeout(10000)
      46            0 :   , m_device_ready(false)
      47            0 :   , m_device_infos_received_count(0)
      48            0 :   , m_hardware_state_recovery_enabled(false)
      49              : {
      50            0 :   for (auto it = m_sent_hw_command_counters.begin(); it != m_sent_hw_command_counters.end(); ++it) {
      51            0 :     it->atomic.store(0);
      52              :   }
      53              : 
      54            0 :   register_command("io_reset", &TimingController::do_io_reset);
      55            0 :   register_command("print_status", &TimingController::do_print_status);
      56            0 : }
      57              : 
      58              : void
      59            0 : TimingController::init(std::shared_ptr<appfwk::ConfigurationManager> mcfg)
      60              : {
      61            0 :   auto mod_config = mcfg->get_dal<dal::TimingController>(get_name());
      62            0 :   m_params = mod_config->get_configuration();
      63            0 : }
      64              : 
      65              : void
      66            0 : TimingController::do_configure(const CommandData_t& /*data*/)
      67              : {
      68            0 :   m_timing_device = m_params->get_device();
      69            0 :   m_hardware_state_recovery_enabled = m_params->get_hardware_state_recovery_enabled();
      70            0 :   m_timing_session_name = m_params->get_timing_session_name();
      71              : 
      72            0 :   if (m_timing_device.empty()) {
      73            0 :     throw UHALDeviceNameIssue(ERS_HERE, "Device name should not be empty");
      74              :   }
      75              : 
      76            0 :   if (!m_hw_command_out_connection.empty()) {
      77            0 :     if (m_timing_session_name.empty()) {
      78            0 :       m_hw_command_sender =
      79            0 :         iomanager::IOManager::get()->get_sender<timingcmd::TimingHwCmd>(m_hw_command_out_connection);
      80              :     } else {
      81            0 :       m_hw_command_sender = iomanager::IOManager::get()->get_sender<timingcmd::TimingHwCmd>(iomanager::ConnectionId{
      82            0 :         m_hw_command_out_connection, datatype_to_string<timingcmd::TimingHwCmd>(), m_timing_session_name });
      83              :     }
      84              : 
      85            0 :     if (m_timing_session_name.empty()) {
      86            0 :       m_device_info_receiver = iomanager::IOManager::get()->get_receiver<nlohmann::json>(m_timing_device + "_info");
      87              :     } else {
      88            0 :       m_device_info_receiver = iomanager::IOManager::get()->get_receiver<nlohmann::json>(iomanager::ConnectionId{
      89            0 :         m_timing_device + "_info", datatype_to_string<nlohmann::json>(), m_timing_session_name });
      90              :     }
      91            0 :     m_device_info_receiver->add_callback(
      92            0 :       std::bind(&TimingController::process_device_info, this, std::placeholders::_1));
      93              :   }
      94            0 : }
      95              : 
      96              : void
      97            0 : TimingController::do_scrap(const CommandData_t&)
      98              : {
      99            0 :   if (m_device_info_receiver) {
     100            0 :     m_device_info_receiver->remove_callback();
     101              :   }
     102            0 :   m_device_infos_received_count = 0;
     103            0 :   m_device_ready = false;
     104              : 
     105            0 :   for (auto it = m_sent_hw_command_counters.begin(); it != m_sent_hw_command_counters.end(); ++it) {
     106            0 :     it->atomic.store(0);
     107              :   }
     108            0 : }
     109              : 
     110              : void
     111            0 : TimingController::send_hw_cmd(timingcmd::TimingHwCmd&& hw_cmd)
     112              : {
     113            0 :   if (!m_hw_command_sender) {
     114            0 :     throw QueueIsNullFatalError(ERS_HERE, get_name(), m_hw_command_out_connection);
     115              :   }
     116            0 :   try {
     117            0 :     m_hw_command_sender->send(std::move(hw_cmd), m_hw_cmd_out_timeout);
     118            0 :   } catch (const dunedaq::iomanager::TimeoutExpired& excpt) {
     119            0 :     std::ostringstream oss_warn;
     120            0 :     oss_warn << "push to output queue \"" << m_hw_command_out_connection << "\"";
     121            0 :     ers::warning(dunedaq::iomanager::TimeoutExpired(
     122            0 :       ERS_HERE,
     123            0 :       get_name(),
     124            0 :       oss_warn.str(),
     125            0 :       std::chrono::duration_cast<std::chrono::milliseconds>(m_hw_cmd_out_timeout).count()));
     126            0 :   }
     127            0 : }
     128              : 
     129              : timingcmd::TimingHwCmd
     130            0 : TimingController::construct_hw_cmd(const std::string& cmd_id)
     131              : {
     132            0 :   timingcmd::TimingHwCmd hw_cmd;
     133            0 :   hw_cmd.id = cmd_id;
     134            0 :   hw_cmd.device = m_timing_device;
     135            0 :   return hw_cmd;
     136            0 : }
     137              : 
     138              : timingcmd::TimingHwCmd
     139            0 : TimingController::construct_hw_cmd(const std::string& cmd_id, const nlohmann::json& payload)
     140              : {
     141            0 :   auto hw_cmd = construct_hw_cmd(cmd_id);
     142            0 :   hw_cmd.payload = payload;
     143            0 :   return hw_cmd;
     144            0 : }
     145              : 
     146              : void
     147            0 : TimingController::do_io_reset(const CommandData_t& data)
     148              : {
     149            0 :   timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd("io_reset", data);
     150              : 
     151            0 :   hw_cmd.payload["clock_source"] = m_params->get_clock_source();
     152            0 :   hw_cmd.payload["soft"] = m_params->get_soft();
     153              : 
     154            0 :   send_hw_cmd(std::move(hw_cmd));
     155            0 :   ++(m_sent_hw_command_counters.at(0).atomic);
     156            0 : }
     157              : 
     158              : void
     159            0 : TimingController::do_print_status(const CommandData_t&)
     160              : {
     161            0 :   timingcmd::TimingHwCmd hw_cmd = construct_hw_cmd("print_status");
     162            0 :   send_hw_cmd(std::move(hw_cmd));
     163            0 :   ++(m_sent_hw_command_counters.at(1).atomic);
     164            0 : }
     165              : 
     166              : } // namespace timinglibs
     167              : } // namespace dunedaq
     168              : 
     169              : // Local Variables:
     170              : // c-basic-offset: 2
     171              : // End:
        

Generated by: LCOV version 2.0-1