From 86577f4b80aa8566a5212edd2712e804b279d638 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 21 Mar 2021 12:51:28 +0100 Subject: [PATCH] fixed for linux --- osal/common/TcpIpBase.cpp | 3 +- osal/common/TcpIpBase.h | 1 + osal/common/TcpTmTcServer.cpp | 20 +- osal/common/TcpTmTcServer.h | 6 +- osal/common/UdpTcPollingTask.cpp | 19 +- osal/common/UdpTcPollingTask.h | 4 - osal/common/UdpTmTcBridge.cpp | 8 +- osal/common/UdpTmTcBridge.h | 10 +- osal/linux/CMakeLists.txt | 2 - osal/linux/TcUnixUdpPollingTask.cpp | 304 ++++++++++++------------- osal/linux/TcUnixUdpPollingTask.h | 134 +++++------ osal/linux/TmTcUnixUdpBridge.cpp | 334 ++++++++++++++-------------- osal/linux/TmTcUnixUdpBridge.h | 106 ++++----- 13 files changed, 484 insertions(+), 467 deletions(-) diff --git a/osal/common/TcpIpBase.cpp b/osal/common/TcpIpBase.cpp index 03de81b1..35524743 100644 --- a/osal/common/TcpIpBase.cpp +++ b/osal/common/TcpIpBase.cpp @@ -2,6 +2,7 @@ #ifdef __unix__ +#include #include #endif @@ -21,7 +22,7 @@ int TcpIpBase::closeSocket(socket_t socket) { #ifdef _WIN32 return closesocket(socket); #elif defined(__unix__) - return close(socket) + return close(socket); #endif } diff --git a/osal/common/TcpIpBase.h b/osal/common/TcpIpBase.h index 8da217bc..652d791a 100644 --- a/osal/common/TcpIpBase.h +++ b/osal/common/TcpIpBase.h @@ -9,6 +9,7 @@ #elif defined(__unix__) +#include #endif diff --git a/osal/common/TcpTmTcServer.cpp b/osal/common/TcpTmTcServer.cpp index 320b937d..2da5da95 100644 --- a/osal/common/TcpTmTcServer.cpp +++ b/osal/common/TcpTmTcServer.cpp @@ -5,6 +5,11 @@ #ifdef _WIN32 #include #include + +#elif defined(__unix__) + +#include + #endif const std::string TcpTmTcServer::DEFAULT_TCP_SERVER_PORT = "7301"; @@ -30,7 +35,6 @@ ReturnValue_t TcpTmTcServer::initialize() { struct addrinfo *addrResult = nullptr; struct addrinfo hints = { 0 }; - ZeroMemory(&hints, sizeof (hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; @@ -74,16 +78,15 @@ ReturnValue_t TcpTmTcServer::initialize() { TcpTmTcServer::~TcpTmTcServer() { - closesocket(listenerTcpSocket); - WSACleanup(); + closeSocket(listenerTcpSocket); } ReturnValue_t TcpTmTcServer::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; + socket_t clientSocket; + sockaddr clientSockAddr; + socklen_t connectorSockAddrLen = 0; int retval = 0; /* Listen for connection requests permanently for lifetime of program */ @@ -94,8 +97,7 @@ ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) { continue; } - clientSocket = accept(listenerTcpSocket, reinterpret_cast(&clientSockAddr), - &connectorSockAddrLen); + clientSocket = accept(listenerTcpSocket, &clientSockAddr, &connectorSockAddrLen); if(clientSocket == INVALID_SOCKET) { handleError(Protocol::TCP, ErrorSources::ACCEPT_CALL, 500); @@ -119,7 +121,7 @@ ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) { } /* Done, shut down connection */ - retval = shutdown(clientSocket, SD_SEND); + retval = shutdown(clientSocket, SHUT_SEND); } return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/common/TcpTmTcServer.h b/osal/common/TcpTmTcServer.h index ff6eb610..4dcc77a2 100644 --- a/osal/common/TcpTmTcServer.h +++ b/osal/common/TcpTmTcServer.h @@ -5,6 +5,10 @@ #include "../../objectmanager/SystemObject.h" #include "../../tasks/ExecutableObjectIF.h" +#ifdef __unix__ +#include +#endif + #include #include @@ -36,7 +40,7 @@ private: std::string tcpPort; socket_t listenerTcpSocket = 0; - struct sockaddr_in tcpAddress; + struct sockaddr tcpAddress; int tcpAddrLen = sizeof(tcpAddress); int currentBacklog = 3; diff --git a/osal/common/UdpTcPollingTask.cpp b/osal/common/UdpTcPollingTask.cpp index 506f1c98..3d51e118 100644 --- a/osal/common/UdpTcPollingTask.cpp +++ b/osal/common/UdpTcPollingTask.cpp @@ -3,8 +3,17 @@ #include "../../globalfunctions/arrayprinter.h" #include "../../serviceinterface/ServiceInterfaceStream.h" +#ifdef _WIN32 + #include +#else + +#include +#include + +#endif + //! Debugging preprocessor define. #define FSFW_UDP_RCV_WIRETAPPING_ENABLED 0 @@ -36,17 +45,17 @@ UdpTcPollingTask::~UdpTcPollingTask() {} ReturnValue_t UdpTcPollingTask::performOperation(uint8_t opCode) { /* Sender Address is cached here. */ - struct sockaddr_in senderAddress; - int senderAddressSize = sizeof(senderAddress); + struct sockaddr senderAddress; + socklen_t senderAddressSize = sizeof(senderAddress); /* Poll for new UDP datagrams in permanent loop. */ while(true) { int bytesReceived = recvfrom( - serverUdpSocket, + this->serverSocket, reinterpret_cast(receptionBuffer.data()), frameSize, receptionFlags, - reinterpret_cast(&senderAddress), + &senderAddress, &senderAddressSize ); if(bytesReceived == SOCKET_ERROR) { @@ -138,7 +147,7 @@ ReturnValue_t UdpTcPollingTask::initializeAfterTaskCreation() { targetTcDestination = tmtcBridge->getRequestQueue(); /* The server socket is set up in the bridge intialization. Calling this function here ensures that it is set up regardless of which class was initialized first */ - serverUdpSocket = tmtcBridge->serverSocket; + this->serverSocket = tmtcBridge->serverSocket; return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/common/UdpTcPollingTask.h b/osal/common/UdpTcPollingTask.h index 6b11cc5a..4df62b94 100644 --- a/osal/common/UdpTcPollingTask.h +++ b/osal/common/UdpTcPollingTask.h @@ -54,10 +54,6 @@ private: //! 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. - //! Will be cached shortly after SW intialization. - SOCKET serverUdpSocket = 0; - std::vector receptionBuffer; size_t frameSize = 0; diff --git a/osal/common/UdpTmTcBridge.cpp b/osal/common/UdpTmTcBridge.cpp index be586745..a8975c0e 100644 --- a/osal/common/UdpTmTcBridge.cpp +++ b/osal/common/UdpTmTcBridge.cpp @@ -5,11 +5,13 @@ #include #ifdef _WIN32 + #include #elif defined(__unix__) -#include +#include +#include #endif @@ -135,7 +137,7 @@ ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) { reinterpret_cast(data), dataLen, flags, - reinterpret_cast(&clientAddress), + &clientAddress, clientAddressLen ); if(bytesSent == SOCKET_ERROR) { @@ -151,7 +153,7 @@ ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) { return HasReturnvaluesIF::RETURN_OK; } -void UdpTmTcBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { +void UdpTmTcBridge::checkAndSetClientAddress(sockaddr& newAddress) { /* The target address can be set by different threads so this lock ensures thread-safety */ MutexGuard lock(mutex, timeoutType, mutexTimeoutMs); diff --git a/osal/common/UdpTmTcBridge.h b/osal/common/UdpTmTcBridge.h index fcf2baec..afc8ee98 100644 --- a/osal/common/UdpTmTcBridge.h +++ b/osal/common/UdpTmTcBridge.h @@ -4,6 +4,10 @@ #include "TcpIpBase.h" #include "../../tmtcservices/TmTcBridge.h" +#ifdef __unix__ +#include +#endif + #include class UdpTmTcBridge: @@ -25,7 +29,7 @@ public: ReturnValue_t initialize() override; - void checkAndSetClientAddress(sockaddr_in& clientAddress); + void checkAndSetClientAddress(sockaddr& clientAddress); protected: virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; @@ -33,8 +37,8 @@ protected: private: std::string udpServerPort; - struct sockaddr_in clientAddress; - int clientAddressLen = 0; + struct sockaddr clientAddress; + socklen_t clientAddressLen = 0; //! Access to the client address is mutex protected as it is set by another task. MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; diff --git a/osal/linux/CMakeLists.txt b/osal/linux/CMakeLists.txt index 6c377844..332fe2f4 100644 --- a/osal/linux/CMakeLists.txt +++ b/osal/linux/CMakeLists.txt @@ -13,8 +13,6 @@ target_sources(${LIB_FSFW_NAME} QueueFactory.cpp SemaphoreFactory.cpp TaskFactory.cpp - TcUnixUdpPollingTask.cpp - TmTcUnixUdpBridge.cpp Timer.cpp tcpipHelpers.cpp ) diff --git a/osal/linux/TcUnixUdpPollingTask.cpp b/osal/linux/TcUnixUdpPollingTask.cpp index 37dadb76..ec3687b9 100644 --- a/osal/linux/TcUnixUdpPollingTask.cpp +++ b/osal/linux/TcUnixUdpPollingTask.cpp @@ -1,152 +1,152 @@ -#include "TcUnixUdpPollingTask.h" -#include "tcpipHelpers.h" - -#include "../../globalfunctions/arrayprinter.h" - -#define FSFW_UDP_RCV_WIRETAPPING_ENABLED 0 - -TcUnixUdpPollingTask::TcUnixUdpPollingTask(object_id_t objectId, - object_id_t tmtcUnixUdpBridge, size_t frameSize, - double timeoutSeconds): SystemObject(objectId), - tmtcBridgeId(tmtcUnixUdpBridge) { - - if(frameSize > 0) { - this->frameSize = frameSize; - } - else { - 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! */ - receptionBuffer.reserve(this->frameSize); - receptionBuffer.resize(this->frameSize); - - if(timeoutSeconds == -1) { - receptionTimeout = DEFAULT_TIMEOUT; - } - else { - receptionTimeout = timevalOperations::toTimeval(timeoutSeconds); - } -} - -TcUnixUdpPollingTask::~TcUnixUdpPollingTask() {} - -ReturnValue_t TcUnixUdpPollingTask::performOperation(uint8_t opCode) { - /* 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 && 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->checkAndSetClientAddress(senderAddress); - } - return HasReturnvaluesIF::RETURN_OK; -} - - -ReturnValue_t TcUnixUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { - store_address_t storeId; - -#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 << "TcUnixUdpPollingTask::handleSuccessfullTcRead: Data " - "storage failed" << std::endl; - sif::error << "Packet size: " << bytesRead << std::endl; -#else -#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ -#endif /* FSFW_VERBOSE_LEVEL >= 1 */ - return HasReturnvaluesIF::RETURN_FAILED; - } - - TmTcMessage message(storeId); - - result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message); - if (result != HasReturnvaluesIF::RETURN_OK) { -#if FSFW_VERBOSE_LEVEL >= 1 -#if FSFW_CPP_OSTREAM_ENABLED == 1 - 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; -} - -ReturnValue_t TcUnixUdpPollingTask::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; -#endif - return ObjectManagerIF::CHILD_INIT_FAILED; - } - - tmtcBridge = objectManager->get(tmtcBridgeId); - if(tmtcBridge == nullptr) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TcSocketPollingTask::TcSocketPollingTask: Invalid" - " TMTC bridge object!" << std::endl; -#endif - return ObjectManagerIF::CHILD_INIT_FAILED; - } - - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t TcUnixUdpPollingTask::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; -} - -void TcUnixUdpPollingTask::setTimeout(double timeoutSeconds) { - timeval tval; - tval = timevalOperations::toTimeval(timeoutSeconds); - int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO, - &tval, sizeof(receptionTimeout)); - if(result == -1) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TcSocketPollingTask::TcSocketPollingTask: Setting " - "receive timeout failed with " << strerror(errno) << std::endl; -#endif - } -} +//#include "TcUnixUdpPollingTask.h" +//#include "tcpipHelpers.h" +// +//#include "../../globalfunctions/arrayprinter.h" +// +//#define FSFW_UDP_RCV_WIRETAPPING_ENABLED 0 +// +//TcUnixUdpPollingTask::TcUnixUdpPollingTask(object_id_t objectId, +// object_id_t tmtcUnixUdpBridge, size_t frameSize, +// double timeoutSeconds): SystemObject(objectId), +// tmtcBridgeId(tmtcUnixUdpBridge) { +// +// if(frameSize > 0) { +// this->frameSize = frameSize; +// } +// else { +// 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! */ +// receptionBuffer.reserve(this->frameSize); +// receptionBuffer.resize(this->frameSize); +// +// if(timeoutSeconds == -1) { +// receptionTimeout = DEFAULT_TIMEOUT; +// } +// else { +// receptionTimeout = timevalOperations::toTimeval(timeoutSeconds); +// } +//} +// +//TcUnixUdpPollingTask::~TcUnixUdpPollingTask() {} +// +//ReturnValue_t TcUnixUdpPollingTask::performOperation(uint8_t opCode) { +// /* 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 && 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->checkAndSetClientAddress(senderAddress); +// } +// return HasReturnvaluesIF::RETURN_OK; +//} +// +// +//ReturnValue_t TcUnixUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { +// store_address_t storeId; +// +//#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 << "TcUnixUdpPollingTask::handleSuccessfullTcRead: Data " +// "storage failed" << std::endl; +// sif::error << "Packet size: " << bytesRead << std::endl; +//#else +//#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +//#endif /* FSFW_VERBOSE_LEVEL >= 1 */ +// return HasReturnvaluesIF::RETURN_FAILED; +// } +// +// TmTcMessage message(storeId); +// +// result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message); +// if (result != HasReturnvaluesIF::RETURN_OK) { +//#if FSFW_VERBOSE_LEVEL >= 1 +//#if FSFW_CPP_OSTREAM_ENABLED == 1 +// 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; +//} +// +//ReturnValue_t TcUnixUdpPollingTask::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; +//#endif +// return ObjectManagerIF::CHILD_INIT_FAILED; +// } +// +// tmtcBridge = objectManager->get(tmtcBridgeId); +// if(tmtcBridge == nullptr) { +//#if FSFW_CPP_OSTREAM_ENABLED == 1 +// sif::error << "TcSocketPollingTask::TcSocketPollingTask: Invalid" +// " TMTC bridge object!" << std::endl; +//#endif +// return ObjectManagerIF::CHILD_INIT_FAILED; +// } +// +// return HasReturnvaluesIF::RETURN_OK; +//} +// +//ReturnValue_t TcUnixUdpPollingTask::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; +//} +// +//void TcUnixUdpPollingTask::setTimeout(double timeoutSeconds) { +// timeval tval; +// tval = timevalOperations::toTimeval(timeoutSeconds); +// int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO, +// &tval, sizeof(receptionTimeout)); +// if(result == -1) { +//#if FSFW_CPP_OSTREAM_ENABLED == 1 +// sif::error << "TcSocketPollingTask::TcSocketPollingTask: Setting " +// "receive timeout failed with " << strerror(errno) << std::endl; +//#endif +// } +//} diff --git a/osal/linux/TcUnixUdpPollingTask.h b/osal/linux/TcUnixUdpPollingTask.h index 39ee0914..1040d1a2 100644 --- a/osal/linux/TcUnixUdpPollingTask.h +++ b/osal/linux/TcUnixUdpPollingTask.h @@ -1,67 +1,67 @@ -#ifndef FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ -#define FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ - -#include "../../objectmanager/SystemObject.h" -#include "../../osal/linux/TmTcUnixUdpBridge.h" -#include "../../tasks/ExecutableObjectIF.h" - -#include -#include - -/** - * @brief This class can be used to implement the polling of a Unix socket, - * using UDP for now. - * @details - * The task will be blocked while the specified number of bytes has not been - * received, so TC reception is handled inside a separate task. - * This class caches the IP address of the sender. It is assumed there - * is only one sender for now. - */ -class TcUnixUdpPollingTask: public SystemObject, - public ExecutableObjectIF { - friend class TmTcUnixUdpBridge; -public: - static constexpr size_t DEFAULT_MAX_FRAME_SIZE = 2048; - //! 0.5 default milliseconds timeout for now. - static constexpr timeval DEFAULT_TIMEOUT = {.tv_sec = 0, .tv_usec = 500}; - - TcUnixUdpPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, - size_t frameSize = 0, double timeoutSeconds = -1); - virtual~ TcUnixUdpPollingTask(); - - /** - * Turn on optional timeout for UDP polling. In the default mode, - * the receive function will block until a packet is received. - * @param timeoutSeconds - */ - void setTimeout(double timeoutSeconds); - - virtual ReturnValue_t performOperation(uint8_t opCode) override; - virtual ReturnValue_t initialize() override; - virtual ReturnValue_t initializeAfterTaskCreation() override; - -protected: - StorageManagerIF* tcStore = nullptr; - -private: - //! TMTC bridge is cached. - 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; - - //! Server socket, which is member of TMTC bridge and is assigned in - //! constructor - int serverUdpSocket = 0; - - std::vector receptionBuffer; - - size_t frameSize = 0; - timeval receptionTimeout; - - ReturnValue_t handleSuccessfullTcRead(size_t bytesRead); -}; - -#endif /* FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ */ +//#ifndef FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ +//#define FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ +// +//#include "../../objectmanager/SystemObject.h" +//#include "../../osal/linux/TmTcUnixUdpBridge.h" +//#include "../../tasks/ExecutableObjectIF.h" +// +//#include +//#include +// +///** +// * @brief This class can be used to implement the polling of a Unix socket, +// * using UDP for now. +// * @details +// * The task will be blocked while the specified number of bytes has not been +// * received, so TC reception is handled inside a separate task. +// * This class caches the IP address of the sender. It is assumed there +// * is only one sender for now. +// */ +//class TcUnixUdpPollingTask: public SystemObject, +// public ExecutableObjectIF { +// friend class TmTcUnixUdpBridge; +//public: +// static constexpr size_t DEFAULT_MAX_FRAME_SIZE = 2048; +// //! 0.5 default milliseconds timeout for now. +// static constexpr timeval DEFAULT_TIMEOUT = {.tv_sec = 0, .tv_usec = 500}; +// +// TcUnixUdpPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, +// size_t frameSize = 0, double timeoutSeconds = -1); +// virtual~ TcUnixUdpPollingTask(); +// +// /** +// * Turn on optional timeout for UDP polling. In the default mode, +// * the receive function will block until a packet is received. +// * @param timeoutSeconds +// */ +// void setTimeout(double timeoutSeconds); +// +// virtual ReturnValue_t performOperation(uint8_t opCode) override; +// virtual ReturnValue_t initialize() override; +// virtual ReturnValue_t initializeAfterTaskCreation() override; +// +//protected: +// StorageManagerIF* tcStore = nullptr; +// +//private: +// //! TMTC bridge is cached. +// 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; +// +// //! Server socket, which is member of TMTC bridge and is assigned in +// //! constructor +// int serverUdpSocket = 0; +// +// std::vector receptionBuffer; +// +// size_t frameSize = 0; +// timeval receptionTimeout; +// +// ReturnValue_t handleSuccessfullTcRead(size_t bytesRead); +//}; +// +//#endif /* FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ */ diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index fa7913ea..c0cd6877 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -1,167 +1,167 @@ -#include "TmTcUnixUdpBridge.h" -#include "tcpipHelpers.h" -#include "../../serviceinterface/ServiceInterface.h" -#include "../../ipc/MutexGuard.h" - -#include -#include -#include - -#include - -//! Debugging preprocessor define. -#define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0 - -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): - TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { - if(udpServerPort == "") { - this->udpServerPort = DEFAULT_UDP_SERVER_PORT; - } - else { - this->udpServerPort = udpServerPort; - } - - mutex = MutexFactory::instance()->createMutex(); - communicationLinkUp = false; -} - -ReturnValue_t TmTcUnixUdpBridge::initialize() { - using namespace tcpip; - - ReturnValue_t result = TmTcBridge::initialize(); - if(result != HasReturnvaluesIF::RETURN_OK) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmTcUnixUdpBridge::initialize: TmTcBridge initialization failed!" - << std::endl; -#endif - return result; - } - - struct addrinfo *addrResult = nullptr; - struct addrinfo hints; - - 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; - - /* 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::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Retrieving address info failed!" << - std::endl; -#endif - 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); - return HasReturnvaluesIF::RETURN_FAILED; - } - - retval = bind(serverSocket, addrResult->ai_addr, static_cast(addrResult->ai_addrlen)); - if(retval != 0) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not bind " - "local port (" << udpServerPort << ") to server socket!" << std::endl; -#endif - freeaddrinfo(addrResult); - handleError(Protocol::UDP, ErrorSources::BIND_CALL); - return HasReturnvaluesIF::RETURN_FAILED; - } - - 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) { - int flags = 0; - - /* 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(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; -#endif - - 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; -#endif - - return HasReturnvaluesIF::RETURN_OK; -} - -void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { - /* 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]; - 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 to reply to. */ - clientAddress = newAddress; - clientAddressLen = sizeof(clientAddress); -} - -void TmTcUnixUdpBridge::setMutexProperties(MutexIF::TimeoutType timeoutType, - dur_millis_t timeoutMs) { - this->timeoutType = timeoutType; - this->mutexTimeoutMs = timeoutMs; -} - -void TmTcUnixUdpBridge::setClientAddressToAny(bool ipAddrAnySet){ - this->ipAddrAnySet = ipAddrAnySet; -} - +//#include "TmTcUnixUdpBridge.h" +//#include "tcpipHelpers.h" +//#include "../../serviceinterface/ServiceInterface.h" +//#include "../../ipc/MutexGuard.h" +// +//#include +//#include +//#include +// +//#include +// +////! Debugging preprocessor define. +//#define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0 +// +//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): +// TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { +// if(udpServerPort == "") { +// this->udpServerPort = DEFAULT_UDP_SERVER_PORT; +// } +// else { +// this->udpServerPort = udpServerPort; +// } +// +// mutex = MutexFactory::instance()->createMutex(); +// communicationLinkUp = false; +//} +// +//ReturnValue_t TmTcUnixUdpBridge::initialize() { +// using namespace tcpip; +// +// ReturnValue_t result = TmTcBridge::initialize(); +// if(result != HasReturnvaluesIF::RETURN_OK) { +//#if FSFW_CPP_OSTREAM_ENABLED == 1 +// sif::error << "TmTcUnixUdpBridge::initialize: TmTcBridge initialization failed!" +// << std::endl; +//#endif +// return result; +// } +// +// struct addrinfo *addrResult = nullptr; +// struct addrinfo hints; +// +// 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; +// +// /* 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::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Retrieving address info failed!" << +// std::endl; +//#endif +// 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); +// return HasReturnvaluesIF::RETURN_FAILED; +// } +// +// retval = bind(serverSocket, addrResult->ai_addr, static_cast(addrResult->ai_addrlen)); +// if(retval != 0) { +//#if FSFW_CPP_OSTREAM_ENABLED == 1 +// sif::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not bind " +// "local port (" << udpServerPort << ") to server socket!" << std::endl; +//#endif +// freeaddrinfo(addrResult); +// handleError(Protocol::UDP, ErrorSources::BIND_CALL); +// return HasReturnvaluesIF::RETURN_FAILED; +// } +// +// 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) { +// int flags = 0; +// +// /* 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(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; +//#endif +// +// 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; +//#endif +// +// return HasReturnvaluesIF::RETURN_OK; +//} +// +//void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) { +// /* 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]; +// 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 to reply to. */ +// clientAddress = newAddress; +// clientAddressLen = sizeof(clientAddress); +//} +// +//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 3ab2118c..b4b00950 100644 --- a/osal/linux/TmTcUnixUdpBridge.h +++ b/osal/linux/TmTcUnixUdpBridge.h @@ -1,53 +1,53 @@ -#ifndef FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ -#define FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ - -#include "../../tmtcservices/AcceptsTelecommandsIF.h" -#include "../../tmtcservices/TmTcBridge.h" -#include -#include -#include - -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 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 = ""); - 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); - - void setClientAddressToAny(bool ipAddrAnySet); - -protected: - virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; - -private: - int serverSocket = 0; - std::string udpServerPort; - - struct sockaddr_in clientAddress; - socklen_t clientAddressLen = 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; -}; - -#endif /* FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ */ +//#ifndef FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ +//#define FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ +// +//#include "../../tmtcservices/AcceptsTelecommandsIF.h" +//#include "../../tmtcservices/TmTcBridge.h" +//#include +//#include +//#include +// +//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 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 = ""); +// 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); +// +// void setClientAddressToAny(bool ipAddrAnySet); +// +//protected: +// virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; +// +//private: +// int serverSocket = 0; +// std::string udpServerPort; +// +// struct sockaddr_in clientAddress; +// socklen_t clientAddressLen = 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; +//}; +// +//#endif /* FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ */