LCOV - code coverage report
Current view: top level - hermesmodules/plugins - HermesModule.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 99 0
Test Date: 2025-12-21 13:07:08 Functions: 0.0 % 9 0

            Line data    Source code
       1              : /**
       2              :  * @file HermesModule.cpp
       3              :  *
       4              :  * Implementations of HermesModule's functions
       5              :  *
       6              :  * This is part of the DUNE DAQ Software Suite, copyright 2020.
       7              :  * Licensing/copyright details are in the COPYING file that you should have
       8              :  * received with this code.
       9              :  */
      10              : 
      11              : #include "appmodel/appmodelIssues.hpp"
      12              : #include "appmodel/HermesModule.hpp"
      13              : #include "appmodel/HermesDataSender.hpp"
      14              : #include "appmodel/IpbusAddressTable.hpp"
      15              : #include "confmodel/NetworkDevice.hpp"
      16              : #include "confmodel/DetectorStream.hpp"
      17              : #include "confmodel/GeoId.hpp"
      18              : #include "confmodel/Session.hpp"
      19              : 
      20              : #include "HermesModule.hpp"
      21              : #include "hermesmodules/opmon/hermescontroller.pb.h"
      22              : 
      23              : #include <string>
      24              : #include <netinet/ether.h>
      25              : #include <arpa/inet.h>
      26              : #include <fmt/core.h>
      27              : #include "logging/Logging.hpp"
      28              : 
      29              : 
      30              : 
      31              : namespace dunedaq::hermesmodules {
      32              : 
      33              : //-----------------------------------------------------------------------------
      34            0 : uint64_t ether_atou64( const std::string& addr_str ) {
      35            0 :     union {
      36              :         uint64_t          result;
      37              :         struct ether_addr address;
      38              :     };
      39            0 :     result = 0;
      40            0 :     struct ether_addr* ptr = ether_aton_r( addr_str.c_str(), &address );
      41            0 :     if( !ptr ) {
      42              :         return (~0);
      43              :     }
      44              :     // Big to little endian
      45            0 :     return (__builtin_bswap64(result) >> 16);
      46              : }
      47              : 
      48              : //-----------------------------------------------------------------------------
      49            0 : uint32_t ip_atou32(const std::string& addr_str) {
      50              :   // Big to little endian
      51            0 :   return __builtin_bswap32(inet_addr(addr_str.c_str()));
      52              : }
      53              : 
      54              : //-----------------------------------------------------------------------------
      55            0 : HermesModule::HermesModule(const std::string& name)
      56            0 :   : dunedaq::appfwk::DAQModule(name)
      57              : {
      58            0 :   register_command("conf", &HermesModule::do_conf);
      59            0 :   register_command("start", &HermesModule::do_start);
      60            0 :   register_command("stop", &HermesModule::do_stop);
      61            0 : }
      62              : 
      63              : //-----------------------------------------------------------------------------
      64              : void
      65            0 : HermesModule::init(std::shared_ptr<appfwk::ConfigurationManager> mcfg)
      66              : {
      67            0 :   uhal::setLogLevelTo(uhal::Error());
      68              : 
      69              :   // Save our DAL for later use by do_conf
      70            0 :   m_dal = mcfg->get_dal<appmodel::HermesModule>(get_name());
      71            0 :   m_session = mcfg->get_session();
      72            0 : }
      73              : 
      74              : //-----------------------------------------------------------------------------
      75              : void
      76            0 : HermesModule::generate_opmon_data() 
      77              : {
      78            0 :   opmon::ControllerInfo ginfo;
      79            0 :   ginfo.set_total_amount( m_total_amount );
      80            0 :   ginfo.set_amount_since_last_get_info_call( m_amount_since_last_get_info_call.exchange(0) );
      81            0 :   publish( std::move(ginfo) );
      82              : 
      83            0 :   if ( ! m_core_controller ) return ;
      84              :   
      85            0 :   const auto& core_info = m_core_controller->get_info();
      86              : 
      87            0 :   for ( uint16_t i(0); i<core_info.n_mgt; ++i){
      88              : 
      89            0 :     try {
      90            0 :       auto geo_info = m_core_controller->read_link_geo_info(i);
      91            0 :       publish( m_core_controller->read_link_stats(i),
      92            0 :                { {"detector",std::to_string(geo_info.detid)},
      93            0 :                  {"crate",   std::to_string(geo_info.crateid)},
      94            0 :                  {"slot",    std::to_string(geo_info.slotid)},
      95            0 :                  {"link",    std::to_string(i)} } );
      96            0 :     } catch ( const uhal::exception::exception& e ) {
      97            0 :       ers::warning(FailedToRetrieveStats(ERS_HERE, i, e));  
      98            0 :     }
      99              :       
     100              :   } // loop over links
     101              :   
     102            0 : }
     103              : 
     104              : //-----------------------------------------------------------------------------
     105              : void
     106            0 : HermesModule::do_conf(const CommandData_t& /*conf_as_json*/)
     107              : { 
     108              :   // Create the ipbus 
     109            0 :   auto hw = uhal::ConnectionManager::getDevice(m_dal->UID(),
     110            0 :                                                m_dal->get_uri(),
     111            0 :                                                m_dal->get_address_table()->get_uri());    
     112            0 :   hw.setTimeoutPeriod(m_dal->get_timeout_ms());
     113              : 
     114            0 :   m_core_controller = std::make_unique<HermesCoreController>(hw);
     115              : 
     116            0 :   const auto& core_info = m_core_controller->get_info();
     117            0 :   fmt::print("Hermes\n");
     118            0 :   fmt::print("n_mgt {}\n", core_info.n_mgt);
     119            0 :   fmt::print("n_src {}\n", core_info.n_src);
     120            0 :   fmt::print("ref_freq {}\n", core_info.ref_freq);
     121            0 :   std::cout << std::flush;
     122              : 
     123            0 :   auto links = m_dal->get_links();
     124              :   // Size check on link conf
     125            0 :   if ( links.size() != core_info.n_mgt ) {
     126            0 :     throw FirmwareConfigLinkMismatch(ERS_HERE, links.size(), core_info.n_mgt);
     127              :   }
     128              : 
     129              :   // Sequence id check
     130            0 :   std::set<uint32_t> ids;
     131            0 :   for( const auto l : links) {
     132            0 :     ids.insert(l->get_link_id());
     133              :   }
     134              : 
     135              :   // Look duplicate link ids
     136            0 :   if ( ids.size() != links.size() ) {
     137            0 :     throw DuplicatedLinkIDs(ERS_HERE, links.size(), ids.size());
     138              :   }
     139              : 
     140              :   // Make sure that the last link id is n_mgt-1
     141            0 :   if ( *ids.rbegin() != (core_info.n_mgt-1)) {
     142            0 :     throw LinkIDConfigurationError(ERS_HERE, *ids.rend(), core_info.n_mgt-1);
     143              :   }
     144              :   
     145              :   // Check ip address consistency
     146              :   // Redundant check, schema enforces 1:1
     147            0 :   if (m_dal->get_destination()->get_ip_address().size() != 1) {
     148            0 :       throw MultipleIPAddressConfigurationError(ERS_HERE, m_dal->get_destination()->UID(), m_dal->get_destination()->get_ip_address().size());
     149              :   }
     150              : 
     151              :   // Redundant check, schema enforces 1:1
     152            0 :   for( const auto& l : links) {
     153            0 :     if (l->get_uses()->get_ip_address().size() != 1) {
     154            0 :       throw MultipleIPAddressConfigurationError(ERS_HERE, l->get_uses()->UID(), l->get_uses()->get_ip_address().size());
     155              :     }
     156              :   }
     157              :   // All good
     158            0 :   for ( uint16_t i(0); i<core_info.n_mgt; ++i){
     159              :     // Put the endpoint in a safe state
     160            0 :     m_core_controller->enable(i, false);
     161              :   }
     162              : 
     163            0 :   m_core_controller->reset();
     164              : 
     165              : 
     166              :   // FIXME: What the hell is this again?
     167            0 :   uint32_t filter_control = 0x07400307;
     168            0 :   for( const auto& l : links) {
     169            0 :     if (l->is_disabled(*m_session)) {
     170            0 :       continue;  
     171              :     }
     172              : 
     173            0 :     m_enabled_link_ids.push_back(l->get_link_id());
     174              : 
     175            0 :     m_core_controller->config_udp(
     176            0 :       l->get_link_id(),
     177            0 :       ether_atou64(l->get_uses()->get_mac_address()),
     178            0 :       ip_atou32(l->get_uses()->get_ip_address().at(0)),
     179            0 :       l->get_port(),
     180            0 :       ether_atou64(m_dal->get_destination()->get_mac_address()),
     181            0 :       ip_atou32(m_dal->get_destination()->get_ip_address().at(0)),
     182            0 :       l->get_port(),
     183              :       filter_control
     184              :     );
     185              : 
     186              :     // Get the first DetectorStream
     187              :     // and use it for the geo id information.
     188            0 :     const confmodel::DetectorStream* source = l->get_streams()[0];
     189            0 :     m_core_controller->config_mux(
     190            0 :       l->get_link_id(),
     191            0 :       source->get_geo_id()->get_detector_id(),
     192            0 :       source->get_geo_id()->get_crate_id(),
     193            0 :       source->get_geo_id()->get_slot_id()
     194              :     );
     195              : 
     196              :   }
     197            0 : }
     198              : 
     199              : void
     200            0 : HermesModule::do_start(const CommandData_t& /*d*/)
     201              : {
     202              : 
     203            0 :   for( auto id : m_enabled_link_ids) {
     204              :     // Put the endpoint in a safe state
     205            0 :     m_core_controller->enable(id, true);
     206              :   }
     207              : 
     208              : 
     209            0 :   for( auto id : m_enabled_link_ids) {
     210              :     // Put the endpoint in a safe state
     211            0 :     m_core_controller->is_link_in_error(id, true);
     212              :   }
     213              : 
     214              : 
     215              :   // for ( uint16_t i(0); i<core_info.n_mgt; ++i){
     216              :   //   // Put the endpoint in a safe state
     217              :   //   m_core_controller->enable(i, true);
     218              :   // }
     219              : 
     220              :   // for ( uint16_t i(0); i<core_info.n_mgt; ++i){
     221              :   //   // Put the endpoint in a safe state
     222              :   //   m_core_controller->is_link_in_error(i);
     223              :   // }
     224              : 
     225            0 : }
     226              : 
     227              : void
     228            0 : HermesModule::do_stop(const CommandData_t& /*d*/)
     229              : {
     230              : 
     231            0 :   for( auto id : m_enabled_link_ids) {
     232              :     // Put the endpoint in a safe state
     233            0 :     m_core_controller->enable(id, false);
     234              :   }
     235            0 : }
     236              : 
     237              : } // namespace dunedaq::hermesmodules
     238              : 
     239            0 : DEFINE_DUNE_DAQ_MODULE(dunedaq::hermesmodules::HermesModule)
        

Generated by: LCOV version 2.0-1