From 9eefd5b95da305f63205f026258426299c803e98 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Mar 2021 14:47:47 +0100 Subject: [PATCH 01/17] added back tcp stuff --- osal/windows/CMakeLists.txt | 1 + osal/windows/TcWinTcpServer.cpp | 177 ++++++++++++++++++++++++++++++++ osal/windows/TcWinTcpServer.h | 56 ++++++++++ 3 files changed, 234 insertions(+) create mode 100644 osal/windows/TcWinTcpServer.cpp create mode 100644 osal/windows/TcWinTcpServer.h diff --git a/osal/windows/CMakeLists.txt b/osal/windows/CMakeLists.txt index a3a719e0..889ea339 100644 --- a/osal/windows/CMakeLists.txt +++ b/osal/windows/CMakeLists.txt @@ -1,6 +1,7 @@ target_sources(${LIB_FSFW_NAME} PRIVATE TcWinUdpPollingTask.cpp TmTcWinUdpBridge.cpp + TcWinTcpServer.cpp ) target_link_libraries(${LIB_FSFW_NAME} PRIVATE diff --git a/osal/windows/TcWinTcpServer.cpp b/osal/windows/TcWinTcpServer.cpp new file mode 100644 index 00000000..f85147f0 --- /dev/null +++ b/osal/windows/TcWinTcpServer.cpp @@ -0,0 +1,177 @@ +#include "TcWinTcpServer.h" +#include "../../serviceinterface/ServiceInterface.h" + +#include +#include + +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, + std::string customTcpServerPort): + 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. */ + WSAData wsaData; + WORD wVersionRequested = MAKEWORD(2, 2); + int err = WSAStartup(wVersionRequested, &wsaData); + if (err != 0) { + /* Tell the user that we could not find a usable Winsock DLL. */ +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge: WSAStartup failed with error: " << + err << std::endl; +#endif + 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 */ + 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); + handleError(ErrorSources::SOCKET_CALL); + return HasReturnvaluesIF::RETURN_FAILED; + } + +// retval = setsockopt(listenerTcpSocket, SOL_SOCKET, SO_REUSEADDR | SO_BROADCAST, +// reinterpret_cast(&tcpSockOpt), sizeof(tcpSockOpt)); +// if(retval != 0) { +// sif::warning << "TcWinTcpServer::TcWinTcpServer: Setting socket options failed!" << +// std::endl; +// handleError(ErrorSources::SETSOCKOPT_CALL); +// return HasReturnvaluesIF::RETURN_FAILED; +// } +// tcpAddress.sin_family = AF_INET; +// tcpAddress.sin_addr.s_addr = htonl(INADDR_ANY); + + retval = bind(listenerTcpSocket, reinterpret_cast(&tcpAddress), + tcpAddrLen); + if(retval == SOCKET_ERROR) { + sif::warning << "TcWinTcpServer::TcWinTcpServer: Binding socket failed!" << + std::endl; + freeaddrinfo(addrResult); + handleError(ErrorSources::BIND_CALL); + } + + freeaddrinfo(addrResult); + return HasReturnvaluesIF::RETURN_OK; +} + + +TcWinTcpServer::~TcWinTcpServer() { + closesocket(listenerTcpSocket); + WSACleanup(); +} + +ReturnValue_t TcWinTcpServer::performOperation(uint8_t opCode) { + /* If a connection is accepted, the corresponding socket will be assigned to the new socket */ + SOCKET clientSocket; + sockaddr_in clientSockAddr; + int connectorSockAddrLen = 0; + int retval = 0; + /* Listen for connection requests permanently for lifetime of program */ + while(true) { + retval = listen(listenerTcpSocket, currentBacklog); + if(retval == SOCKET_ERROR) { + handleError(ErrorSources::LISTEN_CALL); + continue; + } + + clientSocket = accept(listenerTcpSocket, reinterpret_cast(&clientSockAddr), + &connectorSockAddrLen); + + if(clientSocket == INVALID_SOCKET) { + handleError(ErrorSources::ACCEPT_CALL); + continue; + }; + + retval = recv(clientSocket, reinterpret_cast(receptionBuffer.data()), + receptionBuffer.size(), 0); + if(retval > 0) { +#if FSFW_TCP_SERVER_WIRETAPPING_ENABLED == 1 + sif::info << "TcWinTcpServer::performOperation: Received " << retval << " bytes." + std::endl; +#endif + } + else if(retval == 0) { + + } + else { + + } + + /* Done, shut down connection */ + retval = shutdown(clientSocket, SD_SEND); + } + return HasReturnvaluesIF::RETURN_OK; +} + +void TcWinTcpServer::handleError(ErrorSources errorSrc) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + int errCode = WSAGetLastError(); + std::string errorSrcString; + if(errorSrc == ErrorSources::SETSOCKOPT_CALL) { + 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::GETADDRINFO_CALL) { + errorSrcString = "getaddrinfo call"; + } + + switch(errCode) { + case(WSANOTINITIALISED): { + sif::warning << "TmTcWinUdpBridge::handleError: " << errorSrcString << " | " + "WSANOTINITIALISED: WSAStartup call necessary" << std::endl; + break; + } + case(WSAEINVAL): { + sif::warning << "TmTcWinUdpBridge::handleError: " << errorSrcString << " | " + "WSAEINVAL: Invalid parameters" << std::endl; + break; + } + default: { + /* + https://docs.microsoft.com/en-us/windows/win32/winsock/ + windows-sockets-error-codes-2 + */ + sif::warning << "TmTcWinUdpBridge::handleSocketError: Error code: " << errCode << std::endl; + break; + } + } +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +} diff --git a/osal/windows/TcWinTcpServer.h b/osal/windows/TcWinTcpServer.h new file mode 100644 index 00000000..f8aebc53 --- /dev/null +++ b/osal/windows/TcWinTcpServer.h @@ -0,0 +1,56 @@ +#ifndef FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_ +#define FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_ + +#include "../../objectmanager/SystemObject.h" +#include "../../tasks/ExecutableObjectIF.h" + +#include +#include + +//! Debugging preprocessor define. +#define FSFW_TCP_SERVER_WIRETAPPING_ENABLED 0 + +/** + * @brief Windows TCP server used to receive telecommands on a Windows Host + * @details + * Based on: https://docs.microsoft.com/en-us/windows/win32/winsock/complete-server-code + */ +class TcWinTcpServer: + public SystemObject, + public ExecutableObjectIF { +public: + /* The ports chosen here should not be used by any other process. */ + static const std::string DEFAULT_TCP_SERVER_PORT; + static const std::string DEFAULT_TCP_CLIENT_PORT; + + TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge, + std::string customTcpServerPort = ""); + virtual~ TcWinTcpServer(); + + ReturnValue_t initialize() override; + ReturnValue_t performOperation(uint8_t opCode) override; + +private: + + std::string tcpPort; + SOCKET listenerTcpSocket = 0; + struct sockaddr_in tcpAddress; + int tcpAddrLen = sizeof(tcpAddress); + int currentBacklog = 3; + + std::vector receptionBuffer; + int tcpSockOpt = 0; + + enum class ErrorSources { + GETADDRINFO_CALL, + SOCKET_CALL, + SETSOCKOPT_CALL, + BIND_CALL, + LISTEN_CALL, + ACCEPT_CALL + }; + + void handleError(ErrorSources errorSrc); +}; + +#endif /* FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_ */ From 286a3649cf254508f478a280220c52f49e5c2ec5 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Mar 2021 14:51:29 +0100 Subject: [PATCH 02/17] renamed tests --- unittest/tests/datapoollocal/LocalPoolManagerTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp index 4df735cd..52485b01 100644 --- a/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp +++ b/unittest/tests/datapoollocal/LocalPoolManagerTest.cpp @@ -206,7 +206,7 @@ TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") { CHECK(cdsShort.msDay_ll == Catch::Approx(timeCdsNow.msDay_ll).margin(1)); } - SECTION("VariableUpdateTest") { + SECTION("VariableNotificationTest") { /* Acquire subscription interface */ ProvidesDataPoolSubscriptionIF* subscriptionIF = poolOwner->getSubscriptionInterface(); REQUIRE(subscriptionIF != nullptr); From 67b05fee2e6171d2cab37919f2cabd6817af305d Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Mar 2021 15:04:20 +0100 Subject: [PATCH 03/17] newline removed --- unittest/tests/datapoollocal/DataSetTest.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/unittest/tests/datapoollocal/DataSetTest.cpp b/unittest/tests/datapoollocal/DataSetTest.cpp index ce4d9d43..d0b13e86 100644 --- a/unittest/tests/datapoollocal/DataSetTest.cpp +++ b/unittest/tests/datapoollocal/DataSetTest.cpp @@ -275,7 +275,6 @@ TEST_CASE("DataSetTest" , "[DataSetTest]") { } sharedSet.setReadCommitProtectionBehaviour(true); - } /* we need to reset the subscription list because the pool owner From 6e5b032dbbc078c542d83325b214ec375cb04cd0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 12 Mar 2021 00:34:30 +0100 Subject: [PATCH 04/17] trying new udp stuff --- osal/host/MutexFactory.cpp | 4 +- osal/windows/TcWinTcpServer.cpp | 3 +- osal/windows/TcWinUdpPollingTask.cpp | 2 +- osal/windows/TmTcWinUdpBridge.cpp | 117 +++++++++++++++++---------- osal/windows/TmTcWinUdpBridge.h | 10 ++- 5 files changed, 85 insertions(+), 51 deletions(-) diff --git a/osal/host/MutexFactory.cpp b/osal/host/MutexFactory.cpp index bf7707d1..f3b98fd1 100644 --- a/osal/host/MutexFactory.cpp +++ b/osal/host/MutexFactory.cpp @@ -24,5 +24,7 @@ MutexIF* MutexFactory::createMutex() { } void MutexFactory::deleteMutex(MutexIF* mutex) { - delete mutex; + if(mutex != nullptr) { + delete mutex; + } } diff --git a/osal/windows/TcWinTcpServer.cpp b/osal/windows/TcWinTcpServer.cpp index f85147f0..3cdd1d3f 100644 --- a/osal/windows/TcWinTcpServer.cpp +++ b/osal/windows/TcWinTcpServer.cpp @@ -71,8 +71,7 @@ ReturnValue_t TcWinTcpServer::initialize() { // tcpAddress.sin_family = AF_INET; // tcpAddress.sin_addr.s_addr = htonl(INADDR_ANY); - retval = bind(listenerTcpSocket, reinterpret_cast(&tcpAddress), - tcpAddrLen); + retval = bind(listenerTcpSocket, addrResult->ai_addr, static_cast(addrResult->ai_addrlen)); if(retval == SOCKET_ERROR) { sif::warning << "TcWinTcpServer::TcWinTcpServer: Binding socket failed!" << std::endl; diff --git a/osal/windows/TcWinUdpPollingTask.cpp b/osal/windows/TcWinUdpPollingTask.cpp index 06e75bd5..c86fd03a 100644 --- a/osal/windows/TcWinUdpPollingTask.cpp +++ b/osal/windows/TcWinUdpPollingTask.cpp @@ -33,7 +33,7 @@ TcWinUdpPollingTask::~TcWinUdpPollingTask() {} ReturnValue_t TcWinUdpPollingTask::performOperation(uint8_t opCode) { /* Poll for new UDP datagrams in permanent loop. */ while(true) { - //! Sender Address is cached here. + /* Sender Address is cached here. */ struct sockaddr_in senderAddress; int senderAddressSize = sizeof(senderAddress); int bytesReceived = recvfrom(serverUdpSocket, diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index 03daa6d7..eb5db0b3 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -1,19 +1,34 @@ #include "TmTcWinUdpBridge.h" +#include #include +#include -#if defined(_MSC_VER) -#include -typedef SSIZE_T ssize_t; -#endif +const std::string TmTcWinUdpBridge::DEFAULT_UDP_SERVER_PORT = "7301"; +const std::string TmTcWinUdpBridge::DEFAULT_UDP_CLIENT_PORT = "7302"; TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, 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) { + if(udpServerPort == "") { + udpServerPort = DEFAULT_UDP_SERVER_PORT; + } + else { + this->udpServerPort = udpServerPort; + } + if(udpClientPort == "") { + udpClientPort = DEFAULT_UDP_CLIENT_PORT; + } + else { + this->udpClientPort = udpClientPort; + } + mutex = MutexFactory::instance()->createMutex(); communicationLinkUp = false; +} +ReturnValue_t TmTcWinUdpBridge::initialize() { /* Initiates Winsock DLL. */ WSAData wsaData; WORD wVersionRequested = MAKEWORD(2, 2); @@ -22,71 +37,85 @@ TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, /* Tell the user that we could not find a usable */ /* Winsock DLL. */ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge:" - "WSAStartup failed with error: " << err << std::endl; + sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge: WSAStartup failed with error: " << + err << std::endl; +#else + sif::printError("TmTcWinUdpBridge::TmTcWinUdpBridge: WSAStartup failed with error: %d\n", + err); #endif - return; + return HasReturnvaluesIF::RETURN_FAILED; } - uint16_t setServerPort = DEFAULT_UDP_SERVER_PORT; - if(serverPort != 0xFFFF) { - setServerPort = serverPort; - } + struct addrinfo *addrResult = nullptr; + struct addrinfo hints; - uint16_t setClientPort = DEFAULT_UDP_CLIENT_PORT; - if(clientPort != 0xFFFF) { - setClientPort = clientPort; - } + ZeroMemory(&hints, sizeof (hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + hints.ai_flags = AI_PASSIVE; /* Set up UDP socket: - https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket + https://en.wikipedia.org/wiki/Getaddrinfo + Passing nullptr as the first parameter and specifying AI_PASSIVE in hints will cause + getaddrinfo to assign the address 0.0.0.0 (any address) */ - serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + int retval = getaddrinfo(nullptr, udpServerPort.c_str(), &hints, &addrResult); + if (retval != 0) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Retrieving address info failed!" << + std::endl; +#endif + return HasReturnvaluesIF::RETURN_FAILED; + } + + serverSocket = socket(addrResult->ai_family, addrResult->ai_socktype, addrResult->ai_protocol); if(serverSocket == INVALID_SOCKET) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not open UDP socket!" << std::endl; #endif handleSocketError(); - return; - } - - serverAddress.sin_family = AF_INET; - - /* Accept packets from any interface. (potentially insecure). */ - serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); - serverAddress.sin_port = htons(setServerPort); - serverAddressLen = sizeof(serverAddress); - int result = setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, - reinterpret_cast(&serverSocketOptions), - sizeof(serverSocketOptions)); - if(result != 0) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not set socket options!" << - std::endl; -#endif - handleSocketError(); + return HasReturnvaluesIF::RETURN_FAILED; } +// serverAddress.sin_family = AF_INET; +// +// /* Accept packets from any interface. (potentially insecure). */ +// serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); +// serverAddress.sin_port = htons(setServerPort); +// serverAddressLen = sizeof(serverAddress); +// int result = setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, +// reinterpret_cast(&serverSocketOptions), +// sizeof(serverSocketOptions)); +// if(result != 0) { +//#if FSFW_CPP_OSTREAM_ENABLED == 1 +// sif::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not set socket options!" << +// std::endl; +//#endif +// handleSocketError(); +// } +// clientAddress.sin_family = AF_INET; clientAddress.sin_addr.s_addr = htonl(INADDR_ANY); - clientAddress.sin_port = htons(setClientPort); + clientAddress.sin_port = htons(7302); clientAddressLen = sizeof(clientAddress); - result = bind(serverSocket, - reinterpret_cast(&serverAddress), - serverAddressLen); - if(result != 0) { + retval = bind(serverSocket, addrResult->ai_addr, static_cast(addrResult->ai_addrlen)); + if(retval != 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not bind " - "local port " << setServerPort << " to server socket!" - << std::endl; + "local port " << udpServerPort << " to server socket!" << std::endl; #endif handleBindError(); } + return HasReturnvaluesIF::RETURN_OK; } TmTcWinUdpBridge::~TmTcWinUdpBridge() { + if(mutex != nullptr) { + MutexFactory::instance()->deleteMutex(mutex); + } closesocket(serverSocket); WSACleanup(); } @@ -102,7 +131,7 @@ ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; #endif - ssize_t bytesSent = sendto(serverSocket, + int bytesSent = sendto(serverSocket, reinterpret_cast(data), dataLen, flags, reinterpret_cast(&clientAddress), clientAddressLen); if(bytesSent == SOCKET_ERROR) { diff --git a/osal/windows/TmTcWinUdpBridge.h b/osal/windows/TmTcWinUdpBridge.h index 14354139..e32854b6 100644 --- a/osal/windows/TmTcWinUdpBridge.h +++ b/osal/windows/TmTcWinUdpBridge.h @@ -13,14 +13,16 @@ class TmTcWinUdpBridge: public TmTcBridge { friend class TcWinUdpPollingTask; public: /* The ports chosen here should not be used by any other process. */ - static constexpr uint16_t DEFAULT_UDP_SERVER_PORT = 7301; - static constexpr uint16_t DEFAULT_UDP_CLIENT_PORT = 7302; + static const std::string DEFAULT_UDP_SERVER_PORT; + static const std::string DEFAULT_UDP_CLIENT_PORT; TmTcWinUdpBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId, - uint16_t serverPort = 0xFFFF,uint16_t clientPort = 0xFFFF); + std::string udpServerPort = "", std::string udpClientPort = ""); virtual~ TmTcWinUdpBridge(); + ReturnValue_t initialize() override; + void checkAndSetClientAddress(sockaddr_in clientAddress); protected: @@ -28,6 +30,8 @@ protected: private: SOCKET serverSocket = 0; + std::string udpServerPort; + std::string udpClientPort; const int serverSocketOptions = 0; From df7434dae579cc5111c8692913860aa9a8227a2d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 12 Mar 2021 00:45:32 +0100 Subject: [PATCH 05/17] somethings wrong --- osal/windows/TcWinUdpPollingTask.cpp | 4 ++-- osal/windows/TmTcWinUdpBridge.cpp | 5 +++++ tmtcservices/TmTcBridge.cpp | 3 +++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/osal/windows/TcWinUdpPollingTask.cpp b/osal/windows/TcWinUdpPollingTask.cpp index c86fd03a..38633388 100644 --- a/osal/windows/TcWinUdpPollingTask.cpp +++ b/osal/windows/TcWinUdpPollingTask.cpp @@ -122,8 +122,8 @@ ReturnValue_t TcWinUdpPollingTask::initialize() { } ReturnValue_t TcWinUdpPollingTask::initializeAfterTaskCreation() { - // Initialize the destination after task creation. This ensures - // that the destination has already been set in the TMTC bridge. + /* Initialize the destination after task creation. This ensures + that the destination has already been set in the TMTC bridge. */ targetTcDestination = tmtcBridge->getRequestQueue(); return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index eb5db0b3..1a624355 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -29,6 +29,11 @@ TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, } ReturnValue_t TmTcWinUdpBridge::initialize() { + ReturnValue_t result = TmTcBridge::initialize(); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + /* Initiates Winsock DLL. */ WSAData wsaData; WORD wVersionRequested = MAKEWORD(2, 2); diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 12d163d1..228bf4f5 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -173,6 +173,9 @@ ReturnValue_t TmTcBridge::handleTmQueue() { ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { store_address_t storeId = 0; + if(tmFifo == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } if(tmFifo->full()) { #if FSFW_CPP_OSTREAM_ENABLED == 1 From b071c850af1ec81e6a61997a1bcc42bc6e03aff5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 12 Mar 2021 01:40:58 +0100 Subject: [PATCH 06/17] commit with old way --- osal/windows/TcWinUdpPollingTask.cpp | 9 +-- osal/windows/TmTcWinUdpBridge.cpp | 110 +++++++++++++++++++-------- osal/windows/TmTcWinUdpBridge.h | 4 +- 3 files changed, 87 insertions(+), 36 deletions(-) diff --git a/osal/windows/TcWinUdpPollingTask.cpp b/osal/windows/TcWinUdpPollingTask.cpp index 38633388..502b798f 100644 --- a/osal/windows/TcWinUdpPollingTask.cpp +++ b/osal/windows/TcWinUdpPollingTask.cpp @@ -49,7 +49,7 @@ ReturnValue_t TcWinUdpPollingTask::performOperation(uint8_t opCode) { handleReadError(); continue; } -#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_WIRETAPPING_ENABLED == 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 sif::debug << "TcWinUdpPollingTask::performOperation: " << bytesReceived << " bytes received" << std::endl; #endif @@ -58,7 +58,6 @@ ReturnValue_t TcWinUdpPollingTask::performOperation(uint8_t opCode) { if(result != HasReturnvaluesIF::RETURN_FAILED) { } - tmtcBridge->registerCommConnect(); tmtcBridge->checkAndSetClientAddress(senderAddress); } return HasReturnvaluesIF::RETURN_OK; @@ -69,8 +68,8 @@ ReturnValue_t TcWinUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { store_address_t storeId; ReturnValue_t result = tcStore->addData(&storeId, receptionBuffer.data(), bytesRead); -#if FSFW_UDP_WIRETAPPING_ENABLED == 1 - arrayprinter::print(receptionBuffer.data(), bytesRead);# +#if FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 + arrayprinter::print(receptionBuffer.data(), bytesRead); #endif if (result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -113,7 +112,7 @@ ReturnValue_t TcWinUdpPollingTask::initialize() { } serverUdpSocket = tmtcBridge->serverSocket; -#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_WIRETAPPING_ENABLED == 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 sif::info << "TcWinUdpPollingTask::initialize: Server UDP socket " << serverUdpSocket << std::endl; #endif diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index 1a624355..346abcd4 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -12,13 +12,13 @@ TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, std::string udpServerPort, std::string udpClientPort): TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { if(udpServerPort == "") { - udpServerPort = DEFAULT_UDP_SERVER_PORT; + this->udpServerPort = DEFAULT_UDP_SERVER_PORT; } else { this->udpServerPort = udpServerPort; } if(udpClientPort == "") { - udpClientPort = DEFAULT_UDP_CLIENT_PORT; + this->udpClientPort = DEFAULT_UDP_CLIENT_PORT; } else { this->udpClientPort = udpClientPort; @@ -60,11 +60,12 @@ ReturnValue_t TmTcWinUdpBridge::initialize() { hints.ai_protocol = IPPROTO_UDP; hints.ai_flags = AI_PASSIVE; + sif::info << udpServerPort << std::endl; /* Set up UDP socket: - https://en.wikipedia.org/wiki/Getaddrinfo - Passing nullptr as the first parameter and specifying AI_PASSIVE in hints will cause - getaddrinfo to assign the address 0.0.0.0 (any address) - */ + https://en.wikipedia.org/wiki/Getaddrinfo + Passing nullptr as the first parameter and specifying AI_PASSIVE in hints will cause + getaddrinfo to assign the address 0.0.0.0 (any address) + */ int retval = getaddrinfo(nullptr, udpServerPort.c_str(), &hints, &addrResult); if (retval != 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -80,40 +81,22 @@ ReturnValue_t TmTcWinUdpBridge::initialize() { sif::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not open UDP socket!" << std::endl; #endif + freeaddrinfo(addrResult); handleSocketError(); return HasReturnvaluesIF::RETURN_FAILED; } -// serverAddress.sin_family = AF_INET; -// -// /* Accept packets from any interface. (potentially insecure). */ -// serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); -// serverAddress.sin_port = htons(setServerPort); -// serverAddressLen = sizeof(serverAddress); -// int result = setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, -// reinterpret_cast(&serverSocketOptions), -// sizeof(serverSocketOptions)); -// if(result != 0) { -//#if FSFW_CPP_OSTREAM_ENABLED == 1 -// sif::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not set socket options!" << -// std::endl; -//#endif -// handleSocketError(); -// } -// - clientAddress.sin_family = AF_INET; - clientAddress.sin_addr.s_addr = htonl(INADDR_ANY); - clientAddress.sin_port = htons(7302); - clientAddressLen = sizeof(clientAddress); - retval = bind(serverSocket, addrResult->ai_addr, static_cast(addrResult->ai_addrlen)); if(retval != 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not bind " "local port " << udpServerPort << " to server socket!" << std::endl; #endif + freeaddrinfo(addrResult); handleBindError(); } + freeaddrinfo(addrResult); + return HasReturnvaluesIF::RETURN_OK; } @@ -126,6 +109,7 @@ TmTcWinUdpBridge::~TmTcWinUdpBridge() { } ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { + MutexGuard lock(mutex, MutexIF::TimeoutType::WAITING, 10); int flags = 0; #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1 @@ -153,7 +137,7 @@ ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { return HasReturnvaluesIF::RETURN_OK; } -void TmTcWinUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) { +void TmTcWinUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { MutexGuard lock(mutex, MutexIF::TimeoutType::WAITING, 10); #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1 @@ -167,7 +151,7 @@ void TmTcWinUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) { /* Set new IP address if it has changed. */ 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); } } @@ -257,3 +241,69 @@ void TmTcWinUdpBridge::handleSendError() { } } +ReturnValue_t TmTcWinUdpBridge::oldSetup() { + ReturnValue_t result = TmTcBridge::initialize(); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + // Initiates Winsock DLL. + WSAData wsaData; + WORD wVersionRequested = MAKEWORD(2, 2); + int err = WSAStartup(wVersionRequested, &wsaData); + if (err != 0) { + /* Tell the user that we could not find a usable */ + /* Winsock DLL. */ +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge:" + "WSAStartup failed with error: " << err << std::endl; +#endif + } + + uint16_t setServerPort = 7301; + uint16_t setClientPort = 7302; + + // Set up UDP socket: https://man7.org/linux/man-pages/man7/ip.7.html + //clientSocket = socket(AF_INET, SOCK_DGRAM, 0); + serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if(serverSocket == INVALID_SOCKET) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not open" + " UDP socket!" << std::endl; +#endif + handleSocketError(); + } + + serverAddress.sin_family = AF_INET; + + // Accept packets from any interface. (potentially insecure). + serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); + serverAddress.sin_port = htons(setServerPort); + serverAddressLen = sizeof(serverAddress); + +// sif::info << serverAddress.sin_addr.s_addr << std::endl; +// sif::info << serverAddress.sin_port << std::endl; + + setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, + reinterpret_cast(&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 retval = bind(serverSocket, + reinterpret_cast(&serverAddress), + serverAddressLen); + if(retval != 0) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not bind " + "local port " << setServerPort << " to server socket!" + << std::endl; +#endif + handleBindError(); + } + + return HasReturnvaluesIF::RETURN_OK; +} + diff --git a/osal/windows/TmTcWinUdpBridge.h b/osal/windows/TmTcWinUdpBridge.h index e32854b6..b433f6f1 100644 --- a/osal/windows/TmTcWinUdpBridge.h +++ b/osal/windows/TmTcWinUdpBridge.h @@ -23,7 +23,7 @@ public: ReturnValue_t initialize() override; - void checkAndSetClientAddress(sockaddr_in clientAddress); + void checkAndSetClientAddress(sockaddr_in& clientAddress); protected: virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; @@ -53,6 +53,8 @@ private: void handleSocketError(); void handleBindError(); void handleSendError(); + + ReturnValue_t oldSetup(); }; From e92d3901f7c9283d7c57dbd156e0449d9047579e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 12 Mar 2021 02:15:21 +0100 Subject: [PATCH 07/17] improved error handling --- osal/windows/CMakeLists.txt | 1 + osal/windows/TcWinTcpServer.cpp | 69 ++--------- osal/windows/TcWinTcpServer.h | 11 +- osal/windows/TcWinUdpPollingTask.cpp | 100 ++++++---------- osal/windows/TcWinUdpPollingTask.h | 7 +- osal/windows/TmTcWinUdpBridge.cpp | 171 ++------------------------- osal/windows/TmTcWinUdpBridge.h | 16 +-- osal/windows/tcpipHelpers.cpp | 92 ++++++++++++++ osal/windows/tcpipHelpers.h | 31 +++++ 9 files changed, 187 insertions(+), 311 deletions(-) create mode 100644 osal/windows/tcpipHelpers.cpp create mode 100644 osal/windows/tcpipHelpers.h diff --git a/osal/windows/CMakeLists.txt b/osal/windows/CMakeLists.txt index 889ea339..a2b31688 100644 --- a/osal/windows/CMakeLists.txt +++ b/osal/windows/CMakeLists.txt @@ -2,6 +2,7 @@ target_sources(${LIB_FSFW_NAME} PRIVATE TcWinUdpPollingTask.cpp TmTcWinUdpBridge.cpp TcWinTcpServer.cpp + tcpipHelpers.cpp ) target_link_libraries(${LIB_FSFW_NAME} PRIVATE diff --git a/osal/windows/TcWinTcpServer.cpp b/osal/windows/TcWinTcpServer.cpp index 3cdd1d3f..49c278c5 100644 --- a/osal/windows/TcWinTcpServer.cpp +++ b/osal/windows/TcWinTcpServer.cpp @@ -1,4 +1,5 @@ #include "TcWinTcpServer.h" +#include "tcpipHelpers.h" #include "../../serviceinterface/ServiceInterface.h" #include @@ -16,6 +17,7 @@ TcWinTcpServer::TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBrid } ReturnValue_t TcWinTcpServer::initialize() { + using namespace tcpip; int retval = 0; struct addrinfo *addrResult = nullptr; struct addrinfo hints; @@ -44,7 +46,7 @@ ReturnValue_t TcWinTcpServer::initialize() { sif::warning << "TcWinTcpServer::TcWinTcpServer: Retrieving address info failed!" << std::endl; #endif - handleError(ErrorSources::GETADDRINFO_CALL); + handleError(Protocol::TCP, ErrorSources::GETADDRINFO_CALL); return HasReturnvaluesIF::RETURN_FAILED; } @@ -56,27 +58,16 @@ ReturnValue_t TcWinTcpServer::initialize() { sif::warning << "TcWinTcpServer::TcWinTcpServer: Socket creation failed!" << std::endl; #endif freeaddrinfo(addrResult); - handleError(ErrorSources::SOCKET_CALL); + handleError(Protocol::TCP, ErrorSources::SOCKET_CALL); return HasReturnvaluesIF::RETURN_FAILED; } -// retval = setsockopt(listenerTcpSocket, SOL_SOCKET, SO_REUSEADDR | SO_BROADCAST, -// reinterpret_cast(&tcpSockOpt), sizeof(tcpSockOpt)); -// if(retval != 0) { -// sif::warning << "TcWinTcpServer::TcWinTcpServer: Setting socket options failed!" << -// std::endl; -// handleError(ErrorSources::SETSOCKOPT_CALL); -// return HasReturnvaluesIF::RETURN_FAILED; -// } -// tcpAddress.sin_family = AF_INET; -// tcpAddress.sin_addr.s_addr = htonl(INADDR_ANY); - retval = bind(listenerTcpSocket, addrResult->ai_addr, static_cast(addrResult->ai_addrlen)); if(retval == SOCKET_ERROR) { sif::warning << "TcWinTcpServer::TcWinTcpServer: Binding socket failed!" << std::endl; freeaddrinfo(addrResult); - handleError(ErrorSources::BIND_CALL); + handleError(Protocol::TCP, ErrorSources::BIND_CALL); } freeaddrinfo(addrResult); @@ -90,16 +81,18 @@ TcWinTcpServer::~TcWinTcpServer() { } ReturnValue_t TcWinTcpServer::performOperation(uint8_t opCode) { + using namespace tcpip; /* If a connection is accepted, the corresponding socket will be assigned to the new socket */ SOCKET clientSocket; sockaddr_in clientSockAddr; int connectorSockAddrLen = 0; int retval = 0; + /* Listen for connection requests permanently for lifetime of program */ while(true) { retval = listen(listenerTcpSocket, currentBacklog); if(retval == SOCKET_ERROR) { - handleError(ErrorSources::LISTEN_CALL); + handleError(Protocol::TCP, ErrorSources::LISTEN_CALL, 500); continue; } @@ -107,17 +100,18 @@ ReturnValue_t TcWinTcpServer::performOperation(uint8_t opCode) { &connectorSockAddrLen); if(clientSocket == INVALID_SOCKET) { - handleError(ErrorSources::ACCEPT_CALL); + handleError(Protocol::TCP, ErrorSources::ACCEPT_CALL, 500); continue; }; retval = recv(clientSocket, reinterpret_cast(receptionBuffer.data()), receptionBuffer.size(), 0); if(retval > 0) { -#if FSFW_TCP_SERVER_WIRETAPPING_ENABLED == 1 +#if FSFW_TCP_RCV_WIRETAPPING_ENABLED == 1 sif::info << "TcWinTcpServer::performOperation: Received " << retval << " bytes." std::endl; #endif + handleError(Protocol::TCP, ErrorSources::RECV_CALL, 500); } else if(retval == 0) { @@ -132,45 +126,4 @@ ReturnValue_t TcWinTcpServer::performOperation(uint8_t opCode) { return HasReturnvaluesIF::RETURN_OK; } -void TcWinTcpServer::handleError(ErrorSources errorSrc) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - int errCode = WSAGetLastError(); - std::string errorSrcString; - if(errorSrc == ErrorSources::SETSOCKOPT_CALL) { - 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::GETADDRINFO_CALL) { - errorSrcString = "getaddrinfo call"; - } - switch(errCode) { - case(WSANOTINITIALISED): { - sif::warning << "TmTcWinUdpBridge::handleError: " << errorSrcString << " | " - "WSANOTINITIALISED: WSAStartup call necessary" << std::endl; - break; - } - case(WSAEINVAL): { - sif::warning << "TmTcWinUdpBridge::handleError: " << errorSrcString << " | " - "WSAEINVAL: Invalid parameters" << std::endl; - break; - } - default: { - /* - https://docs.microsoft.com/en-us/windows/win32/winsock/ - windows-sockets-error-codes-2 - */ - sif::warning << "TmTcWinUdpBridge::handleSocketError: Error code: " << errCode << std::endl; - break; - } - } -#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ -} diff --git a/osal/windows/TcWinTcpServer.h b/osal/windows/TcWinTcpServer.h index f8aebc53..bd9f3576 100644 --- a/osal/windows/TcWinTcpServer.h +++ b/osal/windows/TcWinTcpServer.h @@ -8,7 +8,7 @@ #include //! Debugging preprocessor define. -#define FSFW_TCP_SERVER_WIRETAPPING_ENABLED 0 +#define FSFW_TCP_RCV_WIRETAPPING_ENABLED 0 /** * @brief Windows TCP server used to receive telecommands on a Windows Host @@ -41,16 +41,7 @@ private: std::vector receptionBuffer; int tcpSockOpt = 0; - enum class ErrorSources { - GETADDRINFO_CALL, - SOCKET_CALL, - SETSOCKOPT_CALL, - BIND_CALL, - LISTEN_CALL, - ACCEPT_CALL - }; - void handleError(ErrorSources errorSrc); }; #endif /* FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_ */ diff --git a/osal/windows/TcWinUdpPollingTask.cpp b/osal/windows/TcWinUdpPollingTask.cpp index 502b798f..324547fa 100644 --- a/osal/windows/TcWinUdpPollingTask.cpp +++ b/osal/windows/TcWinUdpPollingTask.cpp @@ -1,4 +1,5 @@ #include "TcWinUdpPollingTask.h" +#include "tcpipHelpers.h" #include "../../globalfunctions/arrayprinter.h" #include "../../serviceinterface/ServiceInterfaceStream.h" @@ -31,22 +32,26 @@ TcWinUdpPollingTask::TcWinUdpPollingTask(object_id_t objectId, TcWinUdpPollingTask::~TcWinUdpPollingTask() {} ReturnValue_t TcWinUdpPollingTask::performOperation(uint8_t opCode) { + /* Sender Address is cached here. */ + struct sockaddr_in senderAddress; + int senderAddressSize = sizeof(senderAddress); + /* Poll for new UDP datagrams in permanent loop. */ while(true) { - /* Sender Address is cached here. */ - struct sockaddr_in senderAddress; - int senderAddressSize = sizeof(senderAddress); - int bytesReceived = recvfrom(serverUdpSocket, - reinterpret_cast(receptionBuffer.data()), frameSize, - receptionFlags, reinterpret_cast(&senderAddress), - &senderAddressSize); + int bytesReceived = recvfrom( + serverUdpSocket, + reinterpret_cast(receptionBuffer.data()), + frameSize, + receptionFlags, + reinterpret_cast(&senderAddress), + &senderAddressSize + ); if(bytesReceived == SOCKET_ERROR) { /* Handle error */ #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TcWinUdpPollingTask::performOperation: Reception" - " error." << std::endl; + sif::error << "TcWinUdpPollingTask::performOperation: Reception error." << std::endl; #endif - handleReadError(); + tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::RECVFROM_CALL, 1000); continue; } #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 @@ -66,17 +71,20 @@ ReturnValue_t TcWinUdpPollingTask::performOperation(uint8_t opCode) { ReturnValue_t TcWinUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { 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 FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning<< "TcSerialPollingTask::transferPusToSoftwareBus: Data " - "storage failed" << std::endl; + sif::warning<< "TcWinUdpPollingTask::transferPusToSoftwareBus: Data storage failed." << + std::endl; sif::warning << "Packet size: " << bytesRead << std::endl; -#endif +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ return HasReturnvaluesIF::RETURN_FAILED; } @@ -84,9 +92,12 @@ ReturnValue_t TcWinUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message); if (result != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "Serial Polling: Sending message to queue failed" << std::endl; -#endif + sif::warning << "TcWinUdpPollingTask::handleSuccessfullTcRead: " + " Sending message to queue failed" << std::endl; +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ tcStore->deleteData(storeId); } return result; @@ -96,8 +107,7 @@ ReturnValue_t TcWinUdpPollingTask::initialize() { tcStore = objectManager->get(objects::TC_STORE); if (tcStore == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TcSerialPollingTask::initialize: TC Store uninitialized!" - << std::endl; + sif::error << "TcWinUdpPollingTask::initialize: TC store uninitialized!" << std::endl; #endif return ObjectManagerIF::CHILD_INIT_FAILED; } @@ -105,18 +115,11 @@ ReturnValue_t TcWinUdpPollingTask::initialize() { tmtcBridge = objectManager->get(tmtcBridgeId); if(tmtcBridge == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TcSocketPollingTask::TcSocketPollingTask: Invalid" - " TMTC bridge object!" << std::endl; + sif::error << "TcWinUdpPollingTask::initialize: Invalid TMTC bridge object!" << + std::endl; #endif return ObjectManagerIF::CHILD_INIT_FAILED; } - - serverUdpSocket = tmtcBridge->serverSocket; -#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 - sif::info << "TcWinUdpPollingTask::initialize: Server UDP socket " << serverUdpSocket << - std::endl; -#endif - return HasReturnvaluesIF::RETURN_OK; } @@ -124,6 +127,9 @@ ReturnValue_t TcWinUdpPollingTask::initializeAfterTaskCreation() { /* Initialize the destination after task creation. This ensures that the destination has already been set in the TMTC bridge. */ 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; } @@ -138,39 +144,3 @@ void TcWinUdpPollingTask::setTimeout(double timeoutSeconds) { #endif } } - -void TcWinUdpPollingTask::handleReadError() { - int error = WSAGetLastError(); - switch(error) { - case(WSANOTINITIALISED): { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "TcWinUdpPollingTask::handleReadError: WSANOTINITIALISED: " - << "WSAStartup(...) call " << "necessary" << std::endl; -#endif - break; - } - case(WSAEFAULT): { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "TcWinUdpPollingTask::handleReadError: WSADEFAULT: " - << "Bad address " << std::endl; -#endif - break; - } - case(WSAEINVAL): { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "TcWinUdpPollingTask::handleReadError: WSAEINVAL: " - << "Invalid input parameters. " << std::endl; -#endif - break; - } - default: { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "TcWinUdpPollingTask::handleReadError: Error code: " - << error << std::endl; -#endif - break; - } - } - // to prevent spam. - Sleep(1000); -} diff --git a/osal/windows/TcWinUdpPollingTask.h b/osal/windows/TcWinUdpPollingTask.h index 8a9cf51f..707ad282 100644 --- a/osal/windows/TcWinUdpPollingTask.h +++ b/osal/windows/TcWinUdpPollingTask.h @@ -51,10 +51,12 @@ private: object_id_t tmtcBridgeId = objects::NO_OBJECT; TmTcWinUdpBridge* tmtcBridge = nullptr; MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE; - //! Reception flags: https://linux.die.net/man/2/recvfrom. + + //! See: https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recvfrom int receptionFlags = 0; - //! Server socket, which is member of TMTC bridge and is assigned in constructor + //! Server socket, which is member of TMTC bridge. + //! Will be cached shortly after SW intialization. SOCKET serverUdpSocket = 0; std::vector receptionBuffer; @@ -63,7 +65,6 @@ private: timeval receptionTimeout; ReturnValue_t handleSuccessfullTcRead(size_t bytesRead); - void handleReadError(); }; #endif /* FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ */ diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index 346abcd4..204be037 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -1,4 +1,5 @@ #include "TmTcWinUdpBridge.h" +#include "tcpipHelpers.h" #include #include @@ -31,6 +32,10 @@ TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, ReturnValue_t TmTcWinUdpBridge::initialize() { ReturnValue_t result = TmTcBridge::initialize(); if(result != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "TmTcWinUdpBridge::initialize: TmTcBridge initialization failed!" + << std::endl; +#endif return result; } @@ -60,12 +65,10 @@ ReturnValue_t TmTcWinUdpBridge::initialize() { hints.ai_protocol = IPPROTO_UDP; hints.ai_flags = AI_PASSIVE; - sif::info << udpServerPort << std::endl; /* Set up UDP socket: - https://en.wikipedia.org/wiki/Getaddrinfo - Passing nullptr as the first parameter and specifying AI_PASSIVE in hints will cause - getaddrinfo to assign the address 0.0.0.0 (any address) - */ + https://en.wikipedia.org/wiki/Getaddrinfo + Passing nullptr as the first parameter and specifying AI_PASSIVE in hints will cause + getaddrinfo to assign the address 0.0.0.0 (any address) */ int retval = getaddrinfo(nullptr, udpServerPort.c_str(), &hints, &addrResult); if (retval != 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -82,7 +85,7 @@ ReturnValue_t TmTcWinUdpBridge::initialize() { std::endl; #endif freeaddrinfo(addrResult); - handleSocketError(); + tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SOCKET_CALL); return HasReturnvaluesIF::RETURN_FAILED; } @@ -93,10 +96,9 @@ ReturnValue_t TmTcWinUdpBridge::initialize() { "local port " << udpServerPort << " to server socket!" << std::endl; #endif freeaddrinfo(addrResult); - handleBindError(); + tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::BIND_CALL); } freeaddrinfo(addrResult); - return HasReturnvaluesIF::RETURN_OK; } @@ -128,7 +130,7 @@ ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { sif::error << "TmTcWinUdpBridge::sendTm: Send operation failed." << std::endl; #endif - handleSendError(); + tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SENDTO_CALL); } #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1 sif::debug << "TmTcUnixUdpBridge::sendTm: " << bytesSent << " bytes were" @@ -156,154 +158,3 @@ void TmTcWinUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { } } -void TmTcWinUdpBridge::handleSocketError() { - int errCode = WSAGetLastError(); - switch(errCode) { - case(WSANOTINITIALISED): { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "TmTcWinUdpBridge::handleSocketError: WSANOTINITIALISED: WSAStartup" - " call necessary" << std::endl; -#endif - break; - } - default: { - /* - https://docs.microsoft.com/en-us/windows/win32/winsock/ - windows-sockets-error-codes-2 - */ -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "TmTcWinUdpBridge::handleSocketError: Error code: " << errCode << std::endl; -#endif - break; - } - } -} - -void TmTcWinUdpBridge::handleBindError() { - int errCode = WSAGetLastError(); - switch(errCode) { - case(WSANOTINITIALISED): { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "TmTcWinUdpBridge::handleBindError: WSANOTINITIALISED: " - << "WSAStartup call necessary" << std::endl; -#endif - break; - } - case(WSAEADDRINUSE): { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "TmTcWinUdpBridge::handleBindError: WSAEADDRINUSE: " - "Port is already in use!" << std::endl; -#endif - break; - } - default: { - /* - https://docs.microsoft.com/en-us/windows/win32/winsock/ - windows-sockets-error-codes-2 - */ -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "TmTcWinUdpBridge::handleBindError: Error code: " - << errCode << std::endl; -#endif - break; - } - } -} - -void TmTcWinUdpBridge::handleSendError() { - int errCode = WSAGetLastError(); - switch(errCode) { - case(WSANOTINITIALISED): { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "TmTcWinUdpBridge::handleSendError: WSANOTINITIALISED: " - << "WSAStartup(...) call necessary" << std::endl; -#endif - break; - } - case(WSAEADDRNOTAVAIL): { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "TmTcWinUdpBridge::handleSendError: WSAEADDRNOTAVAIL: " - << "Check target address. " << std::endl; -#endif - break; - } - default: { - /* - https://docs.microsoft.com/en-us/windows/win32/winsock/ - windows-sockets-error-codes-2 - */ -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "TmTcWinUdpBridge::handleSendError: Error code: " - << errCode << std::endl; -#endif - break; - } - } -} - -ReturnValue_t TmTcWinUdpBridge::oldSetup() { - ReturnValue_t result = TmTcBridge::initialize(); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - // Initiates Winsock DLL. - WSAData wsaData; - WORD wVersionRequested = MAKEWORD(2, 2); - int err = WSAStartup(wVersionRequested, &wsaData); - if (err != 0) { - /* Tell the user that we could not find a usable */ - /* Winsock DLL. */ -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge:" - "WSAStartup failed with error: " << err << std::endl; -#endif - } - - uint16_t setServerPort = 7301; - uint16_t setClientPort = 7302; - - // Set up UDP socket: https://man7.org/linux/man-pages/man7/ip.7.html - //clientSocket = socket(AF_INET, SOCK_DGRAM, 0); - serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if(serverSocket == INVALID_SOCKET) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not open" - " UDP socket!" << std::endl; -#endif - handleSocketError(); - } - - serverAddress.sin_family = AF_INET; - - // Accept packets from any interface. (potentially insecure). - serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); - serverAddress.sin_port = htons(setServerPort); - serverAddressLen = sizeof(serverAddress); - -// sif::info << serverAddress.sin_addr.s_addr << std::endl; -// sif::info << serverAddress.sin_port << std::endl; - - setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, - reinterpret_cast(&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 retval = bind(serverSocket, - reinterpret_cast(&serverAddress), - serverAddressLen); - if(retval != 0) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not bind " - "local port " << setServerPort << " to server socket!" - << std::endl; -#endif - handleBindError(); - } - - return HasReturnvaluesIF::RETURN_OK; -} - diff --git a/osal/windows/TmTcWinUdpBridge.h b/osal/windows/TmTcWinUdpBridge.h index b433f6f1..b381e2cc 100644 --- a/osal/windows/TmTcWinUdpBridge.h +++ b/osal/windows/TmTcWinUdpBridge.h @@ -41,23 +41,9 @@ private: struct sockaddr_in serverAddress; int serverAddressLen = 0; - //! Access to the client address is mutex protected as it is set - //! by another task. + //! Access to the client address is mutex protected as it is set by another task. MutexIF* mutex; - - enum class ErrorSources { - SOCKET_CALL, - SETSOCKOPT_CALL - }; - - void handleSocketError(); - void handleBindError(); - void handleSendError(); - - ReturnValue_t oldSetup(); }; - - #endif /* FSFW_OSAL_HOST_TMTCWINUDPBRIDGE_H_ */ diff --git a/osal/windows/tcpipHelpers.cpp b/osal/windows/tcpipHelpers.cpp new file mode 100644 index 00000000..3ad4bc82 --- /dev/null +++ b/osal/windows/tcpipHelpers.cpp @@ -0,0 +1,92 @@ +#include "tcpipHelpers.h" +#include + +#include "../../serviceinterface/ServiceInterface.h" + +#include +#include + +void tcpip::handleError(Protocol protocol, ErrorSources errorSrc, dur_millis_t sleepDuration) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + int errCode = WSAGetLastError(); + std::string protocolString; + if(protocol == Protocol::TCP) { + protocolString = "TCP"; + } + else if(protocol == Protocol::UDP) { + protocolString = "UDP"; + } + else { + protocolString = "Unknown protocol"; + } + + std::string errorSrcString; + if(errorSrc == ErrorSources::SETSOCKOPT_CALL) { + 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; + switch(errCode) { + case(WSANOTINITIALISED): { + infoString = "WSANOTINITIALISED"; + sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString << + " | " << infoString << std::endl; + break; + } + case(WSAEADDRINUSE): { + infoString = "WSAEADDRINUSE"; + sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString << + " | " << infoString << std::endl; + break; + } + case(WSAEFAULT): { + infoString = "WSAEFAULT"; + sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString << + " | " << infoString << std::endl; + break; + } + case(WSAEADDRNOTAVAIL): { + infoString = "WSAEADDRNOTAVAIL"; + sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString << + " | " << infoString << std::endl; + break; + } + case(WSAEINVAL): { + infoString = "WSAEINVAL"; + sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString << + " | " << infoString << std::endl; + break; + } + default: { + /* + https://docs.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2 + */ + sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString << + "Error code" << errCode << std::endl; + break; + } + } +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ + if(sleepDuration > 0) { + Sleep(sleepDuration); + } +} + diff --git a/osal/windows/tcpipHelpers.h b/osal/windows/tcpipHelpers.h new file mode 100644 index 00000000..a88b0479 --- /dev/null +++ b/osal/windows/tcpipHelpers.h @@ -0,0 +1,31 @@ +#ifndef FSFW_OSAL_WINDOWS_TCPIPHELPERS_H_ +#define FSFW_OSAL_WINDOWS_TCPIPHELPERS_H_ + +#include "../../timemanager/clockDefinitions.h" + +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); + +} + + + +#endif /* FSFW_OSAL_WINDOWS_TCPIPHELPERS_H_ */ From cf120e2d862f0080ee8e4efeeab08ea4dd57225e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 12 Mar 2021 14:08:58 +0100 Subject: [PATCH 08/17] smaller improvementst --- osal/windows/TmTcWinUdpBridge.cpp | 2 +- osal/windows/TmTcWinUdpBridge.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index 204be037..e4952f35 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -93,7 +93,7 @@ ReturnValue_t TmTcWinUdpBridge::initialize() { if(retval != 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not bind " - "local port " << udpServerPort << " to server socket!" << std::endl; + "local port (" << udpServerPort << ") to server socket!" << std::endl; #endif freeaddrinfo(addrResult); tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::BIND_CALL); diff --git a/osal/windows/TmTcWinUdpBridge.h b/osal/windows/TmTcWinUdpBridge.h index b381e2cc..989b4f7b 100644 --- a/osal/windows/TmTcWinUdpBridge.h +++ b/osal/windows/TmTcWinUdpBridge.h @@ -4,7 +4,6 @@ #include "../../tmtcservices/TmTcBridge.h" #include -#include //! Debugging preprocessor define. #define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0 From 7173d2ecfc7f9a5cde53e083b5267149a0cc7adc Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 12 Mar 2021 16:47:55 +0100 Subject: [PATCH 09/17] revaming linux UDP stuff --- osal/linux/CMakeLists.txt | 1 + osal/linux/tcpipHelpers.cpp | 5 +++++ osal/linux/tcpipHelpers.h | 29 +++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 osal/linux/tcpipHelpers.cpp create mode 100644 osal/linux/tcpipHelpers.h diff --git a/osal/linux/CMakeLists.txt b/osal/linux/CMakeLists.txt index 474e548b..6c377844 100644 --- a/osal/linux/CMakeLists.txt +++ b/osal/linux/CMakeLists.txt @@ -16,6 +16,7 @@ target_sources(${LIB_FSFW_NAME} TcUnixUdpPollingTask.cpp TmTcUnixUdpBridge.cpp Timer.cpp + tcpipHelpers.cpp ) find_package(Threads REQUIRED) diff --git a/osal/linux/tcpipHelpers.cpp b/osal/linux/tcpipHelpers.cpp new file mode 100644 index 00000000..7d25752d --- /dev/null +++ b/osal/linux/tcpipHelpers.cpp @@ -0,0 +1,5 @@ +#include "tcpipHelpers.h" + +void tcpip::handleError(Protocol protocol, ErrorSources errorSrc, dur_millis_t sleepDuration = 0) { + +} diff --git a/osal/linux/tcpipHelpers.h b/osal/linux/tcpipHelpers.h new file mode 100644 index 00000000..269a1036 --- /dev/null +++ b/osal/linux/tcpipHelpers.h @@ -0,0 +1,29 @@ +#ifndef FSFW_OSAL_LINUX_TCPIPHELPERS_H_ +#define FSFW_OSAL_LINUX_TCPIPHELPERS_H_ + +#include "../../timemanager/clockDefinitions.h" + +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); + +} + +#endif /* FSFW_OSAL_LINUX_TCPIPHELPERS_H_ */ From 8ab2044c30ca4c03d6aacfecb387ce22ba950a88 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 12 Mar 2021 17:15:53 +0100 Subject: [PATCH 10/17] refactoring unix udp bridge --- osal/linux/TmTcUnixUdpBridge.cpp | 142 +++++++++++++++++++++--------- osal/linux/TmTcUnixUdpBridge.h | 14 +-- osal/windows/TmTcWinUdpBridge.cpp | 3 + osal/windows/TmTcWinUdpBridge.h | 3 - 4 files changed, 112 insertions(+), 50 deletions(-) diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index 7f110114..ae1ad781 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -1,69 +1,127 @@ #include "TmTcUnixUdpBridge.h" +#include "tcpipHelpers.h" #include "../../serviceinterface/ServiceInterface.h" #include "../../ipc/MutexGuard.h" #include #include +#include +#include +#include + +//! 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, 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) { - 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; - if(serverPort != 0xFFFF) { - setServerPort = serverPort; - } + mutex = MutexFactory::instance()->createMutex(); + communicationLinkUp = false; +} - uint16_t setClientPort = DEFAULT_UDP_CLIENT_PORT; - if(clientPort != 0xFFFF) { - setClientPort = clientPort; - } +ReturnValue_t TmTcUnixUdpBridge::initialize() { + using namespace tcpip; - // Set up UDP socket: https://man7.org/linux/man-pages/man7/ip.7.html - //clientSocket = socket(AF_INET, SOCK_DGRAM, 0); - serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if(serverSocket < 0) { + ReturnValue_t result = TmTcBridge::initialize(); + if(result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not open" - " UDP socket!" << std::endl; + sif::error << "TmTcUnixUdpBridge::initialize: TmTcBridge initialization failed!" + << std::endl; #endif - handleSocketError(); - return; - } + return result; + } - serverAddress.sin_family = AF_INET; + struct addrinfo *addrResult = nullptr; + struct addrinfo hints; - // 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)); + std::memset(hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + hints.ai_flags = AI_PASSIVE; - 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(&serverAddress), - serverAddressLen); - if(result == -1) { + /* Set up UDP socket: + https://man7.org/linux/man-pages/man3/getaddrinfo.3.html + Passing nullptr as the first parameter and specifying AI_PASSIVE in hints will cause + getaddrinfo to assign the address 0.0.0.0 (any address) */ + int retval = getaddrinfo(nullptr, udpServerPort.c_str(), &hints, &addrResult); + if (retval != 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not bind " - "local port " << setServerPort << " to server socket!" - << std::endl; + sif::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Retrieving address info failed!" << + std::endl; #endif - handleBindError(); - return; - } + return HasReturnvaluesIF::RETURN_FAILED; + } + + /* 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(&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() { + if(mutex != nullptr) { + MutexFactory::instance()->deleteMutex(mutex); + } + close(serverSocket); } ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { diff --git a/osal/linux/TmTcUnixUdpBridge.h b/osal/linux/TmTcUnixUdpBridge.h index ae6f6adc..c45672b6 100644 --- a/osal/linux/TmTcUnixUdpBridge.h +++ b/osal/linux/TmTcUnixUdpBridge.h @@ -10,16 +10,18 @@ class TmTcUnixUdpBridge: public TmTcBridge { friend class TcUnixUdpPollingTask; public: - // The ports chosen here should not be used by any other process. - // List of used ports on Linux: /etc/services - static constexpr uint16_t DEFAULT_UDP_SERVER_PORT = 7301; - static constexpr uint16_t DEFAULT_UDP_CLIENT_PORT = 7302; + /* The ports chosen here should not be used by any other process. + List of used ports on Linux: /etc/services */ + static const std::string DEFAULT_UDP_SERVER_PORT; + static const std::string DEFAULT_UDP_CLIENT_PORT; TmTcUnixUdpBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId, - uint16_t serverPort = 0xFFFF,uint16_t clientPort = 0xFFFF); + std::string serverPort = "", std::string clientPort = ""); virtual~ TmTcUnixUdpBridge(); + ReturnValue_t initialize() override; + void checkAndSetClientAddress(sockaddr_in& clientAddress); void setClientAddressToAny(bool ipAddrAnySet); @@ -28,6 +30,8 @@ protected: private: int serverSocket = 0; + std::string udpServerPort; + std::string udpClientPort; const int serverSocketOptions = 0; diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index e4952f35..b857ba67 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -5,6 +5,9 @@ #include #include +//! 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_CLIENT_PORT = "7302"; diff --git a/osal/windows/TmTcWinUdpBridge.h b/osal/windows/TmTcWinUdpBridge.h index 989b4f7b..762849f8 100644 --- a/osal/windows/TmTcWinUdpBridge.h +++ b/osal/windows/TmTcWinUdpBridge.h @@ -5,9 +5,6 @@ #include -//! Debugging preprocessor define. -#define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0 - class TmTcWinUdpBridge: public TmTcBridge { friend class TcWinUdpPollingTask; public: From bceca86da68eae0627ba69dfa9054250e53e1b63 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 12 Mar 2021 18:06:24 +0100 Subject: [PATCH 11/17] finsihed tcpip refactoring for linux udp --- osal/CMakeLists.txt | 4 +- osal/common/CMakeLists.txt | 3 + osal/common/tcpipCommon.cpp | 36 ++++++ osal/common/tcpipCommon.h | 33 ++++++ osal/linux/TcUnixUdpPollingTask.cpp | 103 ++++++++--------- osal/linux/TcUnixUdpPollingTask.h | 2 +- osal/linux/TmTcUnixUdpBridge.cpp | 171 +++++++--------------------- osal/linux/TmTcUnixUdpBridge.h | 4 - osal/linux/tcpipHelpers.cpp | 105 ++++++++++++++++- osal/linux/tcpipHelpers.h | 17 +-- osal/windows/TmTcWinUdpBridge.cpp | 14 ++- osal/windows/tcpipHelpers.cpp | 61 +++------- osal/windows/tcpipHelpers.h | 18 +-- 13 files changed, 294 insertions(+), 277 deletions(-) create mode 100644 osal/common/CMakeLists.txt create mode 100644 osal/common/tcpipCommon.cpp create mode 100644 osal/common/tcpipCommon.h diff --git a/osal/CMakeLists.txt b/osal/CMakeLists.txt index 02ff2405..e4f1de7c 100644 --- a/osal/CMakeLists.txt +++ b/osal/CMakeLists.txt @@ -31,4 +31,6 @@ else() message(FATAL_ERROR "The host OS could not be determined! Aborting.") endif() -endif() \ No newline at end of file +endif() + +add_subdirectory(common) \ No newline at end of file diff --git a/osal/common/CMakeLists.txt b/osal/common/CMakeLists.txt new file mode 100644 index 00000000..b77985fb --- /dev/null +++ b/osal/common/CMakeLists.txt @@ -0,0 +1,3 @@ +target_sources(${LIB_FSFW_NAME} PRIVATE + tcpipCommon.cpp +) diff --git a/osal/common/tcpipCommon.cpp b/osal/common/tcpipCommon.cpp new file mode 100644 index 00000000..9a5e4647 --- /dev/null +++ b/osal/common/tcpipCommon.cpp @@ -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"; + } +} diff --git a/osal/common/tcpipCommon.h b/osal/common/tcpipCommon.h new file mode 100644 index 00000000..b59981ed --- /dev/null +++ b/osal/common/tcpipCommon.h @@ -0,0 +1,33 @@ +#ifndef FSFW_OSAL_COMMON_TCPIPCOMMON_H_ +#define FSFW_OSAL_COMMON_TCPIPCOMMON_H_ + +#include "../../timemanager/clockDefinitions.h" +#include + +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_ */ diff --git a/osal/linux/TcUnixUdpPollingTask.cpp b/osal/linux/TcUnixUdpPollingTask.cpp index 11ed7fee..71557069 100644 --- a/osal/linux/TcUnixUdpPollingTask.cpp +++ b/osal/linux/TcUnixUdpPollingTask.cpp @@ -1,7 +1,9 @@ #include "TcUnixUdpPollingTask.h" +#include "tcpipHelpers.h" + #include "../../globalfunctions/arrayprinter.h" -#include +#define FSFW_UDP_RCV_WIRETAPPING_ENABLED 0 TcUnixUdpPollingTask::TcUnixUdpPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, size_t frameSize, @@ -15,8 +17,8 @@ TcUnixUdpPollingTask::TcUnixUdpPollingTask(object_id_t objectId, this->frameSize = DEFAULT_MAX_FRAME_SIZE; } - // Set up reception buffer with specified frame size. - // For now, it is assumed that only one frame is held in the buffer! + /* Set up reception buffer with specified frame size. + For now, it is assumed that only one frame is held in the buffer! */ receptionBuffer.reserve(this->frameSize); receptionBuffer.resize(this->frameSize); @@ -31,34 +33,37 @@ TcUnixUdpPollingTask::TcUnixUdpPollingTask(object_id_t objectId, TcUnixUdpPollingTask::~TcUnixUdpPollingTask() {} ReturnValue_t TcUnixUdpPollingTask::performOperation(uint8_t opCode) { - // Poll for new UDP datagrams in permanent loop. - while(1) { - //! Sender Address is cached here. - struct sockaddr_in senderAddress; - socklen_t senderSockLen = sizeof(senderAddress); - ssize_t bytesReceived = recvfrom(serverUdpSocket, - receptionBuffer.data(), frameSize, receptionFlags, - reinterpret_cast(&senderAddress), &senderSockLen); - if(bytesReceived < 0) { - // handle error -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TcSocketPollingTask::performOperation: Reception" - "error." << std::endl; -#endif - handleReadError(); + /* Sender Address is cached here. */ + struct sockaddr_in senderAddress; + socklen_t senderAddressSize = sizeof(senderAddress); + /* Poll for new UDP datagrams in permanent loop. */ + while(true) { + ssize_t bytesReceived = recvfrom( + serverUdpSocket, + receptionBuffer.data(), + frameSize, + receptionFlags, + reinterpret_cast(&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; } -#if FSFW_CPP_OSTREAM_ENABLED == 1 -// sif::debug << "TcSocketPollingTask::performOperation: " << bytesReceived -// << " bytes received" << std::endl; +#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 + sif::debug << "TcSocketPollingTask::performOperation: " << bytesReceived + << " bytes received" << std::endl; #endif ReturnValue_t result = handleSuccessfullTcRead(bytesReceived); if(result != HasReturnvaluesIF::RETURN_FAILED) { } - tmtcBridge->registerCommConnect(); tmtcBridge->checkAndSetClientAddress(senderAddress); } return HasReturnvaluesIF::RETURN_OK; @@ -67,15 +72,21 @@ ReturnValue_t TcUnixUdpPollingTask::performOperation(uint8_t opCode) { ReturnValue_t TcUnixUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { store_address_t storeId; - ReturnValue_t result = tcStore->addData(&storeId, - receptionBuffer.data(), bytesRead); - // arrayprinter::print(receptionBuffer.data(), bytesRead); + +#if FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 + arrayprinter::print(receptionBuffer.data(), bytesRead); +#endif + + ReturnValue_t result = tcStore->addData(&storeId, receptionBuffer.data(), bytesRead); if (result != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TcSerialPollingTask::transferPusToSoftwareBus: Data " + sif::error << "TcUnixUdpPollingTask::handleSuccessfullTcRead: Data " "storage failed" << 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; } @@ -83,10 +94,13 @@ ReturnValue_t TcUnixUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message); if (result != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "Serial Polling: Sending message to queue failed" - << std::endl; -#endif + sif::error << "TcUnixUdpPollingTask::handleSuccessfullTcRead: Sending message to queue " + "failed" << std::endl; +#else +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ tcStore->deleteData(storeId); } return result; @@ -111,15 +125,17 @@ ReturnValue_t TcUnixUdpPollingTask::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - serverUdpSocket = tmtcBridge->serverSocket; return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t TcUnixUdpPollingTask::initializeAfterTaskCreation() { - // Initialize the destination after task creation. This ensures - // that the destination will be set in the TMTC bridge. + /* Initialize the destination after task creation. This ensures + that the destination has already been set in the TMTC bridge. */ 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; } @@ -135,24 +151,3 @@ void TcUnixUdpPollingTask::setTimeout(double timeoutSeconds) { #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 - } - } -} diff --git a/osal/linux/TcUnixUdpPollingTask.h b/osal/linux/TcUnixUdpPollingTask.h index cc032561..39ee0914 100644 --- a/osal/linux/TcUnixUdpPollingTask.h +++ b/osal/linux/TcUnixUdpPollingTask.h @@ -48,6 +48,7 @@ private: object_id_t tmtcBridgeId = objects::NO_OBJECT; TmTcUnixUdpBridge* tmtcBridge = nullptr; MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE; + //! Reception flags: https://linux.die.net/man/2/recvfrom. int receptionFlags = 0; @@ -61,7 +62,6 @@ private: timeval receptionTimeout; ReturnValue_t handleSuccessfullTcRead(size_t bytesRead); - void handleReadError(); }; #endif /* FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ */ diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index ae1ad781..85698560 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -3,7 +3,6 @@ #include "../../serviceinterface/ServiceInterface.h" #include "../../ipc/MutexGuard.h" -#include #include #include #include @@ -11,7 +10,7 @@ #include //! 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_CLIENT_PORT = "7302"; @@ -52,7 +51,7 @@ ReturnValue_t TmTcUnixUdpBridge::initialize() { struct addrinfo *addrResult = nullptr; struct addrinfo hints; - std::memset(hints, 0, sizeof(hints)); + std::memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; @@ -82,36 +81,18 @@ ReturnValue_t TmTcUnixUdpBridge::initialize() { #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(&serverAddress), - serverAddressLen); - if(result == -1) { + retval = bind(serverSocket, addrResult->ai_addr, static_cast(addrResult->ai_addrlen)); + if(retval != 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not bind " - "local port " << setServerPort << " to server socket!" - << std::endl; + sif::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not bind " + "local port (" << udpServerPort << ") to server socket!" << std::endl; #endif - handleBindError(); - return; + freeaddrinfo(addrResult); + handleError(Protocol::UDP, ErrorSources::BIND_CALL); + return HasReturnvaluesIF::RETURN_FAILED; } return HasReturnvaluesIF::RETURN_OK; @@ -131,133 +112,57 @@ ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { if(ipAddrAnySet){ 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); } - -// char ipAddress [15]; -#if FSFW_CPP_OSTREAM_ENABLED == 1 -// sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET, -// &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; +#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1 + char ipAddress [15]; + sif::debug << "IP Address Sender: "<< + inet_ntop(AF_INET,&clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; #endif - ssize_t bytesSent = sendto(serverSocket, data, dataLen, flags, - reinterpret_cast(&clientAddress), clientAddressLen); + ssize_t bytesSent = sendto( + serverSocket, + data, + dataLen, + flags, + reinterpret_cast(&clientAddress), + clientAddressLen + ); if(bytesSent < 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmTcUnixUdpBridge::sendTm: Send operation failed." - << std::endl; + sif::warning << "TmTcUnixUdpBridge::sendTm: Send operation failed." << std::endl; #endif - handleSendError(); + tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SENDTO_CALL); } -#if FSFW_CPP_OSTREAM_ENABLED == 1 -// sif::debug << "TmTcUnixUdpBridge::sendTm: " << bytesSent << " bytes were" -// " sent." << std::endl; + +#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1 + sif::debug << "TmTcUnixUdpBridge::sendTm: " << bytesSent << " bytes were" + " sent." << std::endl; #endif + return HasReturnvaluesIF::RETURN_OK; } void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { MutexGuard lock(mutex, MutexIF::TimeoutType::WAITING, 10); -// char ipAddress [15]; -#if FSFW_CPP_OSTREAM_ENABLED == 1 -// sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET, -// &newAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; -// sif::debug << "IP Address Old: " << inet_ntop(AF_INET, -// &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; +#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 + char ipAddress [15]; + sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET, + &newAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; + sif::debug << "IP Address Old: " << inet_ntop(AF_INET, + &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; #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) { - clientAddress.sin_addr.s_addr = newAddress.sin_addr.s_addr; + clientAddress = newAddress; 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){ this->ipAddrAnySet = ipAddrAnySet; } diff --git a/osal/linux/TmTcUnixUdpBridge.h b/osal/linux/TmTcUnixUdpBridge.h index c45672b6..f5e67138 100644 --- a/osal/linux/TmTcUnixUdpBridge.h +++ b/osal/linux/TmTcUnixUdpBridge.h @@ -46,10 +46,6 @@ private: //! Access to the client address is mutex protected as it is set //! by another task. MutexIF* mutex; - - void handleSocketError(); - void handleBindError(); - void handleSendError(); }; #endif /* FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ */ diff --git a/osal/linux/tcpipHelpers.cpp b/osal/linux/tcpipHelpers.cpp index 7d25752d..1c380769 100644 --- a/osal/linux/tcpipHelpers.cpp +++ b/osal/linux/tcpipHelpers.cpp @@ -1,5 +1,108 @@ #include "tcpipHelpers.h" -void tcpip::handleError(Protocol protocol, ErrorSources errorSrc, dur_millis_t sleepDuration = 0) { +#include "../../tasks/TaskFactory.h" +#include +#include + +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); + } } diff --git a/osal/linux/tcpipHelpers.h b/osal/linux/tcpipHelpers.h index 269a1036..6b337c62 100644 --- a/osal/linux/tcpipHelpers.h +++ b/osal/linux/tcpipHelpers.h @@ -2,25 +2,10 @@ #define FSFW_OSAL_LINUX_TCPIPHELPERS_H_ #include "../../timemanager/clockDefinitions.h" +#include "../common/tcpipCommon.h" 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); diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index b857ba67..113c98fb 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -125,13 +125,17 @@ ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; #endif - int bytesSent = sendto(serverSocket, - reinterpret_cast(data), dataLen, flags, - reinterpret_cast(&clientAddress), clientAddressLen); + int bytesSent = sendto( + serverSocket, + reinterpret_cast(data), + dataLen, + flags, + reinterpret_cast(&clientAddress), + clientAddressLen + ); if(bytesSent == SOCKET_ERROR) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmTcWinUdpBridge::sendTm: Send operation failed." - << std::endl; + sif::warning << "TmTcWinUdpBridge::sendTm: Send operation failed." << std::endl; #endif tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SENDTO_CALL); } diff --git a/osal/windows/tcpipHelpers.cpp b/osal/windows/tcpipHelpers.cpp index 3ad4bc82..ef07f5ca 100644 --- a/osal/windows/tcpipHelpers.cpp +++ b/osal/windows/tcpipHelpers.cpp @@ -1,92 +1,63 @@ #include "tcpipHelpers.h" #include +#include "../../tasks/TaskFactory.h" #include "../../serviceinterface/ServiceInterface.h" + #include #include 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(); std::string protocolString; - if(protocol == Protocol::TCP) { - protocolString = "TCP"; - } - else if(protocol == Protocol::UDP) { - protocolString = "UDP"; - } - else { - protocolString = "Unknown protocol"; - } - std::string errorSrcString; - if(errorSrc == ErrorSources::SETSOCKOPT_CALL) { - 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"; - } + determineErrorStrings(protocol, errorSrc, protocolString, errorSrcString); std::string infoString; switch(errCode) { case(WSANOTINITIALISED): { infoString = "WSANOTINITIALISED"; - sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString << - " | " << infoString << std::endl; break; } case(WSAEADDRINUSE): { infoString = "WSAEADDRINUSE"; - sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString << - " | " << infoString << std::endl; break; } case(WSAEFAULT): { infoString = "WSAEFAULT"; - sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString << - " | " << infoString << std::endl; break; } case(WSAEADDRNOTAVAIL): { infoString = "WSAEADDRNOTAVAIL"; - sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString << - " | " << infoString << std::endl; break; } case(WSAEINVAL): { infoString = "WSAEINVAL"; - sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString << - " | " << infoString << std::endl; break; } default: { /* https://docs.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2 */ - sif::warning << "tcpip::handleError: " << protocolString << " | " << errorSrcString << - "Error code" << errCode << std::endl; + infoString = "Error code: " + std::to_string(errCode); 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_VERBOSE_LEVEL >= 1 */ + if(sleepDuration > 0) { - Sleep(sleepDuration); + TaskFactory::instance()->delayTask(sleepDuration); } } diff --git a/osal/windows/tcpipHelpers.h b/osal/windows/tcpipHelpers.h index a88b0479..01f009b9 100644 --- a/osal/windows/tcpipHelpers.h +++ b/osal/windows/tcpipHelpers.h @@ -2,26 +2,10 @@ #define FSFW_OSAL_WINDOWS_TCPIPHELPERS_H_ #include "../../timemanager/clockDefinitions.h" +#include "../common/tcpipCommon.h" 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); } From c08e2f0bf7ce634ab41a3513efba950955828ce9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 12 Mar 2021 18:07:18 +0100 Subject: [PATCH 12/17] removed commented code --- osal/linux/TmTcUnixUdpBridge.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index 85698560..c8dc612c 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -112,9 +112,9 @@ ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { if(ipAddrAnySet){ clientAddress.sin_addr.s_addr = htons(INADDR_ANY); - // clientAddress.sin_addr.s_addr = inet_addr("127.73.73.1"); clientAddressLen = sizeof(serverAddress); } + #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1 char ipAddress [15]; sif::debug << "IP Address Sender: "<< From 76c571b969bdabce34b1bce5b30586e67536388b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 12 Mar 2021 18:12:38 +0100 Subject: [PATCH 13/17] made mutex properties changeable --- osal/linux/TmTcUnixUdpBridge.cpp | 11 +++++++++-- osal/linux/TmTcUnixUdpBridge.h | 10 ++++++++-- osal/windows/TmTcWinUdpBridge.cpp | 12 ++++++++++-- osal/windows/TmTcWinUdpBridge.h | 7 +++++++ 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index c8dc612c..8de62cab 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -108,7 +108,8 @@ TmTcUnixUdpBridge::~TmTcUnixUdpBridge() { ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { int flags = 0; - MutexGuard lock(mutex, MutexIF::TimeoutType::WAITING, 10); + /* The target address can be set by different threads so this lock ensures thread-safety */ + MutexGuard lock(mutex, timeoutType, mutexTimeoutMs); if(ipAddrAnySet){ clientAddress.sin_addr.s_addr = htons(INADDR_ANY); @@ -145,7 +146,7 @@ ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { } void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { - MutexGuard lock(mutex, MutexIF::TimeoutType::WAITING, 10); + MutexGuard lock(mutex, timeoutType, mutexTimeoutMs); #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 char ipAddress [15]; @@ -163,6 +164,12 @@ void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { } } +void TmTcUnixUdpBridge::setMutexProperties(MutexIF::TimeoutType timeoutType, + dur_millis_t timeoutMs) { + this->timeoutType = timeoutType; + this->mutexTimeoutMs = timeoutMs; +} + void TmTcUnixUdpBridge::setClientAddressToAny(bool ipAddrAnySet){ this->ipAddrAnySet = ipAddrAnySet; } diff --git a/osal/linux/TmTcUnixUdpBridge.h b/osal/linux/TmTcUnixUdpBridge.h index f5e67138..26b6f0f7 100644 --- a/osal/linux/TmTcUnixUdpBridge.h +++ b/osal/linux/TmTcUnixUdpBridge.h @@ -20,6 +20,11 @@ public: std::string serverPort = "", std::string clientPort = ""); virtual~ TmTcUnixUdpBridge(); + /** + * Set properties of internal mutex. + */ + void setMutexProperties(MutexIF::TimeoutType timeoutType, dur_millis_t timeoutMs); + ReturnValue_t initialize() override; void checkAndSetClientAddress(sockaddr_in& clientAddress); @@ -43,8 +48,9 @@ private: bool ipAddrAnySet = false; - //! Access to the client address is mutex protected as it is set - //! by another task. + //! Access to the client address is mutex protected as it is set by another task. + MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; + dur_millis_t mutexTimeoutMs = 20; MutexIF* mutex; }; diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index 113c98fb..d2b2b2ec 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -114,9 +114,11 @@ TmTcWinUdpBridge::~TmTcWinUdpBridge() { } ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { - MutexGuard lock(mutex, MutexIF::TimeoutType::WAITING, 10); int flags = 0; + /* The target address can be set by different threads so this lock ensures thread-safety */ + MutexGuard lock(mutex, timeoutType, mutexTimeoutMs); + #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1 clientAddress.sin_addr.s_addr = htons(INADDR_ANY); clientAddressLen = sizeof(serverAddress); @@ -147,7 +149,8 @@ ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { } void TmTcWinUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { - MutexGuard lock(mutex, MutexIF::TimeoutType::WAITING, 10); + /* The target address can be set by different threads so this lock ensures thread-safety */ + MutexGuard lock(mutex, timeoutType, mutexTimeoutMs); #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1 char ipAddress [15]; @@ -165,3 +168,8 @@ void TmTcWinUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { } } +void TmTcWinUdpBridge::setMutexProperties(MutexIF::TimeoutType timeoutType, + dur_millis_t timeoutMs) { + this->timeoutType = timeoutType; + this->mutexTimeoutMs = timeoutMs; +} diff --git a/osal/windows/TmTcWinUdpBridge.h b/osal/windows/TmTcWinUdpBridge.h index 762849f8..5cae308d 100644 --- a/osal/windows/TmTcWinUdpBridge.h +++ b/osal/windows/TmTcWinUdpBridge.h @@ -17,6 +17,11 @@ public: std::string udpServerPort = "", std::string udpClientPort = ""); virtual~ TmTcWinUdpBridge(); + /** + * Set properties of internal mutex. + */ + void setMutexProperties(MutexIF::TimeoutType timeoutType, dur_millis_t timeoutMs); + ReturnValue_t initialize() override; void checkAndSetClientAddress(sockaddr_in& clientAddress); @@ -38,6 +43,8 @@ private: int serverAddressLen = 0; //! Access to the client address is mutex protected as it is set by another task. + MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; + dur_millis_t mutexTimeoutMs = 20; MutexIF* mutex; }; From 2684b0c68e22d10444371f10dadc98c988542d5d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 12 Mar 2021 18:15:16 +0100 Subject: [PATCH 14/17] small doc improvement --- osal/linux/TmTcUnixUdpBridge.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index 8de62cab..cf3c80ec 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -146,7 +146,8 @@ ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { } void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { - MutexGuard lock(mutex, timeoutType, mutexTimeoutMs); + /* The target address can be set by different threads so this lock ensures thread-safety */ + MutexGuard lock(mutex, timeoutType, mutexTimeoutMs); #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 char ipAddress [15]; From 5eb6b277ba4b5b07221005c2b50362c9fadc98bf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 12 Mar 2021 18:20:54 +0100 Subject: [PATCH 15/17] removed unused fields --- osal/windows/TmTcWinUdpBridge.cpp | 13 +++---------- osal/windows/TmTcWinUdpBridge.h | 9 +-------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index d2b2b2ec..8b19b59e 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -11,22 +11,15 @@ const std::string TmTcWinUdpBridge::DEFAULT_UDP_SERVER_PORT = "7301"; const std::string TmTcWinUdpBridge::DEFAULT_UDP_CLIENT_PORT = "7302"; -TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, - object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId, - std::string udpServerPort, std::string udpClientPort): +TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, object_id_t tcDestination, + object_id_t tmStoreId, object_id_t tcStoreId, std::string udpServerPort): TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { if(udpServerPort == "") { - this->udpServerPort = DEFAULT_UDP_SERVER_PORT; + this->udpServerPort = DEFAULT_UDP_SERVER_PORT; } else { this->udpServerPort = udpServerPort; } - if(udpClientPort == "") { - this->udpClientPort = DEFAULT_UDP_CLIENT_PORT; - } - else { - this->udpClientPort = udpClientPort; - } mutex = MutexFactory::instance()->createMutex(); communicationLinkUp = false; diff --git a/osal/windows/TmTcWinUdpBridge.h b/osal/windows/TmTcWinUdpBridge.h index 5cae308d..603f2b08 100644 --- a/osal/windows/TmTcWinUdpBridge.h +++ b/osal/windows/TmTcWinUdpBridge.h @@ -13,8 +13,7 @@ public: static const std::string DEFAULT_UDP_CLIENT_PORT; TmTcWinUdpBridge(object_id_t objectId, object_id_t tcDestination, - object_id_t tmStoreId, object_id_t tcStoreId, - std::string udpServerPort = "", std::string udpClientPort = ""); + object_id_t tmStoreId, object_id_t tcStoreId, std::string udpServerPort = ""); virtual~ TmTcWinUdpBridge(); /** @@ -32,16 +31,10 @@ protected: private: SOCKET serverSocket = 0; std::string udpServerPort; - std::string udpClientPort; - - const int serverSocketOptions = 0; struct sockaddr_in clientAddress; int clientAddressLen = 0; - struct sockaddr_in serverAddress; - int serverAddressLen = 0; - //! Access to the client address is mutex protected as it is set by another task. MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; dur_millis_t mutexTimeoutMs = 20; From 7bc04014e8a7949c8adb1332d6647ff9e63aeca8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 12 Mar 2021 18:21:50 +0100 Subject: [PATCH 16/17] removed more unused fields --- osal/windows/TmTcWinUdpBridge.cpp | 1 - osal/windows/TmTcWinUdpBridge.h | 1 - 2 files changed, 2 deletions(-) diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index 8b19b59e..2dd5699b 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -9,7 +9,6 @@ #define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0 const std::string TmTcWinUdpBridge::DEFAULT_UDP_SERVER_PORT = "7301"; -const std::string TmTcWinUdpBridge::DEFAULT_UDP_CLIENT_PORT = "7302"; TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId, std::string udpServerPort): diff --git a/osal/windows/TmTcWinUdpBridge.h b/osal/windows/TmTcWinUdpBridge.h index 603f2b08..51dcfe99 100644 --- a/osal/windows/TmTcWinUdpBridge.h +++ b/osal/windows/TmTcWinUdpBridge.h @@ -10,7 +10,6 @@ class TmTcWinUdpBridge: public TmTcBridge { public: /* The ports chosen here should not be used by any other process. */ static const std::string DEFAULT_UDP_SERVER_PORT; - static const std::string DEFAULT_UDP_CLIENT_PORT; TmTcWinUdpBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId, std::string udpServerPort = ""); From 703dfe98548398cc2ca52a96a4ecfcad14b4cbf7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 12 Mar 2021 18:30:36 +0100 Subject: [PATCH 17/17] cleaned up a bit, removed unused fields --- osal/common/tcpipCommon.h | 3 ++ osal/linux/TcUnixUdpPollingTask.cpp | 1 - osal/linux/TmTcUnixUdpBridge.cpp | 82 +++++++++++++---------------- osal/linux/TmTcUnixUdpBridge.h | 60 ++++++++++----------- osal/windows/TmTcWinUdpBridge.cpp | 2 +- 5 files changed, 69 insertions(+), 79 deletions(-) diff --git a/osal/common/tcpipCommon.h b/osal/common/tcpipCommon.h index b59981ed..9b38c9fb 100644 --- a/osal/common/tcpipCommon.h +++ b/osal/common/tcpipCommon.h @@ -6,6 +6,9 @@ namespace tcpip { +const char* const DEFAULT_UDP_SERVER_PORT = "7301"; +const char* const DEFAULT_TCP_SERVER_PORT = "7303"; + enum class Protocol { UDP, TCP diff --git a/osal/linux/TcUnixUdpPollingTask.cpp b/osal/linux/TcUnixUdpPollingTask.cpp index 71557069..37dadb76 100644 --- a/osal/linux/TcUnixUdpPollingTask.cpp +++ b/osal/linux/TcUnixUdpPollingTask.cpp @@ -125,7 +125,6 @@ ReturnValue_t TcUnixUdpPollingTask::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index cf3c80ec..2f620849 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -12,25 +12,17 @@ //! Debugging preprocessor define. #define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0 -const std::string TmTcUnixUdpBridge::DEFAULT_UDP_SERVER_PORT = "7301"; -const std::string TmTcUnixUdpBridge::DEFAULT_UDP_CLIENT_PORT = "7302"; +const std::string TmTcUnixUdpBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_UDP_SERVER_PORT; -TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, - object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId, - std::string udpServerPort, std::string udpClientPort): +TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, object_id_t tcDestination, + object_id_t tmStoreId, object_id_t tcStoreId, std::string udpServerPort): TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { if(udpServerPort == "") { - this->udpServerPort = DEFAULT_UDP_SERVER_PORT; + this->udpServerPort = DEFAULT_UDP_SERVER_PORT; } else { this->udpServerPort = udpServerPort; } - if(udpClientPort == "") { - this->udpClientPort = DEFAULT_UDP_CLIENT_PORT; - } - else { - this->udpClientPort = udpClientPort; - } mutex = MutexFactory::instance()->createMutex(); communicationLinkUp = false; @@ -106,43 +98,43 @@ TmTcUnixUdpBridge::~TmTcUnixUdpBridge() { } ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { - int flags = 0; + int flags = 0; - /* The target address can be set by different threads so this lock ensures thread-safety */ - MutexGuard lock(mutex, timeoutType, mutexTimeoutMs); + /* The target address can be set by different threads so this lock ensures thread-safety */ + MutexGuard lock(mutex, timeoutType, mutexTimeoutMs); - if(ipAddrAnySet){ - clientAddress.sin_addr.s_addr = htons(INADDR_ANY); - clientAddressLen = sizeof(serverAddress); - } + if(ipAddrAnySet){ + clientAddress.sin_addr.s_addr = htons(INADDR_ANY); + clientAddressLen = sizeof(clientAddress); + } #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1 char ipAddress [15]; - sif::debug << "IP Address Sender: "<< - inet_ntop(AF_INET,&clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; + sif::debug << "IP Address Sender: "<< + inet_ntop(AF_INET,&clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; #endif - ssize_t bytesSent = sendto( - serverSocket, - data, - dataLen, - flags, - reinterpret_cast(&clientAddress), - clientAddressLen - ); - if(bytesSent < 0) { + ssize_t bytesSent = sendto( + serverSocket, + data, + dataLen, + flags, + reinterpret_cast(&clientAddress), + clientAddressLen + ); + if(bytesSent < 0) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "TmTcUnixUdpBridge::sendTm: Send operation failed." << std::endl; #endif tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SENDTO_CALL); - } + } #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1 - sif::debug << "TmTcUnixUdpBridge::sendTm: " << bytesSent << " bytes were" - " sent." << std::endl; + sif::debug << "TmTcUnixUdpBridge::sendTm: " << bytesSent << " bytes were" + " sent." << std::endl; #endif - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { @@ -151,18 +143,18 @@ void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1 char ipAddress [15]; - sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET, - &newAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; - sif::debug << "IP Address Old: " << inet_ntop(AF_INET, - &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; + sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET, + &newAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; + sif::debug << "IP Address Old: " << inet_ntop(AF_INET, + &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; #endif - registerCommConnect(); + registerCommConnect(); - /* Set new IP address if it has changed. */ - if(clientAddress.sin_addr.s_addr != newAddress.sin_addr.s_addr) { - clientAddress = newAddress; - clientAddressLen = sizeof(clientAddress); - } + /* Set new IP address if it has changed. */ + if(clientAddress.sin_addr.s_addr != newAddress.sin_addr.s_addr) { + clientAddress = newAddress; + clientAddressLen = sizeof(clientAddress); + } } void TmTcUnixUdpBridge::setMutexProperties(MutexIF::TimeoutType timeoutType, @@ -172,6 +164,6 @@ void TmTcUnixUdpBridge::setMutexProperties(MutexIF::TimeoutType timeoutType, } void TmTcUnixUdpBridge::setClientAddressToAny(bool ipAddrAnySet){ - this->ipAddrAnySet = ipAddrAnySet; + this->ipAddrAnySet = ipAddrAnySet; } diff --git a/osal/linux/TmTcUnixUdpBridge.h b/osal/linux/TmTcUnixUdpBridge.h index 26b6f0f7..3ab2118c 100644 --- a/osal/linux/TmTcUnixUdpBridge.h +++ b/osal/linux/TmTcUnixUdpBridge.h @@ -7,51 +7,47 @@ #include #include -class TmTcUnixUdpBridge: public TmTcBridge { - friend class TcUnixUdpPollingTask; +class TmTcUnixUdpBridge: + public TmTcBridge { + friend class TcUnixUdpPollingTask; 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 */ - static const std::string DEFAULT_UDP_SERVER_PORT; - static const std::string DEFAULT_UDP_CLIENT_PORT; + static const std::string DEFAULT_UDP_SERVER_PORT; - TmTcUnixUdpBridge(object_id_t objectId, object_id_t tcDestination, - object_id_t tmStoreId, object_id_t tcStoreId, - std::string serverPort = "", std::string clientPort = ""); - virtual~ TmTcUnixUdpBridge(); + TmTcUnixUdpBridge(object_id_t objectId, object_id_t tcDestination, + object_id_t tmStoreId, object_id_t tcStoreId, + std::string serverPort = ""); + virtual~ TmTcUnixUdpBridge(); - /** - * Set properties of internal mutex. - */ - void setMutexProperties(MutexIF::TimeoutType timeoutType, dur_millis_t timeoutMs); + /** + * Set properties of internal mutex. + */ + void setMutexProperties(MutexIF::TimeoutType timeoutType, dur_millis_t timeoutMs); - ReturnValue_t initialize() override; + ReturnValue_t initialize() override; - void checkAndSetClientAddress(sockaddr_in& clientAddress); + void checkAndSetClientAddress(sockaddr_in& clientAddress); + + void setClientAddressToAny(bool ipAddrAnySet); - void setClientAddressToAny(bool ipAddrAnySet); protected: - virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; + virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; private: - int serverSocket = 0; - std::string udpServerPort; - std::string udpClientPort; + int serverSocket = 0; + std::string udpServerPort; - const int serverSocketOptions = 0; + struct sockaddr_in clientAddress; + socklen_t clientAddressLen = 0; - struct sockaddr_in clientAddress; - socklen_t clientAddressLen = 0; + bool ipAddrAnySet = false; - struct sockaddr_in serverAddress; - socklen_t serverAddressLen = 0; - - bool ipAddrAnySet = false; - - //! Access to the client address is mutex protected as it is set by another task. - MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; - dur_millis_t mutexTimeoutMs = 20; - MutexIF* mutex; + //! Access to the client address is mutex protected as it is set by another task. + MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; + dur_millis_t mutexTimeoutMs = 20; + MutexIF* mutex; }; #endif /* FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ */ diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/windows/TmTcWinUdpBridge.cpp index 2dd5699b..ca0fe2d1 100644 --- a/osal/windows/TmTcWinUdpBridge.cpp +++ b/osal/windows/TmTcWinUdpBridge.cpp @@ -8,7 +8,7 @@ //! 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 = tcpip::DEFAULT_UDP_SERVER_PORT; TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId, std::string udpServerPort):