contiued tcp and improved udp task

This commit is contained in:
Robin Müller 2021-03-09 00:37:42 +01:00
parent 494dd0db32
commit b695242420
3 changed files with 88 additions and 50 deletions

View File

@ -1,86 +1,120 @@
#include "TcWinTcpServer.h" #include "TcWinTcpServer.h"
#include "../../serviceinterface/ServiceInterface.h" #include "../../serviceinterface/ServiceInterface.h"
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h>
const std::string TcWinTcpServer::DEFAULT_TCP_SERVER_PORT = "7301";
const std::string TcWinTcpServer::DEFAULT_TCP_CLIENT_PORT = "7302";
TcWinTcpServer::TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge, TcWinTcpServer::TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge,
uint16_t customTcpServerPort): std::string customTcpServerPort):
SystemObject(objectId) { SystemObject(objectId), tcpPort(customTcpServerPort) {
if(tcpPort == "") {
tcpPort = DEFAULT_TCP_SERVER_PORT;
}
}
ReturnValue_t TcWinTcpServer::initialize() {
int retval = 0;
struct addrinfo *addrResult = nullptr;
struct addrinfo hints;
/* Initiates Winsock DLL. */ /* Initiates Winsock DLL. */
WSAData wsaData; WSAData wsaData;
WORD wVersionRequested = MAKEWORD(2, 2); WORD wVersionRequested = MAKEWORD(2, 2);
int err = WSAStartup(wVersionRequested, &wsaData); int err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) { if (err != 0) {
/* Tell the user that we could not find a usable */ /* Tell the user that we could not find a usable Winsock DLL. */
/* Winsock DLL. */
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge:" sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge: WSAStartup failed with error: " <<
"WSAStartup failed with error: " << err << std::endl; err << std::endl;
#endif #endif
return; return HasReturnvaluesIF::RETURN_FAILED;
}
ZeroMemory(&hints, sizeof (hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
retval = getaddrinfo(nullptr, tcpPort.c_str(), &hints, &addrResult);
if (retval != 0) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TcWinTcpServer::TcWinTcpServer: Retrieving address info failed!" <<
std::endl;
#endif
handleError(ErrorSources::GETADDRINFO_CALL);
return HasReturnvaluesIF::RETURN_FAILED;
} }
/* Open TCP (stream) socket */ /* Open TCP (stream) socket */
serverTcpSocket = socket(AF_INET, SOCK_STREAM, 0); listenerTcpSocket = socket(addrResult->ai_family, addrResult->ai_socktype,
uint16_t tcpPort = customTcpServerPort; addrResult->ai_protocol);
if(listenerTcpSocket == INVALID_SOCKET) {
if(customTcpServerPort == 0xffff) {
tcpPort = DEFAULT_TCP_SERVER_PORT;
}
if(serverTcpSocket == 0) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TcWinTcpServer::TcWinTcpServer: Socket creation failed!" << std::endl; sif::warning << "TcWinTcpServer::TcWinTcpServer: Socket creation failed!" << std::endl;
handleError(ErrorSources::SOCKET_CALL);
#endif #endif
freeaddrinfo(addrResult);
handleError(ErrorSources::SOCKET_CALL);
return HasReturnvaluesIF::RETURN_FAILED;
} }
int retval = setsockopt(serverTcpSocket, SOL_SOCKET, SO_REUSEADDR | SO_BROADCAST, // retval = setsockopt(listenerTcpSocket, SOL_SOCKET, SO_REUSEADDR | SO_BROADCAST,
reinterpret_cast<const char*>(&tcpSockOpt), sizeof(tcpSockOpt)); // reinterpret_cast<const char*>(&tcpSockOpt), sizeof(tcpSockOpt));
if(retval != 0) { // if(retval != 0) {
sif::warning << "TcWinTcpServer::TcWinTcpServer: Setting socket options failed!" << // sif::warning << "TcWinTcpServer::TcWinTcpServer: Setting socket options failed!" <<
std::endl; // std::endl;
handleError(ErrorSources::SETSOCKOPT_CALL); // handleError(ErrorSources::SETSOCKOPT_CALL);
} // return HasReturnvaluesIF::RETURN_FAILED;
tcpAddress.sin_family = AF_INET; // }
tcpAddress.sin_addr.s_addr = htonl(INADDR_ANY); // tcpAddress.sin_family = AF_INET;
tcpAddress.sin_port = htons(tcpPort); // tcpAddress.sin_addr.s_addr = htonl(INADDR_ANY);
retval = bind(serverTcpSocket, reinterpret_cast<const sockaddr*>(&tcpAddress), retval = bind(listenerTcpSocket, reinterpret_cast<const sockaddr*>(&tcpAddress),
tcpAddrLen); tcpAddrLen);
if(retval != 0) { if(retval == SOCKET_ERROR) {
sif::warning << "TcWinTcpServer::TcWinTcpServer: Binding socket failed!" << sif::warning << "TcWinTcpServer::TcWinTcpServer: Binding socket failed!" <<
std::endl; std::endl;
freeaddrinfo(addrResult);
handleError(ErrorSources::BIND_CALL); handleError(ErrorSources::BIND_CALL);
} }
freeaddrinfo(addrResult);
return HasReturnvaluesIF::RETURN_OK;
} }
TcWinTcpServer::~TcWinTcpServer() { TcWinTcpServer::~TcWinTcpServer() {
closesocket(serverTcpSocket); closesocket(listenerTcpSocket);
WSACleanup(); WSACleanup();
} }
ReturnValue_t TcWinTcpServer::initialize() {
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t TcWinTcpServer::performOperation(uint8_t opCode) { ReturnValue_t TcWinTcpServer::performOperation(uint8_t opCode) {
/* If a connection is accepted, the corresponding scoket will be assigned to the new socket */ /* If a connection is accepted, the corresponding scoket will be assigned to the new socket */
SOCKET connectorSocket; SOCKET clientSocket;
sockaddr_in connectorSockAddr; sockaddr_in clientSockAddr;
int connectorSockAddrLen = 0; int connectorSockAddrLen = 0;
int retval = 0;
/* Listen for connection requests permanently for lifetime of program */ /* Listen for connection requests permanently for lifetime of program */
while(true) { while(true) {
int retval = listen(serverTcpSocket, backlog); retval = listen(listenerTcpSocket, currentBacklog);
if(retval != 0) { if(retval == SOCKET_ERROR) {
handleError(ErrorSources::LISTEN_CALL); handleError(ErrorSources::LISTEN_CALL);
continue;
} }
connectorSocket = accept(serverTcpSocket, reinterpret_cast<sockaddr*>(&connectorSockAddr), clientSocket = accept(listenerTcpSocket, reinterpret_cast<sockaddr*>(&clientSockAddr),
&connectorSockAddrLen); &connectorSockAddrLen);
if(connectorSocket) {}; if(clientSocket == INVALID_SOCKET) {
handleError(ErrorSources::ACCEPT_CALL);
continue;
};
retval = recv(clientSocket, reinterpret_cast<char*>(receptionBuffer.data()),
receptionBuffer.size(), 0);
#if FSFW_TCP_SERVER_WIRETAPPING_ENABLED == 1
#endif
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
@ -102,6 +136,9 @@ void TcWinTcpServer::handleError(ErrorSources errorSrc) {
else if(errorSrc == ErrorSources::ACCEPT_CALL) { else if(errorSrc == ErrorSources::ACCEPT_CALL) {
errorSrcString = "accept call"; errorSrcString = "accept call";
} }
else if(errorSrc == ErrorSources::GETADDRINFO_CALL) {
errorSrcString = "getaddrinfo call";
}
switch(errCode) { switch(errCode) {
case(WSANOTINITIALISED): { case(WSANOTINITIALISED): {

View File

@ -4,18 +4,22 @@
#include "../../objectmanager/SystemObject.h" #include "../../objectmanager/SystemObject.h"
#include "../../tasks/ExecutableObjectIF.h" #include "../../tasks/ExecutableObjectIF.h"
#include <string>
#include <vector> #include <vector>
//! Debugging preprocessor define.
#define FSFW_TCP_SERVER_WIRETAPPING_ENABLED 0
class TcWinTcpServer: class TcWinTcpServer:
public SystemObject, public SystemObject,
public ExecutableObjectIF { public ExecutableObjectIF {
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. */
static constexpr uint16_t DEFAULT_TCP_SERVER_PORT = 7301; static const std::string DEFAULT_TCP_SERVER_PORT;
static constexpr uint16_t DEFAULT_TCP_CLIENT_PORT = 7302; static const std::string DEFAULT_TCP_CLIENT_PORT;
TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge, TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge,
uint16_t customTcpServerPort = 0xffff); std::string customTcpServerPort = "");
virtual~ TcWinTcpServer(); virtual~ TcWinTcpServer();
ReturnValue_t initialize() override; ReturnValue_t initialize() override;
@ -23,15 +27,17 @@ public:
private: private:
SOCKET serverTcpSocket = 0; std::string tcpPort;
SOCKET listenerTcpSocket = 0;
struct sockaddr_in tcpAddress; struct sockaddr_in tcpAddress;
int tcpAddrLen = sizeof(tcpAddress); int tcpAddrLen = sizeof(tcpAddress);
int backlog = 3; int currentBacklog = 3;
std::vector<uint8_t> receptionBuffer; std::vector<uint8_t> receptionBuffer;
int tcpSockOpt = 0; int tcpSockOpt = 0;
enum class ErrorSources { enum class ErrorSources {
GETADDRINFO_CALL,
SOCKET_CALL, SOCKET_CALL,
SETSOCKOPT_CALL, SETSOCKOPT_CALL,
BIND_CALL, BIND_CALL,

View File

@ -3,11 +3,6 @@
#include "../../serviceinterface/ServiceInterfaceStream.h" #include "../../serviceinterface/ServiceInterfaceStream.h"
#include <winsock2.h> #include <winsock2.h>
#include <windows.h>
#if defined(_MSC_VER)
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#endif
TcWinUdpPollingTask::TcWinUdpPollingTask(object_id_t objectId, TcWinUdpPollingTask::TcWinUdpPollingTask(object_id_t objectId,
object_id_t tmtcUnixUdpBridge, size_t frameSize, object_id_t tmtcUnixUdpBridge, size_t frameSize,
@ -41,7 +36,7 @@ ReturnValue_t TcWinUdpPollingTask::performOperation(uint8_t opCode) {
//! Sender Address is cached here. //! Sender Address is cached here.
struct sockaddr_in senderAddress; struct sockaddr_in senderAddress;
int senderAddressSize = sizeof(senderAddress); int senderAddressSize = sizeof(senderAddress);
ssize_t bytesReceived = recvfrom(serverUdpSocket, int bytesReceived = recvfrom(serverUdpSocket,
reinterpret_cast<char*>(receptionBuffer.data()), frameSize, reinterpret_cast<char*>(receptionBuffer.data()), frameSize,
receptionFlags, reinterpret_cast<sockaddr*>(&senderAddress), receptionFlags, reinterpret_cast<sockaddr*>(&senderAddress),
&senderAddressSize); &senderAddressSize);