finsihed tcpip refactoring for linux udp

This commit is contained in:
Robin Müller 2021-03-12 18:06:24 +01:00
parent 8ab2044c30
commit bceca86da6
13 changed files with 294 additions and 277 deletions

View File

@ -32,3 +32,5 @@ else()
endif() endif()
endif() endif()
add_subdirectory(common)

View File

@ -0,0 +1,3 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
tcpipCommon.cpp
)

View File

@ -0,0 +1,36 @@
#include "tcpipCommon.h"
void tcpip::determineErrorStrings(Protocol protocol, ErrorSources errorSrc, std::string &protStr,
std::string &srcString) {
if(protocol == Protocol::TCP) {
protStr = "TCP";
}
else if(protocol == Protocol::UDP) {
protStr = "UDP";
}
else {
protStr = "Unknown protocol";
}
if(errorSrc == ErrorSources::SETSOCKOPT_CALL) {
srcString = "setsockopt call";
}
else if(errorSrc == ErrorSources::SOCKET_CALL) {
srcString = "socket call";
}
else if(errorSrc == ErrorSources::LISTEN_CALL) {
srcString = "listen call";
}
else if(errorSrc == ErrorSources::ACCEPT_CALL) {
srcString = "accept call";
}
else if(errorSrc == ErrorSources::RECVFROM_CALL) {
srcString = "recvfrom call";
}
else if(errorSrc == ErrorSources::GETADDRINFO_CALL) {
srcString = "getaddrinfo call";
}
else {
srcString = "unknown call";
}
}

33
osal/common/tcpipCommon.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef FSFW_OSAL_COMMON_TCPIPCOMMON_H_
#define FSFW_OSAL_COMMON_TCPIPCOMMON_H_
#include "../../timemanager/clockDefinitions.h"
#include <string>
namespace tcpip {
enum class Protocol {
UDP,
TCP
};
enum class ErrorSources {
GETADDRINFO_CALL,
SOCKET_CALL,
SETSOCKOPT_CALL,
BIND_CALL,
RECV_CALL,
RECVFROM_CALL,
LISTEN_CALL,
ACCEPT_CALL,
SENDTO_CALL
};
void determineErrorStrings(Protocol protocol, ErrorSources errorSrc, std::string& protStr,
std::string& srcString);
}
#endif /* FSFW_OSAL_COMMON_TCPIPCOMMON_H_ */

View File

@ -1,7 +1,9 @@
#include "TcUnixUdpPollingTask.h" #include "TcUnixUdpPollingTask.h"
#include "tcpipHelpers.h"
#include "../../globalfunctions/arrayprinter.h" #include "../../globalfunctions/arrayprinter.h"
#include <errno.h> #define FSFW_UDP_RCV_WIRETAPPING_ENABLED 0
TcUnixUdpPollingTask::TcUnixUdpPollingTask(object_id_t objectId, TcUnixUdpPollingTask::TcUnixUdpPollingTask(object_id_t objectId,
object_id_t tmtcUnixUdpBridge, size_t frameSize, object_id_t tmtcUnixUdpBridge, size_t frameSize,
@ -15,8 +17,8 @@ TcUnixUdpPollingTask::TcUnixUdpPollingTask(object_id_t objectId,
this->frameSize = DEFAULT_MAX_FRAME_SIZE; this->frameSize = DEFAULT_MAX_FRAME_SIZE;
} }
// Set up reception buffer with specified frame size. /* Set up reception buffer with specified frame size.
// For now, it is assumed that only one frame is held in the buffer! For now, it is assumed that only one frame is held in the buffer! */
receptionBuffer.reserve(this->frameSize); receptionBuffer.reserve(this->frameSize);
receptionBuffer.resize(this->frameSize); receptionBuffer.resize(this->frameSize);
@ -31,34 +33,37 @@ TcUnixUdpPollingTask::TcUnixUdpPollingTask(object_id_t objectId,
TcUnixUdpPollingTask::~TcUnixUdpPollingTask() {} TcUnixUdpPollingTask::~TcUnixUdpPollingTask() {}
ReturnValue_t TcUnixUdpPollingTask::performOperation(uint8_t opCode) { ReturnValue_t TcUnixUdpPollingTask::performOperation(uint8_t opCode) {
// Poll for new UDP datagrams in permanent loop. /* Sender Address is cached here. */
while(1) { struct sockaddr_in senderAddress;
//! Sender Address is cached here. socklen_t senderAddressSize = sizeof(senderAddress);
struct sockaddr_in senderAddress;
socklen_t senderSockLen = sizeof(senderAddress);
ssize_t bytesReceived = recvfrom(serverUdpSocket,
receptionBuffer.data(), frameSize, receptionFlags,
reinterpret_cast<sockaddr*>(&senderAddress), &senderSockLen);
if(bytesReceived < 0) {
// handle error
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TcSocketPollingTask::performOperation: Reception"
"error." << std::endl;
#endif
handleReadError();
/* Poll for new UDP datagrams in permanent loop. */
while(true) {
ssize_t bytesReceived = recvfrom(
serverUdpSocket,
receptionBuffer.data(),
frameSize,
receptionFlags,
reinterpret_cast<sockaddr*>(&senderAddress),
&senderAddressSize
);
if(bytesReceived < 0) {
/* Handle error */
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TcSocketPollingTask::performOperation: Reception error." << std::endl;
#endif
tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::RECVFROM_CALL, 500);
continue; continue;
} }
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1
// sif::debug << "TcSocketPollingTask::performOperation: " << bytesReceived sif::debug << "TcSocketPollingTask::performOperation: " << bytesReceived
// << " bytes received" << std::endl; << " bytes received" << std::endl;
#endif #endif
ReturnValue_t result = handleSuccessfullTcRead(bytesReceived); ReturnValue_t result = handleSuccessfullTcRead(bytesReceived);
if(result != HasReturnvaluesIF::RETURN_FAILED) { if(result != HasReturnvaluesIF::RETURN_FAILED) {
} }
tmtcBridge->registerCommConnect();
tmtcBridge->checkAndSetClientAddress(senderAddress); tmtcBridge->checkAndSetClientAddress(senderAddress);
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
@ -67,15 +72,21 @@ ReturnValue_t TcUnixUdpPollingTask::performOperation(uint8_t opCode) {
ReturnValue_t TcUnixUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { ReturnValue_t TcUnixUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) {
store_address_t storeId; store_address_t storeId;
ReturnValue_t result = tcStore->addData(&storeId,
receptionBuffer.data(), bytesRead); #if FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1
// arrayprinter::print(receptionBuffer.data(), bytesRead); arrayprinter::print(receptionBuffer.data(), bytesRead);
#endif
ReturnValue_t result = tcStore->addData(&storeId, receptionBuffer.data(), bytesRead);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
#if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TcSerialPollingTask::transferPusToSoftwareBus: Data " sif::error << "TcUnixUdpPollingTask::handleSuccessfullTcRead: Data "
"storage failed" << std::endl; "storage failed" << std::endl;
sif::error << "Packet size: " << bytesRead << std::endl; sif::error << "Packet size: " << bytesRead << std::endl;
#endif #else
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
@ -83,10 +94,13 @@ ReturnValue_t TcUnixUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) {
result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message); result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
#if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Serial Polling: Sending message to queue failed" sif::error << "TcUnixUdpPollingTask::handleSuccessfullTcRead: Sending message to queue "
<< std::endl; "failed" << std::endl;
#endif #else
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
tcStore->deleteData(storeId); tcStore->deleteData(storeId);
} }
return result; return result;
@ -111,15 +125,17 @@ ReturnValue_t TcUnixUdpPollingTask::initialize() {
return ObjectManagerIF::CHILD_INIT_FAILED; return ObjectManagerIF::CHILD_INIT_FAILED;
} }
serverUdpSocket = tmtcBridge->serverSocket;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t TcUnixUdpPollingTask::initializeAfterTaskCreation() { ReturnValue_t TcUnixUdpPollingTask::initializeAfterTaskCreation() {
// Initialize the destination after task creation. This ensures /* Initialize the destination after task creation. This ensures
// that the destination will be set in the TMTC bridge. that the destination has already been set in the TMTC bridge. */
targetTcDestination = tmtcBridge->getRequestQueue(); targetTcDestination = tmtcBridge->getRequestQueue();
/* The server socket is set up in the bridge intialization. Calling this function here
ensures that it is set up properly in any case*/
serverUdpSocket = tmtcBridge->serverSocket;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -135,24 +151,3 @@ void TcUnixUdpPollingTask::setTimeout(double timeoutSeconds) {
#endif #endif
} }
} }
// TODO: sleep after error detection to prevent spam
void TcUnixUdpPollingTask::handleReadError() {
switch(errno) {
case(EAGAIN): {
// todo: When working in timeout mode, this will occur more often
// and is not an error.
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TcUnixUdpPollingTask::handleReadError: Timeout."
<< std::endl;
#endif
break;
}
default: {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TcUnixUdpPollingTask::handleReadError: "
<< strerror(errno) << std::endl;
#endif
}
}
}

View File

@ -48,6 +48,7 @@ private:
object_id_t tmtcBridgeId = objects::NO_OBJECT; object_id_t tmtcBridgeId = objects::NO_OBJECT;
TmTcUnixUdpBridge* tmtcBridge = nullptr; TmTcUnixUdpBridge* tmtcBridge = nullptr;
MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE; MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE;
//! Reception flags: https://linux.die.net/man/2/recvfrom. //! Reception flags: https://linux.die.net/man/2/recvfrom.
int receptionFlags = 0; int receptionFlags = 0;
@ -61,7 +62,6 @@ private:
timeval receptionTimeout; timeval receptionTimeout;
ReturnValue_t handleSuccessfullTcRead(size_t bytesRead); ReturnValue_t handleSuccessfullTcRead(size_t bytesRead);
void handleReadError();
}; };
#endif /* FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ */ #endif /* FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ */

