mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-08-07 10:32:25 +02:00
added Server class usable for all detectors
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
#include "DetectorServer.h"
|
||||
#include "TCPInterface.h"
|
||||
#include "communication_funcs.h"
|
||||
#include "fmt/format.h"
|
||||
#include "sls/logger.h"
|
||||
#include "sls/network_utils.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
@@ -14,19 +16,11 @@
|
||||
|
||||
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 {
|
||||
template <typename DerivedServer>
|
||||
class BaseMatterhornServer
|
||||
: public DetectorServer<BaseMatterhornServer<DerivedServer>> {
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -36,7 +30,8 @@ template <typename DerivedServer> class BaseMatterhornServer {
|
||||
* throws an exception in case of failure
|
||||
* @param port TCP/IP port number
|
||||
*/
|
||||
explicit BaseMatterhornServer(uint16_t port = DEFAULT_TCP_CNTRL_PORTNO);
|
||||
explicit BaseMatterhornServer(uint16_t port = DEFAULT_TCP_CNTRL_PORTNO)
|
||||
: DetectorServer<BaseMatterhornServer<DerivedServer>>(port) {}
|
||||
|
||||
~BaseMatterhornServer() = default;
|
||||
|
||||
@@ -46,95 +41,30 @@ template <typename DerivedServer> class BaseMatterhornServer {
|
||||
|
||||
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);
|
||||
|
||||
ReturnCode get_source_udp_ip(ServerInterface &socket);
|
||||
|
||||
ReturnCode get_source_udp_port(ServerInterface &socket);
|
||||
|
||||
ReturnCode get_destination_udp_mac(ServerInterface &socket);
|
||||
|
||||
ReturnCode get_destination_udp_ip(ServerInterface &socket);
|
||||
|
||||
ReturnCode get_destination_udp_port(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
|
||||
/**
|
||||
* @brief call function corresponding to the function ID received from the
|
||||
* client and send back the result
|
||||
* @param function_id the function ID received from the client
|
||||
* @param socket the socket to send the result back to the client
|
||||
*/
|
||||
ReturnCode processFunction(const detFuncs function_id,
|
||||
ServerInterface &socket);
|
||||
|
||||
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);
|
||||
}},
|
||||
|
||||
{detFuncs::F_GET_SOURCE_UDP_IP,
|
||||
[this](ServerInterface &si) {
|
||||
return this->get_source_udp_ip(si);
|
||||
}},
|
||||
{detFuncs::F_GET_DEST_UDP_MAC,
|
||||
[this](ServerInterface &si) {
|
||||
return this->get_destination_udp_mac(si);
|
||||
}},
|
||||
{detFuncs::F_GET_DEST_UDP_IP,
|
||||
[this](ServerInterface &si) {
|
||||
return this->get_destination_udp_ip(si);
|
||||
}},
|
||||
{detFuncs::F_GET_DEST_UDP_PORT, [this](ServerInterface &si) {
|
||||
return this->get_destination_udp_port(si);
|
||||
}}};
|
||||
};
|
||||
|
||||
template <typename DerivedServer>
|
||||
BaseMatterhornServer<DerivedServer>::BaseMatterhornServer(uint16_t port) {
|
||||
ReturnCode
|
||||
BaseMatterhornServer<DerivedServer>::processFunction(const detFuncs function_id,
|
||||
ServerInterface &socket) {
|
||||
|
||||
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.
|
||||
switch (function_id) {
|
||||
default:
|
||||
throw RuntimeError(
|
||||
fmt::format("Function {} not implemented",
|
||||
getFunctionNameFromEnum((enum detFuncs)function_id)));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
@@ -162,52 +92,10 @@ std::string BaseMatterhornServer<DerivedServer>::getMatterhornServerVersion() {
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
size_t BaseMatterhornServer<DerivedServer>::num_udp_interfaces() const {
|
||||
return udpDetails.size();
|
||||
}
|
||||
ReturnCode
|
||||
BaseMatterhornServer<DerivedServer>::initial_checks(ServerInterface &socket) {
|
||||
|
||||
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));
|
||||
return static_cast<DerivedServer *>(this)->initial_checks(socket);
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
ReturnCode BaseMatterhornServer<DerivedServer>::get_source_udp_mac(
|
||||
ServerInterface &socket) {
|
||||
return static_cast<ReturnCode>(socket.sendResult(udpDetails[0].srcmac));
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
ReturnCode BaseMatterhornServer<DerivedServer>::get_source_udp_ip(
|
||||
ServerInterface &socket) {
|
||||
return static_cast<ReturnCode>(socket.sendResult(udpDetails[0].srcip));
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
ReturnCode BaseMatterhornServer<DerivedServer>::get_source_udp_port(
|
||||
ServerInterface &socket) {
|
||||
return static_cast<ReturnCode>(
|
||||
socket.sendResult(static_cast<int>(udpDetails[0].srcport)));
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
ReturnCode BaseMatterhornServer<DerivedServer>::get_destination_udp_mac(
|
||||
ServerInterface &socket) {
|
||||
return static_cast<ReturnCode>(socket.sendResult(udpDetails[0].dstmac));
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
ReturnCode BaseMatterhornServer<DerivedServer>::get_destination_udp_ip(
|
||||
ServerInterface &socket) {
|
||||
return static_cast<ReturnCode>(socket.sendResult(udpDetails[0].dstip));
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
ReturnCode BaseMatterhornServer<DerivedServer>::get_destination_udp_port(
|
||||
ServerInterface &socket) {
|
||||
return static_cast<ReturnCode>(socket.sendResult(udpDetails[0].dstport));
|
||||
};
|
||||
|
||||
} // namespace sls
|
||||
@@ -22,8 +22,6 @@ class MatterhornServer : public BaseMatterhornServer<MatterhornServer> {
|
||||
~MatterhornServer() = default;
|
||||
|
||||
ReturnCode initial_checks(ServerInterface &socket);
|
||||
|
||||
ReturnCode get_update_mode(ServerInterface &socket);
|
||||
};
|
||||
|
||||
} // namespace sls
|
||||
@@ -1,14 +0,0 @@
|
||||
#include "MatterhornServer.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace sls {
|
||||
|
||||
// TODO: should this inherit from MatterhornServer or a base class - depending on virtual or not
|
||||
class StopServer : public MatterhornServer {
|
||||
public:
|
||||
StopServer(uint16_t port);
|
||||
|
||||
~StopServer() = default;
|
||||
};
|
||||
|
||||
} // namespace sls
|
||||
@@ -19,8 +19,6 @@ class VirtualMatterhornServer
|
||||
~VirtualMatterhornServer() = default;
|
||||
|
||||
ReturnCode initial_checks(ServerInterface &socket);
|
||||
|
||||
ReturnCode get_update_mode(ServerInterface &socket);
|
||||
};
|
||||
|
||||
} // namespace sls
|
||||
@@ -21,9 +21,4 @@ ReturnCode VirtualMatterhornServer::initial_checks(ServerInterface &socket) {
|
||||
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
|
||||
@@ -0,0 +1,190 @@
|
||||
#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 <cstring>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace sls {
|
||||
|
||||
// TODO move to defs?
|
||||
/// @brief struct saving udp details (one UDP port per module)
|
||||
struct UDPInfo {
|
||||
uint16_t srcport{};
|
||||
uint16_t srcport2{};
|
||||
uint16_t dstport{};
|
||||
uint16_t dstport2{};
|
||||
uint64_t srcmac{};
|
||||
uint64_t srcmac2{};
|
||||
uint64_t dstmac{};
|
||||
uint64_t dstmac2{};
|
||||
uint32_t srcip{};
|
||||
uint32_t srcip2{};
|
||||
uint32_t dstip{};
|
||||
uint32_t dstip2{};
|
||||
};
|
||||
|
||||
template <typename DerivedDetectorServer> class DetectorServer {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* Creates a detector server.
|
||||
* Assembles a detector server using TCP and UDP detector interfaces
|
||||
* throws an exception in case of failure
|
||||
* @param port TCP/IP port number
|
||||
*/
|
||||
explicit DetectorServer(uint16_t port = DEFAULT_TCP_CNTRL_PORTNO);
|
||||
|
||||
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
|
||||
|
||||
/// @brief TODO what is this?
|
||||
bool updateMode{true};
|
||||
|
||||
private:
|
||||
ReturnCode processFunction(const detFuncs function_id,
|
||||
ServerInterface &socket);
|
||||
|
||||
size_t num_udp_interfaces() const;
|
||||
|
||||
ReturnCode get_num_udp_interfaces(ServerInterface &socket) const;
|
||||
|
||||
// TODO dont know what this does?
|
||||
ReturnCode get_update_mode(ServerInterface &socket) const;
|
||||
|
||||
ReturnCode get_source_udp_mac(ServerInterface &socket) const;
|
||||
|
||||
ReturnCode get_source_udp_ip(ServerInterface &socket) const;
|
||||
|
||||
ReturnCode get_source_udp_port(ServerInterface &socket) const;
|
||||
|
||||
ReturnCode get_destination_udp_mac(ServerInterface &socket) const;
|
||||
|
||||
ReturnCode get_destination_udp_ip(ServerInterface &socket) const;
|
||||
|
||||
ReturnCode get_destination_udp_port(ServerInterface &socket) const;
|
||||
};
|
||||
|
||||
template <typename DerivedDetectorServer>
|
||||
DetectorServer<DerivedDetectorServer>::DetectorServer(uint16_t port) {
|
||||
validatePortNumber(port);
|
||||
|
||||
udpDetails[0].srcport = DEFAULT_UDP_SRC_PORTNO;
|
||||
udpDetails[0].dstport = DEFAULT_UDP_DST_PORTNO;
|
||||
|
||||
std::function<ReturnCode(const detFuncs &, ServerInterface &)> fn =
|
||||
[this](const detFuncs &function_id, ServerInterface &socket) {
|
||||
return this->processFunction(function_id, socket);
|
||||
};
|
||||
tcpInterface = std::make_unique<TCPInterface>(fn, port);
|
||||
}
|
||||
|
||||
template <typename DerivedDetectorServer>
|
||||
ReturnCode DetectorServer<DerivedDetectorServer>::processFunction(
|
||||
const detFuncs function_id, ServerInterface &socket) {
|
||||
|
||||
switch (function_id) {
|
||||
case detFuncs::F_GET_SERVER_VERSION:
|
||||
return static_cast<DerivedDetectorServer *>(this)->get_version(socket);
|
||||
case detFuncs::F_GET_DETECTOR_TYPE:
|
||||
return static_cast<DerivedDetectorServer *>(this)->get_detector_type(
|
||||
socket);
|
||||
case detFuncs::F_INITIAL_CHECKS:
|
||||
return static_cast<DerivedDetectorServer *>(this)->initial_checks(
|
||||
socket);
|
||||
case detFuncs::F_GET_NUM_INTERFACES:
|
||||
return static_cast<DerivedDetectorServer *>(this)
|
||||
->get_num_udp_interfaces(socket);
|
||||
case detFuncs::F_GET_UPDATE_MODE:
|
||||
return get_update_mode(socket);
|
||||
case detFuncs::F_GET_SOURCE_UDP_MAC:
|
||||
return get_source_udp_mac(socket);
|
||||
case detFuncs::F_GET_SOURCE_UDP_IP:
|
||||
return get_source_udp_ip(socket);
|
||||
case detFuncs::F_GET_DEST_UDP_MAC:
|
||||
return get_destination_udp_mac(socket);
|
||||
case detFuncs::F_GET_DEST_UDP_IP:
|
||||
return get_destination_udp_ip(socket);
|
||||
case detFuncs::F_GET_DEST_UDP_PORT:
|
||||
return get_destination_udp_port(socket);
|
||||
default:
|
||||
LOG(logDEBUG) << "Checking specific server functions for function ID: "
|
||||
<< function_id;
|
||||
// process detector specific functions
|
||||
static_cast<DerivedDetectorServer *>(this)->processFunction(function_id,
|
||||
socket);
|
||||
}
|
||||
|
||||
return ReturnCode::FAIL;
|
||||
}
|
||||
|
||||
template <typename DerivedDetectorServer>
|
||||
size_t DetectorServer<DerivedDetectorServer>::num_udp_interfaces() const {
|
||||
return udpDetails.size();
|
||||
}
|
||||
|
||||
template <typename DerivedDetectorServer>
|
||||
ReturnCode DetectorServer<DerivedDetectorServer>::get_num_udp_interfaces(
|
||||
ServerInterface &socket) const {
|
||||
int numUDPInterfaces = static_cast<int>(num_udp_interfaces());
|
||||
return static_cast<ReturnCode>(socket.sendResult(numUDPInterfaces));
|
||||
}
|
||||
|
||||
template <typename DerivedDetectorServer>
|
||||
ReturnCode DetectorServer<DerivedDetectorServer>::get_update_mode(
|
||||
ServerInterface &socket) const {
|
||||
|
||||
return static_cast<ReturnCode>(
|
||||
socket.sendResult(static_cast<int>(updateMode)));
|
||||
}
|
||||
|
||||
template <typename DerivedDetectorServer>
|
||||
ReturnCode DetectorServer<DerivedDetectorServer>::get_source_udp_mac(
|
||||
ServerInterface &socket) const {
|
||||
return static_cast<ReturnCode>(socket.sendResult(udpDetails[0].srcmac));
|
||||
}
|
||||
|
||||
template <typename DerivedDetectorServer>
|
||||
ReturnCode DetectorServer<DerivedDetectorServer>::get_source_udp_ip(
|
||||
ServerInterface &socket) const {
|
||||
return static_cast<ReturnCode>(socket.sendResult(udpDetails[0].srcip));
|
||||
}
|
||||
|
||||
template <typename DerivedDetectorServer>
|
||||
ReturnCode DetectorServer<DerivedDetectorServer>::get_source_udp_port(
|
||||
ServerInterface &socket) const {
|
||||
return static_cast<ReturnCode>(
|
||||
socket.sendResult(static_cast<int>(udpDetails[0].srcport)));
|
||||
}
|
||||
|
||||
template <typename DerivedDetectorServer>
|
||||
ReturnCode DetectorServer<DerivedDetectorServer>::get_destination_udp_mac(
|
||||
ServerInterface &socket) const {
|
||||
return static_cast<ReturnCode>(socket.sendResult(udpDetails[0].dstmac));
|
||||
}
|
||||
|
||||
template <typename DerivedDetectorServer>
|
||||
ReturnCode DetectorServer<DerivedDetectorServer>::get_destination_udp_ip(
|
||||
ServerInterface &socket) const {
|
||||
return static_cast<ReturnCode>(socket.sendResult(udpDetails[0].dstip));
|
||||
}
|
||||
|
||||
template <typename DerivedDetectorServer>
|
||||
ReturnCode DetectorServer<DerivedDetectorServer>::get_destination_udp_port(
|
||||
ServerInterface &socket) const {
|
||||
return static_cast<ReturnCode>(socket.sendResult(udpDetails[0].dstport));
|
||||
};
|
||||
|
||||
} // namespace sls
|
||||
@@ -18,9 +18,8 @@ class TCPInterface {
|
||||
public:
|
||||
~TCPInterface();
|
||||
|
||||
TCPInterface(std::unordered_map<
|
||||
detFuncs, std::function<ReturnCode(ServerInterface &)>>
|
||||
&functionTable_,
|
||||
TCPInterface(std::function<ReturnCode(const detFuncs &, ServerInterface &)>
|
||||
&processFunction_,
|
||||
const uint16_t portNumber = DEFAULT_TCP_CNTRL_PORTNO);
|
||||
|
||||
/// @brief starts the TCP/IP server to listen for client commands
|
||||
@@ -36,8 +35,8 @@ class TCPInterface {
|
||||
ServerInterface &socket);
|
||||
|
||||
/// @brief map of function IDs and corresponding functions
|
||||
std::unordered_map<detFuncs, std::function<ReturnCode(ServerInterface &)>>
|
||||
functionTable{};
|
||||
std::function<ReturnCode(const detFuncs &, ServerInterface &)>
|
||||
processFunction;
|
||||
|
||||
uint16_t portNumber{};
|
||||
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
namespace sls {
|
||||
|
||||
TCPInterface::TCPInterface(
|
||||
std::unordered_map<detFuncs, std::function<ReturnCode(ServerInterface &)>>
|
||||
&functionTable_,
|
||||
std::function<ReturnCode(const detFuncs &, ServerInterface &)>
|
||||
&processFunction_,
|
||||
const uint16_t portNumber)
|
||||
: functionTable(functionTable_), portNumber(portNumber),
|
||||
: processFunction(processFunction_), portNumber(portNumber),
|
||||
server(portNumber) {
|
||||
validatePortNumber(portNumber);
|
||||
}
|
||||
@@ -67,21 +67,12 @@ void TCPInterface::startTCPServer() {
|
||||
|
||||
ReturnCode TCPInterface::processReceivedData(const detFuncs function_id,
|
||||
ServerInterface &socket) {
|
||||
// TODO: is NUM_DET_FUNCTIONS correct?
|
||||
|
||||
LOG(logDEBUG1) << "calling function fnum: " << function_id << " ("
|
||||
<< getFunctionNameFromEnum((enum detFuncs)function_id)
|
||||
<< ")";
|
||||
|
||||
auto function = functionTable.find(function_id);
|
||||
if (function == functionTable.end()) {
|
||||
throw RuntimeError(
|
||||
fmt::format("Function {} not found not implemented",
|
||||
getFunctionNameFromEnum((enum detFuncs)function_id)));
|
||||
}
|
||||
|
||||
ReturnCode returncode =
|
||||
function->second(socket); // how does it pass input arguments?
|
||||
ReturnCode returncode = processFunction(function_id, socket);
|
||||
|
||||
LOG(logDEBUG1) << "Function "
|
||||
<< getFunctionNameFromEnum((enum detFuncs)function_id)
|
||||
|
||||
Reference in New Issue
Block a user