diff --git a/slsDetectorSoftware/include/slsDetector.h b/slsDetectorSoftware/include/slsDetector.h index 631e46eec..f1bfabbc2 100644 --- a/slsDetectorSoftware/include/slsDetector.h +++ b/slsDetectorSoftware/include/slsDetector.h @@ -109,10 +109,6 @@ struct sharedSlsDetector { /** size of the data that are transfered from the detector */ int dataBytes; - /** threaded processing flag - * (i.e. if data are processed in a separate thread) */ - // int threadedProcessing; - /** number of rois defined */ int nROI; @@ -145,22 +141,22 @@ struct sharedSlsDetector { int receiverUDPPort2; /** ip address of the receiver for the detector to send packets to**/ - char receiverUDPIP[MAX_STR_LENGTH]; + uint32_t receiverUDPIP; /** ip address of the receiver for the 2nd interface of the detector to send packets to**/ - char receiverUDPIP2[MAX_STR_LENGTH]; + uint32_t receiverUDPIP2; /** mac address of receiver for the detector to send packets to **/ - char receiverUDPMAC[MAX_STR_LENGTH]; + uint64_t receiverUDPMAC; /** mac address of receiver for the 2nd interface of the detector to send packets to **/ - char receiverUDPMAC2[MAX_STR_LENGTH]; + uint64_t receiverUDPMAC2; /** mac address of the detector **/ - char detectorMAC[MAX_STR_LENGTH]; + uint64_t detectorMAC; /** mac address of the 2nd interface of the detector **/ - char detectorMAC2[MAX_STR_LENGTH]; + uint64_t detectorMAC2; /** ip address of the detector **/ uint32_t detectorIP; diff --git a/slsDetectorSoftware/src/slsDetector.cpp b/slsDetectorSoftware/src/slsDetector.cpp index dad6eaede..90b401de9 100644 --- a/slsDetectorSoftware/src/slsDetector.cpp +++ b/slsDetectorSoftware/src/slsDetector.cpp @@ -7,11 +7,11 @@ #include "file_utils.h" #include "gitInfoLib.h" #include "multiSlsDetector.h" +#include "network_utils.h" #include "slsDetectorCommand.h" #include "sls_detector_exceptions.h" #include "string_utils.h" #include "versionAPI.h" - #include #include #include @@ -24,14 +24,7 @@ #include #include -using sls::DetectorError; -using sls::DetectorSocket; -using sls::NotImplementedError; -using sls::ReceiverError; -using sls::ReceiverSocket; -using sls::RuntimeError; -using sls::SharedMemory; -using sls::SharedMemoryError; +using namespace sls; #define DEFAULT_HOSTNAME "localhost" @@ -317,14 +310,18 @@ void slsDetector::initializeDetectorStructure(detectorType type) { detector_shm()->receiverTCPPort = DEFAULT_PORTNO + 2; detector_shm()->receiverUDPPort = DEFAULT_UDP_PORTNO; detector_shm()->receiverUDPPort2 = DEFAULT_UDP_PORTNO + 1; - sls::strcpy_safe(detector_shm()->receiverUDPIP, "none"); - sls::strcpy_safe(detector_shm()->receiverUDPIP2, "none"); - sls::strcpy_safe(detector_shm()->receiverUDPMAC, "none"); - sls::strcpy_safe(detector_shm()->receiverUDPMAC2, "none"); - sls::strcpy_safe(detector_shm()->detectorMAC, DEFAULT_DET_MAC); - sls::strcpy_safe(detector_shm()->detectorMAC2, DEFAULT_DET_MAC2); + + detector_shm()->receiverUDPIP = 0u; + detector_shm()->receiverUDPIP2 = 0u; + detector_shm()->receiverUDPMAC = 0u; + detector_shm()->receiverUDPMAC2 = 0u; + + detector_shm()->detectorMAC = MacStringToUint(DEFAULT_DET_MAC); + detector_shm()->detectorMAC2 = MacStringToUint(DEFAULT_DET_MAC2); + inet_pton(AF_INET, DEFAULT_DET_IP, &(detector_shm()->detectorIP)); inet_pton(AF_INET, DEFAULT_DET_IP2, &(detector_shm()->detectorIP2)); + detector_shm()->numUDPInterfaces = 1; detector_shm()->selectedUDPInterface = 1; detector_shm()->receiverOnlineFlag = OFFLINE_FLAG; @@ -401,7 +398,8 @@ void slsDetector::initializeDetectorStructure(detectorType type) { detector_shm()->gappixels * detector_shm()->nGappixels[Y]) * detector_shm()->dynamicRange / 8; - // update #nchans and databytes, as it depends on #samples, roi, readoutflags (ctb only) + // update #nchans and databytes, as it depends on #samples, roi, + // readoutflags (ctb only) if (detector_shm()->myDetectorType == CHIPTESTBOARD || detector_shm()->myDetectorType == MOENCH) { updateTotalNumberOfChannels(); @@ -519,9 +517,9 @@ int slsDetector::receiveModule(sls_detector_module *myMod, sls::ClientSocket &cl slsDetectorDefs::detectorType slsDetector::getDetectorTypeFromShm(int multi_id, bool verify) { if (!detector_shm.IsExisting()) { - throw SharedMemoryError( - "Shared memory " + detector_shm.GetName() + - "does not exist.\n Corrupted Multi Shared memory. Please free shared memory."); + throw SharedMemoryError("Shared memory " + detector_shm.GetName() + + "does not exist.\n Corrupted Multi Shared " + "memory. Please free shared memory."); } detector_shm.OpenSharedMemory(); @@ -959,7 +957,8 @@ int slsDetector::updateDetectorNoWait(sls::ClientSocket &client) { } } - // update #nchans and databytes, as it depends on #samples, roi, readoutflags (ctb only) + // update #nchans and databytes, as it depends on #samples, roi, + // readoutflags (ctb only) if (detector_shm()->myDetectorType == CHIPTESTBOARD || detector_shm()->myDetectorType == MOENCH) { updateTotalNumberOfChannels(); @@ -1132,7 +1131,8 @@ slsDetectorDefs::detectorSettings slsDetector::setSettings(detectorSettings iset } } - // others: send only the settings, detector server will update dac values already in server + // others: send only the settings, detector server will update dac values + // already in server return sendSettingsOnly(isettings); } @@ -1156,7 +1156,8 @@ slsDetectorDefs::detectorSettings slsDetector::sendSettingsOnly(detectorSettings } int slsDetector::getThresholdEnergy() { - // moench - get threshold energy from processor (due to different clients, diff shm) + // moench - get threshold energy from processor (due to different clients, + // diff shm) if (detector_shm()->myDetectorType == MOENCH) { // get json from rxr, parse for threshold and update shm getAdditionalJsonHeader(); @@ -1273,7 +1274,8 @@ int slsDetector::setThresholdEnergyAndSettings(int e_eV, detectorSettings isetti FILE_LOG(logDEBUG1) << "Settings File is " << settingsfname; // read the files - // myMod = createModule(); // readSettings also checks if create module is null + // myMod = createModule(); // readSettings also checks if create module + // is null if (nullptr == readSettingsFile(settingsfname, myMod, tb)) { if (myMod) { deleteModule(myMod); @@ -1323,8 +1325,8 @@ int slsDetector::setThresholdEnergyAndSettings(int e_eV, detectorSettings isetti if (myMod1->iodelay != myMod2->iodelay) { deleteModule(myMod1); deleteModule(myMod2); - throw RuntimeError( - "setThresholdEnergyAndSettings: Iodelays do not match between files"); + throw RuntimeError("setThresholdEnergyAndSettings: Iodelays do not " + "match between files"); } // interpolate module @@ -1332,7 +1334,8 @@ int slsDetector::setThresholdEnergyAndSettings(int e_eV, detectorSettings isetti if (myMod == nullptr) { deleteModule(myMod1); deleteModule(myMod2); - throw RuntimeError("setThresholdEnergyAndSettings: Could not interpolate, different " + throw RuntimeError("setThresholdEnergyAndSettings: Could not " + "interpolate, different " "dac values in files"); } // interpolate tau @@ -1349,7 +1352,8 @@ int slsDetector::setThresholdEnergyAndSettings(int e_eV, detectorSettings isetti setModule(*myMod, tb); deleteModule(myMod); if (getSettings() != is) { - throw RuntimeError("setThresholdEnergyAndSettings: Could not set settings in detector"); + throw RuntimeError("setThresholdEnergyAndSettings: Could not set " + "settings in detector"); } return OK; } @@ -1516,7 +1520,8 @@ int slsDetector::startAndReadAll() { if (detector_shm()->onlineFlag == ONLINE_FLAG) { auto client = DetectorSocket(detector_shm()->hostname, detector_shm()->controlPort); ret = client.sendCommandThenRead(fnum, nullptr, 0, nullptr, 0); - // TODO! how to we hande this? ret == FAIL --> detector_shm()->stoppedFlag = 1; + // TODO! how to we hande this? ret == FAIL --> + // detector_shm()->stoppedFlag = 1; FILE_LOG(logDEBUG1) << "Detector successfully finished acquisition"; } if (ret == FORCE_UPDATE) { @@ -1548,7 +1553,8 @@ int slsDetector::readAll() { if (detector_shm()->onlineFlag == ONLINE_FLAG) { auto client = DetectorSocket(detector_shm()->hostname, detector_shm()->controlPort); ret = client.sendCommandThenRead(fnum, nullptr, 0, nullptr, 0); - // TODO! how to we hande this? ret == FAIL --> detector_shm()->stoppedFlag = 1; + // TODO! how to we hande this? ret == FAIL --> + // detector_shm()->stoppedFlag = 1; FILE_LOG(logDEBUG1) << "Detector successfully finished reading all frames"; } if (ret == FORCE_UPDATE) { @@ -1566,31 +1572,15 @@ int slsDetector::configureMAC() { char args[n_args][array_size] = {}; char retvals[n_retvals][array_size] = {}; FILE_LOG(logDEBUG1) << "Configuring MAC"; - - // if rx_udpip is none - if (!(strcmp(detector_shm()->receiverUDPIP, "none"))) { - // hostname is an ip address - if (strchr(detector_shm()->receiver_hostname, '.') != nullptr) { - sls::strcpy_safe(detector_shm()->receiverUDPIP, detector_shm()->receiver_hostname); - // if hostname not ip, convert it to ip - } else { - struct addrinfo *result; - if (sls::ConvertHostnameToInternetAddress(detector_shm()->receiver_hostname, &result) == - 0) { - // on success - memset(detector_shm()->receiverUDPIP, 0, MAX_STR_LENGTH); - // on failure, back to none - if (sls::ConvertInternetAddresstoIpString(result, detector_shm()->receiverUDPIP, - MAX_STR_LENGTH)) { - sls::strcpy_safe(detector_shm()->receiverUDPIP, "none"); - throw RuntimeError("configureMAC: Error. Receiver UDP IP Address not set"); - } - } + if (detector_shm()->receiverUDPIP == 0) { + // Hostname could be ip try to decode otherwise look up the hostname + detector_shm()->receiverUDPIP = IpStringToUint(detector_shm()->receiver_hostname); + if (detector_shm()->receiverUDPIP == 0) { + detector_shm()->receiverUDPIP = HostnameToIp(detector_shm()->receiver_hostname); } } - // rx_udpmac is none - if (!strcmp(detector_shm()->receiverUDPMAC, "none")) { + if (detector_shm()->receiverUDPMAC == 0) { throw RuntimeError("configureMAC: Error. Receiver UDP MAC Addresses not set"); } FILE_LOG(logDEBUG1) << "rx_hostname and rx_udpmac are valid "; @@ -1598,26 +1588,23 @@ int slsDetector::configureMAC() { // jungfrau 2 interfaces // validate for the second interface if (detector_shm()->numUDPInterfaces == 2) { - // copy from udpip (done here as well if udpconnection avoided (no slsrxr) - if (!strcmp(detector_shm()->receiverUDPIP2, "none")) { - sls::strcpy_safe(detector_shm()->receiverUDPIP2, detector_shm()->receiverUDPIP); + // copy from udpip (done here as well if udpconnection avoided (no + // slsrxr) + if (detector_shm()->receiverUDPIP2 == 0) { + detector_shm()->receiverUDPIP2 = detector_shm()->receiverUDPIP; } - // rx_udpmac2 (udpip2 will be copied from udpip if empty) - if (!strcmp(detector_shm()->receiverUDPMAC2, "none")) { - throw RuntimeError("configureMAC: Error. Receiver UDP MAC Addresses 2 not set"); - } - FILE_LOG(logDEBUG1) << "rx_udpmac2 are valid "; + FILE_LOG(logDEBUG1) << "rx_udpmac2 is valid "; } // copy to args snprintf(args[0], array_size, "%x", detector_shm()->receiverUDPPort); - sls::strcpy_safe(args[1], detector_shm()->receiverUDPIP); - sls::strcpy_safe(args[2], detector_shm()->receiverUDPMAC); - sls::strcpy_safe(args[4], detector_shm()->detectorMAC); + sls::strcpy_safe(args[1], getReceiverUDPIP().c_str()); + sls::strcpy_safe(args[2], getReceiverUDPMAC().c_str()); + sls::strcpy_safe(args[4], getDetectorMAC().c_str()); snprintf(args[5], array_size, "%x", detector_shm()->receiverUDPPort2); - sls::strcpy_safe(args[6], detector_shm()->receiverUDPIP2); - sls::strcpy_safe(args[7], detector_shm()->receiverUDPMAC2); - sls::strcpy_safe(args[9], detector_shm()->detectorMAC2); + sls::strcpy_safe(args[6], getReceiverUDPIP2().c_str()); + sls::strcpy_safe(args[7], getReceiverUDPMAC2().c_str()); + sls::strcpy_safe(args[9], getDetectorMAC2().c_str()); // number of interfaces and which one snprintf(args[10], array_size, "%x", detector_shm()->numUDPInterfaces); @@ -1679,34 +1666,22 @@ int slsDetector::configureMAC() { if (detector_shm()->onlineFlag == ONLINE_FLAG) { auto client = DetectorSocket(detector_shm()->hostname, detector_shm()->controlPort); ret = client.sendCommandThenRead(fnum, args, sizeof(args), retvals, sizeof(retvals)); - // get detectormac, detector ip - uint64_t idetectormac = 0; - uint32_t idetectorip = 0; - sscanf(retvals[0], "%lx", &idetectormac); - sscanf(retvals[1], "%x", &idetectorip); - idetectorip = __builtin_bswap32(idetectorip); - snprintf(retvals[0], sizeof(retvals[0]), "%02x:%02x:%02x:%02x:%02x:%02x", - (unsigned int)((idetectormac >> 40) & 0xFF), - (unsigned int)((idetectormac >> 32) & 0xFF), - (unsigned int)((idetectormac >> 24) & 0xFF), - (unsigned int)((idetectormac >> 16) & 0xFF), - (unsigned int)((idetectormac >> 8) & 0xFF), - (unsigned int)((idetectormac >> 0) & 0xFF)); + uint64_t detector_mac = 0; + uint32_t detector_ip = 0; + sscanf(retvals[0], "%lx", &detector_mac); // TODO! (Erik) send mac and ip as int + sscanf(retvals[1], "%x", &detector_ip); + detector_ip = __builtin_bswap32(detector_ip); - - // update if different - if (strcasecmp(retvals[0], detector_shm()->detectorMAC)) { - memset(detector_shm()->detectorMAC, 0, MAX_STR_LENGTH); - sls::strcpy_safe(detector_shm()->detectorMAC, retvals[0]); - FILE_LOG(logINFO) << detId << ": Detector MAC updated to " - << detector_shm()->detectorMAC; + if (detector_shm()->detectorMAC != detector_mac) { + detector_shm()->detectorMAC = detector_mac; + FILE_LOG(logINFO) << detId << ": Detector MAC updated to " << getDetectorMAC(); } - - if (detector_shm()->detectorIP != idetectorip) { - std::cout << "idetectorip: " << idetectorip << '\n'; - detector_shm()->detectorIP = idetectorip; + + if (detector_shm()->detectorIP != detector_ip) { + detector_shm()->detectorIP = detector_ip; FILE_LOG(logINFO) << detId << ": Detector IP updated to " << getDetectorIP(); + std::cout << "ip: " << detector_ip << "\n"; } } if (ret == FORCE_UPDATE) { @@ -1738,7 +1713,8 @@ int64_t slsDetector::setTimer(timerIndex index, int64_t t) { ret = client.sendCommandThenRead(fnum, args, sizeof(args), &retval, sizeof(retval)); FILE_LOG(logDEBUG1) << getTimerType(index) << ": " << retval; detector_shm()->timerValue[index] = retval; - // update #nchans and databytes, as it depends on #samples, roi, readoutflags (ctb only) + // update #nchans and databytes, as it depends on #samples, roi, + // readoutflags (ctb only) if (index == SAMPLES && (detector_shm()->myDetectorType == CHIPTESTBOARD || detector_shm()->myDetectorType == MOENCH)) { updateTotalNumberOfChannels(); @@ -1992,7 +1968,8 @@ int slsDetector::setReadOutFlags(readOutFlags flag) { ret = client.sendCommandThenRead(fnum, &arg, sizeof(arg), &retval, sizeof(retval)); FILE_LOG(logDEBUG1) << "Readout flag: " << retval; detector_shm()->roFlags = (readOutFlags)retval; - // update #nchans and databytes, as it depends on #samples, roi, readoutflags (ctb only) + // update #nchans and databytes, as it depends on #samples, roi, + // readoutflags (ctb only) if (detector_shm()->myDetectorType == CHIPTESTBOARD) { updateTotalNumberOfChannels(); } @@ -2088,17 +2065,17 @@ std::string slsDetector::setDetectorMAC(const std::string &detectorMAC) { } // valid format else { - sls::strcpy_safe(detector_shm()->detectorMAC, detectorMAC.c_str()); + detector_shm()->detectorMAC = MacStringToUint(detectorMAC); if (!strcmp(detector_shm()->receiver_hostname, "none")) { FILE_LOG(logDEBUG1) << "Receiver hostname not set yet"; } else if (setUDPConnection() == FAIL) { FILE_LOG(logWARNING) << "UDP connection set up failed"; } } - return std::string(detector_shm()->detectorMAC); + return getDetectorMAC(); } -std::string slsDetector::getDetectorMAC() { return std::string(detector_shm()->detectorMAC); } +std::string slsDetector::getDetectorMAC() { return MacAddrToString(detector_shm()->detectorMAC); } std::string slsDetector::setDetectorMAC2(const std::string &detectorMAC) { // invalid format @@ -2108,17 +2085,17 @@ std::string slsDetector::setDetectorMAC2(const std::string &detectorMAC) { } // valid format else { - sls::strcpy_safe(detector_shm()->detectorMAC2, detectorMAC.c_str()); + detector_shm()->detectorMAC2 = MacStringToUint(detectorMAC); if (!strcmp(detector_shm()->receiver_hostname, "none")) { FILE_LOG(logDEBUG1) << "Receiver hostname not set yet"; } else if (setUDPConnection() == FAIL) { FILE_LOG(logWARNING) << "UDP connection set up failed"; } } - return std::string(detector_shm()->detectorMAC2); + return getDetectorMAC2(); } -std::string slsDetector::getDetectorMAC2() { return std::string(detector_shm()->detectorMAC2); } +std::string slsDetector::getDetectorMAC2() { return MacAddrToString(detector_shm()->detectorMAC2); } std::string slsDetector::setDetectorIP(const std::string &detectorIP) { // struct sockaddr_in sa; @@ -2126,8 +2103,8 @@ std::string slsDetector::setDetectorIP(const std::string &detectorIP) { if (detectorIP.length() && detectorIP.length() < INET_ADDRSTRLEN) { int result = inet_pton(AF_INET, detectorIP.c_str(), &ip); if (result == 0) { - throw RuntimeError( - "setDetectorIP: IP Address should be VALID and in xxx.xxx.xxx.xxx format"); + throw RuntimeError("setDetectorIP: IP Address should be VALID and " + "in xxx.xxx.xxx.xxx format"); } else { detector_shm()->detectorIP = ip; if (!strcmp(detector_shm()->receiver_hostname, "none")) { @@ -2151,8 +2128,8 @@ std::string slsDetector::setDetectorIP2(const std::string &detectorIP) { if (detectorIP.length() && detectorIP.length() < 16) { int result = inet_pton(AF_INET, detectorIP.c_str(), &ip); if (result == 0) { - throw RuntimeError( - "setDetectorIP: IP Address 2 should be VALID and in xxx.xxx.xxx.xxx format"); + throw RuntimeError("setDetectorIP: IP Address 2 should be VALID " + "and in xxx.xxx.xxx.xxx format"); } else { detector_shm()->detectorIP2 = ip; if (!strcmp(detector_shm()->receiver_hostname, "none")) { @@ -2298,14 +2275,14 @@ std::string slsDetector::getReceiverHostname() const { } std::string slsDetector::setReceiverUDPIP(const std::string &udpip) { - struct sockaddr_in sa; + if (udpip.length() && udpip.length() < 16) { - int result = inet_pton(AF_INET, udpip.c_str(), &(sa.sin_addr)); - if (result == 0) { - throw ReceiverError( - "setReceiverUDPIP: UDP IP Address should be VALID and in xxx.xxx.xxx.xxx format"); + auto ip = IpStringToUint(udpip.c_str()); + if (ip == 0) { + throw ReceiverError("setReceiverUDPIP: UDP IP Address should be " + "VALID and in xxx.xxx.xxx.xxx format"); } else { - sls::strcpy_safe(detector_shm()->receiverUDPIP, udpip.c_str()); + detector_shm()->receiverUDPIP = ip; if (!strcmp(detector_shm()->receiver_hostname, "none")) { FILE_LOG(logDEBUG1) << "Receiver hostname not set yet"; } else if (setUDPConnection() == FAIL) { @@ -2313,22 +2290,21 @@ std::string slsDetector::setReceiverUDPIP(const std::string &udpip) { } } } - return std::string(detector_shm()->receiverUDPIP); + return getReceiverUDPIP(); } std::string slsDetector::getReceiverUDPIP() const { - return std::string(detector_shm()->receiverUDPIP); + return IpToString(detector_shm()->receiverUDPIP); } std::string slsDetector::setReceiverUDPIP2(const std::string &udpip) { - struct sockaddr_in sa; if (udpip.length() && udpip.length() < 16) { - int result = inet_pton(AF_INET, udpip.c_str(), &(sa.sin_addr)); - if (result == 0) { - throw ReceiverError( - "setReceiverUDPIP: UDP IP Address 2 should be VALID and in xxx.xxx.xxx.xxx format"); + auto ip = IpStringToUint(udpip.c_str()); + if (ip == 0) { + throw ReceiverError("setReceiverUDPIP: UDP IP Address 2 should be " + "VALID and in xxx.xxx.xxx.xxx format"); } else { - sls::strcpy_safe(detector_shm()->receiverUDPIP2, udpip.c_str()); + detector_shm()->receiverUDPIP2 = ip; if (!strcmp(detector_shm()->receiver_hostname, "none")) { FILE_LOG(logDEBUG1) << "Receiver hostname not set yet"; } else if (setUDPConnection() == FAIL) { @@ -2336,57 +2312,37 @@ std::string slsDetector::setReceiverUDPIP2(const std::string &udpip) { } } } - return std::string(detector_shm()->receiverUDPIP2); + return getReceiverUDPIP2(); } std::string slsDetector::getReceiverUDPIP2() const { - return std::string(detector_shm()->receiverUDPIP2); + return IpToString(detector_shm()->receiverUDPIP2); } std::string slsDetector::setReceiverUDPMAC(const std::string &udpmac) { - // invalid format - if ((udpmac.length() != 17) || (udpmac[2] != ':') || (udpmac[5] != ':') || (udpmac[8] != ':') || - (udpmac[11] != ':') || (udpmac[14] != ':')) { - throw ReceiverError( - "setReceiverUDPMAC: udp MAC Address should be in xx:xx:xx:xx:xx:xx format"); + auto mac = MacStringToUint(udpmac); + if (mac == 0) { + throw ReceiverError("Could not decode UDPMAC from: " + udpmac); } - // valid format - else { - sls::strcpy_safe(detector_shm()->receiverUDPMAC, udpmac.c_str()); - if (!strcmp(detector_shm()->receiver_hostname, "none")) { - FILE_LOG(logDEBUG1) << "Receiver hostname not set yet"; - } - // not doing setUDPConnection as rx_udpmac will get replaced,(must use configuremac) - sls::strcpy_safe(detector_shm()->receiverUDPMAC, udpmac.c_str()); - } - return std::string(detector_shm()->receiverUDPMAC); + detector_shm()->receiverUDPMAC = mac; + return getReceiverUDPMAC(); } std::string slsDetector::getReceiverUDPMAC() const { - return std::string(detector_shm()->receiverUDPMAC); + return MacAddrToString(detector_shm()->receiverUDPMAC); } std::string slsDetector::setReceiverUDPMAC2(const std::string &udpmac) { - // invalid format - if ((udpmac.length() != 17) || (udpmac[2] != ':') || (udpmac[5] != ':') || (udpmac[8] != ':') || - (udpmac[11] != ':') || (udpmac[14] != ':')) { - throw ReceiverError( - "setReceiverUDPMAC: udp MAC Address 2 should be in xx:xx:xx:xx:xx:xx format"); + auto mac = MacStringToUint(udpmac); + if (mac == 0) { + throw ReceiverError("Could not decode UDPMA2C from: " + udpmac); } - // valid format - else { - sls::strcpy_safe(detector_shm()->receiverUDPMAC2, udpmac.c_str()); - if (!strcmp(detector_shm()->receiver_hostname, "none")) { - FILE_LOG(logDEBUG1) << "Receiver hostname not set yet"; - } - // not doing setUDPConnection as rx_udpmac will get replaced,(must use configuremac) - sls::strcpy_safe(detector_shm()->receiverUDPMAC2, udpmac.c_str()); - } - return std::string(detector_shm()->receiverUDPMAC2); + detector_shm()->receiverUDPMAC2 = mac; + return getReceiverUDPMAC2(); } std::string slsDetector::getReceiverUDPMAC2() const { - return std::string(detector_shm()->receiverUDPMAC2); + return MacAddrToString(detector_shm()->receiverUDPMAC2); } int slsDetector::setReceiverUDPPort(int udpport) { @@ -2494,7 +2450,8 @@ void slsDetector::setReceiverStreamingIP(std::string sourceIP) { // if empty, give rx_hostname if (sourceIP.empty()) { if (!strcmp(detector_shm()->receiver_hostname, "none")) { - throw RuntimeError("Receiver hostname not set yet. Cannot create rx_zmqip from none"); + throw RuntimeError("Receiver hostname not set yet. Cannot create " + "rx_zmqip from none"); } sourceIP.assign(detector_shm()->receiver_hostname); } @@ -2604,18 +2561,20 @@ std::string slsDetector::setAdditionalJsonParameter(const std::string &key, const std::string &value) { // validation (value or key is empty) if (!key.length() || !value.length()) { - throw("Could not set additional json header parameter as the key or value is empty"); + throw("Could not set additional json header parameter as the key or " + "value is empty"); } // validation (ignore if key or value has , : ") if (key.find_first_of(",\":") != std::string::npos || value.find_first_of(",\":") != std::string::npos) { - throw RuntimeError("Could not set additional json header parameter as the key or value has " + throw RuntimeError("Could not set additional json header parameter as " + "the key or value has " "illegal characters (,\":)"); } - // create actual key to search for and actual value to put, (key has additional ':' as value - // could exist the same way) + // create actual key to search for and actual value to put, (key has + // additional ':' as value could exist the same way) std::string keyLiteral(std::string("\"") + key + std::string("\":")); std::string valueLiteral(value); // add quotations to value only if it is a string @@ -2634,7 +2593,8 @@ std::string slsDetector::setAdditionalJsonParameter(const std::string &key, if (keyPos != std::string::npos) { size_t valueStartPos = header.find(std::string(":"), keyPos) + 1; size_t valueEndPos = header.find(std::string(","), valueStartPos) - 1; - // if valueEndPos doesnt find comma (end of string), it goes anyway to end of line + // if valueEndPos doesnt find comma (end of string), it goes anyway to + // end of line header.replace(valueStartPos, valueEndPos - valueStartPos + 1, valueLiteral); } @@ -2730,41 +2690,27 @@ int slsDetector::setUDPConnection() { FILE_LOG(logDEBUG1) << "Receiver hostname not set yet."; return FAIL; } - // if no udp ip given, use hostname - if (!strcmp(detector_shm()->receiverUDPIP, "none")) { - // hostname is an ip address - if (strchr(detector_shm()->receiver_hostname, '.') != nullptr) { - sls::strcpy_safe(detector_shm()->receiverUDPIP, detector_shm()->receiver_hostname); - // if hostname not ip, convert it to ip - } else { - struct addrinfo *result; - if (sls::ConvertHostnameToInternetAddress(detector_shm()->receiver_hostname, &result) == - 0) { - // on success - memset(detector_shm()->receiverUDPIP, 0, MAX_STR_LENGTH); - // on failure, back to none - if (sls::ConvertInternetAddresstoIpString(result, detector_shm()->receiverUDPIP, - MAX_STR_LENGTH)) { - sls::strcpy_safe(detector_shm()->receiverUDPIP, "none"); - throw RuntimeError("setUDPConnection: Error. Receiver UDP IP Address not set"); - } - } + + if (detector_shm()->receiverUDPIP == 0) { + // Hostname could be ip try to decode otherwise look up the hostname + detector_shm()->receiverUDPIP = IpStringToUint(detector_shm()->receiver_hostname); + if (detector_shm()->receiverUDPIP == 0) { + detector_shm()->receiverUDPIP = HostnameToIp(detector_shm()->receiver_hostname); } } - - // jungfrau 2 interfaces or (1 interface and 2nd interface), copy udpip if udpip2 empty + // jungfrau 2 interfaces or (1 interface and 2nd interface), copy udpip if + // udpip2 empty if (detector_shm()->numUDPInterfaces == 2 || detector_shm()->selectedUDPInterface == 2) { - // copy from udpip - if (!strcmp(detector_shm()->receiverUDPIP2, "none")) { - sls::strcpy_safe(detector_shm()->receiverUDPIP2, detector_shm()->receiverUDPIP); + if (detector_shm()->receiverUDPIP2 == 0) { + detector_shm()->receiverUDPIP2 = detector_shm()->receiverUDPIP; } } // copy arguments to args[][] snprintf(args[0], sizeof(args[0]), "%d", detector_shm()->numUDPInterfaces); snprintf(args[1], sizeof(args[1]), "%d", detector_shm()->selectedUDPInterface); - sls::strcpy_safe(args[2], detector_shm()->receiverUDPIP); - sls::strcpy_safe(args[3], detector_shm()->receiverUDPIP2); + sls::strcpy_safe(args[2], getReceiverUDPIP().c_str()); + sls::strcpy_safe(args[3], getReceiverUDPIP2().c_str()); snprintf(args[4], sizeof(args[4]), "%d", detector_shm()->receiverUDPPort); snprintf(args[5], sizeof(args[5]), "%d", detector_shm()->receiverUDPPort2); FILE_LOG(logDEBUG1) << "Receiver Number of UDP Interfaces: " @@ -2781,13 +2727,12 @@ int slsDetector::setUDPConnection() { ret = receiver.sendCommandThenRead(fnum, args, sizeof(args), retvals, sizeof(retvals)); if (strlen(retvals[0])) { FILE_LOG(logDEBUG1) << "Receiver UDP MAC returned : " << retvals[0]; - memset(detector_shm()->receiverUDPMAC, 0, MAX_STR_LENGTH); - sls::strcpy_safe(detector_shm()->receiverUDPMAC, retvals[0]); + detector_shm()->receiverUDPMAC = MacStringToUint(retvals[0]); + } if (strlen(retvals[1])) { FILE_LOG(logDEBUG1) << "Receiver UDP MAC2 returned : " << retvals[1]; - memset(detector_shm()->receiverUDPMAC2, 0, MAX_STR_LENGTH); - sls::strcpy_safe(detector_shm()->receiverUDPMAC2, retvals[1]); + detector_shm()->receiverUDPMAC2 = MacStringToUint(retvals[1]); } if (ret == FORCE_UPDATE) { receiver.close(); @@ -2965,7 +2910,8 @@ int slsDetector::setROI(int n, ROI roiLimits[]) { if (detector_shm()->myDetectorType == MOENCH) { sendROIToProcessor(); } - // update #nchans and databytes, as it depends on #samples, roi, readoutflags (ctb only) + // update #nchans and databytes, as it depends on #samples, roi, + // readoutflags (ctb only) if (detector_shm()->myDetectorType == CHIPTESTBOARD || detector_shm()->myDetectorType == MOENCH) { updateTotalNumberOfChannels(); @@ -2976,12 +2922,13 @@ int slsDetector::setROI(int n, ROI roiLimits[]) { slsDetectorDefs::ROI *slsDetector::getROI(int &n) { sendROI(-1, nullptr); n = detector_shm()->nROI; - // moench - get json header(due to different clients, diff shm) (get roi is from detector: - // updated anyway) + // moench - get json header(due to different clients, diff shm) (get roi is + // from detector: updated anyway) if (detector_shm()->myDetectorType == MOENCH) { getAdditionalJsonHeader(); } - // update #nchans and databytes, as it depends on #samples, roi, readoutflags (ctb only) + // update #nchans and databytes, as it depends on #samples, roi, + // readoutflags (ctb only) if (detector_shm()->myDetectorType == CHIPTESTBOARD || detector_shm()->myDetectorType == MOENCH) { updateTotalNumberOfChannels(); @@ -3171,7 +3118,8 @@ int slsDetector::setFlippedData(dimension d, int value) { throw RuntimeError("Flipped across Y axis is not implemented"); } - // replace get with shm value (write to shm right away as it is a det value, not rx value) + // replace get with shm value (write to shm right away as it is a det value, + // not rx value) if (value > -1) { detector_shm()->flippedData[d] = (value > 0) ? 1 : 0; } @@ -3405,9 +3353,9 @@ int slsDetector::programFPGA(const std::string &fname) { int dst = mkstemp(destfname); // create temporary file and open it in r/w if (dst == -1) { fclose(src); - throw RuntimeError( - std::string("Could not create destination file in /tmp for programming: ") + - destfname); + throw RuntimeError(std::string("Could not create destination file " + "in /tmp for programming: ") + + destfname); } // convert src to dst rawbin @@ -3438,7 +3386,8 @@ int slsDetector::programFPGA(const std::string &fname) { write(dst, &y, 1); } if (filepos < 0x1000000) { - throw RuntimeError("Could not convert programming file. EOF before end of flash"); + throw RuntimeError("Could not convert programming file. EOF " + "before end of flash"); } } if (fclose(src)) { @@ -3473,7 +3422,8 @@ int slsDetector::programFPGA(const std::string &fname) { if (fclose(fp)) { free(fpgasrc); - throw RuntimeError("Program FPGA: Could not close destination file after converting"); + throw RuntimeError("Program FPGA: Could not close destination file " + "after converting"); } unlink(destfname); // delete temporary file FILE_LOG(logDEBUG1) << "Successfully loaded the rawbin file to program memory"; @@ -3775,7 +3725,6 @@ int slsDetector::setReceiverOnline(int value) { detector_shm()->receiverTCPPort); receiver.close(); detector_shm()->receiverOnlineFlag = ONLINE_FLAG; - // check for version compatibility if (detector_shm()->receiverAPIVersion == 0) { checkReceiverVersionCompatibility(); @@ -4501,7 +4450,8 @@ int slsDetector::setPattern(const std::string &fname) { FILE *fd = fopen(fname.c_str(), "r"); if (fd != nullptr) { while (fread(&word, sizeof(word), 1, fd)) { - setPatternWord(addr, word); // TODO! (Erik) do we need to send pattern in 64bit chunks? + setPatternWord(addr, word); // TODO! (Erik) do we need to send + // pattern in 64bit chunks? ++addr; } fclose(fd); @@ -4852,7 +4802,8 @@ slsDetector::readSettingsFile(const std::string &fname, sls_detector_module *myM deleteModule(myMod); } infile.close(); - throw RuntimeError("readSettingsFile: Could not load all values for settings for " + + throw RuntimeError("readSettingsFile: Could not load all values " + "for settings for " + fname); } for (int i = 0; i < myMod->ndac; ++i) { diff --git a/slsSupportLib/CMakeLists.txt b/slsSupportLib/CMakeLists.txt index 08e39c177..471fc9306 100644 --- a/slsSupportLib/CMakeLists.txt +++ b/slsSupportLib/CMakeLists.txt @@ -7,6 +7,7 @@ set(SOURCES src/DataSocket.cpp src/ServerSocket.cpp src/ServerInterface.cpp + src/network_utils.cpp ) set(HEADERS @@ -30,6 +31,7 @@ set(PUBLICHEADERS include/DataSocket.h include/ServerSocket.h include/ServerInterface.h + include/network_utils.h ) add_library(slsSupportLib SHARED diff --git a/slsSupportLib/include/logger.h b/slsSupportLib/include/logger.h index 6f1dcb8f1..2be26378a 100644 --- a/slsSupportLib/include/logger.h +++ b/slsSupportLib/include/logger.h @@ -17,7 +17,7 @@ #endif #ifndef FILELOG_MAX_LEVEL -#define FILELOG_MAX_LEVEL logDEBUG1 +#define FILELOG_MAX_LEVEL logINFO #endif diff --git a/slsSupportLib/include/network_utils.h b/slsSupportLib/include/network_utils.h new file mode 100644 index 000000000..0f274d998 --- /dev/null +++ b/slsSupportLib/include/network_utils.h @@ -0,0 +1,14 @@ +#pragma once +#include + +namespace sls { + +std::string MacAddrToString(uint64_t mac); +uint64_t MacStringToUint(std::string mac); + +uint32_t IpStringToUint(const char* ipstr); +std::string IpToString(uint32_t ip); + +uint32_t HostnameToIp(const char *const hostname); + +} // namespace sls diff --git a/slsSupportLib/src/DataSocket.cpp b/slsSupportLib/src/DataSocket.cpp index cbc9119e2..2991ff21e 100644 --- a/slsSupportLib/src/DataSocket.cpp +++ b/slsSupportLib/src/DataSocket.cpp @@ -81,7 +81,7 @@ void DataSocket::close() { if(::close(socketId_)){ throw SocketError("could not close socket"); } - socketId_ = 0; + socketId_ = -1; } else { throw std::runtime_error("Socket ERROR: close called on bad socket\n"); diff --git a/slsSupportLib/src/network_utils.cpp b/slsSupportLib/src/network_utils.cpp new file mode 100644 index 000000000..3d7fa26a3 --- /dev/null +++ b/slsSupportLib/src/network_utils.cpp @@ -0,0 +1,69 @@ +#include "sls_detector_exceptions.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace sls { + +std::string MacAddrToString(uint64_t mac) { + std::ostringstream ss; + ss << std::hex << std::setfill('0') << std::setw(2); + ss << ((mac >> 40) & 0xFF); + for (int i = 32; i >= 0; i -= 8) { + ss << ':' << ((mac >> i) & 0xFF); + } + return ss.str(); +} + +uint64_t MacStringToUint(std::string mac) { + if ((mac.length() != 17) || (mac[2] != ':') || (mac[5] != ':') || (mac[8] != ':') || + (mac[11] != ':') || (mac[14] != ':')) { + return 0; + } + mac.erase(std::remove(mac.begin(), mac.end(), ':'), mac.end()); + return std::stol(mac, nullptr, 16); +} + +uint32_t IpStringToUint(const char *ipstr) { + uint32_t ip{0}; + inet_pton(AF_INET, ipstr, &ip); + return ip; +} + +std::string IpToString(uint32_t ip) { + char ipstring[INET_ADDRSTRLEN]; + if (inet_ntop(AF_INET, &ip, ipstring, INET_ADDRSTRLEN) == nullptr) { + // handle error + } + // TODO! Check return + return ipstring; +} + +uint32_t HostnameToIp(const char *const hostname) { + struct addrinfo hints, *result; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + if (getaddrinfo(hostname, NULL, &hints, &result)) { + freeaddrinfo(result); + throw RuntimeError("Could not convert hostname to ip"); + } + uint32_t ip = ((struct sockaddr_in *)result->ai_addr)->sin_addr.s_addr; + freeaddrinfo(result); + return ip; +} + +} // namespace sls + +// char ipstring[INET_ADDRSTRLEN]; +// inet_ntop(AF_INET, &detector_shm()->detectorIP, ipstring, INET_ADDRSTRLEN); + +// inet_pton(AF_INET, DEFAULT_DET_IP, &(detector_shm()->detectorIP)); \ No newline at end of file diff --git a/slsSupportLib/tests/CMakeLists.txt b/slsSupportLib/tests/CMakeLists.txt index f46e60a68..a26b0c69c 100644 --- a/slsSupportLib/tests/CMakeLists.txt +++ b/slsSupportLib/tests/CMakeLists.txt @@ -10,6 +10,7 @@ set(SOURCES test-ClientInterface.cpp test-CmdLineParser.cpp test-container_utils.cpp + test-network_utils.cpp test-string_utils.cpp test-Timer.cpp ) diff --git a/slsSupportLib/tests/test-network_utils.cpp b/slsSupportLib/tests/test-network_utils.cpp new file mode 100644 index 000000000..f363f4e39 --- /dev/null +++ b/slsSupportLib/tests/test-network_utils.cpp @@ -0,0 +1,44 @@ + +#include "catch.hpp" +#include "network_utils.h" +#include +#include + +#include "string_utils.h" + +using namespace sls; +TEST_CASE("Convert mac address") { + + std::vector vec_addr{346856806822, 346856806852, 262027939863028}; + std::vector vec_ans{"00:50:c2:46:d9:a6", "00:50:c2:46:d9:c4", "ee:50:22:46:d9:f4"}; + for (int i = 0; i != vec_addr.size(); ++i) { + auto mac = vec_addr[i]; + auto answer = vec_ans[i]; + + std::string string_addr = MacAddrToString(mac); + CHECK(string_addr == answer); + CHECK(MacStringToUint(string_addr) == mac); + } +} + +TEST_CASE("Convert IP"){ + std::vector vec_addr{4073554305, 2747957633, 2697625985}; + std::vector vec_ans{"129.129.205.242", "129.129.202.163", "129.129.202.160"}; + + for (int i=0; i!= vec_addr.size(); ++i){ + auto ip = vec_addr[i]; + auto answer = vec_ans[i]; + + auto string_addr = IpToString(ip); + CHECK(string_addr == answer); + CHECK(IpStringToUint(string_addr.c_str()) == ip); + } +} + +TEST_CASE("IP not valid"){ + + CHECK(IpStringToUint("hej") == 0); + CHECK(IpStringToUint("mpc2408") == 0); +} + +// TEST_CASE("Lookup ip") \ No newline at end of file