View File

@ -3,7 +3,6 @@
#include "../../serviceinterface/ServiceInterface.h" #include "../../serviceinterface/ServiceInterface.h"
#include "../../ipc/MutexGuard.h" #include "../../ipc/MutexGuard.h"
#include <errno.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <unistd.h> #include <unistd.h>
#include <netdb.h> #include <netdb.h>
@ -11,7 +10,7 @@
#include <cstring> #include <cstring>
//! Debugging preprocessor define. //! Debugging preprocessor define.
#define FSFW_UDP_RCV_WIRETAPPING_ENABLED 1 #define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0
const std::string TmTcUnixUdpBridge::DEFAULT_UDP_SERVER_PORT = "7301"; const std::string TmTcUnixUdpBridge::DEFAULT_UDP_SERVER_PORT = "7301";
const std::string TmTcUnixUdpBridge::DEFAULT_UDP_CLIENT_PORT = "7302"; const std::string TmTcUnixUdpBridge::DEFAULT_UDP_CLIENT_PORT = "7302";
@ -52,7 +51,7 @@ ReturnValue_t TmTcUnixUdpBridge::initialize() {
struct addrinfo *addrResult = nullptr; struct addrinfo *addrResult = nullptr;
struct addrinfo hints; struct addrinfo hints;
std::memset(hints, 0, sizeof(hints)); std::memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET; hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM; hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP; hints.ai_protocol = IPPROTO_UDP;
@ -82,36 +81,18 @@ ReturnValue_t TmTcUnixUdpBridge::initialize() {
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
freeaddrinfo(addrResult); freeaddrinfo(addrResult);
handleError(Protocol::UDP, ErrorSources::SOCKET_CALL); handleError(Protocol::UDP, ErrorSources::SOCKET_CALL);
handleSocketError();
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
serverAddress.sin_family = AF_INET; retval = bind(serverSocket, addrResult->ai_addr, static_cast<int>(addrResult->ai_addrlen));
if(retval != 0) {
// 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 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not bind " sif::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not bind "
"local port " << setServerPort << " to server socket!" "local port (" << udpServerPort << ") to server socket!" << std::endl;
<< std::endl;
#endif #endif
handleBindError(); freeaddrinfo(addrResult);
return; handleError(Protocol::UDP, ErrorSources::BIND_CALL);
return HasReturnvaluesIF::RETURN_FAILED;
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
@ -131,133 +112,57 @@ ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) {
if(ipAddrAnySet){ if(ipAddrAnySet){
clientAddress.sin_addr.s_addr = htons(INADDR_ANY); clientAddress.sin_addr.s_addr = htons(INADDR_ANY);
//clientAddress.sin_addr.s_addr = inet_addr("127.73.73.1"); // clientAddress.sin_addr.s_addr = inet_addr("127.73.73.1");
clientAddressLen = sizeof(serverAddress); clientAddressLen = sizeof(serverAddress);
} }
#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1
// char ipAddress [15]; char ipAddress [15];
#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::debug << "IP Address Sender: "<<
// sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET, inet_ntop(AF_INET,&clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl;
// &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl;
#endif #endif
ssize_t bytesSent = sendto(serverSocket, data, dataLen, flags, ssize_t bytesSent = sendto(
reinterpret_cast<sockaddr*>(&clientAddress), clientAddressLen); serverSocket,
data,
dataLen,
flags,
reinterpret_cast<sockaddr*>(&clientAddress),
clientAddressLen
);
if(bytesSent < 0) { if(bytesSent < 0) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TmTcUnixUdpBridge::sendTm: Send operation failed." sif::warning << "TmTcUnixUdpBridge::sendTm: Send operation failed." << std::endl;
<< std::endl;
#endif #endif
handleSendError(); tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SENDTO_CALL);
} }
#if FSFW_CPP_OSTREAM_ENABLED == 1
// sif::debug << "TmTcUnixUdpBridge::sendTm: " << bytesSent << " bytes were" #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1
// " sent." << std::endl; sif::debug << "TmTcUnixUdpBridge::sendTm: " << bytesSent << " bytes were"
" sent." << std::endl;
#endif #endif
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) {
MutexGuard lock(mutex, MutexIF::TimeoutType::WAITING, 10); MutexGuard lock(mutex, MutexIF::TimeoutType::WAITING, 10);
// char ipAddress [15]; #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1
#if FSFW_CPP_OSTREAM_ENABLED == 1 char ipAddress [15];
// sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET, sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET,
// &newAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; &newAddress.sin_addr.s_addr, ipAddress, 15) << std::endl;
// sif::debug << "IP Address Old: " << inet_ntop(AF_INET, sif::debug << "IP Address Old: " << inet_ntop(AF_INET,
// &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl;
#endif #endif
registerCommConnect();
// Set new IP address if it has changed. /* Set new IP address if it has changed. */
if(clientAddress.sin_addr.s_addr != newAddress.sin_addr.s_addr) { if(clientAddress.sin_addr.s_addr != newAddress.sin_addr.s_addr) {
clientAddress.sin_addr.s_addr = newAddress.sin_addr.s_addr; clientAddress = newAddress;
clientAddressLen = sizeof(clientAddress); clientAddressLen = sizeof(clientAddress);
} }
} }
void TmTcUnixUdpBridge::handleSocketError() {
// See: https://man7.org/linux/man-pages/man2/socket.2.html
switch(errno) {
case(EACCES):
case(EINVAL):
case(EMFILE):
case(ENFILE):
case(EAFNOSUPPORT):
case(ENOBUFS):
case(ENOMEM):
case(EPROTONOSUPPORT):
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TmTcUnixBridge::handleSocketError: Socket creation failed"
<< " with " << strerror(errno) << std::endl;
#endif
break;
default:
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TmTcUnixBridge::handleSocketError: Unknown error"
<< std::endl;
#endif
break;
}
}
void TmTcUnixUdpBridge::handleBindError() {
// See: https://man7.org/linux/man-pages/man2/bind.2.html
switch(errno) {
case(EACCES): {
/*
Ephermeral ports can be shown with following command:
sysctl -A | grep ip_local_port_range
*/
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TmTcUnixBridge::handleBindError: Port access issue."
"Ports 1-1024 are reserved on UNIX systems and require root "
"rights while ephermeral ports should not be used as well."
<< std::endl;
#endif
}
break;
case(EADDRINUSE):
case(EBADF):
case(EINVAL):
case(ENOTSOCK):
case(EADDRNOTAVAIL):
case(EFAULT):
case(ELOOP):
case(ENAMETOOLONG):
case(ENOENT):
case(ENOMEM):
case(ENOTDIR):
case(EROFS): {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TmTcUnixBridge::handleBindError: Socket creation failed"
<< " with " << strerror(errno) << std::endl;
#endif
break;
}
default:
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TmTcUnixBridge::handleBindError: Unknown error"
<< std::endl;
#endif
break;
}
}
void TmTcUnixUdpBridge::handleSendError() {
switch(errno) {
default: {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TmTcUnixBridge::handleSendError: "
<< strerror(errno) << std::endl;
#else
sif::printError("TmTcUnixBridge::handleSendError: %s\n",
strerror(errno));
#endif
}
}
}
void TmTcUnixUdpBridge::setClientAddressToAny(bool ipAddrAnySet){ void TmTcUnixUdpBridge::setClientAddressToAny(bool ipAddrAnySet){
this->ipAddrAnySet = ipAddrAnySet; this->ipAddrAnySet = ipAddrAnySet;
} }

View File

@ -46,10 +46,6 @@ private:
//! Access to the client address is mutex protected as it is set //! Access to the client address is mutex protected as it is set
//! by another task. //! by another task.
MutexIF* mutex; MutexIF* mutex;
void handleSocketError();
void handleBindError();
void handleSendError();
}; };
#endif /* FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ */ #endif /* FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ */

View File

@ -1,5 +1,108 @@
#include "tcpipHelpers.h" #include "tcpipHelpers.h"
void tcpip::handleError(Protocol protocol, ErrorSources errorSrc, dur_millis_t sleepDuration = 0) { #include "../../tasks/TaskFactory.h"
#include <errno.h>
#include <string>
void tcpip::handleError(Protocol protocol, ErrorSources errorSrc, dur_millis_t sleepDuration) {
int errCode = errno;
std::string protocolString;
std::string errorSrcString;
determineErrorStrings(protocol, errorSrc, protocolString, errorSrcString);
std::string infoString;
switch(errCode) {
case(EACCES): {
infoString = "EACCES";
break;
}
case(EINVAL): {
infoString = "EINVAL";
break;
}
case(EAGAIN): {
infoString = "EAGAIN";
break;
}
case(EMFILE): {
infoString = "EMFILE";
break;
}
case(ENFILE): {
infoString = "ENFILE";
break;
}
case(EAFNOSUPPORT): {
infoString = "EAFNOSUPPORT";
break;
}
case(ENOBUFS): {
infoString = "ENOBUFS";
break;
}
case(ENOMEM): {
infoString = "ENOMEM";
break;
}
case(EPROTONOSUPPORT): {
infoString = "EPROTONOSUPPORT";
break;
}
case(EADDRINUSE): {
infoString = "EADDRINUSE";
break;
}
case(EBADF): {
infoString = "EBADF";
break;
}
case(ENOTSOCK): {
infoString = "ENOTSOCK";
break;
}
case(EADDRNOTAVAIL): {
infoString = "EADDRNOTAVAIL";
break;
}
case(EFAULT): {
infoString = "EFAULT";
break;
}
case(ELOOP): {
infoString = "ELOOP";
break;
}
case(ENAMETOOLONG): {
infoString = "ENAMETOOLONG";
break;
}
case(ENOENT): {
infoString = "ENOENT";
break;
}
case(ENOTDIR): {
infoString = "ENOTDIR";
break;
}
case(EROFS): {
infoString = "EROFS";
break;
}
default: {
infoString = "Error code: " + std::to_string(errCode);
}
}
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString <<
" | " << infoString << std::endl;
#else
sif::printWarning("tcpip::handleError: %s | %s | %s\n", protocolString,
errorSrcString, infoString);
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
if(sleepDuration > 0) {
TaskFactory::instance()->delayTask(sleepDuration);
}
} }

