merge resolved

This commit is contained in:
maliakal_d 2019-06-11 15:56:13 +02:00
commit 3c1df02414
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.
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{tabular}{|c|c|c|c|c|}
\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
1 & 16 & \textbf{256} & 3901 & \\
\hline
@ -347,10 +348,10 @@ GbE & dynamic range & continuos maximum frame rate(Hz) & minimum period ($\mu$s)
\hline
10 & 16 & \textbf{2560} & 391 & 400\\
\hline
10 & 32 & \textbf{1280}& 782 & 800\\
10 & 32 & \textbf{1280} (675~Hz max)& 782 & 800\\
\hline
\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}
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}
@ -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:
\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{tabular}{ |c| c| }
\hline
max frame rate & settings\\
\hline
\textcolor{red}{170 Hz} & \textcolor{red}{32-bit} \\
\textcolor{red}{189~Hz (977~Hz max)} & \textcolor{red}{32-bit} \\
& Nframes=infinite\\
\hline
\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}
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{tabular}{ |c| c| }
\hline
max frame rate & settings\\
\hline
\textcolor{red}{170 Hz} & \textcolor{red}{32-bit} \\
\textcolor{red}{189~Hz (977~Hz)} & \textcolor{red}{32-bit} \\
& Nframes=infinite\\
\hline
\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}
\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:
@ -539,14 +540,16 @@ The time between 12-bit subframes are listed in table~\ref{t32bitframe}.
\begin{flushleft}
\begin{tabular}{|c|c|c|c|c|c|}
\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
32 & 2 & parallel & 12 & 2 & 170\\
32 & 2 & parallel & 0.00262144 & 12 & 380 & 189\\
\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
\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}
\end{flushleft}
\end{table}
@ -1582,7 +1585,7 @@ In table~\ref{tframescomplete} is a list of all the readout times in the differe
\hline
8 & 1 & parallel & 6.1 & 5.7 & 181 & 15k/52k\\
\hline
8 & 1 & nonparallel & 170.5 & 5.7 & 175 & 15k/52k\\
8 & 1 & nonparallel & 170 & 5.7 & 175 & 15k/52k\\
\hline
8 & 2 & parallel & 11.2 & 2.9 & 342 & infinite\\
\hline

View File

