mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-04-08 04:17:49 +02:00
used CRTP for virtual detector
All checks were successful
All checks were successful
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# TODO: should be different executable if not simulators on !!
|
||||
add_executable(matterhornDetectorServer_virtual
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/MatterhornApp.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/MatterhornServer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StopServer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/VirtualMatterhornServer.cpp
|
||||
#${CMAKE_CURRENT_SOURCE_DIR}/src/StopServer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/CommandLineOptions.cpp
|
||||
)
|
||||
|
||||
@@ -20,7 +20,8 @@ target_link_libraries(matterhornDetectorServer_virtual
|
||||
PUBLIC
|
||||
slsSupportStatic
|
||||
slsDetectorStatic
|
||||
slsServerStatic)
|
||||
slsServerStatic
|
||||
)
|
||||
|
||||
set_target_properties(matterhornDetectorServer_virtual PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
#pragma once
|
||||
#include "TCPInterface.h"
|
||||
#include "communication_funcs.h"
|
||||
#include "sls/logger.h"
|
||||
#include "sls/network_utils.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
#include "sls/versionAPI.h"
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
namespace sls {
|
||||
|
||||
/// @brief struct saving udp details (one UDP port per module)
|
||||
struct UDPInfo {
|
||||
uint16_t srcport{};
|
||||
uint16_t dstport{};
|
||||
uint64_t srcmac{};
|
||||
uint64_t dstmac{};
|
||||
uint32_t srcip{};
|
||||
uint32_t dstip{};
|
||||
};
|
||||
|
||||
/// @brief Base class for Matterhorn Server, can be used to implement a virtual
|
||||
/// server for testing and actual server
|
||||
template <typename DerivedServer> class BaseMatterhornServer {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* Starts up a Matterhorn server.
|
||||
* Assembles a Matterhorn server using TCP and UDP detector interfaces
|
||||
* throws an exception in case of failure
|
||||
* @param port TCP/IP port number
|
||||
*/
|
||||
explicit BaseMatterhornServer(uint16_t port = DEFAULT_TCP_CNTRL_PORTNO);
|
||||
|
||||
~BaseMatterhornServer() = default;
|
||||
|
||||
ReturnCode get_version(ServerInterface &socket);
|
||||
|
||||
ReturnCode get_detector_type(ServerInterface &socket);
|
||||
|
||||
ReturnCode initial_checks(ServerInterface &socket);
|
||||
|
||||
ReturnCode get_num_udp_interfaces(ServerInterface &socket);
|
||||
|
||||
ReturnCode get_update_mode(ServerInterface &socket);
|
||||
|
||||
ReturnCode get_source_udp_mac(ServerInterface &socket);
|
||||
|
||||
protected:
|
||||
size_t num_udp_interfaces() const;
|
||||
|
||||
/// @brief TODO what is this?
|
||||
bool updateMode{true};
|
||||
|
||||
/// @brief TCP/IP interface for communication with the client
|
||||
std::unique_ptr<TCPInterface> tcpInterface;
|
||||
std::array<UDPInfo, 1>
|
||||
udpDetails{}; // TODO: for now only one receiver per module
|
||||
|
||||
private:
|
||||
static std::string getMatterhornServerVersion();
|
||||
|
||||
private:
|
||||
/// @brief map of function IDs and corresponding functions
|
||||
// maybe load from additional file cleaner
|
||||
std::unordered_map<detFuncs, std::function<ReturnCode(ServerInterface &)>>
|
||||
function_table = {
|
||||
{detFuncs::F_GET_SERVER_VERSION,
|
||||
[this](ServerInterface &si) { return this->get_version(si); }},
|
||||
{detFuncs::F_GET_DETECTOR_TYPE,
|
||||
[this](ServerInterface &si) {
|
||||
return this->get_detector_type(si);
|
||||
}},
|
||||
{detFuncs::F_INITIAL_CHECKS,
|
||||
[this](ServerInterface &si) {
|
||||
return static_cast<DerivedServer *>(this)->initial_checks(si);
|
||||
}},
|
||||
{detFuncs::F_GET_NUM_INTERFACES,
|
||||
[this](ServerInterface &si) {
|
||||
return this->get_num_udp_interfaces(si);
|
||||
}},
|
||||
{detFuncs::F_GET_UPDATE_MODE,
|
||||
[this](ServerInterface &si) {
|
||||
return static_cast<DerivedServer *>(this)->get_update_mode(si);
|
||||
}},
|
||||
{detFuncs::F_GET_SOURCE_UDP_MAC, [this](ServerInterface &si) {
|
||||
return this->get_source_udp_mac(si);
|
||||
}}};
|
||||
};
|
||||
|
||||
template <typename DerivedServer>
|
||||
BaseMatterhornServer<DerivedServer>::BaseMatterhornServer(uint16_t port) {
|
||||
|
||||
validatePortNumber(port);
|
||||
|
||||
udpDetails[0].srcport = DEFAULT_UDP_SRC_PORTNO;
|
||||
udpDetails[0].dstport = DEFAULT_UDP_DST_PORTNO;
|
||||
|
||||
// TODO: when do i set the udp mac and ip ?
|
||||
|
||||
tcpInterface = std::make_unique<TCPInterface>(
|
||||
function_table, port); // TODO: need a tcp and udp interface
|
||||
|
||||
// need a function to setup detector - e.g. set all registers etc.
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
ReturnCode
|
||||
BaseMatterhornServer<DerivedServer>::get_version(ServerInterface &socket) {
|
||||
|
||||
auto version = getMatterhornServerVersion();
|
||||
char version_cstr[MAX_STR_LENGTH]{};
|
||||
strncpy(version_cstr, version.c_str(), version.size());
|
||||
LOG(TLogLevel::logDEBUG) << "Matterhorn Server Version: " << version;
|
||||
return static_cast<ReturnCode>(socket.sendResult(
|
||||
version_cstr)); // TODO: check what would be possible return codes!!!
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
ReturnCode BaseMatterhornServer<DerivedServer>::get_detector_type(
|
||||
ServerInterface &socket) {
|
||||
int detectortype = slsDetectorDefs::detectorType::MATTERHORN;
|
||||
return static_cast<ReturnCode>(socket.sendResult(detectortype));
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
std::string BaseMatterhornServer<DerivedServer>::getMatterhornServerVersion() {
|
||||
return APIMATTERHORN;
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
size_t BaseMatterhornServer<DerivedServer>::num_udp_interfaces() const {
|
||||
return udpDetails.size();
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
ReturnCode BaseMatterhornServer<DerivedServer>::get_num_udp_interfaces(
|
||||
ServerInterface &socket) {
|
||||
int numUDPInterfaces = static_cast<int>(num_udp_interfaces());
|
||||
return static_cast<ReturnCode>(socket.sendResult(numUDPInterfaces));
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
ReturnCode BaseMatterhornServer<DerivedServer>::get_source_udp_mac(
|
||||
ServerInterface &socket) {
|
||||
uint64_t srcMac = udpDetails[0].srcmac;
|
||||
return static_cast<ReturnCode>(socket.sendResult(srcMac));
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
@@ -1,88 +1,14 @@
|
||||
#pragma once
|
||||
#include "TCPInterface.h"
|
||||
#include "BaseMatterhornServer.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
namespace sls {
|
||||
|
||||
/// @brief struct saving udp details (one UDP port per module)
|
||||
struct UDPInfo {
|
||||
uint16_t srcport{};
|
||||
uint16_t dstport{};
|
||||
uint64_t srcmac{};
|
||||
uint64_t dstmac{};
|
||||
uint32_t srcip{};
|
||||
uint32_t dstip{};
|
||||
};
|
||||
|
||||
/// @brief Base class for Matterhorn Server, can be used to implement a virtual
|
||||
/// server for testing and actual server
|
||||
class BaseMatterhornServer {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* Starts up a Matterhorn server.
|
||||
* Assembles a Matterhorn server using TCP and UDP detector interfaces
|
||||
* throws an exception in case of failure
|
||||
* @param port TCP/IP port number
|
||||
*/
|
||||
explicit BaseMatterhornServer(uint16_t port = DEFAULT_TCP_CNTRL_PORTNO);
|
||||
|
||||
~BaseMatterhornServer() = default;
|
||||
|
||||
ReturnCode get_version(ServerInterface &socket);
|
||||
|
||||
ReturnCode get_detector_type(ServerInterface &socket);
|
||||
|
||||
virtual ReturnCode initial_checks(ServerInterface &socket) = 0;
|
||||
|
||||
ReturnCode get_num_udp_interfaces(ServerInterface &socket);
|
||||
|
||||
virtual ReturnCode get_update_mode(ServerInterface &socket) = 0;
|
||||
|
||||
ReturnCode get_source_udp_mac(ServerInterface &socket);
|
||||
|
||||
protected:
|
||||
static std::string getMatterhornServerVersion();
|
||||
|
||||
size_t num_udp_interfaces() const;
|
||||
|
||||
/// @brief TODO what is this?
|
||||
bool updateMode{true};
|
||||
|
||||
protected:
|
||||
/// @brief TCP/IP interface for communication with the client
|
||||
std::unique_ptr<TCPInterface> tcpInterface;
|
||||
std::array<UDPInfo, 1>
|
||||
udpDetails{}; // TODO: for now only one receiver per module
|
||||
|
||||
private:
|
||||
/// @brief map of function IDs and corresponding functions
|
||||
// maybe load from additional file cleaner
|
||||
std::unordered_map<detFuncs, std::function<ReturnCode(ServerInterface &)>>
|
||||
function_table = {
|
||||
{detFuncs::F_GET_SERVER_VERSION,
|
||||
[this](ServerInterface &si) { return this->get_version(si); }},
|
||||
{detFuncs::F_GET_DETECTOR_TYPE,
|
||||
[this](ServerInterface &si) {
|
||||
return this->get_detector_type(si);
|
||||
}},
|
||||
{detFuncs::F_INITIAL_CHECKS,
|
||||
[this](ServerInterface &si) { return this->initial_checks(si); }},
|
||||
{detFuncs::F_GET_NUM_INTERFACES,
|
||||
[this](ServerInterface &si) {
|
||||
return this->get_num_udp_interfaces(si);
|
||||
}},
|
||||
{detFuncs::F_GET_UPDATE_MODE,
|
||||
[this](ServerInterface &si) { return this->get_update_mode(si); }},
|
||||
{detFuncs::F_GET_SOURCE_UDP_MAC, [this](ServerInterface &si) {
|
||||
return this->get_source_udp_mac(si);
|
||||
}}};
|
||||
};
|
||||
|
||||
class MatterhornServer : public BaseMatterhornServer {
|
||||
class MatterhornServer : public BaseMatterhornServer<MatterhornServer> {
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -96,28 +22,11 @@ class MatterhornServer : public BaseMatterhornServer {
|
||||
|
||||
~MatterhornServer() = default;
|
||||
|
||||
ReturnCode initial_checks(ServerInterface &socket) override;
|
||||
ReturnCode initial_checks(ServerInterface &socket);
|
||||
|
||||
ReturnCode get_update_mode(ServerInterface &socket) override;
|
||||
ReturnCode get_update_mode(ServerInterface &socket);
|
||||
};
|
||||
|
||||
class VirtualMatterhornServer : public BaseMatterhornServer {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* Starts up a virtual Matterhorn server.
|
||||
* Assembles a virtual Matterhorn server using TCP and UDP detector
|
||||
* interfaces throws an exception in case of failure
|
||||
* @param port TCP/IP port number
|
||||
*/
|
||||
explicit VirtualMatterhornServer(uint16_t port = DEFAULT_TCP_CNTRL_PORTNO);
|
||||
|
||||
~VirtualMatterhornServer() = default;
|
||||
|
||||
ReturnCode initial_checks(ServerInterface &socket) override;
|
||||
|
||||
ReturnCode get_update_mode(ServerInterface &socket) override;
|
||||
};
|
||||
|
||||
} // namespace sls
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
#include "BaseMatterhornServer.h"
|
||||
|
||||
namespace sls {
|
||||
|
||||
class VirtualMatterhornServer
|
||||
: public BaseMatterhornServer<VirtualMatterhornServer> {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* Starts up a virtual Matterhorn server.
|
||||
* Assembles a virtual Matterhorn server using TCP and UDP detector
|
||||
* interfaces throws an exception in case of failure
|
||||
* @param port TCP/IP port number
|
||||
*/
|
||||
explicit VirtualMatterhornServer(uint16_t port = DEFAULT_TCP_CNTRL_PORTNO);
|
||||
|
||||
~VirtualMatterhornServer() = default;
|
||||
|
||||
ReturnCode initial_checks(ServerInterface &socket);
|
||||
|
||||
ReturnCode get_update_mode(ServerInterface &socket);
|
||||
};
|
||||
|
||||
} // namespace sls
|
||||
@@ -1,80 +0,0 @@
|
||||
#include "MatterhornServer.h"
|
||||
#include "communication_funcs.h"
|
||||
#include "sls/logger.h"
|
||||
#include "sls/network_utils.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
#include "sls/versionAPI.h"
|
||||
|
||||
namespace sls {
|
||||
|
||||
BaseMatterhornServer::BaseMatterhornServer(uint16_t port) {
|
||||
|
||||
validatePortNumber(port);
|
||||
|
||||
// mmh do I want a virtual server inheriting from parent Server class? and
|
||||
// parent Matterhorn class - probably better
|
||||
#ifdef VIRTUAL
|
||||
udpDetails[0].srcip = LOCALHOSTIP_INT;
|
||||
#endif
|
||||
udpDetails[0].srcport = DEFAULT_UDP_SRC_PORTNO;
|
||||
udpDetails[0].dstport = DEFAULT_UDP_DST_PORTNO;
|
||||
|
||||
// TODO: when do i set the udp mac and ip ?
|
||||
|
||||
tcpInterface = std::make_unique<TCPInterface>(
|
||||
function_table, port); // TODO: need a tcp and udp interface
|
||||
|
||||
// should maybe be part of the constructor?
|
||||
tcpInterface->startTCPServer();
|
||||
|
||||
// need a function to setup detector - e.g. set all registers etc.
|
||||
}
|
||||
|
||||
ReturnCode BaseMatterhornServer::get_version(ServerInterface &socket) {
|
||||
|
||||
auto version = getMatterhornServerVersion();
|
||||
char version_cstr[MAX_STR_LENGTH]{};
|
||||
strncpy(version_cstr, version.c_str(), version.size());
|
||||
LOG(TLogLevel::logDEBUG) << "Matterhorn Server Version: " << version;
|
||||
return static_cast<ReturnCode>(socket.sendResult(
|
||||
version_cstr)); // TODO: check what would be possible return codes!!!
|
||||
}
|
||||
|
||||
ReturnCode BaseMatterhornServer::get_detector_type(ServerInterface &socket) {
|
||||
int detectortype = slsDetectorDefs::detectorType::MATTERHORN;
|
||||
return static_cast<ReturnCode>(socket.sendResult(detectortype));
|
||||
}
|
||||
|
||||
std::string BaseMatterhornServer::getMatterhornServerVersion() {
|
||||
return APIMATTERHORN;
|
||||
}
|
||||
|
||||
size_t BaseMatterhornServer::num_udp_interfaces() const {
|
||||
return udpDetails.size();
|
||||
}
|
||||
|
||||
ReturnCode MatterhornServer::initial_checks(ServerInterface &socket) {
|
||||
|
||||
// TODO: add more checks here, for now just return true to be able to test
|
||||
// the should check firmware -client compatibility
|
||||
bool initial_checks_passed = true;
|
||||
return static_cast<ReturnCode>(socket.sendResult(initial_checks_passed));
|
||||
}
|
||||
|
||||
ReturnCode
|
||||
BaseMatterhornServer::get_num_udp_interfaces(ServerInterface &socket) {
|
||||
int numUDPInterfaces = static_cast<int>(num_udp_interfaces());
|
||||
return static_cast<ReturnCode>(socket.sendResult(numUDPInterfaces));
|
||||
}
|
||||
|
||||
ReturnCode MatterhornServer::get_update_mode(ServerInterface &socket) {
|
||||
return static_cast<ReturnCode>(
|
||||
socket.sendResult(static_cast<int>(updateMode)));
|
||||
}
|
||||
|
||||
ReturnCode BaseMatterhornServer::get_source_udp_mac(ServerInterface &socket) {
|
||||
uint64_t srcMac = udpDetails[0].srcmac;
|
||||
return static_cast<ReturnCode>(socket.sendResult(srcMac));
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "CommandLineOptions.h"
|
||||
#include "MatterhornServer.h"
|
||||
#include "StopServer.h"
|
||||
#include "VirtualMatterhornServer.h"
|
||||
#include "sls/logger.h"
|
||||
#include "sls/sls_detector_exceptions.h"
|
||||
#include <semaphore.h>
|
||||
@@ -61,7 +61,7 @@ int main(int argc, char *argv[]) {
|
||||
// std::signal(SIGTERM, childSigTermHandler);
|
||||
LOG(TLogLevel::logINFOBLUE) << "Stop Server [" << opts.port + 1 << "]";
|
||||
try {
|
||||
MatterhornServer stopServer(opts.port + 1);
|
||||
VirtualMatterhornServer stopServer(opts.port + 1);
|
||||
} catch (...) {
|
||||
LOG(TLogLevel::logINFOBLUE)
|
||||
<< "Exiting Stop Server [ Tid: " << gettid() << " ]";
|
||||
@@ -79,7 +79,9 @@ int main(int argc, char *argv[]) {
|
||||
LOG(TLogLevel::logINFOBLUE) << "Control Server [" << opts.port << "]\n";
|
||||
|
||||
try {
|
||||
sls::MatterhornServer server(opts.port);
|
||||
VirtualMatterhornServer server(
|
||||
opts.port); // TODO use virtual if compiled with virtual
|
||||
// simulators on
|
||||
} catch (...) {
|
||||
kill(child_pid, SIGTERM); // tell child to exit
|
||||
LOG(sls::logINFOBLUE) << "Exiting [ Tid: " << gettid() << " ]";
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "MatterhornServer.h"
|
||||
|
||||
namespace sls {
|
||||
|
||||
MatterhornServer::MatterhornServer(uint16_t port)
|
||||
: BaseMatterhornServer(port) {
|
||||
|
||||
// TODO: when do i set the udp mac and ip ?
|
||||
|
||||
// should maybe be part of the constructor?
|
||||
tcpInterface->startTCPServer();
|
||||
|
||||
// need a function to setup detector - e.g. set all registers etc.
|
||||
}
|
||||
|
||||
ReturnCode MatterhornServer::initial_checks(ServerInterface &socket) {
|
||||
|
||||
// TODO: add more checks here, for now just return true to be able to test
|
||||
// the should check firmware -client compatibility
|
||||
bool initial_checks_passed = true;
|
||||
return static_cast<ReturnCode>(socket.sendResult(initial_checks_passed));
|
||||
}
|
||||
|
||||
ReturnCode MatterhornServer::get_update_mode(ServerInterface &socket) {
|
||||
return static_cast<ReturnCode>(
|
||||
socket.sendResult(static_cast<int>(updateMode)));
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
@@ -1,21 +1,30 @@
|
||||
#include "MatterhornServer.h"
|
||||
#include "VirtualMatterhornServer.h"
|
||||
|
||||
namespace sls {
|
||||
|
||||
VirtualMatterhornServer::VirtualMatterhornServer(uint16_t port)
|
||||
: BaseMatterhornServer(port) {
|
||||
: BaseMatterhornServer<VirtualMatterhornServer>(port) {
|
||||
|
||||
udpDetails[0].srcip = LOCALHOSTIP_INT;
|
||||
udpDetails[0].srcport = DEFAULT_UDP_SRC_PORTNO;
|
||||
udpDetails[0].dstport = DEFAULT_UDP_DST_PORTNO;
|
||||
|
||||
// TODO: when do i set the udp mac and ip ?
|
||||
|
||||
BaseMatterhornServer(port);
|
||||
|
||||
tcpInterface = std::make_unique<TCPInterface>(
|
||||
function_table, port); // TODO: need a tcp and udp interface
|
||||
|
||||
// should maybe be part of the constructor?
|
||||
tcpInterface->startTCPServer();
|
||||
|
||||
// need a function to setup detector - e.g. set all registers etc.
|
||||
}
|
||||
}
|
||||
|
||||
ReturnCode VirtualMatterhornServer::initial_checks(ServerInterface &socket) {
|
||||
|
||||
// TODO: add more checks here, for now just return true to be able to test
|
||||
// the should check firmware -client compatibility
|
||||
bool initial_checks_passed = true;
|
||||
return static_cast<ReturnCode>(socket.sendResult(initial_checks_passed));
|
||||
}
|
||||
|
||||
ReturnCode VirtualMatterhornServer::get_update_mode(ServerInterface &socket) {
|
||||
return static_cast<ReturnCode>(
|
||||
socket.sendResult(static_cast<int>(updateMode)));
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
Reference in New Issue
Block a user