new socket for slsDetector

This commit is contained in:
Erik Frojdh 2019-01-25 16:44:29 +01:00
parent a1c0d28ddb
commit 89ee1d5bcf
19 changed files with 1341 additions and 1283 deletions

View File

@ -9,21 +9,31 @@ include_directories(
if(USE_TESTS)
set(TEST_SOURCES
src/test-slsDetector.cpp
# src/test.cpp
src/test.cpp
)
add_executable(a ${TEST_SOURCES})
add_executable(detector_test ${TEST_SOURCES})
target_link_libraries(detector_test
slsDetectorShared
slsSupportLib
pthread
rt
)
set_target_properties(detector_test PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
add_executable(a src/a.cpp)
target_link_libraries(a
slsDetectorShared
slsSupportLib
pthread
rt
)
set_target_properties(a PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
set_target_properties(a PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
endif()

View File

@ -0,0 +1,51 @@
#include "catch.hpp"
#include "ClientSocket.h"
#include "logger.h"
#include "slsDetector.h"
#include "sls_detector_defs.h"
#include "Timer.h"
#include "sls_detector_funcs.h"
#include <iostream>
#include <vector>
#define VERBOSE
int main() {
// const std::string hostname = "beb083";
// auto d = slsDetector(hostname);
// d.setOnline(1);
// std::cout << "type: " << d.getDetectorTypeAsString() << '\n';
// std::cout << "hostname: " << d.getHostname() << '\n';
// std::cout << "receiver: " << d.getReceiverOnline() << '\n';
// std::cout << "control: " << d.getControlPort() << '\n';
// std::cout << "stop: " << d.getStopPort() << '\n';
// std::cout << "receiver: " << d.getReceiverPort() << '\n';
// std::cout << "exptime: " << d.setTimer(slsDetectorDefs::timerIndex::ACQUISITION_TIME) << '\n';
// auto d2 = slsDetector(type, 0, 1);
// d2.setHostname("beb098");.
// auto d2 = slsDetector();
// std::cout << "hn: " << d2.getHostname() << '\n';
// sls::Timer t;
// for (int i = 0; i != 100; ++i) {
// int fnum = 1;
// int ret = slsDetectorDefs::FAIL;
// slsDetectorDefs::detectorType retval = slsDetectorDefs::detectorType::GENERIC;
// auto cs = sls::ClientSocket("beb083", 1952);
// cs.sendData(reinterpret_cast<char *>(&fnum), sizeof(fnum));
// cs.receiveData(reinterpret_cast<char *>(&ret), sizeof(ret));
// cs.receiveData(reinterpret_cast<char *>(&retval), sizeof(retval));
// std::cout << "retval: " << retval << '\n';
// }
// t.print_elapsed();
return 0;
}

View File

@ -1,30 +1,207 @@
#include "catch.hpp"
#include "ClientSocket.h"
#include "logger.h"
#include <iostream>
#include <vector>
#include "slsDetector.h"
#include "sls_detector_defs.h"
#include "Timer.h"
#include "sls_detector_funcs.h"
#include <iostream>
#include <vector>
#define VERBOSE
int main(){
const std::string hostname = "beb083";
// const std::string hostname = "129.129.202.194";
auto type = slsDetector::getDetectorTypeAsEnum(hostname);
auto d = slsDetector(type);
d.setHostname(hostname.c_str());
// auto d = slsDetector();
auto type_enum = slsDetectorDefs::detectorType::EIGER;
const std::string hostname = "beb083";
const std::string type_string = "Eiger";
const std::string my_ip = "129.129.205.242";
TEST_CASE("single EIGER detector no receiver basic set and get") {
//TODO! this test should take command line arguments for config
std::cout << "type: " << d.getDetectorTypeAsString() << '\n';
std::cout << "hostname: " << d.getHostname() << '\n';
std::cout << "threshold: " << d.getThresholdEnergy() << '\n';
std::cout << "exptime: " << d.setTimer(slsDetectorDefs::timerIndex::ACQUISITION_TIME) << '\n';
// auto d2 = slsDetector(type, 0, 1);
// d2.setHostname("beb098");.
// auto d2 = slsDetector();
// std::cout << "hn: " << d2.getHostname() << '\n';
return 0;
//Read type by connecting to the detector
auto type = slsDetector::getTypeFromDetector(hostname);
CHECK(type == type_enum);
//Create slsDetector of said type and set hostname and detector online
auto d = slsDetector(type);
CHECK(d.getDetectorTypeAsEnum() == type);
CHECK(d.getDetectorTypeAsString() == type_string);
d.setHostname(hostname);
CHECK(d.getHostname() == hostname);
d.setOnline(true);
CHECK(d.getOnlineFlag() == true);
CHECK(d.getReceiverOnline() == false);
CHECK(d.checkDetectorVersionCompatibility() == slsDetectorDefs::OK);
//Setting and reading exposure time
auto t = 1000000000;
d.setTimer(slsDetectorDefs::timerIndex::ACQUISITION_TIME, t);
CHECK(d.setTimer(slsDetectorDefs::timerIndex::ACQUISITION_TIME) == t);
//size of an eiger half module with and without gap pixels
CHECK(d.getTotalNumberOfChannels() == 256 * 256 * 4);
CHECK(d.getTotalNumberOfChannels(slsDetectorDefs::dimension::X) == 1024);
CHECK(d.getTotalNumberOfChannels(slsDetectorDefs::dimension::Y) == 256);
CHECK(d.getTotalNumberOfChannels(slsDetectorDefs::dimension::Z) == 1);
CHECK(d.getTotalNumberOfChannelsInclGapPixels(slsDetectorDefs::dimension::X) == 1024);
CHECK(d.getTotalNumberOfChannelsInclGapPixels(slsDetectorDefs::dimension::Y) == 256);
CHECK(d.getTotalNumberOfChannelsInclGapPixels(slsDetectorDefs::dimension::Z) == 1);
CHECK(d.getNChans() == 256 * 256);
CHECK(d.getNChans(slsDetectorDefs::dimension::X) == 256);
CHECK(d.getNChans(slsDetectorDefs::dimension::Y) == 256);
CHECK(d.getNChans(slsDetectorDefs::dimension::Z) == 1);
CHECK(d.getNChips() == 4);
CHECK(d.getNChips(slsDetectorDefs::dimension::X) == 4);
CHECK(d.getNChips(slsDetectorDefs::dimension::Y) == 1);
CHECK(d.getNChips(slsDetectorDefs::dimension::Z) == 1);
d.freeSharedMemory();
}
TEST_CASE("Set control port then create a new object with this control port") {
/*
TODO!
Standard port but should not be hardcoded
Is this the best way to initialize the detectors
Using braces to make the object go out of scope
*/
int old_cport = DEFAULT_PORTNO;
int old_sport = DEFAULT_PORTNO + 1;
int new_cport = 1993;
int new_sport = 2000;
{
auto type = slsDetector::getTypeFromDetector(hostname);
CHECK(type == type_enum);
auto d = slsDetector(type);
d.setHostname(hostname);
d.setOnline(true);
CHECK(d.getControlPort() == old_cport);
d.setControlPort(new_cport);
CHECK(d.getStopPort() == old_sport);
d.setStopPort(new_sport);
d.freeSharedMemory();
}
{
auto type = slsDetector::getTypeFromDetector(hostname, new_cport);
CHECK(type == type_enum);
auto d = slsDetector(type);
d.setHostname(hostname);
d.setControlPort(new_cport);
d.setStopPort(new_sport);
CHECK(d.getControlPort() == new_cport);
CHECK(d.getStopPort() == new_sport);
d.setOnline(true);
//Reset standard ports
d.setControlPort(old_cport);
d.setStopPort(old_sport);
d.freeSharedMemory();
}
auto type = slsDetector::getTypeFromDetector(hostname);
CHECK(type == type_enum);
auto d = slsDetector(type);
d.setHostname(hostname);
d.setOnline(true);
CHECK(d.getStopPort() == DEFAULT_PORTNO + 1);
}
TEST_CASE("Locking mechanism and last ip") {
auto type = slsDetector::getTypeFromDetector(hostname);
auto d = slsDetector(type);
d.setHostname(hostname);
d.setOnline(true);
//Check that detector server is unlocked then lock
CHECK(d.lockServer() == 0);
d.lockServer(1);
CHECK(d.lockServer() == 1);
//Can we do things while it is locked
auto t = 1300000000;
d.setTimer(slsDetectorDefs::timerIndex::ACQUISITION_TIME, t);
CHECK(d.setTimer(slsDetectorDefs::timerIndex::ACQUISITION_TIME) == t);
//unlock again
d.lockServer(0);
CHECK(d.lockServer() == 0);
CHECK(d.getLastClientIP() == my_ip);
}
TEST_CASE("Excersise all possible set timer functions") {
// FRAME_NUMBER, /**< number of real time frames: total number of acquisitions is number or frames*number of cycles */
// ACQUISITION_TIME, /**< exposure time */
// FRAME_PERIOD, /**< period between exposures */
// DELAY_AFTER_TRIGGER, /**< delay between trigger and start of exposure or readout (in triggered mode) */
// GATES_NUMBER, /**< number of gates per frame (in gated mode) */
// CYCLES_NUMBER, /**< number of cycles: total number of acquisitions is number or frames*number of cycles */
// ACTUAL_TIME, /**< Actual time of the detector's internal timer */
// MEASUREMENT_TIME, /**< Time of the measurement from the detector (fifo) */
// PROGRESS, /**< fraction of measurement elapsed - only get! */
// MEASUREMENTS_NUMBER,
// FRAMES_FROM_START,
// FRAMES_FROM_START_PG,
// SAMPLES,
// SUBFRAME_ACQUISITION_TIME, /**< subframe exposure time */
// STORAGE_CELL_NUMBER, /**<number of storage cells */
// SUBFRAME_DEADTIME, /**< subframe deadtime */
// MEASURED_PERIOD, /**< measured period */
// MEASURED_SUBPERIOD, /**< measured subperiod */
// MAX_TIMERS
auto type = slsDetector::getTypeFromDetector(hostname);
auto d = slsDetector(type);
d.setHostname(hostname);
d.setOnline(true);
//Number of frames
auto frames = 10;
d.setTimer(slsDetectorDefs::timerIndex::FRAME_NUMBER, frames);
CHECK(d.setTimer(slsDetectorDefs::timerIndex::FRAME_NUMBER) == frames);
auto t = 10000000;
d.setTimer(slsDetectorDefs::timerIndex::ACQUISITION_TIME, t);
CHECK(d.setTimer(slsDetectorDefs::timerIndex::ACQUISITION_TIME) == t);
auto period = 1000000000;
d.setTimer(slsDetectorDefs::timerIndex::FRAME_PERIOD, period);
CHECK(d.setTimer(slsDetectorDefs::timerIndex::FRAME_PERIOD) == period);
// not implemented for EIGER
// auto delay = 10000;
// d.setTimer(slsDetectorDefs::timerIndex::DELAY_AFTER_TRIGGER, delay);
// CHECK(d.setTimer(slsDetectorDefs::timerIndex::DELAY_AFTER_TRIGGER) == delay);
// auto gates = 1;
// d.setTimer(slsDetectorDefs::timerIndex::GATES_NUMBER, gates);
// CHECK(d.setTimer(slsDetectorDefs::timerIndex::GATES_NUMBER) == gates);
auto cycles = 2;
d.setTimer(slsDetectorDefs::timerIndex::CYCLES_NUMBER, cycles);
CHECK(d.setTimer(slsDetectorDefs::timerIndex::CYCLES_NUMBER) == cycles);
auto subtime = 200;
d.setTimer(slsDetectorDefs::timerIndex::SUBFRAME_ACQUISITION_TIME, subtime);
CHECK(d.setTimer(slsDetectorDefs::timerIndex::SUBFRAME_ACQUISITION_TIME) == subtime);
}
// TEST_CASE("ACQ") {
// auto type = slsDetector::getTypeFromDetector(hostname);
// auto d = slsDetector(type);
// d.setHostname(hostname);
// d.setOnline(true);
// d.prepareAcquisition();
// d.startAcquisition();
// d.stopAcquisition();
// }

View File

@ -215,12 +215,21 @@ bool multiSlsDetector::isAcquireReady() {
return OK;
}
int multiSlsDetector::checkVersionCompatibility(portType t, int detPos) {
int multiSlsDetector::checkDetectorVersionCompatibility(int detPos) {
if (detPos >= 0) {
return detectors[detPos]->checkVersionCompatibility(t);
return detectors[detPos]->checkDetectorVersionCompatibility();
}
auto r = parallelCall(&slsDetector::checkVersionCompatibility, t);
auto r = parallelCall(&slsDetector::checkDetectorVersionCompatibility);
return sls::minusOneIfDifferent(r);
}
int multiSlsDetector::checkReceiverVersionCompatibility(int detPos) {
if (detPos >= 0) {
return detectors[detPos]->checkReceiverVersionCompatibility();
}
auto r = parallelCall(&slsDetector::checkReceiverVersionCompatibility);
return sls::minusOneIfDifferent(r);
}
@ -482,14 +491,28 @@ void multiSlsDetector::addSlsDetector(const std::string &hostname) {
}
}
// get type by connecting
detectorType type = slsDetector::getTypeFromDetector(hostname.c_str(), DEFAULT_PORTNO);
if (type == GENERIC) {
FILE_LOG(logERROR) << "Could not connect to Detector " << hostname
<< " to determine the type!";
setErrorMask(getErrorMask() | MULTI_DETECTORS_NOT_ADDED);
appendNotAddedList(hostname.c_str());
return;
}
int pos = (int)detectors.size();
detectors.push_back(sls::make_unique<slsDetector>(hostname, detId, pos, false));
detectors.push_back(sls::make_unique<slsDetector>(type, detId, pos, false));
thisMultiDetector->numberOfDetectors = detectors.size();
thisMultiDetector->dataBytes += detectors[pos]->getDataBytes();
thisMultiDetector->dataBytesInclGapPixels +=
detectors[pos]->getDataBytesInclGapPixels();
thisMultiDetector->numberOfChannels +=
detectors[pos]->getTotalNumberOfChannels();
detectors[pos]->setHostname(hostname);
detectors[pos]->setOnline(true);
}
slsDetectorDefs::detectorType multiSlsDetector::getDetectorTypeAsEnum(int detPos) {

View File

@ -216,14 +216,22 @@ class multiSlsDetector : public virtual slsDetectorDefs,
bool isAcquireReady();
/**
* Check version compatibility with detector/receiver software
* Check version compatibility with detector software
* (if hostname/rx_hostname has been set/ sockets created)
* @param p port type control port or receiver port
* @param detPos -1 for all detectors in list or specific detector position
* @returns FAIL for incompatibility, OK for compatibility
*/
int checkVersionCompatibility(portType t, int detPos = -1);
int checkDetectorVersionCompatibility(int detPos = -1);
/**
* Check version compatibility with receiver software
* (if hostname/rx_hostname has been set/ sockets created)
* @param p port type control port or receiver port
* @param detPos -1 for all detectors in list or specific detector position
* @returns FAIL for incompatibility, OK for compatibility
*/
int checkReceiverVersionCompatibility(int detPos = -1);
/**
* Get ID or version numbers
* @param mode version type

View File

@ -88,8 +88,14 @@ class multiSlsDetectorClient {
// call multi detector command line
slsDetectorCommand myCmd(detPtr);
std::cout << "narg: " << parser.n_arguments()+1 << '\n';
std::cout << "narg: " << parser.argv().data() << '\n';
std::cout << "narg: " << parser.detector_id() << '\n';
std::cout << "HEY!!!!!!!!!!!!!!!!!!!!!!! 55555\n";
std::string answer = myCmd.executeLine(parser.n_arguments()+1, parser.argv().data(), action_, parser.detector_id());
std::cout << "HEY!!!!!!!!!!!!!!!!!!!!!!! 9999\n";
if (parser.multi_id()!=0)
std::cout << parser.multi_id() << '-';
if (parser.detector_id() != -1)

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,9 @@
#include "sls_detector_defs.h"
#include "error_defs.h"
#include "logger.h"
#include "ClientSocket.h"
class ClientInterface;
#include <cmath>
@ -273,7 +276,7 @@ public:
* @param id sls detector id (position in detectors list)
* @param verify true to verify if shared memory version matches existing one
*/
explicit slsDetector(const std::string& hostname,
explicit slsDetector(detectorType type,
int multiId = 0,
int id = 0,
bool verify = true);
@ -284,7 +287,9 @@ public:
* @param id sls detector id (position in detectors list)
* @param verify true to verify if shared memory version matches existing one
*/
explicit slsDetector(int multiId = 0, int id = 0, bool verify = true);
explicit slsDetector(int multiId = 0,
int id = 0,
bool verify = true);
/**
* Destructor
@ -292,12 +297,18 @@ public:
virtual ~slsDetector();
/**
* Check version compatibility with detector/receiver software
* Check version compatibility with receiver software
* (if hostname/rx_hostname has been set/ sockets created)
* @param p port type control port or receiver port
* @returns FAIL for incompatibility, OK for compatibility
*/
int checkVersionCompatibility(portType t);
int checkReceiverVersionCompatibility();
/**
* Check version compatibility with detector software
* @returns FAIL for incompatibility, OK for compatibility
*/
int checkDetectorVersionCompatibility();
/**
* Get ID or version numbers
@ -325,65 +336,27 @@ public:
void freeSharedMemory();
/**
* Sets the hostname of all sls detectors in shared memory
* Connects to them to set up online flag
* Sets the hostname, if online flag is set connects to update the detector
* @param name hostname
*/
void setHostname(const std::string& hostname);
/**
* Gets the hostname of detector
* @param pos insignificant
* @returns hostname
*/
std::string getHostname();
/**
* Connect to the control port
* @returns OK, FAIL or undefined
*/
int connectControl();
/**
* Disconnect the control port
*/
void disconnectControl();
/**
* Could not connect to receiver, log error
*/
void connectDataError();
/**
* Connect to the data port
* @returns OK, FAIL or undefined
*/
int connectData();
/**
* Disconnect the data port
*/
void disconnectData();
/**
* Connect to the stop port
* @returns OK, FAIL or undefined
*/
int connectStop();
/**
* Disconnect the stop port
*/
void disconnectStop();
/**
* Get detector type by connecting to the detector without creating an object
* @param name hostname of detector
* @param cport TCP control port
* Get detector type by connecting to the detector
* @returns detector tpe or GENERIC if failed
*/
static detectorType getDetectorTypeAsEnum(const std::string& hostname, int cport=DEFAULT_PORTNO);
static detectorType getTypeFromDetector(const std::string& hostname, int cport=DEFAULT_PORTNO);
/**
* Get Detector type from shared memory variable
@ -404,12 +377,6 @@ public:
*/
int setDetectorType(detectorType type=GET_DETECTOR_TYPE);
/**
* Gets detector type (string) from detector and set it in receiver
* @param type string of detector type
* @returns detector type in receiver
// */
// int setDetectorType(const std::string& detector_type);
/**
* Returns the total number of channels from shared memory
@ -490,22 +457,19 @@ public:
*/
int setOnline(int value=GET_ONLINE_FLAG);
/**
* Returns the online flag
*/
int getOnlineFlag() const;
/**
* Checks if each of the detector is online/offline
* @returns empty string if it is online
* else returns hostnameif it is offline
* else returns hostname if it is offline
*/
std::string checkOnline();
/**
* Configure the TCP socket communciation and initializes the socket instances
* @param name hostname, empty if current hostname
* @param control_port TCP port for control commands, -1 if current is used
* @param stop_port TCP port for data commands, -1 if current is used
* @returns OK or FAIL
* \sa sharedSlsDetector
*/
int setTCPSocket(const std::string& hostname="", int control_port=-1, int stop_port=-1);
/**
* Set/Gets TCP Port of detector or receiver
@ -515,23 +479,28 @@ public:
*/
int setPort(portType index, int num=-1);
int setControlPort(int port_number);
/**
* Returns the detector TCP control port \sa sharedSlsDetector
* @returns the detector TCP control port
*/
int getControlPort();
int getControlPort() const;
int setStopPort(int port_number);
/**
* Returns the detector TCP stop port \sa sharedSlsDetector
* @returns the detector TCP stop port
*/
int getStopPort();
int getStopPort() const;
/**
* Returns the receiver TCP port \sa sharedSlsDetector
* @returns the receiver TCP port
*/
int getReceiverPort();
int getReceiverPort() const ;
/**
* Lock server for this client IP
@ -564,10 +533,10 @@ public:
* Updates some of the shared memory receiving the data from the detector
* @returns OK
*/
int updateDetectorNoWait();
int updateDetectorNoWait( sls::ClientSocket &client);
/**
* Updates soem of the shared memory receiving the data from the detector
* Updates some of the shared memory receiving the data from the detector
* calls updateDetectorNoWait
* @returns OK or FAIL or FORCE_RET
*/
@ -1325,21 +1294,14 @@ public:
*/
int setReceiverOnline(int value=GET_ONLINE_FLAG);
int getReceiverOnline() const;
/**
* Checks if the receiver is really online
* @returns empty string if online, else returns receiver hostname
*/
std::string checkReceiverOnline();
/**
* Configure the socket communication and initializes the socket instances
* @param name receiver ip - if "" the current receiver hostname is used
* @param receiver_port port for receiving data - if -1 the current is used
* @returns OK is connection succeded, FAIL otherwise
* \sa sharedSlsDetector
*/
int setReceiverTCPSocket(const std::string& name="", int const receiver_port=-1);
/**
* Locks/Unlocks the connection to the receiver
* @param lock sets (1), usets (0), gets (-1) the lock
@ -1371,7 +1333,7 @@ public:
updates the shared memory receiving the data from the detector (without asking and closing the connection
/returns OK
*/
int updateReceiverNoWait();
int updateReceiverNoWait(sls::ClientSocket& receiver);
/**
* Updates the shared memory receiving the data from the detector
@ -1776,24 +1738,6 @@ private:
/** Shared memory structure */
sharedSlsDetector *thisDetector {nullptr};
/** control socket interface */
ServerInterface *thisDetectorControl {nullptr};
/** stop socket interface */
ServerInterface *thisDetectorStop {nullptr};
/** receiver interface */
ServerInterface *thisReceiver {nullptr};
/** socket for control commands */
MySocketTCP *controlSocket {nullptr};
/** socket for emergency stop */
MySocketTCP *stopSocket {nullptr};
/** socket for data acquisition */
MySocketTCP *dataSocket {nullptr};
/** pointer to detector module structures in shared memory */
sls_detector_module *detectorModules {nullptr};

View File

@ -1947,7 +1947,7 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) {
//-----------------------------------------------------------
std::string slsDetectorCommand::executeLine(int narg, char *args[], int action, int detPos) {
std::cout << "HEY!!!!!!!!!!!!!!!!!!!!!!! 984651654\n";
if (action == READOUT_ACTION)
return cmdAcquire(narg, args, action, detPos);
@ -2009,10 +2009,11 @@ std::string slsDetectorCommand::helpLine(int narg, char *args[], int action, int
}
std::string slsDetectorCommand::cmdAcquire(int narg, char *args[], int action, int detPos) {
#ifdef VERBOSE
std::cout << std::string("Executing command ") + std::string(args[0]) + std::string(" ( ") + cmd + std::string(" )\n");
#endif
// #ifdef VERBOSE
// std::cout << std::string("Executing command ") + std::string(args[0]) + std::string(" ( ") + cmd + std::string(" )\n");
// #endif
std::cout << "HEY!!!!!!!!!!!!!!!!!!!!!!! 0\n";
if (action == HELP_ACTION) {
return helpAcquire(HELP_ACTION);
}
@ -2020,14 +2021,17 @@ std::string slsDetectorCommand::cmdAcquire(int narg, char *args[], int action, i
cprintf(RED, "Error: This shared memory has no detectors added. Aborting.\n");
return std::string("acquire unsuccessful");
}
std::cout << "HEY!!!!!!!!!!!!!!!!!!!!!!! 1\n";
if (detPos >= 0) {
cprintf(RED, "Error: Individual detectors not allowed for readout. Aborting.\n");
return std::string("acquire unsuccessful");
}
std::cout << "HEY!!!!!!!!!!!!!!!!!!!!!!! 2\n";
myDet->setOnline(ONLINE_FLAG, detPos);
int r_online = myDet->setReceiverOnline(ONLINE_FLAG, detPos);
std::cout << "HEY!!!!!!!!!!!!!!!!!!!!!!! 3\n";
if (myDet->acquire() == FAIL)
return std::string("acquire unsuccessful");
if (r_online) {
@ -2035,7 +2039,7 @@ std::string slsDetectorCommand::cmdAcquire(int narg, char *args[], int action, i
sprintf(answer, "\nAcquired %d", myDet->getFramesCaughtByReceiver(detPos));
return std::string(answer);
}
std::cout << "HEY!!!!!!!!!!!!!!!!!!!!!!! 4\n";
return std::string("");
}
@ -3449,7 +3453,7 @@ std::string slsDetectorCommand::cmdSN(int narg, char *args[], int action, int de
}
if (cmd == "checkdetversion") {
int retval = myDet->checkVersionCompatibility(CONTROL_PORT, detPos);
int retval = myDet->checkDetectorVersionCompatibility(detPos);
if (retval < 0)
sprintf(answer, "%d", -1);
sprintf(answer, "%s", retval == OK ? "compatible" : "incompatible");
@ -3458,7 +3462,7 @@ std::string slsDetectorCommand::cmdSN(int narg, char *args[], int action, int de
if (cmd == "checkrecversion") {
myDet->setReceiverOnline(ONLINE_FLAG, detPos);
int retval = myDet->checkVersionCompatibility(DATA_PORT, detPos);
int retval = myDet->checkReceiverVersionCompatibility(detPos);
if (retval < 0)
sprintf(answer, "%d", -1);
sprintf(answer, "%s", retval == OK ? "compatible" : "incompatible");

View File

@ -77,11 +77,11 @@ int64_t slsDetectorUsers::getReceiverSoftwareVersion(int detPos){
}
bool slsDetectorUsers::isDetectorVersionCompatible(int detPos) {
return (detector.checkVersionCompatibility(slsDetectorDefs::CONTROL_PORT, detPos) == slsDetectorDefs::OK);
return (detector.checkDetectorVersionCompatibility(detPos) == slsDetectorDefs::OK);
}
bool slsDetectorUsers::isReceiverVersionCompatible(int detPos) {
return (detector.checkVersionCompatibility(slsDetectorDefs::DATA_PORT, detPos) == slsDetectorDefs::OK);
return (detector.checkReceiverVersionCompatibility(detPos) == slsDetectorDefs::OK);
}
int slsDetectorUsers::startMeasurement(){

View File

@ -21,13 +21,16 @@ public:
* @param n for debugging purposes (useful only for client side)
* @param t string to identify type (Detector, Receiver) for printouts (useful only for client side)
*/
ClientInterface(int n, sls::ClientSocket&& s);
ClientInterface(sls::ClientSocket* socket, int n);
/**
* destructor
*/
virtual ~ClientInterface() = default;
void SetSocket(sls::ClientSocket *socket){
socket_ = socket;
}
/**
* Receive ret, mess or retval from Server
@ -61,7 +64,7 @@ private:
/**
* socket for data acquisition
*/
sls::ClientSocket socket_;
sls::ClientSocket* socket_;
/** index for client debugging purposes */
int index;

View File

@ -1,17 +1,19 @@
#pragma once
#include "DataSocket.h"
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <string>
#include <sys/socket.h>
#include <sys/types.h>
namespace sls{
namespace sls {
class ClientSocket: public DataSocket{
public:
ClientSocket(const std::string& hostname, uint16_t port_number);
int connect();
private:
class ClientSocket : public DataSocket {
public:
ClientSocket(const std::string &hostname, uint16_t port_number);
int sendCommandThenRead(int fnum, void *args, size_t args_size, void *retval, size_t retval_size);
private:
void readReply(int &ret, void *retval, size_t retval_size);
struct sockaddr_in serverAddr {};
};

View File

@ -1,27 +1,32 @@
#pragma once
#include <cstdint>
#include <cstddef>
#include <cstdint>
#include <netdb.h>
namespace sls {
class DataSocket {
public:
DataSocket(int socketId);
DataSocket(DataSocket&& move) noexcept;
DataSocket& operator=(DataSocket&& move) noexcept;
void swap(DataSocket& other) noexcept;
DataSocket(DataSocket const&) = delete;
DataSocket& operator=(DataSocket const&) = delete;
int getSocketId() const{
DataSocket(DataSocket &&move) noexcept;
virtual ~DataSocket();
DataSocket &operator=(DataSocket &&move) noexcept;
void swap(DataSocket &other) noexcept;
DataSocket(DataSocket const &) = delete;
DataSocket &operator=(DataSocket const &) = delete;
int getSocketId() const {
return socketId_;
}
size_t sendData(char *buffer, size_t size);
size_t receiveData(char * buffer, size_t size);
size_t sendData(void *buffer, size_t size);
size_t receiveData(void *buffer, size_t size);
int setTimeOut(int t_seconds);
void close();
private:
int socketId_ = -1;
};
int ConvertHostnameToInternetAddress(const char *const hostname, struct ::addrinfo **res);
int ConvertInternetAddresstoIpString(struct ::addrinfo *res, char *ip, const int ipsize);
}; // namespace sls

View File

@ -17,7 +17,7 @@
#endif
#ifndef FILELOG_MAX_LEVEL
#define FILELOG_MAX_LEVEL logINFO
#define FILELOG_MAX_LEVEL logDEBUG5
#endif

View File

@ -1,12 +1,12 @@
#include "ClientInterface.h"
#include "ClientSocket.h"
ClientInterface::ClientInterface(int n, sls::ClientSocket&& s): socket_(std::move(s)),
ClientInterface::ClientInterface(sls::ClientSocket* socket, int n): socket_(socket),
index(n){}
void ClientInterface::Client_Receive(int& ret, char* mess, void* retval, int sizeOfRetval) {
// get result of operation
socket_.receiveData(reinterpret_cast<char *>(&ret), sizeof(ret));
socket_->receiveData(reinterpret_cast<char *>(&ret), sizeof(ret));
bool unrecognizedFunction = false;
if (ret == FAIL) {
@ -18,7 +18,7 @@ void ClientInterface::Client_Receive(int& ret, char* mess, void* retval, int siz
memset(mess, 0, MAX_STR_LENGTH);
}
// get error message
socket_.receiveData(mess,MAX_STR_LENGTH);
socket_->receiveData(mess,MAX_STR_LENGTH);
// cprintf(RED, "%s %d returned error: %s", type.c_str(), index, mess);
// unrecognized function, do not ask for retval
@ -30,7 +30,7 @@ void ClientInterface::Client_Receive(int& ret, char* mess, void* retval, int siz
}
// get retval
if (!unrecognizedFunction)
socket_.receiveData( reinterpret_cast<char *>(retval), sizeOfRetval);
socket_->receiveData( reinterpret_cast<char *>(retval), sizeOfRetval);
}
@ -39,8 +39,8 @@ int ClientInterface::Client_Send(int fnum,
void* retval, int sizeOfRetval,
char* mess) {
int ret = FAIL;
socket_.sendData(reinterpret_cast<char *>(&fnum),sizeof(fnum));
socket_.sendData(reinterpret_cast<char *>(args), sizeOfArgs);
socket_->sendData(reinterpret_cast<char *>(&fnum),sizeof(fnum));
socket_->sendData(reinterpret_cast<char *>(args), sizeOfArgs);
Client_Receive(ret, mess, retval, sizeOfRetval);
return ret;
}

View File

@ -1,9 +1,10 @@
#include "ClientSocket.h"
#include <arpa/inet.h>
#include <cassert>
#include <cstring>
#include <iostream>
#include <unistd.h>
#include "sls_detector_defs.h"
namespace sls {
ClientSocket::ClientSocket(const std::string &host, uint16_t port) : DataSocket(socket(AF_INET, SOCK_STREAM, 0)) {
@ -13,7 +14,7 @@ ClientSocket::ClientSocket(const std::string &host, uint16_t port) : DataSocket(
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags |= AI_CANONNAME;
if (getaddrinfo(host.c_str(), NULL, &hints, &result) != 0) {
throw std::runtime_error("ClientSocket ERROR: cannot decode host\n");
}
@ -23,18 +24,40 @@ ClientSocket::ClientSocket(const std::string &host, uint16_t port) : DataSocket(
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(port);
memcpy((char *)&serverAddr.sin_addr.s_addr,
&((struct sockaddr_in *)result->ai_addr)->sin_addr, sizeof(in_addr_t));
&((struct sockaddr_in *)result->ai_addr)->sin_addr, sizeof(in_addr_t));
if (::connect(getSocketId(), (struct sockaddr *)&serverAddr, sizeof(serverAddr)) != 0){
if (::connect(getSocketId(), (struct sockaddr *)&serverAddr, sizeof(serverAddr)) != 0) {
freeaddrinfo(result);
throw std::runtime_error("ClientSocket ERROR: cannot connect to host\n");
}
freeaddrinfo(result);
}
int ClientSocket::connect(){
//used to reconnect after closing may be removed
return ::connect(getSocketId(), (struct sockaddr *)&serverAddr, sizeof(serverAddr));
int ClientSocket::sendCommandThenRead(int fnum, void *args, size_t args_size, void *retval, size_t retval_size) {
int ret = slsDetectorDefs::FAIL;
sendData(&fnum, sizeof(fnum));
sendData(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));
bool unrecognizedFunction = false;
if (ret == slsDetectorDefs::FAIL) {
char mess[MAX_STR_LENGTH]{};
//get error message
receiveData(mess, sizeof(mess));
// cprintf(RED, "%s %d returned error: %s", type.c_str(), index, mess);
// unrecognized function, do not ask for retval
if (strstr(mess, "Unrecognized Function") != nullptr)
unrecognizedFunction = true;
}
// get retval
if (!unrecognizedFunction)
receiveData(retval, retval_size);
}
}; //namespace sls

View File

@ -73,7 +73,10 @@ void CmdLineParser::DecodeIdAndPosition(const char *c) {
std::vector<char *> CmdLineParser::argv() {
std::vector<char *> vec;
vec.push_back(&command_.front());
if (command_.empty()!=true){
vec.push_back(&command_.front());
}
for (auto &arg : arguments_) {
vec.push_back(&arg.front());
}

View File

@ -1,44 +1,83 @@
#include "DataSocket.h"
#include "logger.h"
#include <algorithm>
#include <arpa/inet.h>
#include <cstring>
#include <iostream>
#include <unistd.h>
#include <algorithm>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
namespace sls {
DataSocket::DataSocket(int socketId) : socketId_(socketId) {}
void DataSocket::swap(DataSocket& other) noexcept{
DataSocket::~DataSocket() {
if (socketId_ == -1) {
return;
} else {
try {
close();
} catch (...) {
//pass
}
}
}
void DataSocket::swap(DataSocket &other) noexcept {
std::swap(socketId_, other.socketId_);
}
DataSocket::DataSocket(DataSocket&& move) noexcept{
DataSocket::DataSocket(DataSocket &&move) noexcept {
move.swap(*this);
}
DataSocket& DataSocket::operator=(DataSocket&& move)noexcept{
DataSocket &DataSocket::operator=(DataSocket &&move) noexcept {
move.swap(*this);
return *this;
}
size_t DataSocket::receiveData(char *buffer, size_t size) {
std::cout << "Sending\n";
size_t DataSocket::receiveData(void *buffer, size_t size) {
// std::cout << "Sending\n";
size_t dataRead = 0;
while (dataRead < size) {
dataRead += read(getSocketId(), buffer + dataRead, size - dataRead);
dataRead += read(getSocketId(), reinterpret_cast<char *>(buffer) + dataRead, size - dataRead);
}
return dataRead;
}
size_t DataSocket::sendData(char *buffer, size_t size) {
std::cout << "Receiving\n";
size_t DataSocket::sendData(void *buffer, size_t size) {
// std::cout << "Receiving\n";
size_t dataSent = 0;
while (dataSent < size) {
dataSent += write(getSocketId(), buffer + dataSent, size - dataSent);
dataSent += write(getSocketId(), reinterpret_cast<char *>(buffer) + dataSent, size - dataSent);
}
return dataSent;
}
int DataSocket::setTimeOut(int t_seconds) {
if (t_seconds <= 0)
return -1;
struct timeval t;
t.tv_sec = 0;
t.tv_usec = 0;
//Receive timeout indefinet
if (::setsockopt(getSocketId(), SOL_SOCKET, SO_RCVTIMEO,
&t, sizeof(struct timeval)) < 0) {
FILE_LOG(logERROR) << "setsockopt SO_RCVTIMEO " << 0;
}
t.tv_sec = t_seconds;
t.tv_usec = 0;
//Sending timeout in seconds
if (::setsockopt(getSocketId(), SOL_SOCKET, SO_SNDTIMEO,
&t, sizeof(struct timeval)) < 0) {
FILE_LOG(logERROR) << "setsockopt SO_SNDTIMEO " << t_seconds;
}
return 0;
}
void DataSocket::close() {
if (socketId_ > 0) {
::close(socketId_);
@ -47,4 +86,45 @@ void DataSocket::close() {
}
}
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, NULL, &hints, res);
if (errcode != 0) {
FILE_LOG(logERROR) << "Could not convert hostname (" << hostname << ") to internet address (zmq):" << gai_strerror(errcode);
} else {
if (*res == NULL) {
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) != NULL) {
::freeaddrinfo(res);
return 0;
}
FILE_LOG(logERROR) << "Could not convert internet address to ip string";
return 1;
}
} // namespace sls

View File

@ -250,4 +250,17 @@ TEST_CASE("Parses string with two arguments") {
REQUIRE("3000" == p.arguments()[0]);
REQUIRE("4000" == p.arguments()[1]);
REQUIRE(p.arguments().size() == 2);
}
TEST_CASE("Build up argv"){
CmdLineParser p;
// p.argv();
REQUIRE(p.argv().empty());
REQUIRE(p.argv().data() == nullptr);
std::string s = "trimen 3000 4000\n";
p.Parse(s);
REQUIRE(p.argv().data() != nullptr);
REQUIRE(p.argv().size() == 3);
}