@ -796,6 +796,10 @@ class multiSlsDetector : public virtual slsDetectorDefs {
*/
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
* @param val value (in V)

View File

@ -16,6 +16,7 @@
class multiSlsDetector;
class ServerInterface;
#define SLS_SHMVERSION 0x190515
@ -176,10 +177,10 @@ struct sharedSlsDetector {
int rxReadFreq;
/** 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) **/
char rxZmqip[MAX_STR_LENGTH];
sls::IpAddr rxZmqip;
/** gap pixels enable */
int gappixels;

View File

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

View File

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

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 <cstdint>
#include <netdb.h>
#include <numeric>
#include <string>
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 {
public:
DataSocket(int socketId);
@ -13,14 +17,36 @@ class DataSocket {
virtual ~DataSocket();
DataSocket &operator=(DataSocket &&move) noexcept;
void swap(DataSocket &other) noexcept;
//No copy since the class manage the underlying socket
DataSocket(const DataSocket &) = delete;
DataSocket &operator=(DataSocket const &) = delete;
int getSocketId() const {
return socketId_;
int getSocketId() const { 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);
int receiveData(void *buffer, size_t size);
// Variadic template to send all arguments
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 write(void *buffer, size_t size);
int setTimeOut(int t_seconds);
int setReceiveTimeout(int us);
void close();
@ -30,9 +56,4 @@ class DataSocket {
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

View File

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

View File

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

View File

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

View File

@ -1,10 +1,10 @@
/** API versions */
#define GITBRANCH "refgui"
#define APIMOENCH 0x181108
#define APILIB 0x190405
#define APIRECEIVER 0x190405
#define APILIB 0x190604
#define APIRECEIVER 0x190604
#define APIGUI 0x190405
#define APIGOTTHARD 0x190604
#define APIJUNGFRAU 0x190604
#define APIEIGER 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 retval_size) {
int ret = slsDetectorDefs::FAIL;
sendData(&fnum, sizeof(fnum));
sendData(args, args_size);
Send(&fnum, sizeof(fnum));
Send(args, args_size);
readReply(ret, retval, retval_size);
return ret;
}
void ClientSocket::readReply(int &ret, void *retval, size_t retval_size) {
receiveData(&ret, sizeof(ret));
Receive(&ret, sizeof(ret));
if (ret == slsDetectorDefs::FAIL) {
char mess[MAX_STR_LENGTH]{};
// get error message
receiveData(mess, sizeof(mess));
FILE_LOG(logERROR) << socketType << " returned error: " << mess;
std::cout << "\n"; // needed to reset the color.
Receive(mess, sizeof(mess));
// Do we need to know hostname here?
// In that case save it???
if (socketType == "Receiver") {
throw ReceiverError(mess);
throw ReceiverError("Receiver returned: " + std::string(mess));
} else if (socketType == "Detector") {
throw DetectorError(mess);
throw DetectorError("Detector returned: " + std::string(mess));
} else {
throw GuiError(mess);
}
}
// get retval
receiveData(retval, retval_size);
Receive(retval, retval_size);
}
}; // namespace sls

View File

@ -3,13 +3,15 @@
#include "sls_detector_exceptions.h"
#include <algorithm>
#include <arpa/inet.h>
#include <cassert>
#include <cstring>
#include <fcntl.h>
#include <iostream>
#include <netdb.h>
#include <sstream>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
namespace sls {
@ -25,7 +27,6 @@ DataSocket::~DataSocket() {
try {
close();
} catch (...) {
// pass
}
}
}
@ -40,18 +41,52 @@ DataSocket &DataSocket::operator=(DataSocket &&move) noexcept {
return *this;
}
int DataSocket::receiveData(void *buffer, size_t size) {
size_t dataRead = 0;
while (dataRead < size) {
dataRead +=
::read(getSocketId(), reinterpret_cast<char *>(buffer) + dataRead,
size - dataRead);
int DataSocket::Receive(void *buffer, size_t size) {
// TODO!(Erik) Add sleep? how many reties?
int bytes_expected = static_cast<int>(size); // signed size
int bytes_read = 0;
while (bytes_read < bytes_expected) {
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){
return ::read(getSocketId(), reinterpret_cast<char *>(buffer), size);
int DataSocket::Send(const void *buffer, size_t 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) {
@ -62,17 +97,6 @@ int DataSocket::setReceiveTimeout(int us) {
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) {
if (t_seconds <= 0)
return -1;
@ -102,7 +126,6 @@ void DataSocket::close() {
throw SocketError("could not close socket");
}
socketId_ = -1;
} else {
throw std::runtime_error("Socket ERROR: close called on bad socket\n");
}
@ -113,73 +136,4 @@ void DataSocket::shutDownSocket() {
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

View File

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

View File

@ -52,26 +52,4 @@ ServerInterface2 ServerSocket::accept() {
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

View File

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

View File

@ -10,14 +10,14 @@ std::vector<char> server() {
auto server = sls::ServerSocket(1950);
auto s = server.accept();
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())
<< '\n';
std::vector<char> to_send(100, '\0');
to_send[0] = 'O';
to_send[1] = 'K';
s.sendData(to_send.data(), to_send.size());
s.Send(to_send.data(), to_send.size());
s.close();
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);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
auto client = sls::DetectorSocket("localhost", 1950);
client.sendData(sent_message.data(), sent_message.size());
client.receiveData(received_message.data(), received_message.size());
client.Send(sent_message.data(), sent_message.size());
client.Receive(received_message.data(), received_message.size());
client.close();
auto server_message = s.get();

View File

@ -11,9 +11,11 @@ using namespace sls;
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",
"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) {
auto mac0 = MacAddr(vec_addr[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]") {
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",
"129.129.202.160", "10.0.1.153", "0.0.0.0"};
std::vector<std::string> vec_hex{"8181cdf2", "8181caa3",
"8181caa0", "0a000199","00000000"};
"129.129.202.160", "10.0.1.153",
"0.0.0.0"};
std::vector<std::string> vec_hex{"8181cdf2", "8181caa3", "8181caa0",
"0a000199", "00000000"};
for (size_t i = 0; i != vec_addr.size(); ++i) {
auto ip0 = IpAddr(vec_addr[i]);
@ -59,7 +62,9 @@ TEST_CASE("Convert IP using classes ", "[support]") {
CHECK(ip0 == vec_ans[i]);
CHECK(ip1 == vec_ans[i]);
CHECK(ip0.str() == vec_ans[i]);
CHECK(ip0.arr().data() == vec_ans[i]);
CHECK(ip1.str() == vec_ans[i]);
CHECK(ip1.arr().data() == vec_ans[i]);
CHECK(ip0.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);
}
TEST_CASE("Hostname lookup failed throws", "[support]"){
TEST_CASE("Hostname lookup failed throws", "[support]") {
CHECK_THROWS_AS(HostnameToIp("pippifax"), RuntimeError);
}
@ -90,7 +95,6 @@ TEST_CASE("IP Output operator gives same result as string", "[support]") {
os << addr;
CHECK(os.str() == "129.129.205.242");
CHECK(os.str() == addr.str());
}
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());
}
//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
)
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})
target_link_libraries(tests
slsProjectOptions
@ -31,8 +41,9 @@ endif (SLS_USE_RECEIVER)
set_target_properties(tests PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
include(CTest)
include(Catch)
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
}
}
}