merge resolved

This commit is contained in:
2019-06-11 15:56:13 +02:00
27 changed files with 5419 additions and 4660 deletions

1264
catch/clara.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -331,11 +331,12 @@ where the {\tt{GapPixelsBetweenModules\_x}} are the one on the short side of the
IMPORTANT: to have faster readout and smaller dead time, one can configure {\tt{clkdivider}}, i.e. the speed at which the data are read, i.e. 200/100/50~MHz for {\tt{clkdivider 0/1/2}} and the dead time between frames through {\tt{flags parallel}}, i.e. acquire and read at the same time or acquire and then read out. IMPORTANT: to have faster readout and smaller dead time, one can configure {\tt{clkdivider}}, i.e. the speed at which the data are read, i.e. 200/100/50~MHz for {\tt{clkdivider 0/1/2}} and the dead time between frames through {\tt{flags parallel}}, i.e. acquire and read at the same time or acquire and then read out.
The configuration of this timing variables allows to achieve different frame rates. NOTE THAT IN EIGER, WHATEVER YOU DO, THE FRAME RATE LIMITATIONS COME FROM THE NETWORK BOTTLENECK AS THE HARDWARE GOES FASTER THAN THE DATA OUT. The configuration of this timing variables allows to achieve different frame rates. NOTE THAT IN EIGER, WHATEVER YOU DO, THE FRAME RATE LIMITATIONS COME FROM THE NETWORK BOTTLENECK AS THE HARDWARE GOES FASTER THAN THE DATA OUT.
In the case of REAL CONTINUOUS readout, i.e. continuous acquire and readout from the boards (independent on how the chip is set), the continuous frame rates are listed in table~\ref{tcont}. The time to send out the frame out of the board In the case of REAL CONTINUOUS readout, i.e. continuous acquire and readout from the boards (independent on how the chip is set), the continuous frame rates are listed in table~\ref{tcont}. The time to send out the frame out of the board are also listed there.
\begin{table} \begin{table}
\begin{tabular}{|c|c|c|c|c|} \begin{tabular}{|c|c|c|c|c|}
\hline \hline
GbE & dynamic range & continuos maximum frame rate(Hz) & minimum period ($\mu$s)& time to send out data ($\mu$s)\\ \tiny{GbE} & \tiny{dynamic range} & \tiny{continuos maximum frame rate(Hz)} & \tiny{minimum period ($\mu$s)}& \tiny{time to send out data ($\mu$s)}\\
\hline \hline
1 & 16 & \textbf{256} & 3901 & \\ 1 & 16 & \textbf{256} & 3901 & \\
\hline \hline
@ -347,10 +348,10 @@ GbE & dynamic range & continuos maximum frame rate(Hz) & minimum period ($\mu$s)
\hline \hline
10 & 16 & \textbf{2560} & 391 & 400\\ 10 & 16 & \textbf{2560} & 391 & 400\\
\hline \hline
10 & 32 & \textbf{1280}& 782 & 800\\ 10 & 32 & \textbf{1280} (675~Hz max)& 782 & 800\\
\hline \hline
\end{tabular} \end{tabular}
\caption{Frame rate limits for the CONTINUOS streaming out of images, i.e. the data rate out is just below 1Gb/s or 10Gb/s.} \caption{Frame rate limits for the CONTINUOS streaming out of images, i.e. the data rate out is just below 1Gb/s or 10Gb/s. 1280~Hz for 32-bit, 10GbE is obtained from the 10GbE limitation. The maximum achievable frame rate is 675~Hz.}
\label{tcont}\end{table} \label{tcont}\end{table}
Note that in the {\tt{continuous}} flag mode, some buffering is still done on the memories, so a higher frame rate than the proper real continuous one can be achieved. Still, this extra buffering is possible till the memories are not saturated. The number of images that can be stored on the DDR2 on board memories are listed in table~\ref{timgs}. Note that in the {\tt{continuous}} flag mode, some buffering is still done on the memories, so a higher frame rate than the proper real continuous one can be achieved. Still, this extra buffering is possible till the memories are not saturated. The number of images that can be stored on the DDR2 on board memories are listed in table~\ref{timgs}.
\begin{table} \begin{table}
@ -455,13 +456,14 @@ In general, choose the maximum frame rate you want to aim, not exceeding what yo
Here below are the final tables for settting the detcetor correctly: Here below are the final tables for settting the detcetor correctly:
\begin{itemize} \begin{itemize}
\item CONTINUOUS redout (imagesnot stored on board memories, frames can be achieved. {\tt{flags parallel}}, {\tt{clkdivider 0}} are always set. In 32-bit no extra {\tt{subdeadtime}} is assumed. The difference between {\tt{exptime}} and {\tt{period}} has to be $\approx$5 $\mu$s: \item CONTINUOUS readout: Images are taken, passed on memories and streamed out through the 1Gb/10Gb Ethernet. Note that you will always pass from the memories even if you require a frame rate that is lower than the 10Gb limitation.
{\tt{flags continuos parallel}}, {\tt{clkdivider 0}} are always set. In 32-bit no extra {\tt{subdeadtime}} is assumed. The difference between {\tt{exptime}} and {\tt{period}} has to be $\approx$5 $\mu$s:
\begin{center} \begin{center}
\begin{tabular}{ |c| c| } \begin{tabular}{ |c| c| }
\hline \hline
max frame rate & settings\\ max frame rate & settings\\
\hline \hline
\textcolor{red}{170 Hz} & \textcolor{red}{32-bit} \\ \textcolor{red}{189~Hz (977~Hz max)} & \textcolor{red}{32-bit} \\
& Nframes=infinite\\ & Nframes=infinite\\
\hline \hline
\textcolor{red}{2.56 kHz} & \textcolor{red}{16-bit}\\ \textcolor{red}{2.56 kHz} & \textcolor{red}{16-bit}\\
@ -477,13 +479,13 @@ Here below are the final tables for settting the detcetor correctly:
\end{center} \end{center}
BE CAREFUL that if you have the transmission delays setup (see sec.~\ref{network}), this will slow down the sending of the data and you risk to fill up the memories of the boards on eiger (30000 images in 4 bit mode) and you will get corrupted data (parts of the memory on the boads will be overwritten). BE CAREFUL that if you have the transmission delays setup (see sec.~\ref{network}), this will slow down the sending of the data and you risk to fill up the memories of the boards on eiger (30000 images in 4 bit mode) and you will get corrupted data (parts of the memory on the boads will be overwritten).
\item BUFFERED readout (images stored on board memories, such that the maximum frame rate can be achieved for a limited amount of frames. {\tt{flags parallel}}, {\tt{clkdivider 0}} are always set. In 32-bit no extra {\tt{subdeadtime}} is assumed. The difference between {\tt{exptime}} and {\tt{period}} has to be $\approx$5 $\mu$s: \item BUFFERED readout (images stored on board memories, such that the maximum frame rate can be achieved for a limited amount of frames. {\tt{flags continuous parallel}}, {\tt {clkdivider 0}} are always set. In 32-bit no extra {\tt{subdeadtime}} is assumed. The difference between {\tt{exptime}} and {\tt{period}} has to be $\approx$5 $\mu$s:
\begin{center} \begin{center}
\begin{tabular}{ |c| c| } \begin{tabular}{ |c| c| }
\hline \hline
max frame rate & settings\\ max frame rate & settings\\
\hline \hline
\textcolor{red}{170 Hz} & \textcolor{red}{32-bit} \\ \textcolor{red}{189~Hz (977~Hz)} & \textcolor{red}{32-bit} \\
& Nframes=infinite\\ & Nframes=infinite\\
\hline \hline
\textcolor{red}{6.1 kHz} & \textcolor{red}{16-bit}\\ \textcolor{red}{6.1 kHz} & \textcolor{red}{16-bit}\\
@ -500,7 +502,6 @@ BE CAREFUL that if you have the transmission delays setup (see sec.~\ref{network
\end{itemize} \end{itemize}
\subsubsection{4 and 8 bit mode} \subsubsection{4 and 8 bit mode}
In {\tt{parallel}} mode, the minimum time between frames is due to the time required to latch the values of the counter with capacitors. These values are determined in firmware and they can be estimated as: In {\tt{parallel}} mode, the minimum time between frames is due to the time required to latch the values of the counter with capacitors. These values are determined in firmware and they can be estimated as:
@ -539,14 +540,16 @@ The time between 12-bit subframes are listed in table~\ref{t32bitframe}.
\begin{flushleft} \begin{flushleft}
\begin{tabular}{|c|c|c|c|c|c|} \begin{tabular}{|c|c|c|c|c|c|}
\hline \hline
\tiny{dr} & \tiny{clkdivider} & \tiny{flags} & \tiny{t difference between subframes($\mu$s)} & \tiny{max internal subframe rate (kHz)} & \tiny{maximum frame rate (Hz)}\\ \tiny{dr} & \tiny{clkdivider} & \tiny{flags} & \tiny{subexptime (s)} & \tiny{t difference between subframes($\mu$s)} & \tiny{max internal subframe rate (kHz)} & \tiny{maximum frame rate (Hz)}\\
\hline \hline
32 & 2 & parallel & 12 & 2 & 170\\ 32 & 2 & parallel & 0.00262144 & 12 & 380 & 189\\
\hline \hline
32 & 2 & nonparallel & 504 & $<2$ & 160\\ 32 & 2 & nonparallel & 0.00262144 & 504 & 320 & 160\\
\hline
32 & 2 & parallel & 0.000490 & 12 & 2 & 674\\
\hline \hline
\end{tabular} \end{tabular}
\caption{Timing for the 32bit case. The maximum frame rate has been computed assuming 2 subframes of default {\tt{subexptime}} of 2.62144 ms.} \caption{Timing for the 32bit case. The maximum frame rate has been computed assuming 2 subframes of default {\tt{subexptime}} of 2.62144 ms, which is the default value. By setting up {\tt{subexptime}} to 490~$\mu$s one can achieve a maximum frame rate. Note that one has to leave 490$\mu$s extra between a frame and the following.}
\label{t32bitframe} \label{t32bitframe}
\end{flushleft} \end{flushleft}
\end{table} \end{table}
@ -1582,7 +1585,7 @@ In table~\ref{tframescomplete} is a list of all the readout times in the differe
\hline \hline
8 & 1 & parallel & 6.1 & 5.7 & 181 & 15k/52k\\ 8 & 1 & parallel & 6.1 & 5.7 & 181 & 15k/52k\\
\hline \hline
8 & 1 & nonparallel & 170.5 & 5.7 & 175 & 15k/52k\\ 8 & 1 & nonparallel & 170 & 5.7 & 175 & 15k/52k\\
\hline \hline
8 & 2 & parallel & 11.2 & 2.9 & 342 & infinite\\ 8 & 2 & parallel & 11.2 & 2.9 & 342 & infinite\\
\hline \hline

View File

@ -796,6 +796,10 @@ class multiSlsDetector : public virtual slsDetectorDefs {
*/ */
int getDataBytes(int detPos = -1); int getDataBytes(int detPos = -1);
/**
* Returns the number of detectors in the multi structure*/
size_t size() const{ return detectors.size();}
/** /**
* Set/get dacs value * Set/get dacs value
* @param val value (in V) * @param val value (in V)

View File

@ -16,6 +16,7 @@
class multiSlsDetector; class multiSlsDetector;
class ServerInterface; class ServerInterface;
#define SLS_SHMVERSION 0x190515 #define SLS_SHMVERSION 0x190515
@ -176,10 +177,10 @@ struct sharedSlsDetector {
int rxReadFreq; int rxReadFreq;
/** zmq tcp src ip address in client (only data) **/ /** zmq tcp src ip address in client (only data) **/
char zmqip[MAX_STR_LENGTH]; sls::IpAddr zmqip;
/** zmq tcp src ip address in receiver (only data) **/ /** zmq tcp src ip address in receiver (only data) **/
char rxZmqip[MAX_STR_LENGTH]; sls::IpAddr rxZmqip;
/** gap pixels enable */ /** gap pixels enable */
int gappixels; int gappixels;

View File

@ -348,9 +348,9 @@ void slsDetector::initializeDetectorStructure(detectorType type) {
(detId * ((shm()->myDetectorType == EIGER) ? 2 : 1)); (detId * ((shm()->myDetectorType == EIGER) ? 2 : 1));
shm()->rxUpstream = false; shm()->rxUpstream = false;
shm()->rxReadFreq = 0; shm()->rxReadFreq = 0;
memset(shm()->zmqip, 0, MAX_STR_LENGTH); shm()->zmqip = 0u;
memset(shm()->rxZmqip, 0, MAX_STR_LENGTH); shm()->rxZmqip = 0u;
shm()->gappixels = 0; shm()->gappixels = 0u;
memset(shm()->rxAdditionalJsonHeader, 0, MAX_STR_LENGTH); memset(shm()->rxAdditionalJsonHeader, 0, MAX_STR_LENGTH);
shm()->detectorControlAPIVersion = 0; shm()->detectorControlAPIVersion = 0;
shm()->detectorStopAPIVersion = 0; shm()->detectorStopAPIVersion = 0;
@ -413,7 +413,7 @@ void slsDetector::initializeDetectorStructure(detectorType type) {
// update #nchans and databytes, as it depends on #samples, adcmask, // update #nchans and databytes, as it depends on #samples, adcmask,
// readoutflags (ctb only) // readoutflags (ctb only)
updateTotalNumberOfChannels(); updateTotalNumberOfChannels();
} }
int slsDetector::sendModule(sls_detector_module *myMod, int slsDetector::sendModule(sls_detector_module *myMod,
@ -422,49 +422,49 @@ int slsDetector::sendModule(sls_detector_module *myMod,
FILE_LOG(level) << "Sending Module"; FILE_LOG(level) << "Sending Module";
int ts = 0; int ts = 0;
int n = 0; int n = 0;
n = client.sendData(&(myMod->serialnumber), sizeof(myMod->serialnumber)); n = client.Send(&(myMod->serialnumber), sizeof(myMod->serialnumber));
ts += n; ts += n;
FILE_LOG(level) << "Serial number sent. " << n FILE_LOG(level) << "Serial number sent. " << n
<< " bytes. serialno: " << myMod->serialnumber; << " bytes. serialno: " << myMod->serialnumber;
n = client.sendData(&(myMod->nchan), sizeof(myMod->nchan)); n = client.Send(&(myMod->nchan), sizeof(myMod->nchan));
ts += n; ts += n;
FILE_LOG(level) << "nchan sent. " << n FILE_LOG(level) << "nchan sent. " << n
<< " bytes. serialno: " << myMod->nchan; << " bytes. serialno: " << myMod->nchan;
n = client.sendData(&(myMod->nchip), sizeof(myMod->nchip)); n = client.Send(&(myMod->nchip), sizeof(myMod->nchip));
ts += n; ts += n;
FILE_LOG(level) << "nchip sent. " << n FILE_LOG(level) << "nchip sent. " << n
<< " bytes. serialno: " << myMod->nchip; << " bytes. serialno: " << myMod->nchip;
n = client.sendData(&(myMod->ndac), sizeof(myMod->ndac)); n = client.Send(&(myMod->ndac), sizeof(myMod->ndac));
ts += n; ts += n;
FILE_LOG(level) << "ndac sent. " << n FILE_LOG(level) << "ndac sent. " << n
<< " bytes. serialno: " << myMod->ndac; << " bytes. serialno: " << myMod->ndac;
n = client.sendData(&(myMod->reg), sizeof(myMod->reg)); n = client.Send(&(myMod->reg), sizeof(myMod->reg));
ts += n; ts += n;
FILE_LOG(level) << "reg sent. " << n << " bytes. serialno: " << myMod->reg; FILE_LOG(level) << "reg sent. " << n << " bytes. serialno: " << myMod->reg;
n = client.sendData(&(myMod->iodelay), sizeof(myMod->iodelay)); n = client.Send(&(myMod->iodelay), sizeof(myMod->iodelay));
ts += n; ts += n;
FILE_LOG(level) << "iodelay sent. " << n FILE_LOG(level) << "iodelay sent. " << n
<< " bytes. serialno: " << myMod->iodelay; << " bytes. serialno: " << myMod->iodelay;
n = client.sendData(&(myMod->tau), sizeof(myMod->tau)); n = client.Send(&(myMod->tau), sizeof(myMod->tau));
ts += n; ts += n;
FILE_LOG(level) << "tau sent. " << n << " bytes. serialno: " << myMod->tau; FILE_LOG(level) << "tau sent. " << n << " bytes. serialno: " << myMod->tau;
n = client.sendData(&(myMod->eV), sizeof(myMod->eV)); n = client.Send(&(myMod->eV), sizeof(myMod->eV));
ts += n; ts += n;
FILE_LOG(level) << "ev sent. " << n << " bytes. serialno: " << myMod->eV; FILE_LOG(level) << "ev sent. " << n << " bytes. serialno: " << myMod->eV;
n = client.sendData(myMod->dacs, sizeof(int) * (myMod->ndac)); n = client.Send(myMod->dacs, sizeof(int) * (myMod->ndac));
ts += n; ts += n;
FILE_LOG(level) << "dacs sent. " << n << " bytes"; FILE_LOG(level) << "dacs sent. " << n << " bytes";
if (shm()->myDetectorType == EIGER) { if (shm()->myDetectorType == EIGER) {
n = client.sendData(myMod->chanregs, sizeof(int) * (myMod->nchan)); n = client.Send(myMod->chanregs, sizeof(int) * (myMod->nchan));
ts += n; ts += n;
FILE_LOG(level) << "channels sent. " << n << " bytes"; FILE_LOG(level) << "channels sent. " << n << " bytes";
} }
@ -474,20 +474,19 @@ int slsDetector::sendModule(sls_detector_module *myMod,
int slsDetector::receiveModule(sls_detector_module *myMod, int slsDetector::receiveModule(sls_detector_module *myMod,
sls::ClientSocket &client) { sls::ClientSocket &client) {
int ts = 0; int ts = 0;
ts += ts += client.Receive(&(myMod->serialnumber), sizeof(myMod->serialnumber));
client.receiveData(&(myMod->serialnumber), sizeof(myMod->serialnumber)); ts += client.Receive(&(myMod->nchan), sizeof(myMod->nchan));
ts += client.receiveData(&(myMod->nchan), sizeof(myMod->nchan)); ts += client.Receive(&(myMod->nchip), sizeof(myMod->nchip));
ts += client.receiveData(&(myMod->nchip), sizeof(myMod->nchip)); ts += client.Receive(&(myMod->ndac), sizeof(myMod->ndac));
ts += client.receiveData(&(myMod->ndac), sizeof(myMod->ndac)); ts += client.Receive(&(myMod->reg), sizeof(myMod->reg));
ts += client.receiveData(&(myMod->reg), sizeof(myMod->reg)); ts += client.Receive(&(myMod->iodelay), sizeof(myMod->iodelay));
ts += client.receiveData(&(myMod->iodelay), sizeof(myMod->iodelay)); ts += client.Receive(&(myMod->tau), sizeof(myMod->tau));
ts += client.receiveData(&(myMod->tau), sizeof(myMod->tau)); ts += client.Receive(&(myMod->eV), sizeof(myMod->eV));
ts += client.receiveData(&(myMod->eV), sizeof(myMod->eV));
ts += client.receiveData(myMod->dacs, sizeof(int) * (myMod->ndac)); ts += client.Receive(myMod->dacs, sizeof(int) * (myMod->ndac));
FILE_LOG(logDEBUG1) << "received dacs of size " << ts; FILE_LOG(logDEBUG1) << "received dacs of size " << ts;
if (shm()->myDetectorType == EIGER) { if (shm()->myDetectorType == EIGER) {
ts += client.receiveData(myMod->chanregs, sizeof(int) * (myMod->nchan)); ts += client.Receive(myMod->chanregs, sizeof(int) * (myMod->nchan));
FILE_LOG(logDEBUG1) FILE_LOG(logDEBUG1)
<< "nchans= " << shm()->nChans << " nchips= " << shm()->nChips << "nchans= " << shm()->nChans << " nchips= " << shm()->nChips
<< "mod - nchans= " << myMod->nchan << " nchips= " << myMod->nchip << "mod - nchans= " << myMod->nchan << " nchips= " << myMod->nchip
@ -511,7 +510,7 @@ slsDetectorDefs::detectorType slsDetector::getDetectorTypeFromShm(int multi_id,
std::ostringstream ss; std::ostringstream ss;
ss << "Single shared memory (" << multi_id << "-" << detId ss << "Single shared memory (" << multi_id << "-" << detId
<< ":)version mismatch (expected 0x" << std::hex << SLS_SHMVERSION << ":)version mismatch (expected 0x" << std::hex << SLS_SHMVERSION
<< " but got 0x" << shm()->shmversion << ")" << std::dec << " but got 0x" << shm()->shmversion << ")" << std::dec
<< ". Clear Shared memory to continue."; << ". Clear Shared memory to continue.";
shm.UnmapSharedMemory(); shm.UnmapSharedMemory();
throw SharedMemoryError(ss.str()); throw SharedMemoryError(ss.str());
@ -528,9 +527,9 @@ slsDetector::getTypeFromDetector(const std::string &hostname, int cport) {
detectorType retval = GENERIC; detectorType retval = GENERIC;
FILE_LOG(logDEBUG1) << "Getting detector type "; FILE_LOG(logDEBUG1) << "Getting detector type ";
sls::ClientSocket cs("Detector", hostname, cport); sls::ClientSocket cs("Detector", hostname, cport);
cs.sendData(reinterpret_cast<char *>(&fnum), sizeof(fnum)); cs.Send(reinterpret_cast<char *>(&fnum), sizeof(fnum));
cs.receiveData(reinterpret_cast<char *>(&ret), sizeof(ret)); cs.Receive(reinterpret_cast<char *>(&ret), sizeof(ret));
cs.receiveData(reinterpret_cast<char *>(&retval), sizeof(retval)); cs.Receive(reinterpret_cast<char *>(&retval), sizeof(retval));
FILE_LOG(logDEBUG1) << "Detector type is " << retval; FILE_LOG(logDEBUG1) << "Detector type is " << retval;
return retval; return retval;
} }
@ -591,24 +590,26 @@ void slsDetector::updateTotalNumberOfChannels() {
++nachans; ++nachans;
} }
} }
adatabytes = nachans * (shm()->dynamicRange / 8) * adatabytes = nachans * (shm()->dynamicRange / 8) *
shm()->timerValue[ANALOG_SAMPLES]; shm()->timerValue[ANALOG_SAMPLES];
FILE_LOG(logDEBUG1) FILE_LOG(logDEBUG1) << "#Analog Channels:" << nachans
<< "#Analog Channels:" << nachans << " Databytes: " << adatabytes; << " Databytes: " << adatabytes;
} }
// digital channels (ctb only, digital, analog/digital readout) // digital channels (ctb only, digital, analog/digital readout)
if (shm()->myDetectorType == CHIPTESTBOARD && if (shm()->myDetectorType == CHIPTESTBOARD &&
(((shm()->roFlags & DIGITAL_ONLY) != 0) || ((shm()->roFlags & ANALOG_AND_DIGITAL) != 0))) { (((shm()->roFlags & DIGITAL_ONLY) != 0) ||
((shm()->roFlags & ANALOG_AND_DIGITAL) != 0))) {
ndchans = 64; ndchans = 64;
ddatabytes = (sizeof(uint64_t) * shm()->timerValue[DIGITAL_SAMPLES]); ddatabytes =
(sizeof(uint64_t) * shm()->timerValue[DIGITAL_SAMPLES]);
FILE_LOG(logDEBUG1) << "#Digital Channels:" << ndchans FILE_LOG(logDEBUG1) << "#Digital Channels:" << ndchans
<< " Databytes: " << ddatabytes; << " Databytes: " << ddatabytes;
} }
shm()->nChans = nachans + ndchans; shm()->nChans = nachans + ndchans;
shm()->dataBytes = adatabytes + ddatabytes; shm()->dataBytes = adatabytes + ddatabytes;
FILE_LOG(logDEBUG1) << "# Total #Channels:" << shm()->nChans FILE_LOG(logDEBUG1) << "# Total #Channels:" << shm()->nChans
<< " Databytes: " << shm()->dataBytes; << " Databytes: " << shm()->dataBytes;
} }
} }
@ -788,91 +789,91 @@ int slsDetector::updateDetectorNoWait(sls::ClientSocket &client) {
int n = 0, i32 = 0; int n = 0, i32 = 0;
int64_t i64 = 0; int64_t i64 = 0;
char lastClientIP[INET_ADDRSTRLEN] = {0}; char lastClientIP[INET_ADDRSTRLEN] = {0};
n += client.receiveData(lastClientIP, sizeof(lastClientIP)); n += client.Receive(lastClientIP, sizeof(lastClientIP));
FILE_LOG(logDEBUG1) << "Updating detector last modified by " FILE_LOG(logDEBUG1) << "Updating detector last modified by "
<< lastClientIP; << lastClientIP;
// dr // dr
n += client.receiveData(&i32, sizeof(i32)); n += client.Receive(&i32, sizeof(i32));
shm()->dynamicRange = i32; shm()->dynamicRange = i32;
// databytes // databytes
n += client.receiveData(&i32, sizeof(i32)); n += client.Receive(&i32, sizeof(i32));
shm()->dataBytes = i32; shm()->dataBytes = i32;
// settings // settings
if ((shm()->myDetectorType != CHIPTESTBOARD) && if ((shm()->myDetectorType != CHIPTESTBOARD) &&
(shm()->myDetectorType != MOENCH)) { (shm()->myDetectorType != MOENCH)) {
n += client.receiveData(&i32, sizeof(i32)); n += client.Receive(&i32, sizeof(i32));
shm()->currentSettings = static_cast<detectorSettings>(i32); shm()->currentSettings = static_cast<detectorSettings>(i32);
} }
// threshold // threshold
if (shm()->myDetectorType == EIGER) { if (shm()->myDetectorType == EIGER) {
n += client.receiveData(&i32, sizeof(i32)); n += client.Receive(&i32, sizeof(i32));
shm()->currentThresholdEV = i32; shm()->currentThresholdEV = i32;
} }
// frame number // frame number
n += client.receiveData(&i64, sizeof(i64)); n += client.Receive(&i64, sizeof(i64));
shm()->timerValue[FRAME_NUMBER] = i64; shm()->timerValue[FRAME_NUMBER] = i64;
// exptime // exptime
n += client.receiveData(&i64, sizeof(i64)); n += client.Receive(&i64, sizeof(i64));
shm()->timerValue[ACQUISITION_TIME] = i64; shm()->timerValue[ACQUISITION_TIME] = i64;
// subexptime, subdeadtime // subexptime, subdeadtime
if (shm()->myDetectorType == EIGER) { if (shm()->myDetectorType == EIGER) {
n += client.receiveData(&i64, sizeof(i64)); n += client.Receive(&i64, sizeof(i64));
shm()->timerValue[SUBFRAME_ACQUISITION_TIME] = i64; shm()->timerValue[SUBFRAME_ACQUISITION_TIME] = i64;
n += client.receiveData(&i64, sizeof(i64)); n += client.Receive(&i64, sizeof(i64));
shm()->timerValue[SUBFRAME_DEADTIME] = i64; shm()->timerValue[SUBFRAME_DEADTIME] = i64;
} }
// period // period
n += client.receiveData(&i64, sizeof(i64)); n += client.Receive(&i64, sizeof(i64));
shm()->timerValue[FRAME_PERIOD] = i64; shm()->timerValue[FRAME_PERIOD] = i64;
// delay // delay
if (shm()->myDetectorType != EIGER) { if (shm()->myDetectorType != EIGER) {
n += client.receiveData(&i64, sizeof(i64)); n += client.Receive(&i64, sizeof(i64));
shm()->timerValue[DELAY_AFTER_TRIGGER] = i64; shm()->timerValue[DELAY_AFTER_TRIGGER] = i64;
} }
if (shm()->myDetectorType == JUNGFRAU) { if (shm()->myDetectorType == JUNGFRAU) {
// storage cell // storage cell
n += client.receiveData(&i64, sizeof(i64)); n += client.Receive(&i64, sizeof(i64));
shm()->timerValue[STORAGE_CELL_NUMBER] = i64; shm()->timerValue[STORAGE_CELL_NUMBER] = i64;
// storage cell delay // storage cell delay
n += client.receiveData(&i64, sizeof(i64)); n += client.Receive(&i64, sizeof(i64));
shm()->timerValue[STORAGE_CELL_DELAY] = i64; shm()->timerValue[STORAGE_CELL_DELAY] = i64;
} }
// cycles // cycles
n += client.receiveData(&i64, sizeof(i64)); n += client.Receive(&i64, sizeof(i64));
shm()->timerValue[CYCLES_NUMBER] = i64; shm()->timerValue[CYCLES_NUMBER] = i64;
// readout flags // readout flags
if (shm()->myDetectorType == EIGER || if (shm()->myDetectorType == EIGER ||
shm()->myDetectorType == CHIPTESTBOARD) { shm()->myDetectorType == CHIPTESTBOARD) {
n += client.receiveData(&i32, sizeof(i32)); n += client.Receive(&i32, sizeof(i32));
shm()->roFlags = static_cast<readOutFlags>(i32); shm()->roFlags = static_cast<readOutFlags>(i32);
} }
// roi // roi
if (shm()->myDetectorType == GOTTHARD) { if (shm()->myDetectorType == GOTTHARD) {
n += client.receiveData(&i32, sizeof(i32)); n += client.Receive(&i32, sizeof(i32));
shm()->nROI = i32; shm()->nROI = i32;
for (int i = 0; i < shm()->nROI; ++i) { for (int i = 0; i < shm()->nROI; ++i) {
n += client.receiveData(&i32, sizeof(i32)); n += client.Receive(&i32, sizeof(i32));
shm()->roiLimits[i].xmin = i32; shm()->roiLimits[i].xmin = i32;
n += client.receiveData(&i32, sizeof(i32)); n += client.Receive(&i32, sizeof(i32));
shm()->roiLimits[i].xmax = i32; shm()->roiLimits[i].xmax = i32;
n += client.receiveData(&i32, sizeof(i32)); n += client.Receive(&i32, sizeof(i32));
shm()->roiLimits[i].ymin = i32; shm()->roiLimits[i].ymin = i32;
n += client.receiveData(&i32, sizeof(i32)); n += client.Receive(&i32, sizeof(i32));
shm()->roiLimits[i].xmax = i32; shm()->roiLimits[i].xmax = i32;
} }
} }
@ -880,26 +881,26 @@ int slsDetector::updateDetectorNoWait(sls::ClientSocket &client) {
if (shm()->myDetectorType == CHIPTESTBOARD || if (shm()->myDetectorType == CHIPTESTBOARD ||
shm()->myDetectorType == MOENCH) { shm()->myDetectorType == MOENCH) {
// analog samples // analog samples
n += client.receiveData(&i64, sizeof(i64)); n += client.Receive(&i64, sizeof(i64));
if (i64 >= 0) { if (i64 >= 0) {
shm()->timerValue[ANALOG_SAMPLES] = i64; shm()->timerValue[ANALOG_SAMPLES] = i64;
} }
// digital samples // digital samples
n += client.receiveData(&i64, sizeof(i64)); n += client.Receive(&i64, sizeof(i64));
if (i64 >= 0) { if (i64 >= 0) {
shm()->timerValue[DIGITAL_SAMPLES] = i64; shm()->timerValue[DIGITAL_SAMPLES] = i64;
} }
// adcmask // adcmask
uint32_t u32 = 0; uint32_t u32 = 0;
n += client.receiveData(&u32, sizeof(u32)); n += client.Receive(&u32, sizeof(u32));
shm()->adcEnableMask = u32; shm()->adcEnableMask = u32;
if (shm()->myDetectorType == MOENCH) if (shm()->myDetectorType == MOENCH)
setAdditionalJsonParameter("adcmask", std::to_string(u32)); setAdditionalJsonParameter("adcmask", std::to_string(u32));
// update #nchans and databytes, as it depends on #samples, adcmask, // update #nchans and databytes, as it depends on #samples, adcmask,
// readoutflags // readoutflags
updateTotalNumberOfChannels(); updateTotalNumberOfChannels();
} }
@ -1472,7 +1473,7 @@ int slsDetector::configureMAC() {
ret = client.sendCommandThenRead(fnum, args, sizeof(args), retvals, ret = client.sendCommandThenRead(fnum, args, sizeof(args), retvals,
sizeof(retvals)); sizeof(retvals));
//TODO!(Erik) Send as int already from detector // TODO!(Erik) Send as int already from detector
uint64_t detector_mac = 0; uint64_t detector_mac = 0;
uint32_t detector_ip = 0; uint32_t detector_ip = 0;
sscanf(retvals[0], "%lx", &detector_mac); sscanf(retvals[0], "%lx", &detector_mac);
@ -1537,7 +1538,7 @@ int64_t slsDetector::setTimer(timerIndex index, int64_t t) {
FILE_LOG(logDEBUG1) << getTimerType(index) << ": " << retval; FILE_LOG(logDEBUG1) << getTimerType(index) << ": " << retval;
shm()->timerValue[index] = retval; shm()->timerValue[index] = retval;
// update #nchans and databytes, as it depends on #samples, adcmask, // update #nchans and databytes, as it depends on #samples, adcmask,
// readoutflags // readoutflags
if (index == ANALOG_SAMPLES || index == DIGITAL_SAMPLES) { if (index == ANALOG_SAMPLES || index == DIGITAL_SAMPLES) {
updateTotalNumberOfChannels(); updateTotalNumberOfChannels();
} }
@ -1729,7 +1730,7 @@ int slsDetector::setReadOutFlags(readOutFlags flag) {
FILE_LOG(logDEBUG1) << "Readout flag: " << retval; FILE_LOG(logDEBUG1) << "Readout flag: " << retval;
shm()->roFlags = retval; shm()->roFlags = retval;
// update #nchans and databytes, as it depends on #samples, adcmask, // update #nchans and databytes, as it depends on #samples, adcmask,
// readoutflags // readoutflags
if (shm()->myDetectorType == CHIPTESTBOARD) { if (shm()->myDetectorType == CHIPTESTBOARD) {
updateTotalNumberOfChannels(); updateTotalNumberOfChannels();
} }
@ -1904,7 +1905,7 @@ std::string slsDetector::setReceiverHostname(const std::string &receiverIP) {
<< (shm()->timerValue[SUBFRAME_ACQUISITION_TIME]) << (shm()->timerValue[SUBFRAME_ACQUISITION_TIME])
<< "\nsub dead time:" << (shm()->timerValue[SUBFRAME_DEADTIME]) << "\nsub dead time:" << (shm()->timerValue[SUBFRAME_DEADTIME])
<< "\nasamples:" << (shm()->timerValue[ANALOG_SAMPLES]) << "\nasamples:" << (shm()->timerValue[ANALOG_SAMPLES])
<< "\ndsamples:" << (shm()->timerValue[DIGITAL_SAMPLES]) << "\ndsamples:" << (shm()->timerValue[DIGITAL_SAMPLES])
<< "\ndynamic range:" << shm()->dynamicRange << "\ndynamic range:" << shm()->dynamicRange
<< "\nflippeddatax:" << (shm()->flippedData[X]) << "\nflippeddatax:" << (shm()->flippedData[X])
<< "\nactivated: " << shm()->activated << "\nactivated: " << shm()->activated
@ -1919,8 +1920,7 @@ std::string slsDetector::setReceiverHostname(const std::string &receiverIP) {
<< "\nrx additional json header:" << shm()->rxAdditionalJsonHeader << "\nrx additional json header:" << shm()->rxAdditionalJsonHeader
<< "\nrx_datastream:" << enableDataStreamingFromReceiver(-1) << "\nrx_datastream:" << enableDataStreamingFromReceiver(-1)
<< "\nrx_dbitlistsize:" << shm()->rxDbitList.size() << "\nrx_dbitlistsize:" << shm()->rxDbitList.size()
<< "\nrx_DbitOffset:" << shm()->rxDbitOffset << "\nrx_DbitOffset:" << shm()->rxDbitOffset << std::endl;
<< std::endl;
if (setDetectorType(shm()->myDetectorType) != GENERIC) { if (setDetectorType(shm()->myDetectorType) != GENERIC) {
sendMultiDetectorSize(); sendMultiDetectorSize();
@ -1959,7 +1959,7 @@ std::string slsDetector::setReceiverHostname(const std::string &receiverIP) {
enableTenGigabitEthernet(shm()->tenGigaEnable); enableTenGigabitEthernet(shm()->tenGigaEnable);
setReadOutFlags(GET_READOUT_FLAGS); setReadOutFlags(GET_READOUT_FLAGS);
break; break;
case CHIPTESTBOARD: case CHIPTESTBOARD:
setTimer(ANALOG_SAMPLES, shm()->timerValue[ANALOG_SAMPLES]); setTimer(ANALOG_SAMPLES, shm()->timerValue[ANALOG_SAMPLES]);
setTimer(DIGITAL_SAMPLES, shm()->timerValue[DIGITAL_SAMPLES]); setTimer(DIGITAL_SAMPLES, shm()->timerValue[DIGITAL_SAMPLES]);
@ -1977,8 +1977,8 @@ std::string slsDetector::setReceiverHostname(const std::string &receiverIP) {
break; break;
case GOTTHARD: case GOTTHARD:
sendROI(-1, nullptr); sendROI(-1, nullptr);
break; break;
default: default:
break; break;
@ -2141,25 +2141,17 @@ void slsDetector::setReceiverStreamingPort(int port) {
int slsDetector::getReceiverStreamingPort() { return shm()->rxZmqport; } int slsDetector::getReceiverStreamingPort() { return shm()->rxZmqport; }
void slsDetector::setClientStreamingIP(const std::string &sourceIP) { void slsDetector::setClientStreamingIP(const std::string &sourceIP) {
struct addrinfo *result; auto ip = HostnameToIp(sourceIP.c_str());
// on failure to convert to a valid ip if (ip != 0) {
if (sls::ConvertHostnameToInternetAddress(sourceIP.c_str(), &result) != 0) { shm()->zmqip = ip;
throw RuntimeError("Could not convert zmqip into a valid IP" + } else {
sourceIP); throw sls::RuntimeError("Could not set zmqip");
} }
// on success put IP as std::string into arg
memset(shm()->zmqip, 0, MAX_STR_LENGTH);
sls::ConvertInternetAddresstoIpString(result, shm()->zmqip, MAX_STR_LENGTH);
} }
std::string slsDetector::getClientStreamingIP() { std::string slsDetector::getClientStreamingIP() { return shm()->zmqip.str(); }
return std::string(shm()->zmqip);
}
void slsDetector::setReceiverStreamingIP(std::string sourceIP) { void slsDetector::setReceiverStreamingIP(std::string sourceIP) {
char args[MAX_STR_LENGTH]{};
char retvals[MAX_STR_LENGTH]{};
// if empty, give rx_hostname // if empty, give rx_hostname
if (sourceIP.empty()) { if (sourceIP.empty()) {
if (strcmp(shm()->rxHostname, "none") == 0) { if (strcmp(shm()->rxHostname, "none") == 0) {
@ -2171,40 +2163,28 @@ void slsDetector::setReceiverStreamingIP(std::string sourceIP) {
FILE_LOG(logDEBUG1) << "Sending receiver streaming IP to receiver: " FILE_LOG(logDEBUG1) << "Sending receiver streaming IP to receiver: "
<< sourceIP; << sourceIP;
// verify the ip shm()->rxZmqip = HostnameToIp(sourceIP.c_str());
{
struct addrinfo *result;
// on failure to convert to a valid ip
if (sls::ConvertHostnameToInternetAddress(sourceIP.c_str(), &result) !=
0) {
throw RuntimeError("Could not convert rx_zmqip into a valid IP" +
sourceIP);
}
// on success put IP as std::string into arg
sls::ConvertInternetAddresstoIpString(result, args, sizeof(args));
}
// set it anyway, else it is lost if rx_hostname is not set yet
memset(shm()->rxZmqip, 0, MAX_STR_LENGTH);
sls::strcpy_safe(shm()->rxZmqip, args);
// if zmqip is empty, update it // if zmqip is empty, update it
if (shm()->zmqip != 0u) { if (shm()->zmqip == 0) {
sls::strcpy_safe(shm()->zmqip, args); shm()->zmqip = shm()->rxZmqip;
} }
FILE_LOG(logDEBUG1) << "Sending receiver streaming IP to receiver: "
<< args;
// send to receiver // send to receiver
if (shm()->rxOnlineFlag == ONLINE_FLAG) { if (shm()->rxOnlineFlag == ONLINE_FLAG) {
char retvals[MAX_STR_LENGTH]{};
char args[MAX_STR_LENGTH]{};
sls::strcpy_safe(args, shm()->rxZmqip.str()); //TODO send int
FILE_LOG(logDEBUG1)
<< "Sending receiver streaming IP to receiver: " << args;
sendToReceiver(F_RECEIVER_STREAMING_SRC_IP, args, retvals); sendToReceiver(F_RECEIVER_STREAMING_SRC_IP, args, retvals);
FILE_LOG(logDEBUG1) << "Receiver streaming port: " << retvals; FILE_LOG(logDEBUG1) << "Receiver streaming ip: " << retvals;
memset(shm()->rxZmqip, 0, MAX_STR_LENGTH); shm()->rxZmqip = retvals;
sls::strcpy_safe(shm()->rxZmqip, retvals);
} }
} }
std::string slsDetector::getReceiverStreamingIP() { std::string slsDetector::getReceiverStreamingIP() {
return std::string(shm()->rxZmqip); return shm()->rxZmqip.str();
} }
int slsDetector::setDetectorNetworkParameter(networkParameter index, int slsDetector::setDetectorNetworkParameter(networkParameter index,
@ -2459,13 +2439,13 @@ int slsDetector::sendImageToDetector(imageType index, int16_t imageVals[]) {
if (shm()->onlineFlag == ONLINE_FLAG) { if (shm()->onlineFlag == ONLINE_FLAG) {
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.sendData(&fnum, sizeof(fnum)); client.Send(&fnum, sizeof(fnum));
client.sendData(args, sizeof(args)); client.Send(args, sizeof(args));
client.sendData(imageVals, nChan * sizeof(int16_t)); client.Send(imageVals, nChan * sizeof(int16_t));
client.receiveData(&ret, sizeof(ret)); client.Receive(&ret, sizeof(ret));
if (ret == FAIL) { if (ret == FAIL) {
char mess[MAX_STR_LENGTH]{}; char mess[MAX_STR_LENGTH]{};
client.receiveData(mess, MAX_STR_LENGTH); client.Receive(mess, MAX_STR_LENGTH);
throw DetectorError("Detector " + std::to_string(detId) + throw DetectorError("Detector " + std::to_string(detId) +
" returned error: " + std::string(mess)); " returned error: " + std::string(mess));
} }
@ -2554,32 +2534,32 @@ int slsDetector::sendROI(int n, ROI roiLimits[]) {
if (shm()->onlineFlag == ONLINE_FLAG) { if (shm()->onlineFlag == ONLINE_FLAG) {
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.sendData(&fnum, sizeof(fnum)); client.Send(&fnum, sizeof(fnum));
client.sendData(&narg, sizeof(narg)); client.Send(&narg, sizeof(narg));
if (narg != -1) { if (narg != -1) {
for (int i = 0; i < narg; ++i) { for (int i = 0; i < narg; ++i) {
client.sendData(&arg[i].xmin, sizeof(int)); client.Send(&arg[i].xmin, sizeof(int));
client.sendData(&arg[i].xmax, sizeof(int)); client.Send(&arg[i].xmax, sizeof(int));
client.sendData(&arg[i].ymin, sizeof(int)); client.Send(&arg[i].ymin, sizeof(int));
client.sendData(&arg[i].ymax, sizeof(int)); client.Send(&arg[i].ymax, sizeof(int));
} }
} }
client.receiveData(&ret, sizeof(ret)); client.Receive(&ret, sizeof(ret));
// handle ret // handle ret
if (ret == FAIL) { if (ret == FAIL) {
char mess[MAX_STR_LENGTH]{}; char mess[MAX_STR_LENGTH]{};
client.receiveData(mess, MAX_STR_LENGTH); client.Receive(mess, MAX_STR_LENGTH);
throw RuntimeError("Detector " + std::to_string(detId) + throw RuntimeError("Detector " + std::to_string(detId) +
" returned error: " + std::string(mess)); " returned error: " + std::string(mess));
} else { } else {
client.receiveData(&nretval, sizeof(nretval)); client.Receive(&nretval, sizeof(nretval));
int nrec = 0; int nrec = 0;
for (int i = 0; i < nretval; ++i) { for (int i = 0; i < nretval; ++i) {
nrec += client.receiveData(&retval[i].xmin, sizeof(int)); nrec += client.Receive(&retval[i].xmin, sizeof(int));
nrec += client.receiveData(&retval[i].xmax, sizeof(int)); nrec += client.Receive(&retval[i].xmax, sizeof(int));
nrec += client.receiveData(&retval[i].ymin, sizeof(int)); nrec += client.Receive(&retval[i].ymin, sizeof(int));
nrec += client.receiveData(&retval[i].ymax, sizeof(int)); nrec += client.Receive(&retval[i].ymax, sizeof(int));
} }
shm()->nROI = nretval; shm()->nROI = nretval;
FILE_LOG(logDEBUG1) << "nRoi: " << nretval; FILE_LOG(logDEBUG1) << "nRoi: " << nretval;
@ -2618,21 +2598,21 @@ int slsDetector::sendROI(int n, ROI roiLimits[]) {
FILE_LOG(logDEBUG1) << "Sending ROI to receiver: " << shm()->nROI; FILE_LOG(logDEBUG1) << "Sending ROI to receiver: " << shm()->nROI;
auto receiver = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); auto receiver = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort);
receiver.sendData(&fnum, sizeof(fnum)); receiver.Send(&fnum, sizeof(fnum));
receiver.sendData(&narg, sizeof(narg)); receiver.Send(&narg, sizeof(narg));
if (narg != -1) { if (narg != -1) {
for (int i = 0; i < narg; ++i) { for (int i = 0; i < narg; ++i) {
receiver.sendData(&arg[i].xmin, sizeof(int)); receiver.Send(&arg[i].xmin, sizeof(int));
receiver.sendData(&arg[i].xmax, sizeof(int)); receiver.Send(&arg[i].xmax, sizeof(int));
receiver.sendData(&arg[i].ymin, sizeof(int)); receiver.Send(&arg[i].ymin, sizeof(int));
receiver.sendData(&arg[i].ymax, sizeof(int)); receiver.Send(&arg[i].ymax, sizeof(int));
} }
} }
receiver.receiveData(&ret, sizeof(ret)); receiver.Receive(&ret, sizeof(ret));
if (ret == FAIL) { if (ret == FAIL) {
char mess[MAX_STR_LENGTH]{}; char mess[MAX_STR_LENGTH]{};
receiver.receiveData(mess, MAX_STR_LENGTH); receiver.Receive(mess, MAX_STR_LENGTH);
throw ReceiverError("Receiver " + std::to_string(detId) + throw ReceiverError("Receiver " + std::to_string(detId) +
" returned error: " + std::string(mess)); " returned error: " + std::string(mess));
} }
@ -2645,25 +2625,28 @@ int slsDetector::sendROI(int n, ROI roiLimits[]) {
void slsDetector::setADCEnableMask(uint32_t mask) { void slsDetector::setADCEnableMask(uint32_t mask) {
uint32_t arg = mask; uint32_t arg = mask;
FILE_LOG(logDEBUG1) << "Setting ADC Enable mask to 0x" << std::hex << arg << std::dec; FILE_LOG(logDEBUG1) << "Setting ADC Enable mask to 0x" << std::hex << arg
<< std::dec;
if (shm()->onlineFlag == ONLINE_FLAG) { if (shm()->onlineFlag == ONLINE_FLAG) {
sendToDetector(F_SET_ADC_ENABLE_MASK, &arg, sizeof(arg), nullptr, 0); sendToDetector(F_SET_ADC_ENABLE_MASK, &arg, sizeof(arg), nullptr, 0);
shm()->adcEnableMask = mask; shm()->adcEnableMask = mask;
} }
// update #nchans and databytes, as it depends on #samples, adcmask, readoutflags // update #nchans and databytes, as it depends on #samples, adcmask,
// readoutflags
updateTotalNumberOfChannels(); updateTotalNumberOfChannels();
// send to processor // send to processor
if (shm()->myDetectorType == MOENCH) if (shm()->myDetectorType == MOENCH)
setAdditionalJsonParameter("adcmask", std::to_string(shm()->adcEnableMask)); setAdditionalJsonParameter("adcmask",
std::to_string(shm()->adcEnableMask));
if (shm()->rxOnlineFlag == ONLINE_FLAG) { if (shm()->rxOnlineFlag == ONLINE_FLAG) {
int fnum = F_RECEIVER_SET_ADC_MASK; int fnum = F_RECEIVER_SET_ADC_MASK;
int retval = -1; int retval = -1;
mask = shm()->adcEnableMask; mask = shm()->adcEnableMask;
FILE_LOG(logDEBUG1) FILE_LOG(logDEBUG1) << "Setting ADC Enable mask to 0x" << std::hex
<< "Setting ADC Enable mask to 0x" << std:: hex << mask << std::dec << " in receiver"; << mask << std::dec << " in receiver";
sendToReceiver(fnum, &mask, sizeof(mask), &retval, sizeof(retval)); sendToReceiver(fnum, &mask, sizeof(mask), &retval, sizeof(retval));
} }
} }
@ -2672,15 +2655,18 @@ uint32_t slsDetector::getADCEnableMask() {
uint32_t retval = -1; uint32_t retval = -1;
FILE_LOG(logDEBUG1) << "Getting ADC Enable mask"; FILE_LOG(logDEBUG1) << "Getting ADC Enable mask";
if (shm()->onlineFlag == ONLINE_FLAG) { if (shm()->onlineFlag == ONLINE_FLAG) {
sendToDetector(F_GET_ADC_ENABLE_MASK, nullptr, 0, &retval, sizeof(retval)); sendToDetector(F_GET_ADC_ENABLE_MASK, nullptr, 0, &retval,
sizeof(retval));
shm()->adcEnableMask = retval; shm()->adcEnableMask = retval;
FILE_LOG(logDEBUG1) << "ADC Enable Mask: 0x" << std::hex << retval << std::dec; FILE_LOG(logDEBUG1)
<< "ADC Enable Mask: 0x" << std::hex << retval << std::dec;
} }
return shm()->adcEnableMask; return shm()->adcEnableMask;
} }
void slsDetector::setADCInvert(uint32_t value) { void slsDetector::setADCInvert(uint32_t value) {
FILE_LOG(logDEBUG1) << "Setting ADC Invert to 0x" << std::hex << value << std::dec; FILE_LOG(logDEBUG1) << "Setting ADC Invert to 0x" << std::hex << value
<< std::dec;
if (shm()->onlineFlag == ONLINE_FLAG) { if (shm()->onlineFlag == ONLINE_FLAG) {
sendToDetector(F_SET_ADC_INVERT, value, nullptr); sendToDetector(F_SET_ADC_INVERT, value, nullptr);
} }
@ -2691,7 +2677,8 @@ uint32_t slsDetector::getADCInvert() {
FILE_LOG(logDEBUG1) << "Getting ADC Invert"; FILE_LOG(logDEBUG1) << "Getting ADC Invert";
if (shm()->onlineFlag == ONLINE_FLAG) { if (shm()->onlineFlag == ONLINE_FLAG) {
sendToDetector(F_GET_ADC_INVERT, nullptr, retval); sendToDetector(F_GET_ADC_INVERT, nullptr, retval);
FILE_LOG(logDEBUG1) << "ADC Invert: 0x" << std::hex << retval << std::dec; FILE_LOG(logDEBUG1)
<< "ADC Invert: 0x" << std::hex << retval << std::dec;
} }
return retval; return retval;
} }
@ -2722,9 +2709,7 @@ int slsDetector::setExternalSampling(int value) {
return retval; return retval;
} }
int slsDetector::getExternalSampling() { int slsDetector::getExternalSampling() { return setExternalSampling(-1); }
return setExternalSampling(-1);
}
void slsDetector::setReceiverDbitList(std::vector<int> list) { void slsDetector::setReceiverDbitList(std::vector<int> list) {
FILE_LOG(logDEBUG1) << "Setting Receiver Dbit List"; FILE_LOG(logDEBUG1) << "Setting Receiver Dbit List";
@ -2734,7 +2719,8 @@ void slsDetector::setReceiverDbitList(std::vector<int> list) {
} }
for (auto &it : list) { for (auto &it : list) {
if (it < 0 || it > 63) { if (it < 0 || it > 63) {
throw sls::RuntimeError("Dbit list value must be between 0 and 63\n"); throw sls::RuntimeError(
"Dbit list value must be between 0 and 63\n");
} }
} }
shm()->rxDbitList = list; shm()->rxDbitList = list;
@ -2749,7 +2735,7 @@ std::vector<int> slsDetector::getReceiverDbitList() {
if (shm()->rxOnlineFlag == ONLINE_FLAG) { if (shm()->rxOnlineFlag == ONLINE_FLAG) {
sendToReceiver(F_GET_RECEIVER_DBIT_LIST, nullptr, retval); sendToReceiver(F_GET_RECEIVER_DBIT_LIST, nullptr, retval);
shm()->rxDbitList = retval; shm()->rxDbitList = retval;
} }
return shm()->rxDbitList; return shm()->rxDbitList;
} }
@ -2757,7 +2743,8 @@ int slsDetector::setReceiverDbitOffset(int value) {
int retval = -1; int retval = -1;
if (value >= 0) if (value >= 0)
shm()->rxDbitOffset = value; shm()->rxDbitOffset = value;
FILE_LOG(logDEBUG1) << "Setting digital bit offset in receiver to " << value; FILE_LOG(logDEBUG1) << "Setting digital bit offset in receiver to "
<< value;
if (shm()->rxOnlineFlag == ONLINE_FLAG) { if (shm()->rxOnlineFlag == ONLINE_FLAG) {
sendToReceiver(F_RECEIVER_DBIT_OFFSET, value, retval); sendToReceiver(F_RECEIVER_DBIT_OFFSET, value, retval);
FILE_LOG(logDEBUG1) << "Receiver digital bit offset: " << retval; FILE_LOG(logDEBUG1) << "Receiver digital bit offset: " << retval;
@ -2765,9 +2752,7 @@ int slsDetector::setReceiverDbitOffset(int value) {
return shm()->rxDbitOffset; return shm()->rxDbitOffset;
} }
int slsDetector::getReceiverDbitOffset() { int slsDetector::getReceiverDbitOffset() { return shm()->rxDbitOffset; }
return shm()->rxDbitOffset;
}
int slsDetector::writeAdcRegister(uint32_t addr, uint32_t val) { int slsDetector::writeAdcRegister(uint32_t addr, uint32_t val) {
uint32_t args[]{addr, val}; uint32_t args[]{addr, val};
@ -2979,12 +2964,12 @@ int slsDetector::programFPGA(std::vector<char> buffer) {
if (shm()->onlineFlag == ONLINE_FLAG) { if (shm()->onlineFlag == ONLINE_FLAG) {
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.sendData(&fnum, sizeof(fnum)); client.Send(&fnum, sizeof(fnum));
client.sendData(&filesize, sizeof(filesize)); client.Send(&filesize, sizeof(filesize));
client.receiveData(&ret, sizeof(ret)); client.Receive(&ret, sizeof(ret));
// error in detector at opening file pointer to flash // error in detector at opening file pointer to flash
if (ret == FAIL) { if (ret == FAIL) {
client.receiveData(mess, sizeof(mess)); client.Receive(mess, sizeof(mess));
std::ostringstream os; std::ostringstream os;
os << "Detector " << detId << " (" << shm()->hostname << ")" os << "Detector " << detId << " (" << shm()->hostname << ")"
<< " returned error: " << mess; << " returned error: " << mess;
@ -3029,8 +3014,8 @@ int slsDetector::programFPGA(std::vector<char> buffer) {
FILE_LOG(logDEBUG1) << "unitprogramsize:" << unitprogramsize FILE_LOG(logDEBUG1) << "unitprogramsize:" << unitprogramsize
<< "\t filesize:" << filesize; << "\t filesize:" << filesize;
client.sendData(&buffer[currentPointer], unitprogramsize); client.Send(&buffer[currentPointer], unitprogramsize);
client.receiveData(&ret, sizeof(ret)); client.Receive(&ret, sizeof(ret));
if (ret != FAIL) { if (ret != FAIL) {
filesize -= unitprogramsize; filesize -= unitprogramsize;
currentPointer += unitprogramsize; currentPointer += unitprogramsize;
@ -3043,7 +3028,7 @@ int slsDetector::programFPGA(std::vector<char> buffer) {
std::cout << std::flush; std::cout << std::flush;
} else { } else {
printf("\n"); printf("\n");
client.receiveData(mess, sizeof(mess)); client.Receive(mess, sizeof(mess));
std::ostringstream os; std::ostringstream os;
os << "Detector " << detId << " (" << shm()->hostname << ")" os << "Detector " << detId << " (" << shm()->hostname << ")"
<< " returned error: " << mess; << " returned error: " << mess;
@ -3090,7 +3075,7 @@ int slsDetector::rebootController() {
<< " (" << shm()->hostname << ")"; << " (" << shm()->hostname << ")";
if (shm()->onlineFlag == ONLINE_FLAG) { if (shm()->onlineFlag == ONLINE_FLAG) {
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.sendData(&fnum, sizeof(fnum)); client.Send(&fnum, sizeof(fnum));
ret = OK; ret = OK;
} }
return ret; return ret;
@ -3128,16 +3113,16 @@ int slsDetector::setModule(sls_detector_module &module, int tb) {
} }
if (shm()->onlineFlag == ONLINE_FLAG) { if (shm()->onlineFlag == ONLINE_FLAG) {
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.sendData(&fnum, sizeof(fnum)); client.Send(&fnum, sizeof(fnum));
sendModule(&module, client); sendModule(&module, client);
client.receiveData(&ret, sizeof(ret)); client.Receive(&ret, sizeof(ret));
if (ret == FAIL) { if (ret == FAIL) {
char mess[MAX_STR_LENGTH] = {0}; char mess[MAX_STR_LENGTH] = {0};
client.receiveData(mess, sizeof(mess)); client.Receive(mess, sizeof(mess));
throw RuntimeError("Detector " + std::to_string(detId) + throw RuntimeError("Detector " + std::to_string(detId) +
" returned error: " + mess); " returned error: " + mess);
} }
client.receiveData(&retval, sizeof(retval)); client.Receive(&retval, sizeof(retval));
FILE_LOG(logDEBUG1) << "Set Module returned: " << retval; FILE_LOG(logDEBUG1) << "Set Module returned: " << retval;
} }
if (ret == FORCE_UPDATE) { if (ret == FORCE_UPDATE) {
@ -3231,10 +3216,6 @@ int slsDetector::setReceiverOnline(int value) {
} else { } else {
shm()->rxOnlineFlag = OFFLINE_FLAG; shm()->rxOnlineFlag = OFFLINE_FLAG;
if (value == ONLINE_FLAG) { if (value == ONLINE_FLAG) {
// Connect and ask for receiver id to verify that
// it's online and working
int64_t retval{0};
sendToReceiver(F_GET_RECEIVER_ID, nullptr, retval);
shm()->rxOnlineFlag = ONLINE_FLAG; shm()->rxOnlineFlag = ONLINE_FLAG;
if (shm()->receiverAPIVersion == 0) { if (shm()->receiverAPIVersion == 0) {
checkReceiverVersionCompatibility(); checkReceiverVersionCompatibility();
@ -3317,95 +3298,95 @@ int slsDetector::updateCachedReceiverVariables() const {
char cstring[MAX_STR_LENGTH]{}; char cstring[MAX_STR_LENGTH]{};
char lastClientIP[INET_ADDRSTRLEN]{}; char lastClientIP[INET_ADDRSTRLEN]{};
n += receiver.receiveData(lastClientIP, sizeof(lastClientIP)); n += receiver.Receive(lastClientIP, sizeof(lastClientIP));
FILE_LOG(logDEBUG1) FILE_LOG(logDEBUG1)
<< "Updating receiver last modified by " << lastClientIP; << "Updating receiver last modified by " << lastClientIP;
// filepath // filepath
n += receiver.receiveData(cstring, sizeof(cstring)); n += receiver.Receive(cstring, sizeof(cstring));
sls::strcpy_safe(shm()->rxFilePath, cstring); sls::strcpy_safe(shm()->rxFilePath, cstring);
// filename // filename
n += receiver.receiveData(cstring, sizeof(cstring)); n += receiver.Receive(cstring, sizeof(cstring));
sls::strcpy_safe(shm()->rxFileName, cstring); sls::strcpy_safe(shm()->rxFileName, cstring);
// index // index
n += receiver.receiveData(&i32, sizeof(i32)); n += receiver.Receive(&i32, sizeof(i32));
shm()->rxFileIndex = i32; shm()->rxFileIndex = i32;
// file format // file format
n += receiver.receiveData(&i32, sizeof(i32)); n += receiver.Receive(&i32, sizeof(i32));
shm()->rxFileFormat = static_cast<fileFormat>(i32); shm()->rxFileFormat = static_cast<fileFormat>(i32);
// frames per file // frames per file
n += receiver.receiveData(&i32, sizeof(i32)); n += receiver.Receive(&i32, sizeof(i32));
shm()->rxFramesPerFile = i32; shm()->rxFramesPerFile = i32;
// frame discard policy // frame discard policy
n += receiver.receiveData(&i32, sizeof(i32)); n += receiver.Receive(&i32, sizeof(i32));
shm()->rxFrameDiscardMode = static_cast<frameDiscardPolicy>(i32); shm()->rxFrameDiscardMode = static_cast<frameDiscardPolicy>(i32);
// frame padding // frame padding
n += receiver.receiveData(&i32, sizeof(i32)); n += receiver.Receive(&i32, sizeof(i32));
shm()->rxFramePadding = static_cast<bool>(i32); shm()->rxFramePadding = static_cast<bool>(i32);
// file write enable // file write enable
n += receiver.receiveData(&i32, sizeof(i32)); n += receiver.Receive(&i32, sizeof(i32));
shm()->rxFileWrite = static_cast<bool>(i32); shm()->rxFileWrite = static_cast<bool>(i32);
// master file write enable // master file write enable
n += receiver.receiveData(&i32, sizeof(i32)); n += receiver.Receive(&i32, sizeof(i32));
shm()->rxMasterFileWrite = static_cast<bool>(i32); shm()->rxMasterFileWrite = static_cast<bool>(i32);
// file overwrite enable // file overwrite enable
n += receiver.receiveData(&i32, sizeof(i32)); n += receiver.Receive(&i32, sizeof(i32));
shm()->rxFileOverWrite = static_cast<bool>(i32); shm()->rxFileOverWrite = static_cast<bool>(i32);
// gap pixels // gap pixels
n += receiver.receiveData(&i32, sizeof(i32)); n += receiver.Receive(&i32, sizeof(i32));
shm()->gappixels = i32; shm()->gappixels = i32;
// receiver read frequency // receiver read frequency
n += receiver.receiveData(&i32, sizeof(i32)); n += receiver.Receive(&i32, sizeof(i32));
shm()->rxReadFreq = i32; shm()->rxReadFreq = i32;
// receiver streaming port // receiver streaming port
n += receiver.receiveData(&i32, sizeof(i32)); n += receiver.Receive(&i32, sizeof(i32));
shm()->rxZmqport = i32; shm()->rxZmqport = i32;
// streaming source ip // streaming source ip
n += receiver.receiveData(cstring, sizeof(cstring)); n += receiver.Receive(cstring, sizeof(cstring));
sls::strcpy_safe(shm()->rxZmqip, cstring); shm()->rxZmqip = cstring;
// additional json header // additional json header
n += receiver.receiveData(cstring, sizeof(cstring)); n += receiver.Receive(cstring, sizeof(cstring));
sls::strcpy_safe(shm()->rxAdditionalJsonHeader, cstring); sls::strcpy_safe(shm()->rxAdditionalJsonHeader, cstring);
// receiver streaming enable // receiver streaming enable
n += receiver.receiveData(&i32, sizeof(i32)); n += receiver.Receive(&i32, sizeof(i32));
shm()->rxUpstream = static_cast<bool>(i32); shm()->rxUpstream = static_cast<bool>(i32);
// activate // activate
n += receiver.receiveData(&i32, sizeof(i32)); n += receiver.Receive(&i32, sizeof(i32));
shm()->activated = static_cast<bool>(i32); shm()->activated = static_cast<bool>(i32);
// deactivated padding enable // deactivated padding enable
n += receiver.receiveData(&i32, sizeof(i32)); n += receiver.Receive(&i32, sizeof(i32));
shm()->rxPadDeactivatedModules = static_cast<bool>(i32); shm()->rxPadDeactivatedModules = static_cast<bool>(i32);
// silent mode // silent mode
n += receiver.receiveData(&i32, sizeof(i32)); n += receiver.Receive(&i32, sizeof(i32));
shm()->rxSilentMode = static_cast<bool>(i32); shm()->rxSilentMode = static_cast<bool>(i32);
// dbit list // dbit list
{ {
sls::FixedCapacityContainer<int, MAX_RX_DBIT> temp; sls::FixedCapacityContainer<int, MAX_RX_DBIT> temp;
n += receiver.receiveData(&temp, sizeof(temp)); n += receiver.Receive(&temp, sizeof(temp));
shm()->rxDbitList = temp; shm()->rxDbitList = temp;
} }
// dbit offset // dbit offset
n += receiver.receiveData(&i32, sizeof(i32)); n += receiver.Receive(&i32, sizeof(i32));
shm()->rxDbitOffset = i32; shm()->rxDbitOffset = i32;
if (n == 0) { if (n == 0) {
@ -3643,7 +3624,8 @@ bool slsDetector::getFileWrite() const { return shm()->rxFileWrite; }
bool slsDetector::setMasterFileWrite(bool value) { bool slsDetector::setMasterFileWrite(bool value) {
int arg = static_cast<int>(value); int arg = static_cast<int>(value);
int retval = -1; int retval = -1;
FILE_LOG(logDEBUG1) << "Sending enable master file write to receiver: " << arg; FILE_LOG(logDEBUG1) << "Sending enable master file write to receiver: "
<< arg;
if (shm()->rxOnlineFlag == ONLINE_FLAG) { if (shm()->rxOnlineFlag == ONLINE_FLAG) {
sendToReceiver(F_ENABLE_RECEIVER_MASTER_FILE_WRITE, arg, retval); sendToReceiver(F_ENABLE_RECEIVER_MASTER_FILE_WRITE, arg, retval);
FILE_LOG(logDEBUG1) << "Receiver master file write enable: " << retval; FILE_LOG(logDEBUG1) << "Receiver master file write enable: " << retval;
@ -3652,7 +3634,9 @@ bool slsDetector::setMasterFileWrite(bool value) {
return getMasterFileWrite(); return getMasterFileWrite();
} }
bool slsDetector::getMasterFileWrite() const { return shm()->rxMasterFileWrite; } bool slsDetector::getMasterFileWrite() const {
return shm()->rxMasterFileWrite;
}
bool slsDetector::setFileOverWrite(bool value) { bool slsDetector::setFileOverWrite(bool value) {
int arg = static_cast<int>(value); int arg = static_cast<int>(value);

View File

@ -1,12 +1,13 @@
#include "versionAPI.h"
#include "multiSlsDetectorClient.h" #include "multiSlsDetectorClient.h"
#include "versionAPI.h"
#include <cstdlib> #include <cstdlib>
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
for (int i = 1; i < argc; ++i) { for (int i = 1; i < argc; ++i) {
if (!(strcmp(argv[i], "--version")) || !(strcmp(argv[i], "-v"))) { if (!(strcmp(argv[i], "--version")) || !(strcmp(argv[i], "-v"))) {
int64_t tempval = APILIB; int64_t tempval = APILIB;
std::cout << argv[0] << " " << GITBRANCH << " (0x" << std::hex << tempval << ")" << std::endl; std::cout << argv[0] << " " << GITBRANCH << " (0x" << std::hex
<< tempval << ")" << std::endl;
return 0; return 0;
} }
} }
@ -27,5 +28,8 @@ int main(int argc, char *argv[]) {
int action = slsDetectorDefs::HELP_ACTION; int action = slsDetectorDefs::HELP_ACTION;
#endif #endif
multiSlsDetectorClient(argc, argv, action); try {
multiSlsDetectorClient(argc, argv, action);
} catch (const sls::RuntimeError &e) {
}
} }

View File

@ -7,34 +7,331 @@ auto GET = slsDetectorDefs::GET_ACTION;
auto PUT = slsDetectorDefs::PUT_ACTION; auto PUT = slsDetectorDefs::PUT_ACTION;
TEST_CASE("rx_fifodepth", "[.cmd]") { TEST_CASE("rx_fifodepth", "[.cmd]") {
auto oss = std::ostringstream{};
multiSlsDetectorClient("rx_fifodepth 10", PUT, nullptr, oss);
REQUIRE(oss.str() == "rx_fifodepth 10\n");
oss = std::ostringstream{}; {
multiSlsDetectorClient("rx_fifodepth 100", PUT, nullptr, oss); std::ostringstream oss;
REQUIRE(oss.str() == "rx_fifodepth 100\n"); multiSlsDetectorClient("rx_fifodepth 10", PUT, nullptr, oss);
REQUIRE(oss.str() == "rx_fifodepth 10\n");
}
oss = std::ostringstream{}; {
multiSlsDetectorClient("rx_fifodepth", GET, nullptr, oss); std::ostringstream oss;
REQUIRE(oss.str() == "rx_fifodepth 100\n"); multiSlsDetectorClient("rx_fifodepth 100", PUT, nullptr, oss);
REQUIRE(oss.str() == "rx_fifodepth 100\n");
}
oss = std::ostringstream{}; {
multiSlsDetectorClient("0:rx_fifodepth", GET, nullptr, oss); std::ostringstream oss;
REQUIRE(oss.str() == "0:rx_fifodepth 100\n"); multiSlsDetectorClient("rx_fifodepth", GET, nullptr, oss);
REQUIRE(oss.str() == "rx_fifodepth 100\n");
}
} }
TEST_CASE("frames", "[.cmd]"){ TEST_CASE("frames", "[.cmd]") {
auto oss = std::ostringstream{};
multiSlsDetectorClient("frames 1000", PUT, nullptr, oss);
REQUIRE(oss.str() == "frames 1000\n");
oss = std::ostringstream{}; {
multiSlsDetectorClient("frames", GET, nullptr, oss); std::ostringstream oss;
REQUIRE(oss.str() == "frames 1000\n"); multiSlsDetectorClient("frames 1000", PUT, nullptr, oss);
REQUIRE(oss.str() == "frames 1000\n");
}
oss = std::ostringstream{}; {
multiSlsDetectorClient("frames 1", PUT, nullptr, oss); std::ostringstream oss;
REQUIRE(oss.str() == "frames 1\n"); multiSlsDetectorClient("frames", GET, nullptr, oss);
REQUIRE(oss.str() == "frames 1000\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("frames 1", PUT, nullptr, oss);
REQUIRE(oss.str() == "frames 1\n");
}
}
} TEST_CASE("receiver", "[.cmd]") {
{
std::ostringstream oss;
multiSlsDetectorClient("receiver start", PUT, nullptr, oss);
REQUIRE(oss.str() == "receiver running\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("receiver", GET, nullptr, oss);
REQUIRE(oss.str() == "receiver running\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("receiver stop", PUT, nullptr, oss);
REQUIRE(oss.str() == "receiver idle\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("receiver", GET, nullptr, oss);
REQUIRE(oss.str() == "receiver idle\n");
}
}
TEST_CASE("enablefwrite", "[.cmd]") {
{
std::ostringstream oss;
multiSlsDetectorClient("enablefwrite 1", PUT, nullptr, oss);
REQUIRE(oss.str() == "enablefwrite 1\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("enablefwrite", GET, nullptr, oss);
REQUIRE(oss.str() == "enablefwrite 1\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("enablefwrite 0", PUT, nullptr, oss);
REQUIRE(oss.str() == "enablefwrite 0\n");
}
}
TEST_CASE("enableoverwrite", "[.cmd]") {
{
std::ostringstream oss;
multiSlsDetectorClient("overwrite 1", PUT, nullptr, oss);
REQUIRE(oss.str() == "overwrite 1\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("overwrite", GET, nullptr, oss);
REQUIRE(oss.str() == "overwrite 1\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("overwrite 0", PUT, nullptr, oss);
REQUIRE(oss.str() == "overwrite 0\n");
}
}
TEST_CASE("activatecmd", "[.cmd]") {
{
// TODO! read padding from somewhere
std::ostringstream oss;
multiSlsDetectorClient("activate 0", PUT, nullptr, oss);
REQUIRE(oss.str() == "activate 0 padding\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("activate", GET, nullptr, oss);
REQUIRE(oss.str() == "activate 0 padding\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("activate 1", PUT, nullptr, oss);
REQUIRE(oss.str() == "activate 1 padding\n");
}
}
TEST_CASE("masterfile", "[.cmd]") {
{
std::ostringstream oss;
multiSlsDetectorClient("masterfile 0", PUT, nullptr, oss);
REQUIRE(oss.str() == "masterfile 0\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("masterfile", GET, nullptr, oss);
REQUIRE(oss.str() == "masterfile 0\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("masterfile 1", PUT, nullptr, oss);
REQUIRE(oss.str() == "masterfile 1\n");
}
}
TEST_CASE("index", "[.cmd]") {
{
std::ostringstream oss;
multiSlsDetectorClient("index 57", PUT, nullptr, oss);
REQUIRE(oss.str() == "index 57\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("index", GET, nullptr, oss);
REQUIRE(oss.str() == "index 57\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("index 0", PUT, nullptr, oss);
REQUIRE(oss.str() == "index 0\n");
}
}
TEST_CASE("rx_tcpport", "[.cmd]") {
multiSlsDetector d;
int port = 1500;
int base = 1954;
for (size_t i = 0; i != d.size(); ++i) {
std::ostringstream oss;
std::string cmd =
std::to_string(i) + ":rx_tcpport " + std::to_string(port + i);
std::cout << cmd << "\n";
multiSlsDetectorClient(cmd, PUT, nullptr, oss);
REQUIRE(oss.str() == cmd + "\n");
}
{
std::ostringstream oss;
REQUIRE_THROWS(
multiSlsDetectorClient("rx_tcpport 15", PUT, nullptr, oss));
}
for (size_t i = 0; i != d.size(); ++i) {
std::ostringstream oss;
std::string cmd = std::to_string(i) + ":rx_tcpport";
multiSlsDetectorClient(cmd, GET, nullptr, oss);
REQUIRE(oss.str() == cmd + " " + std::to_string(port + i) + "\n");
}
for (size_t i = 0; i != d.size(); ++i) {
std::ostringstream oss;
std::string cmd =
std::to_string(i) + ":rx_tcpport " + std::to_string(base + i);
multiSlsDetectorClient(cmd, PUT, nullptr, oss);
REQUIRE(oss.str() == cmd + "\n");
}
}
TEST_CASE("fname", "[.cmd]") {
{
std::ostringstream oss;
multiSlsDetectorClient("fname somename", PUT, nullptr, oss);
REQUIRE(oss.str() == "fname somename\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("fname", GET, nullptr, oss);
REQUIRE(oss.str() == "fname somename\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("fname run", PUT, nullptr, oss);
REQUIRE(oss.str() == "fname run\n");
}
}
TEST_CASE("resetframescaught get framescaught", "[.cmd]") {
{
std::ostringstream oss;
multiSlsDetectorClient("resetframescaught 0", PUT, nullptr, oss);
REQUIRE(oss.str() == "resetframescaught successful\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("framescaught", GET, nullptr, oss);
REQUIRE(oss.str() == "framescaught 0\n");
}
}
TEST_CASE("r_silent", "[.cmd]") {
{
std::ostringstream oss;
multiSlsDetectorClient("r_silent 1", PUT, nullptr, oss);
REQUIRE(oss.str() == "r_silent 1\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("r_silent", GET, nullptr, oss);
REQUIRE(oss.str() == "r_silent 1\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("r_silent 0", PUT, nullptr, oss);
REQUIRE(oss.str() == "r_silent 0\n");
}
}
// TEST_CASE("rx_jsonaddheader", "[.cmd]") {
// std::ostringstream oss;
// multiSlsDetectorClient("rx_jsonaddheader \"hej\":\"5\"", PUT, nullptr,
// oss); REQUIRE(oss.str() == "rx_jsonaddheader \"hej\":\"5\"\n");
// std::ostringstream oss;
// multiSlsDetectorClient("rx_jsonaddheader", GET, nullptr, oss);
// REQUIRE(oss.str() == "rx_jsonaddheader \"hej\":\"5\"\n");
// std::ostringstream oss;
// multiSlsDetectorClient("rx_jsonaddheader \"\"", PUT, nullptr, oss);
// REQUIRE(oss.str() == "rx_jsonaddheader\n");
// }
// TEST_CASE("rx_udpsocksize", "[.cmd]") {
// std::ostringstream oss;
// multiSlsDetectorClient("rx_udpsocksize 4857600", PUT, nullptr, oss);
// REQUIRE(oss.str() == "rx_udpsocksize 4857600\n");
// std::ostringstream oss;
// multiSlsDetectorClient("rx_udpsocksize", GET, nullptr, oss);
// REQUIRE(oss.str() == "rx_udpsocksize 4857600\n");
// std::ostringstream oss;
// multiSlsDetectorClient("rx_udpsocksize 104857600", PUT, nullptr, oss);
// REQUIRE(oss.str() == "rx_udpsocksize 104857600\n");
// }
TEST_CASE("r_framesperfile", "[.cmd]") {
{
std::ostringstream oss;
multiSlsDetectorClient("r_framesperfile 50", PUT, nullptr, oss);
REQUIRE(oss.str() == "r_framesperfile 50\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("r_framesperfile", GET, nullptr, oss);
REQUIRE(oss.str() == "r_framesperfile 50\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("r_framesperfile 10000", PUT, nullptr, oss);
REQUIRE(oss.str() == "r_framesperfile 10000\n");
}
}
TEST_CASE("r_discardpolicy", "[.cmd]") {
{
std::ostringstream oss;
multiSlsDetectorClient("r_discardpolicy discardempty", PUT, nullptr,
oss);
REQUIRE(oss.str() == "r_discardpolicy discardempty\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("r_discardpolicy", GET, nullptr, oss);
REQUIRE(oss.str() == "r_discardpolicy discardempty\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("r_discardpolicy discardpartial", PUT, nullptr,
oss);
REQUIRE(oss.str() == "r_discardpolicy discardpartial\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("r_discardpolicy nodiscard", PUT, nullptr, oss);
REQUIRE(oss.str() == "r_discardpolicy nodiscard\n");
}
}
TEST_CASE("r_padding", "[.cmd]") {
{
std::ostringstream oss;
multiSlsDetectorClient("r_padding 0", PUT, nullptr, oss);
REQUIRE(oss.str() == "r_padding 0\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("r_padding", GET, nullptr, oss);
REQUIRE(oss.str() == "r_padding 0\n");
}
{
std::ostringstream oss;
multiSlsDetectorClient("r_padding 1", PUT, nullptr, oss);
REQUIRE(oss.str() == "r_padding 1\n");
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,85 +1,87 @@
#pragma once #pragma once
/********************************************//** /********************************************/ /**
* @file slsReceiverTCPIPInterface.h * @file
* @short interface between receiver and client *slsReceiverTCPIPInterface.h
***********************************************/ * @short interface between
*receiver and client
***********************************************/
#include "sls_detector_defs.h"
#include "receiver_defs.h" #include "receiver_defs.h"
#include "sls_detector_defs.h"
class MySocketTCP; class MySocketTCP;
class ServerInterface; class ServerInterface;
#include "slsReceiverImplementation.h"
#include "ServerSocket.h" #include "ServerSocket.h"
#include "slsReceiverImplementation.h"
/** /**
*@short interface between receiver and client *@short interface between receiver and client
*/ */
class slsReceiverTCPIPInterface : private virtual slsDetectorDefs { class slsReceiverTCPIPInterface : private virtual slsDetectorDefs {
private: private:
enum numberMode {DEC, HEX}; enum numberMode { DEC, HEX };
public:
/** Destructor */ public:
virtual ~slsReceiverTCPIPInterface(); /** Destructor */
virtual ~slsReceiverTCPIPInterface();
/** /**
* Constructor * Constructor
* reads config file, creates socket, assigns function table * reads config file, creates socket, assigns function table
* throws an exception in case of failure to construct * throws an exception in case of failure to construct
* @param pn port number (defaults to default port number) * @param pn port number (defaults to default port number)
*/ */
slsReceiverTCPIPInterface(int pn=-1); slsReceiverTCPIPInterface(int pn = -1);
/** /**
* Starts listening on the TCP port for client comminication * Starts listening on the TCP port for client comminication
\returns OK or FAIL \returns OK or FAIL
*/ */
int start(); int start();
/** stop listening on the TCP & UDP port for client comminication */ /** stop listening on the TCP & UDP port for client comminication */
void stop(); void stop();
/** gets version */
int64_t getReceiverVersion();
/** gets version */ //***callback functions***
int64_t getReceiverVersion(); /**
* Call back for start acquisition
* callback arguments are
* filepath
* filename
* fileindex
* datasize
*
* return value is insignificant at the moment
* we write depending on file write enable
* users get data to write depending on call backs registered
*/
void registerCallBackStartAcquisition(int (*func)(char *, char *, uint64_t,
uint32_t, void *),
void *arg);
//***callback functions*** /**
/** * Call back for acquisition finished
* Call back for start acquisition * callback argument is
* callback arguments are * total frames caught
* filepath */
* filename void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void *),
* fileindex void *arg);
* datasize
*
* return value is insignificant at the moment
* we write depending on file write enable
* users get data to write depending on call backs registered
*/
void registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg);
/** /**
* Call back for acquisition finished * Call back for raw data
* callback argument is * args to raw data ready callback are
* total frames caught * sls_receiver_header frame metadata
*/ * dataPointer is the pointer to the data
void registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg); * dataSize in bytes is the size of the data in bytes.
*/
/** void registerCallBackRawDataReady(void (*func)(char *, char *, uint32_t,
* Call back for raw data void *),
* args to raw data ready callback are void *arg);
* sls_receiver_header frame metadata
* dataPointer is the pointer to the data
* dataSize in bytes is the size of the data in bytes.
*/
void registerCallBackRawDataReady(void (*func)(char* ,
char*, uint32_t, void*),void *arg);
/** /**
* Call back for raw data (modified) * Call back for raw data (modified)
@ -87,174 +89,168 @@ class slsReceiverTCPIPInterface : private virtual slsDetectorDefs {
* sls_receiver_header frame metadata * sls_receiver_header frame metadata
* dataPointer is the pointer to the data * dataPointer is the pointer to the data
* revDatasize is the reference of data size in bytes. * revDatasize is the reference of data size in bytes.
* Can be modified to the new size to be written/streamed. (only smaller value). * Can be modified to the new size to be written/streamed. (only smaller
* value).
*/ */
void registerCallBackRawDataModifyReady(void (*func)(char* , void registerCallBackRawDataModifyReady(void (*func)(char *, char *,
char*, uint32_t &,void*),void *arg); uint32_t &, void *),
void *arg);
private:
/**
* Static function - Thread started which is a TCP server
* Called by start()
* @param this_pointer pointer to this object
*/
static void *startTCPServerThread(void *this_pointer);
private: /**
* Thread started which is a TCP server
* Called by start()
*/
void startTCPServer();
/** /** assigns functions to the fnum enum */
* Static function - Thread started which is a TCP server int function_table();
* Called by start()
* @param this_pointer pointer to this object
*/
static void* startTCPServerThread(void *this_pointer);
/** Decodes Function */
int decode_function(sls::ServerInterface2 &socket);
/** /** function not implemented for specific detector */
* Thread started which is a TCP server void functionNotImplemented();
* Called by start()
*/
void startTCPServer();
/** assigns functions to the fnum enum */ /** mode not implemented for specific detector */
int function_table(); void modeNotImplemented(const std::string& modename, int mode);
/** Decodes Function */ /** validate and set error */
int decode_function(sls::ServerInterface2 &socket); template <typename T>
void validate(T arg, T retval, std::string modename, numberMode hex);
/** function not implemented for specific detector */ /** Execute command */
void functionNotImplemented(); int exec_command(sls::ServerInterface2 &socket);
/** mode not implemented for specific detector */ /** Exit Receiver Server */
void modeNotImplemented(std::string modename, int mode); int exit_server(sls::ServerInterface2 &socket);
/** validate and set error */ /** Locks Receiver */
template <typename T> int lock_receiver(sls::ServerInterface2 &socket);
void validate(T arg, T retval, std::string modename, numberMode hex);
/** Unrecognized Function */ /** Get Last Client IP*/
int M_nofunc(sls::ServerInterface2 & socket); int get_last_client_ip(sls::ServerInterface2 &socket);
/** Set port */
int set_port(sls::ServerInterface2 &socket);
/** Updates Client if different clients connect */
int update_client(sls::ServerInterface2 &socket);
/** Execute command */ /** Sends the updated parameters to client */
int exec_command(sls::ServerInterface2 &socket); int send_update(sls::ServerInterface2 &socket);
/** Exit Receiver Server */ /** get version, calls get_version */
int exit_server(sls::ServerInterface2 &socket); int get_id(sls::ServerInterface2 &socket);
/** Locks Receiver */ /** Set detector type */
int lock_receiver(sls::ServerInterface2 &socket); int set_detector_type(sls::ServerInterface2 &socket);
/** Get Last Client IP*/ /** set detector hostname */
int get_last_client_ip(sls::ServerInterface2 &socket); int set_detector_hostname(sls::ServerInterface2 &socket);
/** Set port */ /** set roi */
int set_port(sls::ServerInterface2 &socket); int set_roi(sls::ServerInterface2 &socket);
/** Updates Client if different clients connect */ /** Set up UDP Details */
int update_client(sls::ServerInterface2 &socket); int setup_udp(sls::ServerInterface2 &socket);
/** Sends the updated parameters to client */ /** set acquisition period, frame number etc */
int send_update(sls::ServerInterface2 &socket); int set_timer(sls::ServerInterface2 &socket);
/** get version, calls get_version */ /** set dynamic range */
int get_id(sls::ServerInterface2 &socket); int set_dynamic_range(sls::ServerInterface2 &socket);
/** Set detector type */ /** Sets the receiver streaming frequency */
int set_detector_type(sls::ServerInterface2 &socket); int set_streaming_frequency(sls::ServerInterface2 &socket);
/** set detector hostname */ /** Gets receiver status */
int set_detector_hostname(sls::ServerInterface2 &socket); int get_status(sls::ServerInterface2 &socket);
/** set roi */ /** Start Receiver - starts listening to udp packets from detector */
int set_roi(sls::ServerInterface2 &socket); int start_receiver(sls::ServerInterface2 &socket);
/** Set up UDP Details */ /** Stop Receiver - stops listening to udp packets from detector*/
int setup_udp(sls::ServerInterface2 &socket); int stop_receiver(sls::ServerInterface2 &socket);
/** set acquisition period, frame number etc */ /** Set File path */
int set_timer(sls::ServerInterface2 &socket); int set_file_dir(sls::ServerInterface2 &socket);
/** set dynamic range */ /** Set File name without frame index, file index and extension */
int set_dynamic_range(sls::ServerInterface2 &socket); int set_file_name(sls::ServerInterface2 &socket);
/** Sets the receiver streaming frequency */ /** Set File index */
int set_streaming_frequency(sls::ServerInterface2 &socket); int set_file_index(sls::ServerInterface2 &socket);
/** Gets receiver status */ /** Gets frame index for each acquisition */
int get_status(sls::ServerInterface2 &socket); int get_frame_index(sls::ServerInterface2 &socket);
/** Start Receiver - starts listening to udp packets from detector */ /** Gets Total Frames Caught */
int start_receiver(sls::ServerInterface2 &socket); int get_frames_caught(sls::ServerInterface2 &socket);
/** Stop Receiver - stops listening to udp packets from detector*/ /** Resets Total Frames Caught */
int stop_receiver(sls::ServerInterface2 &socket); int reset_frames_caught(sls::ServerInterface2 &socket);
/** Set File path */ /** Enable File Write*/
int set_file_dir(sls::ServerInterface2 &socket); int enable_file_write(sls::ServerInterface2 &socket);
/** Set File name without frame index, file index and extension */ /** Enable Master File Write */
int set_file_name(sls::ServerInterface2 &socket); int enable_master_file_write(sls::ServerInterface2 &socket);
/** Set File index */ /** enable compression */
int set_file_index(sls::ServerInterface2 &socket); int enable_compression(sls::ServerInterface2 &socket);
/** Gets frame index for each acquisition */ /** enable overwrite */
int get_frame_index(sls::ServerInterface2 &socket); int enable_overwrite(sls::ServerInterface2 &socket);
/** Gets Total Frames Caught */ /** enable 10Gbe */
int get_frames_caught(sls::ServerInterface2 &socket); int enable_tengiga(sls::ServerInterface2 &socket);
/** Resets Total Frames Caught */ /** set fifo depth */
int reset_frames_caught(sls::ServerInterface2 &socket); int set_fifo_depth(sls::ServerInterface2 &socket);
/** Enable File Write*/ /** activate/ deactivate */
int enable_file_write(sls::ServerInterface2 &socket); int set_activate(sls::ServerInterface2 &socket);
/** Enable Master File Write */ /* Set the data stream enable */
int enable_master_file_write(sls::ServerInterface2 &socket); int set_data_stream_enable(sls::ServerInterface2 &socket);
/** enable compression */ /** Sets the steadming timer when frequency is set to 0 */
int enable_compression(sls::ServerInterface2 &socket); int set_streaming_timer(sls::ServerInterface2 &socket);
/** enable overwrite */ /** enable flipped data */
int enable_overwrite(sls::ServerInterface2 &socket); int set_flipped_data(sls::ServerInterface2 &socket);
/** enable 10Gbe */ /** set file format */
int enable_tengiga(sls::ServerInterface2 &socket); int set_file_format(sls::ServerInterface2 &socket);
/** set fifo depth */ /** set position id */
int set_fifo_depth(sls::ServerInterface2 &socket); int set_detector_posid(sls::ServerInterface2 &socket);
/** activate/ deactivate */ /** set multi detector size */
int set_activate(sls::ServerInterface2 &socket); int set_multi_detector_size(sls::ServerInterface2 &socket);
/* Set the data stream enable */ /** set streaming port */
int set_data_stream_enable(sls::ServerInterface2 &socket); int set_streaming_port(sls::ServerInterface2 &socket);
/** Sets the steadming timer when frequency is set to 0 */ /** set streaming source ip */
int set_streaming_timer(sls::ServerInterface2 &socket); int set_streaming_source_ip(sls::ServerInterface2 &socket);
/** enable flipped data */ /** set silent mode */
int set_flipped_data(sls::ServerInterface2 &socket); int set_silent_mode(sls::ServerInterface2 &socket);
/** set file format */ /** enable gap pixels */
int set_file_format(sls::ServerInterface2 &socket); int enable_gap_pixels(sls::ServerInterface2 &socket);
/** set position id */ /** restream stop packet */
int set_detector_posid(sls::ServerInterface2 &socket); int restream_stop(sls::ServerInterface2 &socket);
/** set multi detector size */
int set_multi_detector_size(sls::ServerInterface2 &socket);
/** set streaming port */
int set_streaming_port(sls::ServerInterface2 &socket);
/** set streaming source ip */
int set_streaming_source_ip(sls::ServerInterface2 &socket);
/** set silent mode */
int set_silent_mode(sls::ServerInterface2 &socket);
/** enable gap pixels */
int enable_gap_pixels(sls::ServerInterface2 &socket);
/** restream stop packet */
int restream_stop(sls::ServerInterface2 &socket);
/** set additional json header */ /** set additional json header */
int set_additional_json_header(sls::ServerInterface2 &socket); int set_additional_json_header(sls::ServerInterface2 &socket);
@ -286,110 +282,112 @@ class slsReceiverTCPIPInterface : private virtual slsDetectorDefs {
/** set readout flags */ /** set readout flags */
int set_readout_flags(sls::ServerInterface2 &socket); int set_readout_flags(sls::ServerInterface2 &socket);
/** set adc mask */ /** set adc mask */
int set_adc_mask(sls::ServerInterface2 &socket); int set_adc_mask(sls::ServerInterface2 &socket);
/** set receiver dbit list */ /** set receiver dbit list */
int set_dbit_list(sls::ServerInterface2 &socket); int set_dbit_list(sls::ServerInterface2 &socket);
/** get receiver dbit list */ /** get receiver dbit list */
int get_dbit_list(sls::ServerInterface2 &socket); int get_dbit_list(sls::ServerInterface2 &socket);
/** set dbit offset */ /** set dbit offset */
int set_dbit_offset(sls::ServerInterface2 &socket); int set_dbit_offset(sls::ServerInterface2 &socket);
/** detector type */
detectorType myDetectorType;
int LogSocketCrash(); /** slsReceiverBase object */
void NullObjectError(int& ret, char* mess); std::unique_ptr<slsReceiverImplementation> receiver{nullptr};
/** detector type */ /** Function List */
detectorType myDetectorType; int (slsReceiverTCPIPInterface::*flist[NUM_REC_FUNCTIONS])(
sls::ServerInterface2 &socket);
/** slsReceiverBase object */ /** Message */
std::unique_ptr<slsReceiverImplementation> receiver{nullptr}; char mess[MAX_STR_LENGTH]{};
/** Function List */ /** success/failure */
int (slsReceiverTCPIPInterface::*flist[NUM_REC_FUNCTIONS])(sls::ServerInterface2& socket); int ret{OK};
/** Message */ /** function index */
char mess[MAX_STR_LENGTH]{}; int fnum{-1};
/** success/failure */ /** Lock Status if server locked to a client */
int ret{OK}; int lockStatus{0};
/** function index */ /** kill tcp server thread */
int fnum{-1}; int killTCPServerThread{0};
/** Lock Status if server locked to a client */ /** thread for TCP server */
int lockStatus{0}; pthread_t TCPServer_thread;
/** kill tcp server thread */ /** tcp thread created flag*/
int killTCPServerThread{0}; bool tcpThreadCreated{false};
/** thread for TCP server */ /** port number */
pthread_t TCPServer_thread; int portNumber;
/** tcp thread created flag*/ //***callback parameters***
bool tcpThreadCreated{false}; /**
* Call back for start acquisition
* callback arguments are
* filepath
* filename
* fileindex
* datasize
*
* return value is insignificant at the moment
* we write depending on file write enable
* users get data to write depending on call backs registered
*/
int (*startAcquisitionCallBack)(char *, char *, uint64_t, uint32_t,
void *) = nullptr;
void *pStartAcquisition{nullptr};
/** port number */ /**
int portNumber; * Call back for acquisition finished
* callback argument is
* total frames caught
*/
void (*acquisitionFinishedCallBack)(uint64_t, void *) = nullptr;
void *pAcquisitionFinished{nullptr};
//***callback parameters*** /**
/** * Call back for raw data
* Call back for start acquisition * args to raw data ready callback are
* callback arguments are * sls_receiver_header frame metadata
* filepath * dataPointer is the pointer to the data
* filename * dataSize in bytes is the size of the data in bytes.
* fileindex */
* datasize void (*rawDataReadyCallBack)(char *, char *, uint32_t, void *) = nullptr;
*
* return value is insignificant at the moment
* we write depending on file write enable
* users get data to write depending on call backs registered
*/
int (*startAcquisitionCallBack)(char*, char*, uint64_t, uint32_t, void*) = nullptr;
void *pStartAcquisition{nullptr};
/**
* Call back for acquisition finished
* callback argument is
* total frames caught
*/
void (*acquisitionFinishedCallBack)(uint64_t, void*) = nullptr;
void *pAcquisitionFinished{nullptr};
/**
* Call back for raw data
* args to raw data ready callback are
* sls_receiver_header frame metadata
* dataPointer is the pointer to the data
* dataSize in bytes is the size of the data in bytes.
*/
void (*rawDataReadyCallBack)(char* ,
char*, uint32_t, void*) = nullptr;
/** /**
* Call back for raw data (modified) * Call back for raw data (modified)
* args to raw data ready callback are * args to raw data ready callback are
* sls_receiver_header frame metadata * sls_receiver_header frame metadata
* dataPointer is the pointer to the data * dataPointer is the pointer to the data
* revDatasize is the reference of data size in bytes. Can be modified to the new size to be written/streamed. (only smaller value). * revDatasize is the reference of data size in bytes. Can be modified to
* the new size to be written/streamed. (only smaller value).
*/ */
void (*rawDataModifyReadyCallBack)(char* , void (*rawDataModifyReadyCallBack)(char *, char *, uint32_t &,
char*, uint32_t &, void*) = nullptr; void *) = nullptr;
void *pRawDataReady{nullptr}; void *pRawDataReady{nullptr};
protected:
std::unique_ptr<sls::ServerSocket> server{nullptr};
private:
void VerifyLock();
void VerifyIdle(sls::ServerInterface2 &socket);
protected: slsReceiverImplementation *impl() {
if (receiver != nullptr) {
return receiver.get();
std::unique_ptr<sls::ServerSocket> server{nullptr}; } else {
throw sls::SocketError(
private: "Receiver not set up. Please use rx_hostname first.\n");
int VerifyLock(int &ret, char *mess); }
int VerifyLockAndIdle(int &ret, char *mess, int fnum); }
}; };

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3,9 +3,13 @@
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <netdb.h> #include <netdb.h>
#include <numeric>
#include <string> #include <string>
namespace sls { namespace sls {
/* Base class for TCP socket, this is used to send data between detector, client
and receiver. Specific protocols inherit from this class.*/
class DataSocket { class DataSocket {
public: public:
DataSocket(int socketId); DataSocket(int socketId);
@ -13,14 +17,36 @@ class DataSocket {
virtual ~DataSocket(); virtual ~DataSocket();
DataSocket &operator=(DataSocket &&move) noexcept; DataSocket &operator=(DataSocket &&move) noexcept;
void swap(DataSocket &other) noexcept; void swap(DataSocket &other) noexcept;
//No copy since the class manage the underlying socket
DataSocket(const DataSocket &) = delete; DataSocket(const DataSocket &) = delete;
DataSocket &operator=(DataSocket const &) = delete; DataSocket &operator=(DataSocket const &) = delete;
int getSocketId() const { int getSocketId() const { return socketId_; }
return socketId_;
int Send(const void *buffer, size_t size);
template <typename T> int Send(T &&data) {
return Send(&data, sizeof(data));
} }
int sendData(const void *buffer, size_t size); // Variadic template to send all arguments
int receiveData(void *buffer, size_t size); template <class... Args> int SendAll(Args &&... args) {
auto l = std::initializer_list<int>{Send(args)...};
auto sum = std::accumulate(begin(l), end(l), 0);
return sum;
}
int Receive(void *buffer, size_t size);
template <typename T> int Receive(T &arg) {
return Receive(&arg, sizeof(arg));
}
template <typename T> T Receive() {
T arg;
Receive(&arg, sizeof(arg));
return arg;
}
int read(void *buffer, size_t size); int read(void *buffer, size_t size);
int write(void *buffer, size_t size);
int setTimeOut(int t_seconds); int setTimeOut(int t_seconds);
int setReceiveTimeout(int us); int setReceiveTimeout(int us);
void close(); void close();
@ -30,9 +56,4 @@ class DataSocket {
int socketId_ = -1; int socketId_ = -1;
}; };
int ConvertHostnameToInternetAddress(const char *const hostname, struct ::addrinfo **res);
int ConvertInternetAddresstoIpString(struct ::addrinfo *res, char *ip, const int ipsize);
struct ::sockaddr_in ConvertHostnameToInternetAddress(const std::string &hostname);
}; // namespace sls }; // namespace sls

View File

@ -13,16 +13,19 @@ class ServerInterface2 : public DataSocket {
using defs = slsDetectorDefs; using defs = slsDetectorDefs;
public: public:
ServerInterface2(int socketId) : DataSocket(socketId){} ServerInterface2(int socketId) : DataSocket(socketId) {}
int sendResult(bool update, int ret, void *retval, int retvalSize, int sendResult(int ret, void *retval, int retvalSize, char *mess = nullptr);
char *mess = nullptr);
int receiveArg(int &ret, char *mess, void *arg, int sizeofArg);
template <typename T> int sendResult(int ret, T &retval) {
return sendResult(ret, &retval, sizeof(retval, nullptr));
}
template <typename T> int sendResult(T &&retval) {
private: Send(defs::OK);
Send(retval);
return defs::OK;
}
}; };
} // namespace sls } // namespace sls

View File

@ -15,13 +15,13 @@ class ServerSocket : public DataSocket {
public: public:
ServerSocket(int port); ServerSocket(int port);
ServerInterface2 accept(); ServerInterface2 accept();
IpAddr getLastClient() noexcept { return lastClient; } IpAddr getLastClient() const noexcept { return lastClient; }
IpAddr getThisClient() noexcept { return thisClient; } IpAddr getThisClient() const noexcept { return thisClient; }
IpAddr getLockedBy() noexcept { return lockedBy; } IpAddr getLockedBy() const noexcept { return lockedBy; }
bool differentClients() const noexcept {return lastClient != thisClient;}
void setLockedBy(IpAddr addr) { lockedBy = addr; } void setLockedBy(IpAddr addr) { lockedBy = addr; }
void setLastClient(IpAddr addr) { lastClient = addr; } void setLastClient(IpAddr addr) { lastClient = addr; }
int getPort() const; int getPort() const noexcept { return serverPort; }
void SendResult(int &ret, void *retval, int retvalSize, char *mess);
private: private:
IpAddr thisClient; IpAddr thisClient;

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <array>
namespace sls { namespace sls {
@ -15,6 +16,7 @@ class IpAddr {
IpAddr(const char *address); IpAddr(const char *address);
std::string str() const; std::string str() const;
std::string hex() const; std::string hex() const;
std::array<char, 16u> arr() const;
constexpr bool operator==(const IpAddr &other) const noexcept { constexpr bool operator==(const IpAddr &other) const noexcept {
return addr_ == other.addr_; return addr_ == other.addr_;
} }
@ -56,7 +58,7 @@ class MacAddr {
constexpr uint64_t uint64() const noexcept { return addr_; } constexpr uint64_t uint64() const noexcept { return addr_; }
}; };
uint32_t HostnameToIp(const char *hostname); IpAddr HostnameToIp(const char *hostname);
std::string IpToInterfaceName(const std::string& ip); std::string IpToInterfaceName(const std::string& ip);
MacAddr InterfaceNameToMac(std::string inf); MacAddr InterfaceNameToMac(std::string inf);

View File

@ -1,10 +1,10 @@
/** API versions */ /** API versions */
#define GITBRANCH "refgui" #define GITBRANCH "refgui"
#define APIMOENCH 0x181108 #define APIMOENCH 0x181108
#define APILIB 0x190405 #define APILIB 0x190604
#define APIRECEIVER 0x190405 #define APIRECEIVER 0x190604
#define APIGUI 0x190405 #define APIGUI 0x190405
#define APIGOTTHARD 0x190604
#define APIJUNGFRAU 0x190604
#define APIEIGER 0x190604
#define APICTB 0x190604 #define APICTB 0x190604
#define APIEIGER 0x190604
#define APIJUNGFRAU 0x190604
#define APIGOTTHARD 0x190604

View File

@ -62,34 +62,31 @@ int ClientSocket::sendCommandThenRead(int fnum, const void *args,
size_t args_size, void *retval, size_t args_size, void *retval,
size_t retval_size) { size_t retval_size) {
int ret = slsDetectorDefs::FAIL; int ret = slsDetectorDefs::FAIL;
sendData(&fnum, sizeof(fnum)); Send(&fnum, sizeof(fnum));
sendData(args, args_size); Send(args, args_size);
readReply(ret, retval, retval_size); readReply(ret, retval, retval_size);
return ret; return ret;
} }
void ClientSocket::readReply(int &ret, void *retval, size_t retval_size) { void ClientSocket::readReply(int &ret, void *retval, size_t retval_size) {
receiveData(&ret, sizeof(ret)); Receive(&ret, sizeof(ret));
if (ret == slsDetectorDefs::FAIL) { if (ret == slsDetectorDefs::FAIL) {
char mess[MAX_STR_LENGTH]{}; char mess[MAX_STR_LENGTH]{};
// get error message // get error message
receiveData(mess, sizeof(mess)); Receive(mess, sizeof(mess));
FILE_LOG(logERROR) << socketType << " returned error: " << mess;
std::cout << "\n"; // needed to reset the color.
// Do we need to know hostname here? // Do we need to know hostname here?
// In that case save it??? // In that case save it???
if (socketType == "Receiver") { if (socketType == "Receiver") {
throw ReceiverError(mess); throw ReceiverError("Receiver returned: " + std::string(mess));
} else if (socketType == "Detector") { } else if (socketType == "Detector") {
throw DetectorError(mess); throw DetectorError("Detector returned: " + std::string(mess));
} else { } else {
throw GuiError(mess); throw GuiError(mess);
} }
} }
// get retval // get retval
receiveData(retval, retval_size); Receive(retval, retval_size);
} }
}; // namespace sls }; // namespace sls

View File

@ -3,13 +3,15 @@
#include "sls_detector_exceptions.h" #include "sls_detector_exceptions.h"
#include <algorithm> #include <algorithm>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <cassert>
#include <cstring> #include <cstring>
#include <fcntl.h>
#include <iostream> #include <iostream>
#include <netdb.h> #include <netdb.h>
#include <sstream>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h>
namespace sls { namespace sls {
@ -25,7 +27,6 @@ DataSocket::~DataSocket() {
try { try {
close(); close();
} catch (...) { } catch (...) {
// pass
} }
} }
} }
@ -40,18 +41,52 @@ DataSocket &DataSocket::operator=(DataSocket &&move) noexcept {
return *this; return *this;
} }
int DataSocket::receiveData(void *buffer, size_t size) { int DataSocket::Receive(void *buffer, size_t size) {
size_t dataRead = 0; // TODO!(Erik) Add sleep? how many reties?
while (dataRead < size) { int bytes_expected = static_cast<int>(size); // signed size
dataRead += int bytes_read = 0;
::read(getSocketId(), reinterpret_cast<char *>(buffer) + dataRead, while (bytes_read < bytes_expected) {
size - dataRead); auto this_read =
::read(getSocketId(), reinterpret_cast<char *>(buffer) + bytes_read,
bytes_expected - bytes_read);
if (this_read <= 0)
break;
bytes_read += this_read;
}
if (bytes_read == bytes_expected) {
return bytes_read;
} else {
std::ostringstream ss;
ss << "TCP socket read " << bytes_read << " bytes instead of "
<< bytes_expected << " bytes";
throw sls::SocketError(ss.str());
} }
return dataRead;
} }
int DataSocket::read(void *buffer, size_t size){ int DataSocket::Send(const void *buffer, size_t size) {
return ::read(getSocketId(), reinterpret_cast<char *>(buffer), size); int bytes_sent = 0;
int data_size = static_cast<int>(size); // signed size
while (bytes_sent < (data_size)) {
auto this_send = ::write(getSocketId(), buffer, size);
if (this_send <= 0)
break;
bytes_sent += this_send;
}
if (bytes_sent != data_size) {
std::ostringstream ss;
ss << "TCP socket sent " << bytes_sent << " bytes instead of "
<< data_size << " bytes";
throw sls::SocketError(ss.str());
}
return bytes_sent;
}
int DataSocket::write(void *buffer, size_t size) {
return ::write(getSocketId(), buffer, size);
}
int DataSocket::read(void *buffer, size_t size) {
return ::read(getSocketId(), buffer, size);
} }
int DataSocket::setReceiveTimeout(int us) { int DataSocket::setReceiveTimeout(int us) {
@ -62,17 +97,6 @@ int DataSocket::setReceiveTimeout(int us) {
sizeof(struct timeval)); sizeof(struct timeval));
} }
int DataSocket::sendData(const void *buffer, size_t size) {
int dataSent = 0;
while (dataSent < (int)size) {
dataSent +=
write(getSocketId(), reinterpret_cast<const char *>(buffer) + dataSent,
size - dataSent);
}
return dataSent;
}
int DataSocket::setTimeOut(int t_seconds) { int DataSocket::setTimeOut(int t_seconds) {
if (t_seconds <= 0) if (t_seconds <= 0)
return -1; return -1;
@ -102,7 +126,6 @@ void DataSocket::close() {
throw SocketError("could not close socket"); throw SocketError("could not close socket");
} }
socketId_ = -1; socketId_ = -1;
} else { } else {
throw std::runtime_error("Socket ERROR: close called on bad socket\n"); throw std::runtime_error("Socket ERROR: close called on bad socket\n");
} }
@ -113,73 +136,4 @@ void DataSocket::shutDownSocket() {
close(); close();
} }
struct sockaddr_in
ConvertHostnameToInternetAddress(const std::string &hostname) {
struct addrinfo hints, *result;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags |= AI_CANONNAME;
struct sockaddr_in serverAddr {};
if (getaddrinfo(hostname.c_str(), nullptr, &hints, &result) != 0) {
freeaddrinfo(result);
std::string msg = "ClientSocket cannot decode host:" + hostname + "\n";
throw SocketError(msg);
}
serverAddr.sin_family = AF_INET;
memcpy((char *)&serverAddr.sin_addr.s_addr,
&((struct sockaddr_in *)result->ai_addr)->sin_addr,
sizeof(in_addr_t));
freeaddrinfo(result);
return serverAddr;
}
int ConvertHostnameToInternetAddress(const char *const hostname,
struct ::addrinfo **res) {
// criteria in selecting socket address structures returned by res
struct ::addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
// get host info into res
int errcode = getaddrinfo(hostname, nullptr, &hints, res);
if (errcode != 0) {
FILE_LOG(logERROR) << "Could not convert hostname (" << hostname
<< ") to internet address (zmq):"
<< gai_strerror(errcode);
} else {
if (*res == nullptr) {
FILE_LOG(logERROR) << "Could not converthostname (" << hostname
<< ") to internet address (zmq):"
"gettaddrinfo returned null";
} else {
return 0;
}
}
FILE_LOG(logERROR) << "Could not convert hostname to internet address";
return 1;
};
/**
* Convert Internet Address structure pointer to ip string (char*)
* Clears the internet address structure as well
* @param res pointer to internet address structure
* @param ip pointer to char array to store result in
* @param ipsize size available in ip buffer
* @return 1 for fail, 0 for success
*/
// Do not make this static (for multi threading environment)
int ConvertInternetAddresstoIpString(struct ::addrinfo *res, char *ip,
const int ipsize) {
if (inet_ntop(res->ai_family,
&((struct sockaddr_in *)res->ai_addr)->sin_addr, ip,
ipsize) != nullptr) {
::freeaddrinfo(res);
return 0;
}
FILE_LOG(logERROR) << "Could not convert internet address to ip string";
return 1;
}
} // namespace sls } // namespace sls

View File

@ -1,38 +1,24 @@
#include "ServerInterface2.h" #include "ServerInterface2.h"
#include <cassert> #include <cassert>
#include <cstring>
#include <sstream>
namespace sls { namespace sls {
int ServerInterface2::sendResult(bool update, int ret, void *retval, int ServerInterface2::sendResult(int ret, void *retval, int retvalSize,
int retvalSize, char *mess) { char *mess) {
// if (update && ret == defs::OK && server_->DifferentClients()) { write(&ret, sizeof(ret));
// ret = defs::FORCE_UPDATE;
// }
sendData(&ret, sizeof(ret));
if (ret == defs::FAIL) { if (ret == defs::FAIL) {
// send error message if (mess != nullptr) {
if (mess) write(mess, MAX_STR_LENGTH);
sendData(mess, MAX_STR_LENGTH); } else {
// debugging feature. should not happen.
else
FILE_LOG(logERROR) << "No error message provided for this " FILE_LOG(logERROR) << "No error message provided for this "
"failure. Will mess up TCP\n"; "failure. Will mess up TCP\n";
}
} else {
write(retval, retvalSize);
} }
sendData(retval, retvalSize);
return ret; return ret;
} }
int ServerInterface2::receiveArg(int &ret, char *mess, void *arg,
int sizeofArg) {
assert(sizeofArg > 0);
int bytes_read = read(arg, sizeofArg);
if (bytes_read == sizeofArg) {
return defs::OK;
} else {
FILE_LOG(logERROR) << "Read: " << bytes_read << " instead of "
<< sizeofArg;
return defs::FAIL;
}
}
} // namespace sls } // namespace sls

View File

@ -52,26 +52,4 @@ ServerInterface2 ServerSocket::accept() {
return ServerInterface2(newSocket); return ServerInterface2(newSocket);
} }
int ServerSocket::getPort() const { return serverPort; }
void ServerSocket::SendResult(int &ret, void* retval, int retvalSize, char* mess) {
// send success of operation
sendData(&ret, sizeof(ret));
if (ret == slsDetectorDefs::FAIL) {
// create error message if empty
if (!strlen(mess)) {
strcpy(mess, "No error message provided for this failure in server. Will mess up TCP.");
}
sendData(mess, MAX_STR_LENGTH);
throw sls::RuntimeError(mess);
}
// send return value
sendData(retval, retvalSize);
}
}; // namespace sls }; // namespace sls

View File

@ -27,10 +27,15 @@ IpAddr::IpAddr(const std::string &address) {
IpAddr::IpAddr(const char *address) { inet_pton(AF_INET, address, &addr_); } IpAddr::IpAddr(const char *address) { inet_pton(AF_INET, address, &addr_); }
std::string IpAddr::str() const { std::string IpAddr::str() const {
char ipstring[INET_ADDRSTRLEN]{}; return arr().data();
inet_ntop(AF_INET, &addr_, ipstring, INET_ADDRSTRLEN); }
std::array<char, INET_ADDRSTRLEN> IpAddr::arr() const{
std::array<char, INET_ADDRSTRLEN> ipstring{};
inet_ntop(AF_INET, &addr_, ipstring.data(), INET_ADDRSTRLEN);
return ipstring; return ipstring;
} }
std::string IpAddr::hex() const { std::string IpAddr::hex() const {
std::ostringstream ss; std::ostringstream ss;
ss << std::hex << std::setfill('0'); ss << std::hex << std::setfill('0');
@ -75,7 +80,7 @@ std::ostream &operator<<(std::ostream &out, const MacAddr &addr) {
return out << addr.str(); return out << addr.str();
} }
uint32_t HostnameToIp(const char *hostname) { IpAddr HostnameToIp(const char *hostname) {
addrinfo hints; addrinfo hints;
addrinfo *result = nullptr; addrinfo *result = nullptr;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
@ -87,7 +92,7 @@ uint32_t HostnameToIp(const char *hostname) {
} }
uint32_t ip = ((sockaddr_in *)result->ai_addr)->sin_addr.s_addr; uint32_t ip = ((sockaddr_in *)result->ai_addr)->sin_addr.s_addr;
freeaddrinfo(result); freeaddrinfo(result);
return ip; return IpAddr(ip);
} }
std::string IpToInterfaceName(const std::string &ip) { std::string IpToInterfaceName(const std::string &ip) {

View File

@ -10,14 +10,14 @@ std::vector<char> server() {
auto server = sls::ServerSocket(1950); auto server = sls::ServerSocket(1950);
auto s = server.accept(); auto s = server.accept();
std::vector<char> buffer(100, '\0'); std::vector<char> buffer(100, '\0');
s.receiveData(buffer.data(), buffer.size()); s.Receive(buffer.data(), buffer.size());
std::cout << "ServerReceived: " << std::string(buffer.begin(), buffer.end()) std::cout << "ServerReceived: " << std::string(buffer.begin(), buffer.end())
<< '\n'; << '\n';
std::vector<char> to_send(100, '\0'); std::vector<char> to_send(100, '\0');
to_send[0] = 'O'; to_send[0] = 'O';
to_send[1] = 'K'; to_send[1] = 'K';
s.sendData(to_send.data(), to_send.size()); s.Send(to_send.data(), to_send.size());
s.close(); s.close();
return buffer; return buffer;
} }
@ -31,8 +31,8 @@ TEST_CASE("The server recive the same message as we send", "[support]") {
auto s = std::async(std::launch::async, server); auto s = std::async(std::launch::async, server);
std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::this_thread::sleep_for(std::chrono::milliseconds(100));
auto client = sls::DetectorSocket("localhost", 1950); auto client = sls::DetectorSocket("localhost", 1950);
client.sendData(sent_message.data(), sent_message.size()); client.Send(sent_message.data(), sent_message.size());
client.receiveData(received_message.data(), received_message.size()); client.Receive(received_message.data(), received_message.size());
client.close(); client.close();
auto server_message = s.get(); auto server_message = s.get();

View File

@ -11,9 +11,11 @@ using namespace sls;
TEST_CASE("Convert mac address using classes", "[support]") { TEST_CASE("Convert mac address using classes", "[support]") {
std::vector<uint64_t> vec_addr{346856806822, 346856806852, 262027939863028,0, 281474976710655}; std::vector<uint64_t> vec_addr{346856806822, 346856806852, 262027939863028,
0, 281474976710655};
std::vector<std::string> vec_ans{"00:50:c2:46:d9:a6", "00:50:c2:46:d9:c4", std::vector<std::string> vec_ans{"00:50:c2:46:d9:a6", "00:50:c2:46:d9:c4",
"ee:50:22:46:d9:f4", "00:00:00:00:00:00", "ff:ff:ff:ff:ff:ff"}; "ee:50:22:46:d9:f4", "00:00:00:00:00:00",
"ff:ff:ff:ff:ff:ff"};
for (size_t i = 0; i != vec_addr.size(); ++i) { for (size_t i = 0; i != vec_addr.size(); ++i) {
auto mac0 = MacAddr(vec_addr[i]); auto mac0 = MacAddr(vec_addr[i]);
auto mac1 = MacAddr(vec_ans[i]); auto mac1 = MacAddr(vec_ans[i]);
@ -42,12 +44,13 @@ TEST_CASE("Hex representation of MAC", "[support]") {
} }
TEST_CASE("Convert IP using classes ", "[support]") { TEST_CASE("Convert IP using classes ", "[support]") {
std::vector<uint32_t> vec_addr{4073554305, 2747957633, 2697625985, 2566979594, 0}; std::vector<uint32_t> vec_addr{4073554305, 2747957633, 2697625985,
2566979594, 0};
std::vector<std::string> vec_ans{"129.129.205.242", "129.129.202.163", std::vector<std::string> vec_ans{"129.129.205.242", "129.129.202.163",
"129.129.202.160", "10.0.1.153", "0.0.0.0"}; "129.129.202.160", "10.0.1.153",
std::vector<std::string> vec_hex{"8181cdf2", "8181caa3", "0.0.0.0"};
"8181caa0", "0a000199","00000000"}; std::vector<std::string> vec_hex{"8181cdf2", "8181caa3", "8181caa0",
"0a000199", "00000000"};
for (size_t i = 0; i != vec_addr.size(); ++i) { for (size_t i = 0; i != vec_addr.size(); ++i) {
auto ip0 = IpAddr(vec_addr[i]); auto ip0 = IpAddr(vec_addr[i]);
@ -59,7 +62,9 @@ TEST_CASE("Convert IP using classes ", "[support]") {
CHECK(ip0 == vec_ans[i]); CHECK(ip0 == vec_ans[i]);
CHECK(ip1 == vec_ans[i]); CHECK(ip1 == vec_ans[i]);
CHECK(ip0.str() == vec_ans[i]); CHECK(ip0.str() == vec_ans[i]);
CHECK(ip0.arr().data() == vec_ans[i]);
CHECK(ip1.str() == vec_ans[i]); CHECK(ip1.str() == vec_ans[i]);
CHECK(ip1.arr().data() == vec_ans[i]);
CHECK(ip0.hex() == vec_hex[i]); CHECK(ip0.hex() == vec_hex[i]);
CHECK(ip1.hex() == vec_hex[i]); CHECK(ip1.hex() == vec_hex[i]);
} }
@ -80,7 +85,7 @@ TEST_CASE("Convert to uint for sending over network", "[support]") {
CHECK(b == 4073554305); CHECK(b == 4073554305);
} }
TEST_CASE("Hostname lookup failed throws", "[support]"){ TEST_CASE("Hostname lookup failed throws", "[support]") {
CHECK_THROWS_AS(HostnameToIp("pippifax"), RuntimeError); CHECK_THROWS_AS(HostnameToIp("pippifax"), RuntimeError);
} }
@ -90,7 +95,6 @@ TEST_CASE("IP Output operator gives same result as string", "[support]") {
os << addr; os << addr;
CHECK(os.str() == "129.129.205.242"); CHECK(os.str() == "129.129.205.242");
CHECK(os.str() == addr.str()); CHECK(os.str() == addr.str());
} }
TEST_CASE("MAC Output operator gives same result as string", "[support]") { TEST_CASE("MAC Output operator gives same result as string", "[support]") {
@ -101,4 +105,4 @@ TEST_CASE("MAC Output operator gives same result as string", "[support]") {
CHECK(os.str() == addr.str()); CHECK(os.str() == addr.str());
} }
//TODO!(Erik) Look up a real hostname and verify the IP // TODO!(Erik) Look up a real hostname and verify the IP

View File

@ -7,6 +7,16 @@ set(SLS_TEST_SOURCES
test.cpp test.cpp
) )
add_executable(testclient src/testclient.cpp)
target_link_libraries(testclient slsSupportLib)
set_target_properties(testclient PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
add_executable(testserver src/testserver.cpp)
target_link_libraries(testserver slsSupportLib)
set_target_properties(testserver PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
add_executable(tests ${SLS_TEST_SOURCES}) add_executable(tests ${SLS_TEST_SOURCES})
target_link_libraries(tests target_link_libraries(tests
slsProjectOptions slsProjectOptions
@ -31,8 +41,9 @@ endif (SLS_USE_RECEIVER)
set_target_properties(tests PROPERTIES set_target_properties(tests PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
) )
include(CTest) include(CTest)
include(Catch) include(Catch)
catch_discover_tests(tests) catch_discover_tests(tests)
# #TODO! Move to automatic test discovery
# add_test(test ${CMAKE_BINARY_DIR}/bin/testSlsReceiver)

View File

@ -0,0 +1,5 @@
#pragma once
#include <cstdint>
enum class func_id{read_data, read_int, read_half_data, combined};
constexpr size_t MB = 1048576;
constexpr size_t DATA_SIZE = 50*MB;

85
tests/src/testclient.cpp Normal file
View File

@ -0,0 +1,85 @@
#include "ClientSocket.h"
#include "clara.hpp"
#include "sls_detector_exceptions.h"
#include "tests/testenum.h"
#include "container_utils.h"
#include <iostream>
bool help = false;
int main(int argc, char **argv) {
std::cout << "Test client\n";
std::string hostname{"localhost"};
int port = 2345;
auto cli =
clara::Help(help) |
clara::Opt(hostname, "hostname")["-n"]["--hostname"]("Hostname") |
clara::Opt(port, "port")["-p"]["--port"]("Port to send to");
auto result = cli.parse(clara::Args(argc, argv));
if (!result) {
std::cerr << "Error in command line: " << result.errorMessage()
<< std::endl;
exit(1);
}
if (help) {
std::cout << cli << std::endl;
return 0;
}
std::cout << "Sending to: " << hostname << ":" << port << "\n";
auto data = sls::make_unique<char[]>(DATA_SIZE);
// Many connections sending small amounts
for (int i = 0; i != 100; ++i) {
std::cout << "Sending: " << i << "\n";
auto socket = sls::ClientSocket("test", hostname, port);
std::cout << "Sent: " << socket.Send(func_id::read_int) << " bytes\n";
std::cout << "Sent: " << socket.Send(i) << " bytes\n";
}
// Sending larger blocks
for (int i = 0; i != 5; ++i) {
std::cout << "Sending data\n";
auto socket = sls::ClientSocket("test", hostname, port);
std::cout << "Sent: " << socket.Send(func_id::read_data) << " bytes\n";
std::cout << "Sent: " << socket.Send(data.get(), DATA_SIZE)
<< " bytes\n";
}
// Send too little data
{
auto socket = sls::ClientSocket("test", hostname, port);
std::cout << "Sent: " << socket.Send(func_id::read_data) << " bytes\n";
std::cout << "Sent: " << socket.Send(data.get(), DATA_SIZE / 2)
<< " bytes\n";
}
// Send too much data
try {
auto socket = sls::ClientSocket("test", hostname, port);
std::cout << "Sent: " << socket.Send(func_id::read_half_data)
<< " bytes\n";
std::cout << "Sent: " << socket.Send(data.get(), DATA_SIZE)
<< " bytes\n";
} catch (const sls::SocketError &e) {
}
// Some ints again
for (int i = 0; i != 10; ++i) {
std::cout << "Sending: " << i << "\n";
auto socket = sls::ClientSocket("test", hostname, port);
std::cout << "Sent: " << socket.Send(func_id::read_int) << " bytes\n";
std::cout << "Sent: " << socket.Send(i) << " bytes\n";
}
// some combined sends
{
int a = 9;
double b = 18.3;
float c = -1.2;
auto socket = sls::ClientSocket("test", hostname, port);
int s = socket.SendAll(func_id::combined, a, b, c);
std::cout << "send all: " << s << "\n";
}
}

82
tests/src/testserver.cpp Normal file
View File

@ -0,0 +1,82 @@
#include "ServerSocket.h"
#include "clara.hpp"
#include "tests/testenum.h"
#include "ServerInterface2.h"
#include "container_utils.h"
#include <iostream>
#include <unordered_map>
// For hashing of enum with C++11, not needed in 14
struct EnumClassHash {
template <typename T> std::size_t operator()(T t) const {
return static_cast<std::size_t>(t);
}
};
using Interface = sls::ServerInterface2;
using func_ptr = void (*)(Interface &);
/********************************************
* Mapped functions *
********************************************/
void read_data(Interface &socket) {
auto data = sls::make_unique<char[]>(DATA_SIZE);
std::cout << "Read: " << socket.Receive(data.get(), DATA_SIZE)
<< " bytes into buffer\n";
}
void read_half_data(Interface &socket) {
auto data = sls::make_unique<char[]>(DATA_SIZE);
std::cout << "Read: " << socket.Receive(data.get(), DATA_SIZE / 2)
<< " bytes into buffer\n";
}
void read_int(Interface &socket) {
auto i = socket.Receive<int>();
std::cout << "Read <int>: " << i << "\n";
}
void read_combined(Interface &socket){
auto i = socket.Receive<int>();
auto d = socket.Receive<double>();
auto f = socket.Receive<float>();
std::cout << "read i: " << i << " d: " << d << " f: " << f << "\n";
}
// Map from int to function pointer, in this case probably a map would be faster
std::unordered_map<func_id, func_ptr, EnumClassHash> fmap{
{func_id::read_data, &read_data},
{func_id::read_int, &read_int},
{func_id::read_half_data, &read_half_data},
{func_id::combined, &read_combined}};
int main(int argc, char **argv) {
std::cout << "Starting test server...\n";
int port = 2345;
// Parse command line arguments using clara
auto cli = clara::Opt(port, "port")["-p"]["--port"]("Port to send to");
auto result = cli.parse(clara::Args(argc, argv));
if (!result) {
std::cerr << "Error in command line: " << result.errorMessage()
<< std::endl;
exit(1);
}
std::cout << "Listening to port: " << port << "\n";
auto server = sls::ServerSocket(port);
while (true) {
try {
auto socket = server.accept();
auto fnum = socket.Receive<func_id>();
std::cout << "Calling func: " << (int)fnum << "\n";
(*fmap[fnum])(socket); // call mapped function
} catch (const sls::RuntimeError &e) {
// Do nothing, error is printed when the exeption is created
}
}
}