some refactoring

This commit is contained in:
2026-02-23 16:33:26 +01:00
parent d062b34a58
commit 23a94b28cc
8 changed files with 120 additions and 154 deletions
@@ -2,7 +2,6 @@
add_executable(matterhornDetectorServer_virtual
${CMAKE_CURRENT_SOURCE_DIR}/src/MatterhornApp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/MatterhornServer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/MatterhornClientInterface.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/StopServer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/CommandLineOptions.cpp
)
@@ -1,25 +0,0 @@
#include "ClientInterface.h"
namespace sls {
class MatterhornClientInterface : public ClientInterface {
public:
MatterhornClientInterface(
const uint16_t portNumber = DEFAULT_TCP_CNTRL_PORTNO);
~MatterhornClientInterface() = default;
private:
ReturnCode get_version(ServerInterface &socket);
ReturnCode get_detector_type(ServerInterface &socket);
ReturnCode initial_checks(ServerInterface &socket);
ReturnCode get_num_udp_interfaces(ServerInterface &socket);
static std::string getMatterhornServerVersion();
};
} // namespace sls
@@ -1,18 +1,19 @@
#pragma once
#include "MatterhornClientInterface.h"
#include "TCPInterface.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;
uint16_t srcport{};
uint16_t dstport{};
uint64_t srcmac{};
uint64_t dstmac{};
uint32_t srcip{};
uint32_t dstip{};
};
class MatterhornServer {
@@ -29,9 +30,41 @@ class MatterhornServer {
~MatterhornServer() = default;
ReturnCode get_version(ServerInterface &socket);
ReturnCode get_detector_type(ServerInterface &socket);
ReturnCode initial_checks(ServerInterface &socket);
ReturnCode get_num_udp_interfaces(ServerInterface &socket);
private:
std::unique_ptr<MatterhornClientInterface> tcpipInterface;
UDPInfo udpDetails{}; // TODO: for now only one receiver per module
static std::string getMatterhornServerVersion();
size_t num_udp_interfaces() const;
private:
/// @brief @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);
}}};
};
} // namespace sls
@@ -1,64 +0,0 @@
#include "MatterhornClientInterface.h"
#include "sls/logger.h"
#include "sls/sls_detector_defs.h"
#include "sls/sls_detector_funcs.h"
#include "sls/versionAPI.h"
namespace sls {
MatterhornClientInterface::MatterhornClientInterface(const uint16_t portNumber)
: ClientInterface(portNumber) {
// TODO: maybe define the function list in another .hpp file as inline
// unorderer map also this F_GET_SERVER_VERSION should be a global enum
// shared by client and server
functionTable = {
{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);
}}};
startTCPServer();
}
ReturnCode MatterhornClientInterface::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
MatterhornClientInterface::get_detector_type(ServerInterface &socket) {
int detectortype = slsDetectorDefs::detectorType::MATTERHORN;
return static_cast<ReturnCode>(socket.sendResult(detectortype));
}
std::string MatterhornClientInterface::getMatterhornServerVersion() {
return APIMATTERHORN;
}
ReturnCode MatterhornClientInterface::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
MatterhornClientInterface::get_num_udp_interfaces(ServerInterface &socket) {
int numUDPInterfaces = 1;
return static_cast<ReturnCode>(socket.sendResult(numUDPInterfaces));
}
} // namespace sls
@@ -1,35 +1,69 @@
#include "MatterhornServer.h"
#include "communication_funcs.h"
#include "sls/logger.h"
#include "sls/network_utils.h"
#include "sls/sls_detector_defs.h"
// #include "sharedMemory.h"
#include "communication_funcs.h"
#include "sls/versionAPI.h"
namespace sls {
MatterhornServer::MatterhornServer(uint16_t port) {
validatePortNumber(port);
/*
// TODO: keep the c code for now
if (sharedMemory_create(port) == slsDetectorDefs::FAIL) {
throw sls::RuntimeError("Failed to create shared memory");
}
*/
// mmh do I want a virtual server inheriting from parent Server class? and
// parent Matterhorn class - probably better
#ifdef VIRTUAL
udpDetails.srcip = LOCALHOSTIP_INT;
udpDetails[0].srcip = LOCALHOSTIP_INT;
#endif
udpDetails.srcport = DEFAULT_UDP_SRC_PORTNO;
udpDetails.dstport = DEFAULT_UDP_DST_PORTNO;
udpDetails[0].srcport = DEFAULT_UDP_SRC_PORTNO;
udpDetails[0].dstport = DEFAULT_UDP_DST_PORTNO;
// TODO: when do i set the udp mac and ip ?
tcpipInterface = std::make_unique<MatterhornClientInterface>(
port); // TODO: need a tcp and udp interface
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 MatterhornServer::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 MatterhornServer::get_detector_type(ServerInterface &socket) {
int detectortype = slsDetectorDefs::detectorType::MATTERHORN;
return static_cast<ReturnCode>(socket.sendResult(detectortype));
}
std::string MatterhornServer::getMatterhornServerVersion() {
return APIMATTERHORN;
}
size_t MatterhornServer::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 MatterhornServer::get_num_udp_interfaces(ServerInterface &socket) {
int numUDPInterfaces = static_cast<int>(num_udp_interfaces());
return static_cast<ReturnCode>(socket.sendResult(numUDPInterfaces));
}
} // namespace sls
@@ -1,5 +1,5 @@
set(SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/ClientInterface.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/TCPInterface.cpp
)
add_library(slsServerObject OBJECT
@@ -23,7 +23,7 @@ target_link_libraries(slsServerObject
set(DETECTOR_LIBRARY_TARGETS slsServerObject)
set(PUBLICHEADERS
${CMAKE_CURRENT_SOURCE_DIR}/include/ClientInterface.h
${CMAKE_CURRENT_SOURCE_DIR}/include/TCPInterface.h
)
#Shared library
@@ -10,45 +10,24 @@
namespace sls {
/**
* @brief ClientInterface class handles communication and processing of commands
* @brief TCPInterface class handles communication and processing of commands
* from Client to Server.
*/
class ClientInterface {
class TCPInterface {
protected:
// TODO probably requires std::variant
/// @brief map of function IDs and corresponding functions
std::unordered_map<detFuncs, std::function<ReturnCode(ServerInterface &)>>
functionTable{}; // set in constructor of child process
public:
~TCPInterface();
TCPInterface(std::unordered_map<
detFuncs, std::function<ReturnCode(ServerInterface &)>>
&functionTable_,
const uint16_t portNumber = DEFAULT_TCP_CNTRL_PORTNO);
/// @brief starts the TCP/IP server to listen for client commands
void startTCPServer();
private:
/// @brief listener thread for TCP/IP communication with the client
std::unique_ptr<std::thread> tcpThread;
/// @brief flag to signal the TCP/IP listener thread to stop
std::atomic<bool> killTcpThread{false};
/// @brief flag to indicate if the receiver is currently locked by a client
bool lockedByClient{false}; // TODO should it be atomic?
uint16_t portNumber{};
/// @brief socket for TCP/IP communication with the client
ServerSocket server;
public:
~ClientInterface();
explicit ClientInterface(
const uint16_t portNumber = DEFAULT_TCP_CNTRL_PORTNO);
// std::string getReceiverVersion();
private:
/**
/**
* @brief decodes the received command and calls the corresponding function
* @param function_id The ID of the function recived by the server and to
* be executed
@@ -56,7 +35,14 @@ class ClientInterface {
ReturnCode processReceivedData(const detFuncs function_id,
ServerInterface &socket);
bool checkifReceiverLocked();
/// @brief map of function IDs and corresponding functions
std::unordered_map<detFuncs, std::function<ReturnCode(ServerInterface &)>>
functionTable{};
uint16_t portNumber{};
/// @brief socket for TCP/IP communication with the client
ServerSocket server;
};
} // namespace sls
@@ -1,4 +1,4 @@
#include "ClientInterface.h"
#include "TCPInterface.h"
#include "fmt/format.h"
#include "sls/logger.h"
@@ -7,19 +7,22 @@
namespace sls {
ClientInterface::ClientInterface(const uint16_t portNumber)
: portNumber(portNumber), server(portNumber) {
TCPInterface::TCPInterface(
std::unordered_map<detFuncs, std::function<ReturnCode(ServerInterface &)>>
&functionTable_,
const uint16_t portNumber)
: functionTable(functionTable_), portNumber(portNumber),
server(portNumber) {
validatePortNumber(portNumber);
}
ClientInterface::~ClientInterface() {
killTcpThread = true;
TCPInterface::~TCPInterface() {
LOG(logINFORED) << "Shutting down TCP Socket on port " << portNumber;
server.shutdown();
LOG(logDEBUG) << "TCP Socket closed on port " << portNumber;
}
void ClientInterface::startTCPServer() {
void TCPInterface::startTCPServer() {
LOG(logINFO) << "SLS Server starting TCP Server on port " << portNumber
<< '\n';
@@ -63,8 +66,8 @@ void ClientInterface::startTCPServer() {
LOG(logINFOBLUE) << "Exiting TCP Server";
}
ReturnCode ClientInterface::processReceivedData(const detFuncs function_id,
ServerInterface &socket) {
ReturnCode TCPInterface::processReceivedData(const detFuncs function_id,
ServerInterface &socket) {
// TODO: is NUM_DET_FUNCTIONS correct?
LOG(logDEBUG1) << "calling function fnum: " << function_id << " ("