diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index 2799850f3..7ab4304f2 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -826,10 +826,10 @@ class Detector { * receiver property (not on detector). \n receiver is receiver hostname or * IP address, can include tcp port eg. hostname:port */ - void setRxHostname(const std::string &receiver, Positions pos = {}); + void setRxHostname(const std::string &receiver, Positions pos = {}, const int rxIndex = 0); - /** multiple rx hostnames. Single element will set it for all */ - void setRxHostname(const std::vector &name); + /** single element assumes only one receiver per module. If multiple element and position for multi module, each element for each module */ + void setRxHostname(const std::vector &name, Positions pos); Result getRxPort(Positions pos = {}, const int rx_index = 0) const; diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index ddbfaeed1..ba8e049ba 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -1464,7 +1464,7 @@ std::string CmdProxy::UDPDestinationIP(int action) { "rx_hostname." << '\n'; } else if (action == defs::GET_ACTION) { - auto t = det->getDestinationUDPIP(std::vector{det_id}); + auto t = det->getDestinationUDPIP(std::vector{det_id}, rx_id); if (!args.empty()) { WrongNumberOfParameters(0); } @@ -1477,11 +1477,11 @@ std::string CmdProxy::UDPDestinationIP(int action) { auto val = getIpFromAuto(); LOG(logINFO) << "Setting udp_dstip of detector " << det_id << " to " << val; - det->setDestinationUDPIP(val, std::vector{det_id}); + det->setDestinationUDPIP(val, std::vector{det_id}, rx_id); os << val << '\n'; } else { auto val = IpAddr(args[0]); - det->setDestinationUDPIP(val, std::vector{det_id}); + det->setDestinationUDPIP(val, std::vector{det_id}, rx_id); os << args.front() << '\n'; } } else { @@ -1500,7 +1500,7 @@ std::string CmdProxy::UDPDestinationIP2(int action) { "\n\t[Gotthard2] veto debugging. " << '\n'; } else if (action == defs::GET_ACTION) { - auto t = det->getDestinationUDPIP2(std::vector{det_id}); + auto t = det->getDestinationUDPIP2(std::vector{det_id}, rx_id); if (!args.empty()) { WrongNumberOfParameters(0); } @@ -1513,11 +1513,11 @@ std::string CmdProxy::UDPDestinationIP2(int action) { auto val = getIpFromAuto(); LOG(logINFO) << "Setting udp_dstip2 of detector " << det_id << " to " << val; - det->setDestinationUDPIP2(val, std::vector{det_id}); + det->setDestinationUDPIP2(val, std::vector{det_id}, rx_id); os << val << '\n'; } else { auto val = IpAddr(args[0]); - det->setDestinationUDPIP2(val, std::vector{det_id}); + det->setDestinationUDPIP2(val, std::vector{det_id}, rx_id); os << args.front() << '\n'; } } else { @@ -1578,13 +1578,21 @@ std::string CmdProxy::ReceiverHostname(int action) { throw sls::RuntimeError( "Cannot add multiple receivers at RR level"); } - auto t = sls::split(args[0], '+'); - det->setRxHostname(args[0]); - os << ToString(args[0]) << '\n'; + // split it for each module + if (det->size() > 1 && det_id == -1) { + auto t = sls::split(args[0], '+'); + det->setRxHostname(t); + os << ToString(t) << '\n'; + } + // for specific module + else { + det->setRxHostname(args[0], {det_id}); + os << ToString(args[0]) << '\n'; + } } // single receiver else { - det->setRxHostname(args[0], std::vector{det_id}); + det->setRxHostname(args[0], std::vector{det_id}, rx_id); os << ToString(args) << '\n'; } } diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index bb04d16bf..e91b63beb 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -185,6 +185,31 @@ return os.str(); \ } +#define INTEGER_COMMAND_VEC_ID_RX(CMDNAME, GETFCN, SETFCN, CONV, HLPSTR) \ + std::string CMDNAME(const int action) { \ + std::ostringstream os; \ + os << cmd << ' '; \ + if (action == slsDetectorDefs::HELP_ACTION) \ + os << HLPSTR << '\n'; \ + else if (action == slsDetectorDefs::GET_ACTION) { \ + if (!args.empty()) { \ + WrongNumberOfParameters(0); \ + } \ + auto t = det->GETFCN(std::vector{det_id}, rx_id); \ + os << OutString(t) << '\n'; \ + } else if (action == slsDetectorDefs::PUT_ACTION) { \ + if (args.size() != 1) { \ + WrongNumberOfParameters(1); \ + } \ + auto val = CONV(args[0]); \ + det->SETFCN(val, std::vector{det_id}, rx_id); \ + os << args.front() << '\n'; \ + } else { \ + throw sls::RuntimeError("Unknown action"); \ + } \ + return os.str(); \ + } + /** int or enum */ #define INTEGER_COMMAND_VEC_ID_PUT_SINGLE_ID(CMDNAME, GETFCN, SETFCN, CONV, HLPSTR) \ std::string CMDNAME(const int action) { \ @@ -486,6 +511,26 @@ return os.str(); \ } +#define GET_COMMAND_RX(CMDNAME, GETFCN, HLPSTR) \ + std::string CMDNAME(const int action) { \ + std::ostringstream os; \ + os << cmd << ' '; \ + if (action == slsDetectorDefs::HELP_ACTION) \ + os << HLPSTR << '\n'; \ + else if (action == slsDetectorDefs::GET_ACTION) { \ + if (!args.empty()) { \ + WrongNumberOfParameters(0); \ + } \ + auto t = det->GETFCN(std::vector{det_id}); \ + os << OutString(t) << '\n'; \ + } else if (action == slsDetectorDefs::PUT_ACTION) { \ + throw sls::RuntimeError("Cannot put"); \ + } else { \ + throw sls::RuntimeError("Unknown action"); \ + } \ + return os.str(); \ + } + /** get only no id (vector, not result) */ #define GET_COMMAND_NOID(CMDNAME, GETFCN, HLPSTR) \ std::string CMDNAME(const int action) { \ @@ -1621,14 +1666,14 @@ class CmdProxy { "[x:x:x:x:x:x]\n\t[Jungfrau] Mac address of the top " "half or inner (source) udp interface. "); - INTEGER_COMMAND_VEC_ID( + INTEGER_COMMAND_VEC_ID_RX( udp_dstmac, getDestinationUDPMAC, setDestinationUDPMAC, MacAddr, "[x:x:x:x:x:x]\n\tMac address of the receiver (destination) udp " "interface. Not mandatory to set as udp_dstip retrieves it from " "slsReceiver process, but must be set if you use a custom receiver " "(not slsReceiver)."); - INTEGER_COMMAND_VEC_ID( + INTEGER_COMMAND_VEC_ID_RX( udp_dstmac2, getDestinationUDPMAC2, setDestinationUDPMAC2, MacAddr, "[x:x:x:x:x:x]\n\t[Jungfrau] Mac address of the receiver (destination) " "udp interface 2. Not mandatory to set as udp_dstip2 retrieves it from " @@ -1666,7 +1711,7 @@ class CmdProxy { "valid. If not configured, it will throw with error message " "requesting missing udp information."); - GET_COMMAND(rx_printconfig, printRxConfiguration, + GET_COMMAND_RX(rx_printconfig, printRxConfiguration, "\n\tPrints the receiver configuration."); INTEGER_COMMAND_VEC_ID( @@ -1843,7 +1888,7 @@ class CmdProxy { "port). Multi command will automatically increment for individual " "modules."); - INTEGER_COMMAND_VEC_ID( + INTEGER_COMMAND_VEC_ID_RX( rx_zmqip, getRxZmqIP, setRxZmqIP, IpAddr, "[x.x.x.x]\n\tZmq Ip Address from which data is to be streamed out of " "the receiver. Also restarts receiver zmq streaming if enabled. " diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index a60aa981e..9d5225fe6 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -1077,24 +1077,35 @@ Result Detector::getRxHostname(Positions pos, } // rr added using + at module level -void Detector::setRxHostname(const std::string &receiver, Positions pos) { - pimpl->Parallel(&Module::setReceiverHostname, pos, receiver); +void Detector::setRxHostname(const std::string &receiver, Positions pos, const int rxIndex) { + pimpl->Parallel(&Module::setReceiverHostname, pos, receiver, rxIndex); updateRxRateCorrections(); } -void Detector::setRxHostname(const std::vector &name) { +void Detector::setRxHostname(const std::vector &name, Positions pos) { // set all to same rx_hostname if (name.size() == 1) { - pimpl->Parallel(&Module::setReceiverHostname, {}, name[0]); + pimpl->Parallel(&Module::setReceiverHostname, pos, name[0], 0); } else { /*if ((int)name.size() != size()) { throw RuntimeError( "Receiver hostnames size " + std::to_string(name.size()) + " does not match detector size " + std::to_string(size())); }*/ - // set each rx_hostname - for (int idet = 0; idet < size(); ++idet) { - pimpl->Parallel(&Module::setReceiverHostname, {idet}, name[idet]); + // multi module + if ((size() > 1) && (pos.empty() || pos[0] == -1)) { + for (int idet = 0; idet < size(); ++idet) { + pimpl->Parallel(&Module::setReceiverHostname, {idet}, name[idet], 0); + } + } + // setting rr for specific module + else { + if (pos.empty() || pos[0] == -1) { + pimpl->Parallel(&Module::setAllReceiverHostnames, {0}, name); + } else { + pimpl->Parallel(&Module::setAllReceiverHostnames, {pos}, name); + } + } } updateRxRateCorrections(); diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index a26d7158f..42a4af6c4 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -1261,86 +1261,92 @@ std::string Module::getReceiverHostname(const int rxIndex) const { return std::string(shm()->receivers[rxIndex].hostname); } -void Module::setReceiverHostname(const std::string &receiverIP) { - LOG(logDEBUG1) << "Setting up Receiver with " << receiverIP; +void Module::setAllReceiverHostnames(const std::vector &receiver) { + if (receiver.size() == 1) { + setReceiverHostname(receiver[0], 0); + } else { + if (receiver.size() >= MAX_UDP_DESTINATION) { + std::ostringstream oss; + oss << "Receiver hostnames size " << receiver.size() << " exceeded max " << MAX_UDP_DESTINATION << " entries allowed."; + throw RuntimeError(oss.str()); + } + for (size_t irr = 0; irr < receiver.size(); ++irr) { + setReceiverHostname(receiver[irr], irr); + } + } +} + +void Module::setReceiverHostname(const std::string &receiverIP, const int rxIndex) { + LOG(logDEBUG1) << "Setting up Receiver " << rxIndex << " with " << receiverIP; if (getRunStatus() == RUNNING) { throw RuntimeError( "Cannot set rx hostname when detector is acquiring."); } + // clear current receiver for current module + memset(shm()->receivers[rxIndex].hostname, 0, MAX_STR_LENGTH); + sls::strcpy_safe(shm()->receivers[rxIndex].hostname, "none"); + + // check if any other RR is set before returning if (receiverIP == "none") { - for (int i = 0; i != MAX_UDP_DESTINATION; ++i) { - memset(shm()->receivers[i].hostname, 0, MAX_STR_LENGTH); - sls::strcpy_safe(shm()->receivers[i].hostname, "none"); - } shm()->useReceiverFlag = false; + for (int i = 0; i != MAX_UDP_DESTINATION; ++i) { + if (strcmp(shm()->receivers[i].hostname, "none")) { + shm()->useReceiverFlag = true; + LOG(logINFORED) << "still one RR, so use receeverflag true"; + } + } return; } - std::vector list; - // many rx hostames concatenated with + (RR) - if (receiverIP.find('+') != std::string::npos) { - list = sls::split(receiverIP, '+'); - } else { - list.push_back(receiverIP); - } - - // clear all rxrs for current module - for (int i = 0; i != MAX_UDP_DESTINATION; ++i) { - memset(shm()->receivers[i].hostname, 0, MAX_STR_LENGTH); - sls::strcpy_safe(shm()->receivers[i].hostname, "none"); - } - // start updating - for (size_t i = 0; i != list.size(); ++i) { - LOG(logINFOBLUE) << i << ": " << list[i]; - std::string host = list[i]; - auto res = sls::split(host, ':'); - if (res.size() > 1) { - host = res[0]; - shm()->receivers[i].tcpPort = std::stoi(res[1]); - } - sls::strcpy_safe(shm()->receivers[i].hostname, host.c_str()); - shm()->useReceiverFlag = true; - checkReceiverVersionCompatibility(); - - // populate parameters from detector - rxParameters retval; - sendToDetector(F_GET_RECEIVER_PARAMETERS, nullptr, retval); - - // populate from shared memory - retval.detType = shm()->detType; - retval.numberOfModule.x = shm()->numberOfModule.x; - retval.numberOfModule.y = shm()->numberOfModule.y; - retval.moduleIndex = moduleIndex; - memset(retval.hostname, 0, sizeof(retval.hostname)); - strcpy_safe(retval.hostname, shm()->hostname); - - sls::MacAddr retvals[2]; - sendToReceiver(i, F_SETUP_RECEIVER, retval, retvals); - - if (i == 0) { - // update Modules with dest mac - if (retval.udp_dstmac == 0 && retvals[0] != 0) { - LOG(logINFO) << "Setting destination udp mac of " - "Module " - << moduleIndex << " to " << retvals[0]; - sendToDetector(F_SET_DEST_UDP_MAC, retvals[0], nullptr); - } - if (retval.udp_dstmac2 == 0 && retvals[1] != 0) { - LOG(logINFO) << "Setting destination udp mac2 of " - "Module " - << moduleIndex << " to " << retvals[1]; - sendToDetector(F_SET_DEST_UDP_MAC2, retvals[1], nullptr); - } - } - - shm()->numUDPInterfaces = retval.udpInterfaces; - - // to use rx_hostname if empty and also update client zmqip - updateReceiverStreamingIP(i); + LOG(logINFOBLUE) << rxIndex << ": " << receiverIP; + std::string host = receiverIP; + auto res = sls::split(host, ':'); + if (res.size() > 1) { + host = res[0]; + shm()->receivers[rxIndex].tcpPort = std::stoi(res[1]); } + sls::strcpy_safe(shm()->receivers[rxIndex].hostname, host.c_str()); + shm()->useReceiverFlag = true; + checkReceiverVersionCompatibility(); + + // populate parameters from detector + rxParameters retval; + sendToDetector(F_GET_RECEIVER_PARAMETERS, nullptr, retval); + + // populate from shared memory + retval.detType = shm()->detType; + retval.numberOfModule.x = shm()->numberOfModule.x; + retval.numberOfModule.y = shm()->numberOfModule.y; + retval.moduleIndex = moduleIndex; + memset(retval.hostname, 0, sizeof(retval.hostname)); + strcpy_safe(retval.hostname, shm()->hostname); + + sls::MacAddr retvals[2]; + sendToReceiver(rxIndex, F_SETUP_RECEIVER, retval, retvals); + + if (rxIndex == 0) { + // update Modules with dest mac + if (retval.udp_dstmac == 0 && retvals[0] != 0) { + LOG(logINFO) << "Setting destination udp mac of " + "Module " + << moduleIndex << " to " << retvals[0]; + sendToDetector(F_SET_DEST_UDP_MAC, retvals[0], nullptr); + } + if (retval.udp_dstmac2 == 0 && retvals[1] != 0) { + LOG(logINFO) << "Setting destination udp mac2 of " + "Module " + << moduleIndex << " to " << retvals[1]; + sendToDetector(F_SET_DEST_UDP_MAC2, retvals[1], nullptr); + } + } + + shm()->numUDPInterfaces = retval.udpInterfaces; + + // to use rx_hostname if empty and also update client zmqip + updateReceiverStreamingIP(rxIndex); } int Module::getReceiverPort(const int rxIndex) const { diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 5dc69eb4c..2c4d2727a 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -272,7 +272,8 @@ class Module : public virtual slsDetectorDefs { * ************************************************/ bool getUseReceiverFlag() const; std::string getReceiverHostname(const int rxIndex) const; - void setReceiverHostname(const std::string &receiver); + void setAllReceiverHostnames(const std::vector &receiver); + void setReceiverHostname(const std::string &receiver, const int rxIndex); int getReceiverPort(const int rxIndex) const; int setReceiverPort(int port_number, const int rxIndex); int getReceiverFifoDepth() const;