refactoring unix udp bridge

This commit is contained in:
Robin Müller 2021-03-12 17:15:53 +01:00
parent 7173d2ecfc
commit 8ab2044c30
4 changed files with 112 additions and 50 deletions

View File

@ -1,69 +1,127 @@
#include "TmTcUnixUdpBridge.h" #include "TmTcUnixUdpBridge.h"
#include "tcpipHelpers.h"
#include "../../serviceinterface/ServiceInterface.h" #include "../../serviceinterface/ServiceInterface.h"
#include "../../ipc/MutexGuard.h" #include "../../ipc/MutexGuard.h"
#include <errno.h> #include <errno.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <cstring>
//! Debugging preprocessor define.
#define FSFW_UDP_RCV_WIRETAPPING_ENABLED 1
const std::string TmTcUnixUdpBridge::DEFAULT_UDP_SERVER_PORT = "7301";
const std::string TmTcUnixUdpBridge::DEFAULT_UDP_CLIENT_PORT = "7302";
TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId,
object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId,
uint16_t serverPort, uint16_t clientPort): std::string udpServerPort, std::string udpClientPort):
TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) {
mutex = MutexFactory::instance()->createMutex(); if(udpServerPort == "") {
this->udpServerPort = DEFAULT_UDP_SERVER_PORT;
}
else {
this->udpServerPort = udpServerPort;
}
if(udpClientPort == "") {
this->udpClientPort = DEFAULT_UDP_CLIENT_PORT;
}
else {
this->udpClientPort = udpClientPort;
}
uint16_t setServerPort = DEFAULT_UDP_SERVER_PORT; mutex = MutexFactory::instance()->createMutex();
if(serverPort != 0xFFFF) { communicationLinkUp = false;
setServerPort = serverPort; }
}
uint16_t setClientPort = DEFAULT_UDP_CLIENT_PORT; ReturnValue_t TmTcUnixUdpBridge::initialize() {
if(clientPort != 0xFFFF) { using namespace tcpip;
setClientPort = clientPort;
}
// Set up UDP socket: https://man7.org/linux/man-pages/man7/ip.7.html ReturnValue_t result = TmTcBridge::initialize();
//clientSocket = socket(AF_INET, SOCK_DGRAM, 0); if(result != HasReturnvaluesIF::RETURN_OK) {
serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(serverSocket < 0) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not open" sif::error << "TmTcUnixUdpBridge::initialize: TmTcBridge initialization failed!"
" UDP socket!" << std::endl; << std::endl;
#endif #endif
handleSocketError(); return result;
return; }
}
serverAddress.sin_family = AF_INET; struct addrinfo *addrResult = nullptr;
struct addrinfo hints;
// Accept packets from any interface. std::memset(hints, 0, sizeof(hints));
//serverAddress.sin_addr.s_addr = inet_addr("127.73.73.0"); hints.ai_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); hints.ai_socktype = SOCK_DGRAM;
serverAddress.sin_port = htons(setServerPort); hints.ai_protocol = IPPROTO_UDP;
serverAddressLen = sizeof(serverAddress); hints.ai_flags = AI_PASSIVE;
setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &serverSocketOptions,
sizeof(serverSocketOptions));
clientAddress.sin_family = AF_INET; /* Set up UDP socket:
clientAddress.sin_addr.s_addr = htonl(INADDR_ANY); https://man7.org/linux/man-pages/man3/getaddrinfo.3.html
clientAddress.sin_port = htons(setClientPort); Passing nullptr as the first parameter and specifying AI_PASSIVE in hints will cause
clientAddressLen = sizeof(clientAddress); getaddrinfo to assign the address 0.0.0.0 (any address) */
int retval = getaddrinfo(nullptr, udpServerPort.c_str(), &hints, &addrResult);
int result = bind(serverSocket, if (retval != 0) {
reinterpret_cast<struct sockaddr*>(&serverAddress),
serverAddressLen);
if(result == -1) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not bind " sif::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Retrieving address info failed!" <<
"local port " << setServerPort << " to server socket!" std::endl;
<< std::endl;
#endif #endif
handleBindError(); return HasReturnvaluesIF::RETURN_FAILED;
return; }
}
/* Set up UDP socket: https://man7.org/linux/man-pages/man7/ip.7.html */
serverSocket = socket(addrResult->ai_family, addrResult->ai_socktype, addrResult->ai_protocol);
if(serverSocket < 0) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not open UDP socket!" <<
std::endl;
#else
sif::printError("TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not open UDP socket!\n");
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
freeaddrinfo(addrResult);
handleError(Protocol::UDP, ErrorSources::SOCKET_CALL);
handleSocketError();
return HasReturnvaluesIF::RETURN_FAILED;
}
serverAddress.sin_family = AF_INET;
// Accept packets from any interface.
//serverAddress.sin_addr.s_addr = inet_addr("127.73.73.0");
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddress.sin_port = htons(setServerPort);
serverAddressLen = sizeof(serverAddress);
setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &serverSocketOptions,
sizeof(serverSocketOptions));
clientAddress.sin_family = AF_INET;
clientAddress.sin_addr.s_addr = htonl(INADDR_ANY);
clientAddress.sin_port = htons(setClientPort);
clientAddressLen = sizeof(clientAddress);
int result = bind(serverSocket,
reinterpret_cast<struct sockaddr*>(&serverAddress),
serverAddressLen);
if(result == -1) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not bind "
"local port " << setServerPort << " to server socket!"
<< std::endl;
#endif
handleBindError();
return;
}
return HasReturnvaluesIF::RETURN_OK;
} }
TmTcUnixUdpBridge::~TmTcUnixUdpBridge() { TmTcUnixUdpBridge::~TmTcUnixUdpBridge() {
if(mutex != nullptr) {
MutexFactory::instance()->deleteMutex(mutex);
}
close(serverSocket);
} }
ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) {

View File

@ -10,16 +10,18 @@
class TmTcUnixUdpBridge: public TmTcBridge { class TmTcUnixUdpBridge: public TmTcBridge {
friend class TcUnixUdpPollingTask; friend class TcUnixUdpPollingTask;
public: public:
// The ports chosen here should not be used by any other process. /* The ports chosen here should not be used by any other process.
// List of used ports on Linux: /etc/services List of used ports on Linux: /etc/services */
static constexpr uint16_t DEFAULT_UDP_SERVER_PORT = 7301; static const std::string DEFAULT_UDP_SERVER_PORT;
static constexpr uint16_t DEFAULT_UDP_CLIENT_PORT = 7302; static const std::string DEFAULT_UDP_CLIENT_PORT;
TmTcUnixUdpBridge(object_id_t objectId, object_id_t tcDestination, TmTcUnixUdpBridge(object_id_t objectId, object_id_t tcDestination,
object_id_t tmStoreId, object_id_t tcStoreId, object_id_t tmStoreId, object_id_t tcStoreId,
uint16_t serverPort = 0xFFFF,uint16_t clientPort = 0xFFFF); std::string serverPort = "", std::string clientPort = "");
virtual~ TmTcUnixUdpBridge(); virtual~ TmTcUnixUdpBridge();
ReturnValue_t initialize() override;
void checkAndSetClientAddress(sockaddr_in& clientAddress); void checkAndSetClientAddress(sockaddr_in& clientAddress);
void setClientAddressToAny(bool ipAddrAnySet); void setClientAddressToAny(bool ipAddrAnySet);
@ -28,6 +30,8 @@ protected:
private: private:
int serverSocket = 0; int serverSocket = 0;
std::string udpServerPort;
std::string udpClientPort;
const int serverSocketOptions = 0; const int serverSocketOptions = 0;

View File

@ -5,6 +5,9 @@
#include <fsfw/ipc/MutexGuard.h> #include <fsfw/ipc/MutexGuard.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
//! Debugging preprocessor define.
#define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0
const std::string TmTcWinUdpBridge::DEFAULT_UDP_SERVER_PORT = "7301"; const std::string TmTcWinUdpBridge::DEFAULT_UDP_SERVER_PORT = "7301";
const std::string TmTcWinUdpBridge::DEFAULT_UDP_CLIENT_PORT = "7302"; const std::string TmTcWinUdpBridge::DEFAULT_UDP_CLIENT_PORT = "7302";

View File

@ -5,9 +5,6 @@
#include <winsock2.h> #include <winsock2.h>
//! Debugging preprocessor define.
#define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0
class TmTcWinUdpBridge: public TmTcBridge { class TmTcWinUdpBridge: public TmTcBridge {
friend class TcWinUdpPollingTask; friend class TcWinUdpPollingTask;
public: public: