LCOV - code coverage report
Current view: top level - artdaq/DAQdata - PortManager.cc (source / functions) Coverage Total Hit
Test: artdaq.info.cleaned Lines: 6.0 % 218 13
Test Date: 2025-09-04 00:45:34 Functions: 6.8 % 44 3

            Line data    Source code
       1              : #include "artdaq/DAQdata/PortManager.hh"
       2              : #include "TRACE/tracemf.h"
       3              : #define TRACE_NAME "PortManager"
       4              : 
       5              : #include "artdaq/DAQdata/Globals.hh"
       6              : #include "artdaq/DAQdata/TCPConnect.hh"
       7              : 
       8              : #include "fhiclcpp/ParameterSet.h"
       9              : 
      10              : #include <cstdlib>
      11              : #include <sstream>
      12              : #include <string>
      13              : 
      14           17 : artdaq::PortManager::PortManager()
      15           17 :     : multicast_interface_address_()
      16           17 :     , request_message_group_pattern_("227.128.PPP.SSS")
      17           34 :     , routing_table_group_pattern_("227.129.PPP.SSS")
      18           51 :     , multicast_transfer_group_pattern_("227.130.14.PPP")
      19              : {
      20           17 : }
      21              : 
      22            0 : void artdaq::PortManager::UpdateConfiguration(fhicl::ParameterSet const& ps)
      23              : {
      24            0 :         if (ps.has_key("artdaq_base_port"))
      25              :         {
      26            0 :                 auto newVal = ps.get<int>("artdaq_base_port");
      27            0 :                 if (base_port_ != DEFAULT_BASE && base_port_ != newVal)
      28              :                 {
      29            0 :                         TLOG(TLVL_WARNING) << "Base port has changed! This may lead to misconfiguration and non-functional systems!";
      30              :                 }
      31            0 :                 base_port_ = newVal;
      32              :         }
      33            0 :         if (ps.has_key("ports_per_partition"))
      34              :         {
      35            0 :                 auto newVal = ps.get<int>("ports_per_partition");
      36            0 :                 if (ports_per_partition_ != DEFAULT_PORTS_PER_PARTITION && ports_per_partition_ != newVal)
      37              :                 {
      38            0 :                         TLOG(TLVL_WARNING) << "Ports per Partition has changed! This may lead to misconfiguration and non-functional systems!";
      39              :                 }
      40            0 :                 ports_per_partition_ = newVal;
      41              :         }
      42              : 
      43            0 :         auto bp = getenv("ARTDAQ_BASE_PORT");  // Environment overrides configuration
      44            0 :         if (bp != nullptr)
      45              :         {
      46              :                 try
      47              :                 {
      48            0 :                         auto bp_s = std::string(bp);
      49            0 :                         auto bp_tmp = std::stoi(bp_s, nullptr, 0);
      50            0 :                         if (bp_tmp < 1024 || bp_tmp > 32000)
      51              :                         {
      52            0 :                                 TLOG(TLVL_ERROR) << "Base port specified in ARTDAQ_BASE_PORT is invalid! Ignoring...";
      53            0 :                         }
      54              :                         else
      55              :                         {
      56            0 :                                 base_port_ = bp_tmp;
      57              :                         }
      58            0 :                 }
      59            0 :                 catch (const std::invalid_argument&)
      60            0 :                 {}
      61            0 :                 catch (const std::out_of_range&)
      62            0 :                 {}
      63              :         }
      64              : 
      65            0 :         auto ppp = getenv("ARTDAQ_PORTS_PER_PARTITION");  // Environment overrides configuration
      66            0 :         if (ppp != nullptr)
      67              :         {
      68              :                 try
      69              :                 {
      70            0 :                         auto ppp_s = std::string(ppp);
      71            0 :                         auto ppp_tmp = std::stoi(ppp_s, nullptr, 0);
      72            0 :                         if (ppp_tmp < 0 || ppp_tmp > 32000)
      73              :                         {
      74            0 :                                 TLOG(TLVL_ERROR) << "Ports per partition specified in ARTDAQ_PORTS_PER_PARTITION is invalid! Ignoring...";
      75            0 :                         }
      76              :                         else
      77              :                         {
      78            0 :                                 ports_per_partition_ = ppp_tmp;
      79              :                         }
      80            0 :                 }
      81            0 :                 catch (const std::invalid_argument&)
      82            0 :                 {}
      83            0 :                 catch (const std::out_of_range&)
      84            0 :                 {}
      85              :         }
      86              : 
      87            0 :         if (!base_configured_ && (base_port_ != DEFAULT_BASE || ports_per_partition_ != DEFAULT_PORTS_PER_PARTITION))
      88              :         {
      89            0 :                 base_configured_ = true;
      90            0 :                 auto max_partitions = (65535 - base_port_) / ports_per_partition_;
      91            0 :                 TLOG(TLVL_INFO) << "Based on configuration, there can be " << max_partitions << " partitions of " << ports_per_partition_ << " ports each, starting at port " << base_port_;
      92            0 :                 if (Globals::GetPartitionNumber() > max_partitions)
      93              :                 {
      94            0 :                         TLOG(TLVL_ERROR) << "Currently-configured partition number is greater than the allowed number! The system WILL NOT WORK!";
      95            0 :                         exit(22);
      96              :                 }
      97              :         }
      98              : 
      99              :         in_addr tmp_addr;
     100            0 :         bool multicast_configured = false;
     101            0 :         if (ps.has_key("multicast_output_interface"))
     102              :         {
     103            0 :                 multicast_configured = GetIPOfInterface(ps.get<std::string>("multicast_output_interface"), tmp_addr) == 0;
     104              :         }
     105            0 :         else if (ps.has_key("multicast_output_network"))
     106              :         {
     107            0 :                 multicast_configured = GetInterfaceForNetwork(ps.get<std::string>("multicast_output_network").c_str(), tmp_addr) == 0;
     108              :         }
     109            0 :         if (multicast_configured && multicasts_configured_ && tmp_addr.s_addr != multicast_interface_address_.s_addr)
     110              :         {
     111            0 :                 TLOG(TLVL_WARNING) << "Multicast output address has changed! This may lead to misconfiguration and non-functional systems!";
     112            0 :         }
     113            0 :         else if (multicast_configured)
     114              :         {
     115            0 :                 multicasts_configured_ = true;
     116            0 :                 multicast_interface_address_ = tmp_addr;
     117              :         }
     118              : 
     119            0 :         if (ps.has_key("multicast_group_offset"))
     120              :         {
     121            0 :                 auto newVal = ps.get<int>("multicast_group_offset");
     122            0 :                 if (multicast_group_offset_ != DEFAULT_MULTICAST_GROUP_OFFSET && multicast_group_offset_ != newVal)
     123              :                 {
     124            0 :                         TLOG(TLVL_WARNING) << "Multicast group offset (added to last part of group IP address) has changed! This may lead to misconfiguration and non-functional systems!";
     125              :                 }
     126            0 :                 multicast_group_offset_ = newVal;
     127              :         }
     128              : 
     129            0 :         if (ps.has_key("routing_token_port_offset"))
     130              :         {
     131            0 :                 auto newVal = ps.get<int>("routing_token_port_offset");
     132            0 :                 if (routing_tokens_configured_ && newVal != routing_token_offset_)
     133              :                 {
     134            0 :                         TLOG(TLVL_WARNING) << "Routing Token Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
     135              :                 }
     136              : 
     137            0 :                 routing_tokens_configured_ = true;
     138            0 :                 routing_token_offset_ = newVal;
     139              :         }
     140              : 
     141            0 :         if (ps.has_key("routing_table_ack_port_offset"))
     142              :         {
     143            0 :                 auto newVal = ps.get<int>("routing_table_ack_port_offset");
     144            0 :                 if (routing_acks_configured_ && newVal != routing_ack_offset_)
     145              :                 {
     146            0 :                         TLOG(TLVL_WARNING) << "Routing Table Acknowledgement Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
     147              :                 }
     148              : 
     149            0 :                 routing_acks_configured_ = true;
     150            0 :                 routing_ack_offset_ = newVal;
     151              :         }
     152              : 
     153            0 :         if (ps.has_key("xmlrpc_port_offset"))
     154              :         {
     155            0 :                 auto newVal = ps.get<int>("xmlrpc_port_offset");
     156            0 :                 if (xmlrpc_configured_ && newVal != xmlrpc_offset_)
     157              :                 {
     158            0 :                         TLOG(TLVL_WARNING) << "XMLRPC Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
     159              :                 }
     160              : 
     161            0 :                 xmlrpc_configured_ = true;
     162            0 :                 xmlrpc_offset_ = newVal;
     163              :         }
     164              : 
     165            0 :         if (ps.has_key("tcp_socket_port_offset"))
     166              :         {
     167            0 :                 auto newVal = ps.get<int>("tcp_socket_port_offset");
     168            0 :                 if (tcpsocket_configured_ && newVal != tcp_socket_offset_)
     169              :                 {
     170            0 :                         TLOG(TLVL_WARNING) << "TCPSocketTransfer Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
     171              :                 }
     172              : 
     173            0 :                 tcpsocket_configured_ = true;
     174            0 :                 tcp_socket_offset_ = newVal;
     175              :         }
     176              : 
     177            0 :         if (ps.has_key("request_port"))
     178              :         {
     179            0 :                 auto newVal = ps.get<int>("request_port");
     180            0 :                 if (request_port_configured_ && newVal != request_message_port_)
     181              :                 {
     182            0 :                         TLOG(TLVL_WARNING) << "Request Message Port has changed! This may lead to misconfiguration and non-functional systems!";
     183              :                 }
     184              : 
     185            0 :                 request_port_configured_ = true;
     186            0 :                 request_message_port_ = newVal;
     187              :         }
     188              : 
     189            0 :         if (ps.has_key("request_pattern"))
     190              :         {
     191            0 :                 auto newVal = ps.get<std::string>("request_pattern");
     192            0 :                 if (request_pattern_configured_ && newVal != request_message_group_pattern_)
     193              :                 {
     194            0 :                         TLOG(TLVL_WARNING) << "Request Message Multicast Group Pattern has changed! This may lead to misconfiguration and non-functional systems!";
     195              :                 }
     196              : 
     197            0 :                 request_pattern_configured_ = true;
     198            0 :                 request_message_group_pattern_ = newVal;
     199            0 :         }
     200              : 
     201            0 :         if (ps.has_key("routing_table_port"))
     202              :         {
     203            0 :                 auto newVal = ps.get<int>("routing_table_port");
     204            0 :                 if (routing_table_port_configured_ && newVal != routing_table_port_)
     205              :                 {
     206            0 :                         TLOG(TLVL_WARNING) << "Routing Table Port has changed! This may lead to misconfiguration and non-functional systems!";
     207              :                 }
     208              : 
     209            0 :                 routing_table_port_configured_ = true;
     210            0 :                 routing_table_port_ = newVal;
     211              :         }
     212              : 
     213            0 :         if (ps.has_key("routing_table_pattern"))
     214              :         {
     215            0 :                 auto newVal = ps.get<std::string>("routing_table_pattern");
     216            0 :                 if (routing_table_pattern_configured_ && newVal != routing_table_group_pattern_)
     217              :                 {
     218            0 :                         TLOG(TLVL_WARNING) << "Routing Table Multicast Group Pattern has changed! This may lead to misconfiguration and non-functional systems!";
     219              :                 }
     220              : 
     221            0 :                 routing_table_pattern_configured_ = true;
     222            0 :                 routing_table_group_pattern_ = newVal;
     223            0 :         }
     224              : 
     225            0 :         if (ps.has_key("multicast_transfer_port_offset"))
     226              :         {
     227            0 :                 auto newVal = ps.get<int>("multicast_transfer_port_offset");
     228            0 :                 if (multicast_transfer_port_configued_ && newVal != multicast_transfer_offset_)
     229              :                 {
     230            0 :                         TLOG(TLVL_WARNING) << "Multicast Transfer Port Offset has changed! This may lead to misconfiguration and non-functional systems!";
     231              :                 }
     232              : 
     233            0 :                 multicast_transfer_port_configued_ = true;
     234            0 :                 multicast_transfer_offset_ = newVal;
     235              :         }
     236              : 
     237            0 :         if (ps.has_key("multicast_transfer_pattern"))
     238              :         {
     239            0 :                 auto newVal = ps.get<std::string>("multicast_transfer_pattern");
     240            0 :                 if (multicast_transfer_pattern_configured_ && newVal != multicast_transfer_group_pattern_)
     241              :                 {
     242            0 :                         TLOG(TLVL_WARNING) << "Multicast Transfer Multicast Group Pattern has changed! This may lead to misconfiguration and non-functional systems!";
     243              :                 }
     244              : 
     245            0 :                 multicast_transfer_pattern_configured_ = true;
     246            0 :                 multicast_transfer_group_pattern_ = newVal;
     247            0 :         }
     248            0 : }
     249              : 
     250            0 : int artdaq::PortManager::GetRoutingTokenPort(int subsystemID)
     251              : {
     252            0 :         if (!routing_tokens_configured_)
     253              :         {
     254            0 :                 TLOG(TLVL_INFO) << "Using default port range for Routing Tokens, port=base+offset+partition+subsystem: "
     255            0 :                                 << (base_port_ + routing_token_offset_ + (Globals::GetPartitionNumber() * ports_per_partition_) + subsystemID)
     256            0 :                                 << "=" << base_port_ << "+" << routing_token_offset_ << "+" << (Globals::GetPartitionNumber() * ports_per_partition_) << "+" << subsystemID;
     257            0 :                 routing_tokens_configured_ = true;
     258              :         }
     259              : 
     260            0 :         return base_port_ + routing_token_offset_ + (Globals::GetPartitionNumber() * ports_per_partition_) + subsystemID;
     261              : }
     262              : 
     263            0 : int artdaq::PortManager::GetRoutingAckPort(int subsystemID)
     264              : {
     265            0 :         if (!routing_acks_configured_)
     266              :         {
     267            0 :                 TLOG(TLVL_INFO) << "Using default port range for Routing Table Acknowledgements, port=base+offset+partition+subsystem: "
     268            0 :                                 << (base_port_ + routing_ack_offset_ + (Globals::GetPartitionNumber() * ports_per_partition_) + subsystemID)
     269            0 :                                 << "=" << base_port_ << "+" << routing_ack_offset_ << "+" << (Globals::GetPartitionNumber() * ports_per_partition_) << "+" << subsystemID;
     270            0 :                 routing_acks_configured_ = true;
     271              :         }
     272            0 :         return base_port_ + routing_ack_offset_ + (Globals::GetPartitionNumber() * ports_per_partition_) + subsystemID;
     273              : }
     274              : 
     275            0 : int artdaq::PortManager::GetXMLRPCPort(int rank)
     276              : {
     277            0 :         if (!xmlrpc_configured_)
     278              :         {
     279            0 :                 TLOG(TLVL_INFO) << "Using default port range for XMLRPC, port=base+offset+partition+rank: "
     280            0 :                                 << (base_port_ + xmlrpc_offset_ + (Globals::GetPartitionNumber() * ports_per_partition_) + rank)
     281            0 :                                 << "=" << base_port_ << "+" << xmlrpc_offset_ << "+" << (Globals::GetPartitionNumber() * ports_per_partition_) << "+" << rank;
     282            0 :                 xmlrpc_configured_ = true;
     283              :         }
     284            0 :         return base_port_ + xmlrpc_offset_ + rank + (Globals::GetPartitionNumber() * ports_per_partition_);
     285              : }
     286              : 
     287            3 : int artdaq::PortManager::GetTCPSocketTransferPort(int rank)
     288              : {
     289            3 :         if (!tcpsocket_configured_)
     290              :         {
     291            3 :                 TLOG(TLVL_INFO) << "Using default port range for TCPSocket Transfer, port=base+offset+partition+rank: "
     292            1 :                                 << (base_port_ + tcp_socket_offset_ + (Globals::GetPartitionNumber() * ports_per_partition_) + rank)
     293            2 :                                 << "=" << base_port_ << "+" << tcp_socket_offset_ << "+" << (Globals::GetPartitionNumber() * ports_per_partition_) << "+" << rank;
     294            1 :                 tcpsocket_configured_ = true;
     295              :         }
     296            3 :         return base_port_ + tcp_socket_offset_ + (Globals::GetPartitionNumber() * ports_per_partition_) + rank;
     297              : }
     298              : 
     299            0 : int artdaq::PortManager::GetRequestMessagePort()
     300              : {
     301            0 :         if (!request_port_configured_)
     302              :         {
     303            0 :                 TLOG(TLVL_INFO) << "Using default port for Request Messages, port=" << request_message_port_;
     304            0 :                 request_port_configured_ = true;
     305              :         }
     306            0 :         return request_message_port_;
     307              : }
     308              : 
     309            0 : std::string artdaq::PortManager::GetRequestMessageGroupAddress(int subsystemID)
     310              : {
     311            0 :         if (!request_pattern_configured_)
     312              :         {
     313            0 :                 TLOG(TLVL_INFO) << "Using default address for Request Messages";
     314            0 :                 request_pattern_configured_ = true;
     315              :         }
     316              : 
     317            0 :         return parse_pattern_(request_message_group_pattern_, subsystemID);
     318              : }
     319              : 
     320            0 : int artdaq::PortManager::GetRoutingTablePort()
     321              : {
     322            0 :         if (!routing_table_port_configured_)
     323              :         {
     324            0 :                 TLOG(TLVL_INFO) << "Using default port for Routing Tables, port= " << routing_table_port_;
     325            0 :                 routing_table_port_configured_ = true;
     326              :         }
     327              : 
     328            0 :         return routing_table_port_;
     329              : }
     330              : 
     331            0 : std::string artdaq::PortManager::GetRoutingTableGroupAddress(int subsystemID)
     332              : {
     333            0 :         if (!routing_table_pattern_configured_)
     334              :         {
     335            0 :                 TLOG(TLVL_INFO) << "Using default address for Routing Tables";
     336            0 :                 routing_table_pattern_configured_ = true;
     337              :         }
     338              : 
     339            0 :         return parse_pattern_(routing_table_group_pattern_, subsystemID);
     340              : }
     341              : 
     342            0 : int artdaq::PortManager::GetMulticastTransferPort(int rank)
     343              : {
     344            0 :         if (!multicast_transfer_port_configued_)
     345              :         {
     346            0 :                 TLOG(TLVL_INFO) << "Using default port for Multicast Transfer, port=offset+rank: "
     347            0 :                                 << (multicast_transfer_offset_ + rank) << "=" << multicast_transfer_offset_ << "+" << rank;
     348            0 :                 multicast_transfer_port_configued_ = true;
     349              :         }
     350              : 
     351            0 :         return multicast_transfer_offset_ + rank;
     352              : }
     353              : 
     354            0 : std::string artdaq::PortManager::GetMulticastTransferGroupAddress()
     355              : {
     356            0 :         if (!multicast_transfer_pattern_configured_)
     357              :         {
     358            0 :                 TLOG(TLVL_INFO) << "Using default address for Multicast Transfer";
     359            0 :                 multicast_transfer_pattern_configured_ = true;
     360              :         }
     361              : 
     362            0 :         return parse_pattern_(multicast_transfer_group_pattern_);
     363              : }
     364              : 
     365            0 : in_addr artdaq::PortManager::GetMulticastOutputAddress(const std::string& interface_name, const std::string& interface_address)
     366              : {
     367            0 :         if (!multicasts_configured_)
     368              :         {
     369            0 :                 if (interface_name.empty() && interface_address.empty())
     370              :                 {
     371            0 :                         TLOG(TLVL_INFO) << "Using default multicast output address (autodetected private interface)";
     372              :                 }
     373            0 :                 if (!interface_name.empty())
     374              :                 {
     375            0 :                         GetIPOfInterface(interface_name, multicast_interface_address_);
     376              :                 }
     377            0 :                 else if (!interface_address.empty())
     378              :                 {
     379            0 :                         GetInterfaceForNetwork(interface_address.c_str(), multicast_interface_address_);
     380              :                 }
     381              :                 else
     382              :                 {
     383            0 :                         AutodetectPrivateInterface(multicast_interface_address_);
     384              :                 }
     385            0 :                 multicasts_configured_ = true;
     386              :         }
     387            0 :         return multicast_interface_address_;
     388              : }
     389              : 
     390            0 : std::string artdaq::PortManager::parse_pattern_(const std::string& pattern, int subsystemID, int rank)
     391              : {
     392            0 :         std::istringstream f(pattern);
     393            0 :         std::vector<int> address(4);
     394            0 :         std::string s;
     395              : 
     396            0 :         while (getline(f, s, '.'))
     397              :         {
     398            0 :                 if (s == "PPP")
     399              :                 {
     400            0 :                         address.push_back(Globals::GetPartitionNumber());
     401              :                 }
     402            0 :                 else if (s == "SSS")
     403              :                 {
     404            0 :                         address.push_back(subsystemID);
     405              :                 }
     406            0 :                 else if (s == "RRR")
     407              :                 {
     408            0 :                         address.push_back(rank);
     409              :                 }
     410              :                 else
     411              :                 {
     412            0 :                         address.push_back(stoi(s));
     413              :                 }
     414              :         }
     415              : 
     416            0 :         if (address.size() != 4)
     417              :         {
     418            0 :                 TLOG(TLVL_ERROR) << "Invalid address pattern:" << pattern << "!";
     419            0 :                 while (address.size() < 4) { address.push_back(0); }
     420              :         }
     421            0 :         address[3] += multicast_group_offset_;
     422              : 
     423            0 :         return std::to_string(address[0]) + "." + std::to_string(address[1]) + "." + std::to_string(address[2]) + "." + std::to_string(address[3]);
     424            0 : }
        

Generated by: LCOV version 2.0-1