View File

@ -2,25 +2,10 @@
#define FSFW_OSAL_LINUX_TCPIPHELPERS_H_ #define FSFW_OSAL_LINUX_TCPIPHELPERS_H_
#include "../../timemanager/clockDefinitions.h" #include "../../timemanager/clockDefinitions.h"
#include "../common/tcpipCommon.h"
namespace tcpip { namespace tcpip {
enum class Protocol {
UDP,
TCP
};
enum class ErrorSources {
GETADDRINFO_CALL,
SOCKET_CALL,
SETSOCKOPT_CALL,
BIND_CALL,
RECV_CALL,
RECVFROM_CALL,
LISTEN_CALL,
ACCEPT_CALL,
SENDTO_CALL
};
void handleError(Protocol protocol, ErrorSources errorSrc, dur_millis_t sleepDuration = 0); void handleError(Protocol protocol, ErrorSources errorSrc, dur_millis_t sleepDuration = 0);

View File

@ -125,13 +125,17 @@ ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) {
&clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl;
#endif #endif
int bytesSent = sendto(serverSocket, int bytesSent = sendto(
reinterpret_cast<const char*>(data), dataLen, flags, serverSocket,
reinterpret_cast<sockaddr*>(&clientAddress), clientAddressLen); reinterpret_cast<const char*>(data),
dataLen,
flags,
reinterpret_cast<sockaddr*>(&clientAddress),
clientAddressLen
);
if(bytesSent == SOCKET_ERROR) { if(bytesSent == SOCKET_ERROR) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TmTcWinUdpBridge::sendTm: Send operation failed." sif::warning << "TmTcWinUdpBridge::sendTm: Send operation failed." << std::endl;
<< std::endl;
#endif #endif
tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SENDTO_CALL); tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SENDTO_CALL);
} }

View File

