fsfw/osal/common/TcpTmTcServer.cpp

133 lines
4.0 KiB
C++
Raw Normal View History

#include "TcpTmTcServer.h"
2021-03-12 02:15:21 +01:00
#include "tcpipHelpers.h"
2021-03-11 14:47:47 +01:00
#include "../../serviceinterface/ServiceInterface.h"
#ifdef _WIN32
2021-03-11 14:47:47 +01:00
#include <winsock2.h>
#include <ws2tcpip.h>
2021-03-21 12:51:28 +01:00
#elif defined(__unix__)
#include <netdb.h>
#endif
2021-03-11 14:47:47 +01:00
const std::string TcpTmTcServer::DEFAULT_TCP_SERVER_PORT = "7301";
const std::string TcpTmTcServer::DEFAULT_TCP_CLIENT_PORT = "7302";
2021-03-11 14:47:47 +01:00
TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge,
2021-03-11 14:47:47 +01:00
std::string customTcpServerPort):
SystemObject(objectId), tcpPort(customTcpServerPort) {
if(tcpPort == "") {
tcpPort = DEFAULT_TCP_SERVER_PORT;
}
}
ReturnValue_t TcpTmTcServer::initialize() {
2021-03-12 02:15:21 +01:00
using namespace tcpip;
ReturnValue_t result = TcpIpBase::initialize();
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
2021-03-11 14:47:47 +01:00
int retval = 0;
struct addrinfo *addrResult = nullptr;
struct addrinfo hints = {};
2021-03-11 14:47:47 +01:00
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::TcpTmTcServer: Retrieving address info failed!" <<
2021-03-11 14:47:47 +01:00
std::endl;
#endif
2021-03-12 02:15:21 +01:00
handleError(Protocol::TCP, ErrorSources::GETADDRINFO_CALL);
2021-03-11 14:47:47 +01:00
return HasReturnvaluesIF::RETURN_FAILED;
}
/* Open TCP (stream) socket */
listenerTcpSocket = socket(addrResult->ai_family, addrResult->ai_socktype,
addrResult->ai_protocol);
if(listenerTcpSocket == INVALID_SOCKET) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TcWinTcpServer::TcWinTcpServer: Socket creation failed!" << std::endl;
#endif
freeaddrinfo(addrResult);
2021-03-12 02:15:21 +01:00
handleError(Protocol::TCP, ErrorSources::SOCKET_CALL);
2021-03-11 14:47:47 +01:00
return HasReturnvaluesIF::RETURN_FAILED;
}
2021-03-12 00:34:30 +01:00
retval = bind(listenerTcpSocket, addrResult->ai_addr, static_cast<int>(addrResult->ai_addrlen));
2021-03-11 14:47:47 +01:00
if(retval == SOCKET_ERROR) {
2021-03-17 15:43:01 +01:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TcWinTcpServer::TcpTmTcServer: Binding socket failed!" <<
2021-03-11 14:47:47 +01:00
std::endl;
2021-03-17 15:43:01 +01:00
#endif
2021-03-11 14:47:47 +01:00
freeaddrinfo(addrResult);
2021-03-12 02:15:21 +01:00
handleError(Protocol::TCP, ErrorSources::BIND_CALL);
2021-04-11 21:54:48 +02:00
return HasReturnvaluesIF::RETURN_FAILED;
2021-03-11 14:47:47 +01:00
}
freeaddrinfo(addrResult);
return HasReturnvaluesIF::RETURN_OK;
}
TcpTmTcServer::~TcpTmTcServer() {
2021-03-21 12:51:28 +01:00
closeSocket(listenerTcpSocket);
2021-03-11 14:47:47 +01:00
}
ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) {
2021-03-12 02:15:21 +01:00
using namespace tcpip;
2021-03-11 14:47:47 +01:00
/* If a connection is accepted, the corresponding socket will be assigned to the new socket */
2021-04-11 21:54:48 +02:00
socket_t clientSocket = 0;
sockaddr clientSockAddr = {};
2021-03-21 12:51:28 +01:00
socklen_t connectorSockAddrLen = 0;
2021-03-11 14:47:47 +01:00
int retval = 0;
2021-03-12 02:15:21 +01:00
2021-03-11 14:47:47 +01:00
/* Listen for connection requests permanently for lifetime of program */
while(true) {
retval = listen(listenerTcpSocket, currentBacklog);
if(retval == SOCKET_ERROR) {
2021-03-12 02:15:21 +01:00
handleError(Protocol::TCP, ErrorSources::LISTEN_CALL, 500);
2021-03-11 14:47:47 +01:00
continue;
}
2021-03-21 12:51:28 +01:00
clientSocket = accept(listenerTcpSocket, &clientSockAddr, &connectorSockAddrLen);
2021-03-11 14:47:47 +01:00
if(clientSocket == INVALID_SOCKET) {
2021-03-12 02:15:21 +01:00
handleError(Protocol::TCP, ErrorSources::ACCEPT_CALL, 500);
2021-04-11 21:54:48 +02:00
closeSocket(clientSocket);
2021-03-11 14:47:47 +01:00
continue;
};
retval = recv(clientSocket, reinterpret_cast<char*>(receptionBuffer.data()),
receptionBuffer.size(), 0);
if(retval > 0) {
2021-03-12 02:15:21 +01:00
#if FSFW_TCP_RCV_WIRETAPPING_ENABLED == 1
sif::info << "TcpTmTcServer::performOperation: Received " << retval << " bytes."
2021-03-11 14:47:47 +01:00
std::endl;
#endif
2021-03-12 02:15:21 +01:00
handleError(Protocol::TCP, ErrorSources::RECV_CALL, 500);
2021-03-11 14:47:47 +01:00
}
else if(retval == 0) {
}
else {
}
/* Done, shut down connection */
2021-03-21 12:51:28 +01:00
retval = shutdown(clientSocket, SHUT_SEND);
2021-04-11 21:54:48 +02:00
closeSocket(clientSocket);
2021-03-11 14:47:47 +01:00
}
return HasReturnvaluesIF::RETURN_OK;
}