LCOV - code coverage report
Current view: top level - src/config - config.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 58 107 54.2 %
Date: 2025-09-09 12:09:29 Functions: 12 16 75.0 %

          Line data    Source code
       1             : #include "config.hpp"
       2             : #include "felixtag.h"
       3             : #include "log.hpp"
       4             : 
       5             : #include "felix/felix_fid.h"
       6             : #include "felix/felix_ports.h"
       7             : #include "felix/felix_client_util.hpp"
       8             : #include <cstdint>
       9             : 
      10          27 : std::string Config::options() {
      11          27 :     return
      12          27 : R"(
      13             :     General Options:
      14             :         --bus-dir=DIRECTORY         Write felix-bus information to this directory. [default: ./bus]
      15             :         --bus-groupname=NAME        Use this groupname for the bus. [default: FELIX]
      16             :         --cid=<cid>...              CID (Connector Ids) to set in FID (Felix ID). Can be used multiple times. [default: device]
      17             :         --did=<did>                 DID (Detector Id) to set in FID (Felix ID). [default: 0]
      18             :     -d, --device=<device>...        Use FLX device DEVICE. [default: 0]
      19             :         --error-out=<fifo>          Write error information to a UNIX FIFO
      20             :         --free-cmem                 Free previously booked cmem segment by name-<device>-<dma>
      21             :         --iface=<iface>             Send data to the interface. [calculated: use --ip value]
      22             :     -i, --ip=<ip>                   Publish data on the ip address IP. [default: libfabric:127.0.0.1]
      23             :     -b, --netio-pagesize=<size>     NetIO page size in Byte. [default: 65536]
      24             :     -B, --netio-pages=<size>        Number of NetIO pages. [default: 256]
      25             :         --stats-out=<fifo>          Write periodic statistics data to a UNIX FIFO
      26             :         --stats-period=<ms>         Period in milliseconds for statistics dumps. [default: 1000]
      27             :     -?, --help                      Give this help list
      28             :     -v, --verbose                   Produce verbose output
      29             :         --verbose-bus               Produce verbose output for bus
      30             :     -V, --version                   Print program version
      31             :         --evloop-type=<type>        Event loop type to use. [default: netio-next]
      32             :         --vid=N                     VID (Version Id) to set in FID (Felix ID) [default: 1]
      33             : )";
      34             : }
      35             : 
      36          27 : Config::Config() {}
      37             : 
      38          27 : Config::~Config() {}
      39             : 
      40             : 
      41          27 : void Config::parse(int argc, char **argv) {
      42          27 :     appname = argv[0];
      43             : 
      44          27 :     std::map<std::string, docopt::value> args
      45          54 :             = docopt::docopt(usage() + options() + bugs(),
      46          27 :                             { argv + 1, argv + argc },
      47             :                             true,               // show help if requested
      48         135 :                             (std::string(argv[0]) + " " + FELIX_TAG).c_str());  // version string
      49             : 
      50          54 :     handle_cmd_line(args);
      51          27 : }
      52             : 
      53           0 : std::ostream& Config::format(std::ostream& os) const {
      54           0 :     os << "Config" << std::endl;
      55           0 :     os << "bus_dir: " << network.bus_dir << std::endl;
      56           0 :     os << "bus_groupname: " << network.bus_groupname << std::endl;
      57           0 :     os << "cid: ";
      58           0 :         std::copy(resource.cid.begin(), resource.cid.end(), std::ostream_iterator<int>(os << std::hex << std::showbase, " "));
      59           0 :         os << std::endl;
      60           0 :     os << "did: 0x" << std::hex << resource.did << std::dec << std::endl;
      61           0 :     os << "device: ";
      62           0 :         std::copy(resource.device.begin(), resource.device.end(), std::ostream_iterator<int>(os, " "));
      63           0 :         os << std::endl;
      64           0 :     os << "free_previous_cmem: " << resource.free_previous_cmem << std::endl;
      65           0 :     os << "ip: " << network.ip << std::endl;
      66           0 :     os << "netio_pagesize: " << network.netio_pagesize << std::endl;
      67           0 :     os << "netio_pages: " << network.netio_pages << std::endl;
      68           0 :     os << "statistics_fifo: " << stats.monitoring_fifo << std::endl;
      69           0 :     os << "statistics_period: " << stats.monitoring_period_ms << std::endl;
      70           0 :     os << "verbose: " << verbose << std::endl;
      71           0 :     os << "verbose_bus: " << network.verbose_bus << std::endl;
      72           0 :     os << "eventloop_type: " << evloop_type_to_str(network.evloop_type) << std::endl;
      73           0 :     os << "vid: 0x" << std::hex << (uint32_t)resource.vid << std::dec << std::endl;
      74           0 :     os << std::endl;
      75           0 :     return os;
      76             : }
      77             : 
      78           0 : std::ostream& operator<<(std::ostream& os, const Config& c) {
      79           0 :     return c.format(os);
      80             : }
      81             : 
      82          27 : void Config::handle_cmd_line(std::map<std::string, docopt::value> args) {
      83             : 
      84          27 :     auto devices = args["--device"].asStringList();
      85          54 :     for(const auto& i : devices){
      86          27 :         resource.device.push_back(stoi(i));
      87             :     }
      88             : 
      89          27 :     resource.vid = args["--vid"].asLong();
      90          27 :     resource.did = args["--did"].asLong();
      91             : 
      92          27 :     auto cids = args["--cid"].asStringList();
      93          27 :     if (cids.empty()) { // No cids, impossible, there should be the default
      94           0 :         LOG_ERR("No cid provided, aborting.");
      95           0 :         throw std::runtime_error("No cid provided, aborting.");
      96             :     }
      97          27 :     else if (cids.size() == 1) {
      98          27 :         if ( cids.at(0) == "device" ) {
      99           0 :             resource.cid = resource.device;
     100             :         }
     101             :         else {
     102          27 :             int base_cid = stoi(cids.at(0), 0, 16);
     103          54 :             for(unsigned int i = 0; i < resource.device.size(); ++i) {
     104          27 :                 resource.cid.push_back(base_cid + i);
     105             :             }
     106             :         }
     107             :     }
     108           0 :     else if (cids.size() == devices.size()){
     109           0 :         for(unsigned int i = 0; i < cids.size(); ++i) {
     110           0 :             uint16_t cid = static_cast<uint16_t>(stoi(cids.at(i), 0, 16));
     111           0 :             resource.cid.push_back(cid);
     112             :         }
     113             :     }
     114             :     else {
     115           0 :         LOG_ERR("The number of provided CIDs is not one nor equal to the number of devices.");
     116           0 :         throw std::runtime_error("No cid provided, aborting.");
     117             :     }
     118             : 
     119          27 :     resource.free_previous_cmem = args["--free-cmem"].asBool();
     120             : 
     121          54 :     network.bus_dir = args["--bus-dir"].asString();
     122          54 :     network.bus_groupname = args["--bus-groupname"].asString();
     123          27 :     network.dcs_tcp = false;
     124          27 :     network.netio_pagesize = args["--netio-pagesize"].asLong();
     125          27 :     network.netio_pages = args["--netio-pages"].asLong();
     126          27 :     network.verbose_bus = args["--verbose-bus"].asBool();
     127             : 
     128          27 :     network.evloop_type = evloop_type_from_str(args["--evloop-type"].asString());
     129             : 
     130          54 :     stats.monitoring_fifo = args["--stats-out"] ? args["--stats-out"].asString() : "";
     131          27 :     stats.monitoring_period_ms = args["--stats-period"].asLong();
     132             : 
     133          27 :     verbose = args["--verbose"].asBool();
     134             : 
     135             :     // derive ip
     136          27 :     if (args["--iface"]) {
     137           0 :         network.ip = get_value_from_getifaddrs(args["--iface"].asString(), true);
     138             :     } else {
     139          54 :         network.ip = args["--ip"].asString();
     140             :     }
     141          27 : }
     142             : 
     143             : 
     144          27 : std::string Config::bugs() {
     145          27 :     return
     146          27 : R"(
     147             : Report bugs to <https://its.cern.ch/jira/projects/FLXUSERS>.
     148             : )";
     149             : }
     150             : 
     151             : 
     152          27 : int Config::get_number_devices()
     153             : {
     154          27 :     return resource.device.size();
     155             : };
     156             : 
     157             : 
     158          27 : uint16_t Config::get_device_cid(unsigned int dev_no)
     159             : {
     160          27 :     auto it = std::find(resource.device.begin(), resource.device.end(), dev_no);
     161          27 :     if ( it == resource.device.end() ){
     162           0 :         throw std::invalid_argument("Cannot find cid for the requested device.");
     163             :     } else {
     164          27 :         int idx = it - resource.device.begin();
     165          27 :         return resource.cid.at(idx);
     166             :     }
     167             : }
     168             : 
     169             : 
     170          66 : int Config::get_unique_dmaid(int dmaid, uint16_t device)
     171             : {
     172          66 :     return (dmaid + 10*device);
     173             : }
     174             : 
     175             : 
     176         375 : int Config::udmaid_to_dmaid(int udmaid)
     177             : {
     178         375 :     return (udmaid % 10);
     179             : }
     180             : 
     181             : 
     182         177 : int Config::udmaid_to_deviceid(int udmaid)
     183             : {
     184         177 :     return ( (udmaid - udmaid_to_dmaid(udmaid)) / 10 );
     185             : }
     186             : 
     187           0 : std::string Config::evloop_type_to_str(EventLoopType type)
     188             : {
     189           0 :     switch (type) {
     190           0 :         case EventLoopType::netio_next:
     191           0 :             return "netio-next";
     192           0 :         case EventLoopType::netio3_native:
     193           0 :             return "netio3-native";
     194           0 :         case EventLoopType::netio3_asio:
     195           0 :             return "netio3-asio";
     196           0 :         default:
     197           0 :             throw std::logic_error("Invalid EventLoopType");
     198             :     }
     199             : }
     200             : 
     201          27 : EventLoopType Config::evloop_type_from_str(std::string_view type)
     202             : {
     203          27 :     if (type == "netio-next") {
     204             :         return EventLoopType::netio_next;
     205           0 :     } else if (type == "netio3-native") {
     206             :         return EventLoopType::netio3_native;
     207           0 :     } else if (type == "netio3-asio") {
     208             :         return EventLoopType::netio3_asio;
     209             :     } else {
     210           0 :         throw std::logic_error("Invalid EventLoopType");
     211             :     }
     212             : }

Generated by: LCOV version 1.0