@ -1,92 +1,63 @@
#include "tcpipHelpers.h" #include "tcpipHelpers.h"
#include <FSFWConfig.h> #include <FSFWConfig.h>
#include "../../tasks/TaskFactory.h"
#include "../../serviceinterface/ServiceInterface.h" #include "../../serviceinterface/ServiceInterface.h"
#include <winsock2.h> #include <winsock2.h>
#include <string> #include <string>
void tcpip::handleError(Protocol protocol, ErrorSources errorSrc, dur_millis_t sleepDuration) { void tcpip::handleError(Protocol protocol, ErrorSources errorSrc, dur_millis_t sleepDuration) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_VERBOSE_LEVEL >= 1
int errCode = WSAGetLastError(); int errCode = WSAGetLastError();
std::string protocolString; std::string protocolString;
if(protocol == Protocol::TCP) {
protocolString = "TCP";
}
else if(protocol == Protocol::UDP) {
protocolString = "UDP";
}
else {
protocolString = "Unknown protocol";
}
std::string errorSrcString; std::string errorSrcString;
if(errorSrc == ErrorSources::SETSOCKOPT_CALL) { determineErrorStrings(protocol, errorSrc, protocolString, errorSrcString);
errorSrcString = "setsockopt call";
}
else if(errorSrc == ErrorSources::SOCKET_CALL) {
errorSrcString = "socket call";
}
else if(errorSrc == ErrorSources::LISTEN_CALL) {
errorSrcString = "listen call";
}
else if(errorSrc == ErrorSources::ACCEPT_CALL) {
errorSrcString = "accept call";
}
else if(errorSrc == ErrorSources::RECVFROM_CALL) {
errorSrcString = "recvfrom call";
}
else if(errorSrc == ErrorSources::GETADDRINFO_CALL) {
errorSrcString = "getaddrinfo call";
}
else {
errorSrcString = "unknown call";
}
std::string infoString; std::string infoString;
switch(errCode) { switch(errCode) {
case(WSANOTINITIALISED): { case(WSANOTINITIALISED): {
infoString = "WSANOTINITIALISED"; infoString = "WSANOTINITIALISED";
sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString <<
" | " << infoString << std::endl;
break; break;
} }
case(WSAEADDRINUSE): { case(WSAEADDRINUSE): {
infoString = "WSAEADDRINUSE"; infoString = "WSAEADDRINUSE";
sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString <<
" | " << infoString << std::endl;
break; break;
} }
case(WSAEFAULT): { case(WSAEFAULT): {
infoString = "WSAEFAULT"; infoString = "WSAEFAULT";
sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString <<
" | " << infoString << std::endl;
break; break;
} }
case(WSAEADDRNOTAVAIL): { case(WSAEADDRNOTAVAIL): {
infoString = "WSAEADDRNOTAVAIL"; infoString = "WSAEADDRNOTAVAIL";
sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString <<
" | " << infoString << std::endl;
break; break;
} }
case(WSAEINVAL): { case(WSAEINVAL): {
infoString = "WSAEINVAL"; infoString = "WSAEINVAL";
sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString <<
" | " << infoString << std::endl;
break; break;
} }
default: { default: {
/* /*
https://docs.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2 https://docs.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2
*/ */
sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString << infoString = "Error code: " + std::to_string(errCode);
"Error code" << errCode << std::endl;
break; break;
} }
} }
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString <<
" | " << infoString << std::endl;
#else
sif::printWarning("tcpip::handleError: %s | %s | %s\n", protocolString,
errorSrcString, infoString);
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
if(sleepDuration > 0) { if(sleepDuration > 0) {
Sleep(sleepDuration); TaskFactory::instance()->delayTask(sleepDuration);
} }
} }

View File

@ -2,26 +2,10 @@
#define FSFW_OSAL_WINDOWS_TCPIPHELPERS_H_ #define FSFW_OSAL_WINDOWS_TCPIPHELPERS_H_
#include "../../timemanager/clockDefinitions.h" #include "../../timemanager/clockDefinitions.h"
#include "../common/tcpipCommon.h"
namespace tcpip { namespace tcpip {
enum class Protocol {
UDP,
TCP
};
enum class ErrorSources {
GETADDRINFO_CALL,
SOCKET_CALL,
SETSOCKOPT_CALL,
BIND_CALL,
RECV_CALL,
RECVFROM_CALL,
LISTEN_CALL,
ACCEPT_CALL,
SENDTO_CALL
};
void handleError(Protocol protocol, ErrorSources errorSrc, dur_millis_t sleepDuration = 0); void handleError(Protocol protocol, ErrorSources errorSrc, dur_millis_t sleepDuration = 0);
} }